TestUseAsDictionary.cpp (6419B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include <ostream> 6 7 #include "gtest/gtest-param-test.h" 8 #include "gtest/gtest.h" 9 10 #include "mozilla/gtest/MozAssertions.h" 11 #include "nsNetUtil.h" 12 13 using namespace mozilla::net; 14 15 struct TestData { 16 bool mResult; 17 const nsCString mHeader; 18 // output to match: 19 const nsCString mMatchVal; 20 const nsCString mMatchIdVal; 21 const nsCString mTypeVal; 22 // matchDestVal ends with ""_ns 23 const nsCString mMatchDestVal[5]; 24 }; 25 26 TEST(TestUseAsDictionary, Match) 27 { 28 // Note: we're not trying to test Structured Fields 29 // (https://datatracker.ietf.org/doc/html/rfc8941) here, but the data within 30 // it, so generally we aren't looking for format errors 31 const struct TestData gTestArray[] = { 32 {true, 33 "match=\"/app/*/main.js\""_ns, 34 "/app/*/main.js"_ns, 35 ""_ns, 36 ""_ns, 37 {""_ns}}, 38 {true, 39 "match=\"/app/*/main.js\", id=\"some_id\""_ns, 40 "/app/*/main.js"_ns, 41 "some_id"_ns, 42 ""_ns, 43 {""_ns}}, 44 // match= is required 45 {false, "id=\"some_id\""_ns, ""_ns, "some_id"_ns, ""_ns, {""_ns}}, 46 {true, 47 "match=\"/app/*/main.js\", id=\"some_id\", type=raw"_ns, 48 "/app/*/main.js"_ns, 49 "some_id"_ns, 50 "raw"_ns, 51 {""_ns}}, 52 // only raw is supported for type 53 {false, 54 "match=\"/app/*/main.js\", id=\"some_id\", type=not_raw"_ns, 55 "/app/*/main.js"_ns, 56 "some_id"_ns, 57 "raw"_ns, 58 {""_ns}}, 59 {true, 60 "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\")"_ns, 61 "/app/*/main.js"_ns, 62 "some_id"_ns, 63 ""_ns, 64 {"style"_ns, ""_ns}}, 65 {true, 66 "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\"), type=raw"_ns, 67 "/app/*/main.js"_ns, 68 "some_id"_ns, 69 "raw"_ns, 70 {"style"_ns, ""_ns}}, 71 {true, 72 "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\" \"document\"), type=raw"_ns, 73 "/app/*/main.js"_ns, 74 "some_id"_ns, 75 "raw"_ns, 76 {"style"_ns, "document"_ns, ""_ns}}, 77 // adding the comma after style is a syntax error for structured fields 78 {false, 79 "match=\"/app/*/main.js\", id=\"some_id\", match-dest=(\"style\", \"document\"), type=raw"_ns, 80 "/app/*/main.js"_ns, 81 "some_id"_ns, 82 "raw"_ns, 83 {"style"_ns, "document"_ns, ""_ns}}, 84 // --- Additional tests for spec compliance and edge cases --- 85 // 1. Missing quotes around match value 86 {false, 87 "match=/app/*/main.js, id=\"id1\""_ns, 88 ""_ns, 89 "id1"_ns, 90 ""_ns, 91 {""_ns}}, 92 // 2. Extra unknown parameter 93 {true, 94 "match=\"/foo.js\", foo=bar"_ns, 95 "/foo.js"_ns, 96 ""_ns, 97 ""_ns, 98 {""_ns}}, 99 // 3. Whitespace variations 100 {true, 101 " match=\"/foo.js\" , id=\"id2\" "_ns, 102 "/foo.js"_ns, 103 "id2"_ns, 104 ""_ns, 105 {""_ns}}, 106 // 4. Empty match value 107 {false, "match=\"\""_ns, ""_ns, ""_ns, ""_ns, {""_ns}}, 108 // 5. Duplicate match parameter (should use the last) 109 {true, 110 "match=\"/foo.js\", match=\"/bar.js\""_ns, 111 "/bar.js"_ns, 112 ""_ns, 113 ""_ns, 114 {""_ns}}, 115 // 6. Duplicate id parameter (should use the last) 116 {true, 117 "match=\"/foo.js\", id=\"id1\", id=\"id2\""_ns, 118 "/foo.js"_ns, 119 "id2"_ns, 120 ""_ns, 121 {""_ns}}, 122 // 7. Parameter order: id before match 123 {true, 124 "id=\"id3\", match=\"/foo.js\""_ns, 125 "/foo.js"_ns, 126 "id3"_ns, 127 ""_ns, 128 {""_ns}}, 129 // 8. Non-raw type (should fail) 130 {false, 131 "match=\"/foo.js\", type=compressed"_ns, 132 "/foo.js"_ns, 133 ""_ns, 134 "raw"_ns, 135 {""_ns}}, 136 // 9. Empty header 137 {false, ""_ns, ""_ns, ""_ns, ""_ns, {""_ns}}, 138 // 10. match-dest with empty list 139 {true, 140 "match=\"/foo.js\", match-dest=()"_ns, 141 "/foo.js"_ns, 142 ""_ns, 143 ""_ns, 144 {""_ns}}, 145 // 11. match-dest with whitespace and multiple values 146 {true, 147 "match=\"/foo.js\", match-dest=( \"a\" \"b\" )"_ns, 148 "/foo.js"_ns, 149 ""_ns, 150 ""_ns, 151 {"a"_ns, "b"_ns, ""_ns}}, 152 // 12. match-dest with invalid value (missing quotes) 153 {false, 154 "match=\"/foo.js\", match-dest=(a)"_ns, 155 "/foo.js"_ns, 156 ""_ns, 157 ""_ns, 158 {""_ns}}, 159 // 13. match-dest with duplicate values 160 {true, 161 "match=\"/foo.js\", match-dest=(\"a\" \"a\")"_ns, 162 "/foo.js"_ns, 163 ""_ns, 164 ""_ns, 165 {"a"_ns, "a"_ns, ""_ns}}, 166 // 14. Case sensitivity: type=RAW (should fail, only 'raw' allowed) 167 {false, 168 "match=\"/foo.js\", type=RAW"_ns, 169 "/foo.js"_ns, 170 ""_ns, 171 "raw"_ns, 172 {""_ns}}, 173 174 // Note: Structured Fields requires all input to be ASCII 175 176 // 18. match-dest with trailing whitespace 177 {true, 178 "match=\"/foo.js\", match-dest=(\"a\" )"_ns, 179 "/foo.js"_ns, 180 ""_ns, 181 ""_ns, 182 {"a"_ns, ""_ns}}, 183 // 19. match-dest with only whitespace in list (should be empty) 184 {true, 185 "match=\"/foo.js\", match-dest=( )"_ns, 186 "/foo.js"_ns, 187 ""_ns, 188 ""_ns, 189 {""_ns}}, 190 // 20. match-dest with comma and whitespace (invalid) 191 {false, 192 "match=\"/foo.js\", match-dest=(\"a\", \"b\")"_ns, 193 "/foo.js"_ns, 194 ""_ns, 195 ""_ns, 196 {"a"_ns, "b"_ns, ""_ns}}, 197 }; 198 199 for (auto& test : gTestArray) { 200 nsCString match, matchId, type; 201 nsTArray<nsCString> matchDest; 202 nsTArray<nsCString> matchDestVal; 203 204 for (auto& dest : test.mMatchDestVal) { 205 if (dest.IsEmpty()) { 206 break; 207 } 208 matchDestVal.AppendElement(dest); 209 } 210 211 fprintf(stderr, "Testing %s\n", test.mHeader.get()); 212 ASSERT_EQ( 213 NS_ParseUseAsDictionary(test.mHeader, match, matchId, matchDest, type), 214 test.mResult); 215 216 if (test.mResult) { 217 ASSERT_EQ(match, test.mMatchVal); 218 ASSERT_EQ(matchId, test.mMatchIdVal); 219 ASSERT_EQ(matchDest.Length(), matchDestVal.Length()); 220 for (size_t i = 0; i < matchDest.Length(); i++) { 221 ASSERT_EQ(matchDest[i], matchDestVal[i]); 222 } 223 ASSERT_EQ(type, test.mTypeVal); 224 } 225 } 226 }