blob: 8b83969bbc15809a248a7d136ca5ac48037c5a9c [file] [log] [blame]
Andrew Top61a84952019-04-30 15:07:33 -07001<!DOCTYPE html>
2<html>
3 <head>
4 <title>app:URI compliance tests</title>
5 <script src='resources/testharness.js'></script>
6 <script src='resources/testharnessreport.js'></script>
7 <link rel='stylesheet' href='resource/testharness.css'>
8 <link rel="help" href="http://app-uri.sysapps.org/" data-tested-assertations="following::OL[1]/LI[2]" />
9 <style>
10 div {padding:5px 5px 10px 5px;}
11 </style>
12 </head>
13 <body>
14 <div id="logs"></div>
15 <div id="log"></div>
16
17
18 <script>
19 /**********************************************************************************************
20 * This test suite checks your implementation for compliance with the app-URI specification *
21 **********************************************************************************************/
22
23 /* Check if protocol is "app" */
24 if (window.location.protocol === "app:") {
25
26 /* Logging current domain */
27 var domain = window.location.protocol + "//" + window.location.host + "/";
28 document.getElementById("logs").innerHTML = "Current domain: " + domain;
29
30 /* Function that will change HOST value if it is equal to currect application host */
31 function ChangeHostIfEqCurrent(URI){
32 /* Check if URI host is NOT the same as current application host */
33 if (URI.substring(6, 35) === window.location.host) {
34 if (URI.substring(6, 7) !== 4)
35 URI = URI.replace(URI.substring(6, 7), "4");
36 else
37 URI = URI.replace(URI.substring(6, 7), "5");
38 }
39 return URI;
40 }
41
42 /********************************************************
43 * 6.1 Synthesizing an app: URI
44 *
45 * link: http://app-uri.sysapps.org/#synthesizing
46 *
47 ********************************************************/
48
49 /**
50 * Syntax-Based Normalization
51 *
52 * rules for dereferencing an app: URI => 3. Let URI be the value of the [HTTP] Request URI.
53 */
54
55 var TC_name = "Test: Synthesizing an app:URI. Syntax-Based Normalization";
56
57 // variable needed to test scheme-based normalization
58 var tmp_domain = window.location.protocol + "//" + window.location.host;
59
60 var CaseNormalizationXHRtests = [ /* scheme: [ TC name, URI] */
61 [TC_name + " XHR full path: {} => %7b%7d",
62 domain + 'resources/ExamPLE/%7bmY%7d/z...z/index.html'],
63 [TC_name + " XHR full path: } => %7D",
64 domain + 'resources/ExamPLE/%7bmY%7D/z...z/index.html'],
65 [TC_name + " XHR full path: {} => %7B%7D",
66 domain + 'resources/ExamPLE/%7BmY%7D/z...z/index.html'],
67 [TC_name + " XHR full path: Capital letters in patch",
68 domain + 'resources/ExamPLE/mmY/index.html'],
69 [TC_name + " XHR relative path: {} => %7b%7d",
70 'resources/ExamPLE/%7bmY%7d/z...z/index.html'],
71 [TC_name + " XHR relative path: } => %7D",
72 'resources/ExamPLE/%7bmY%7D/z...z/index.html'],
73 [TC_name + " XHR relative path: P. => %50%2e",
74 'resources/Exam%50LE/%7bmY%7d/z%2e..z/index.html'],
75 [TC_name + " XHR relative path: Capital letters in patch",
76 'resources/ExamPLE/mmY/index.html'],
77 [TC_name + " XHR relative path: ~ => ~",
78 'resources/ImaGes/~t/{!a}/~sth.png'],
79 [TC_name + " XHR relative path: ~{} => ~%7b%7d",
80 'resources/ImaGes/~t/%7b!a%7d/~sth.png'],
81
82 /* Percent-Encoding Normalization*/
83 [TC_name + " Percent-Encoding Normalization - XHR full path: c. => %63%2e",
84 domain + 'resources/ExamPLE/%7bmY%7d/z%2e..z/index.html'],
85 [TC_name + " Percent-Encoding Normalization - XHR full path: P. => %50%2e",
86 domain + 'resources/Exam%50LE/%7bmY%7d/z%2e..z/index.html'],
87 [TC_name + " Percent-Encoding Normalization - XHR relative path: {} => %7B%7D",
88 'resources/ExamPLE/%7BmY%7D/z...z/index.html'],
89 [TC_name + " Percent-Encoding Normalization - XHR relative path: c. => %63%2e",
90 'resources/ExamPLE/%7bmY%7d/z%2e..z/index.html'],
91 [TC_name + " XHR relative path: ~{} => ~%7b%7d",
92 'resources/ImaGes/~t/%7b!a%7d/~sth.png'],
93
94 /* Path Segment Normalization */
95 [TC_name + " Path Segment Normalization: using '../..' in path ",
96 'resources/ExamPLE/mmY/../../ImaGes/~t/%7b!a%7d/~sth.png'],
97
98 /* Scheme-Based Normalization */
99 [TC_name + " Scheme-Based Normalization: domain:/",
100 tmp_domain + ':/resources/ImaGes/~t/%7b!a%7d/~sth.png']
101 ];
102
103 CaseNormalizationXHRtests.forEach(function (data, i) {
104 var name = data[0];
105 var URI = data[1];
106 var xhrTest = async_test(name + " [case " + i + "]");
107 var xhr;
108 xhrTest.step(function () {
109 xhr = new XMLHttpRequest();
110 xhr.open("GET", URI, true);
111 xhr.onreadystatechange = xhrTest.step_func(function (ev) {
112 if (xhr.readyState === 4 && xhr.status === 200) {
113 assert_true(true);
114 xhrTest.done();
115 }
116 if (xhr.readyState !== 4 && xhr.status !== 200 && xhr.status !== 0) {
117 assert_true(false,
118 "[ Error: readyState=" + xhr.readyState + " satus=" + xhr.status + "] ");
119 }
120 });
121 xhr.send();
122 });
123 delete name, URI, xhr, xhrTest;
124 });
125 delete CaseNormalizationXHRtests;
126
127
128 /**
129 * ContentType response
130 *
131 * rules for dereferencing an app: URI =>
132 8. Let potential-file be the result of attempting locate the file at path
133 */
134
135 TC_name = "Test: [HTTP] 200 response status (OK),value of content-type as the [HTTP] ";
136 TC_name += "Content-Type header, and the contents of potential-file as the response body";
137
138 var ContentTypeResponsetests = [ /* scheme:[ TC name, URI, content-type] */
139 [TC_name + ' [text/html]', 'resources/ExamPLE/mmY/index.html', 'text/html'],
140 [TC_name + " [image/png]", 'resources/ImaGes/~t/%7b!a%7d/~sth.png', "image/png"],
141 [TC_name + " [text/plain]", 'resources/ExamPLE/mmY/sth.txt', "text/plain"]
142 ];
143
144 ContentTypeResponsetests.forEach(function (data, i) {
145 var name = data[0];
146 var URI = data[1];
147 var content_type = data[2];
148 var xhrTest = async_test(name + " [case " + i + "]");
149 var xhr;
150 xhrTest.step(function () {
151 xhr = new XMLHttpRequest();
152 xhr.open("GET", URI, true);
153 xhr.onreadystatechange = xhrTest.step_func(function (ev) {
154 if (xhr.readyState === 4 && xhr.status === 200) {
155 assert_true(xhr.getResponseHeader("Content-Type") === content_type,
156 "[Content-Type does not mach with expected, it is: "
157 + xhr.getResponseHeader("Content-Type") + "]");
158
159 xhrTest.done();
160 }
161 if (xhr.readyState !== 4 && xhr.status !== 200 && xhr.status !== 0) {
162 assert_true(false,
163 "[ Error: readyState=" + xhr.readyState + " satus=" + xhr.status + "] ");
164 }
165 });
166 xhr.send();
167 });
168 delete name, URI, xhr, xhrTest, content_type;
169 });
170 delete ContentTypeResponsetests;
171
172
173 /**
174 * Case Normalization in Path
175 *
176 * rules for dereferencing an app: URI =>
177 4. Resolve URI into an absolute URL using the document's origin as the base.
178 * rules for dereferencing an app: URI => 7. Let path be the path component of URI.
179 *
180 * Character Normalization in domain name
181 */
182
183
184
185 TC_name = "Test: Synthesizing an app:URI. Syntax-Based Normalization: Case Normalization";
186 var PathCaseNormalizationtests = [ /* scheme: [ TC name, URI] */
187 [TC_name, "resources/ImaGes/{{a}}/Test_1/$a/sth34!.png",
188 domain + "resources/ImaGes/%7B%7Ba%7D%7D/Test_1/$a/sth34!.png", true],
189 [TC_name, "resources/ImaGes/{{a}}/Test_1/$a/sth34!.png",
190 domain + "resources/ImaGes/%7b%7Ba%7D%7D/Test_1/$a/sth34!.png", false],
191
192 /* Character Normalization in Domain */
193 [TC_name, window.location.protocol + "//" + window.location.host.toUpperCase()
194 + "/resources/ImaGes/{{a}}/Test_1/$a/sth34!.png",
195 domain + "resources/ImaGes/%7B%7Ba%7D%7D/Test_1/$a/sth34!.png", true]
196 ];
197
198 PathCaseNormalizationtests.forEach(function (data, i) {
199 var name = data[0];
200 var elem_path = data[1];
201 var path_expected = data[2];
202 var expected = data[3];
203 test(function () {
204 var img = document.createElement("img");
205 img.src = elem_path;
206 if (expected)
207 assert_true(img.src === path_expected,
208 "[Error, path=" + img.src + " Expected=" + domain + path_expected + "]");
209 else
210 assert_false(img.src === path_expected,
211 "[Error, path=" + img.src + " Expected=" + domain + path_expected + "]");
212 delete img;
213
214 }, name + " [case " + i + "]");
215 delete elem_path, path_expected, expected, name;
216 });
217 delete PathCaseNormalizationtests;
218
219
220
221
222 /********************************************************************************************
223 * 6.4 Dereferencing and retrieval of files from a container
224 *
225 * link: http://app-uri.sysapps.org/#dereferencing-and-retrieval-of-files-from-a-container
226 *
227 ********************************************************************************************/
228
229
230
231 /**
232 * 501 Method Not Implemented error - response body MUST be empty
233 *
234 * rules for dereferencing an app: URI =>
235 1. If the request is not a [HTTP] GET request,
236 return a [HTTP] 501 Not Implemented response and terminate this algorithm.
237 */
238
239
240 function Get_501_reponse(name, URI, expected_response) {
241 var xhrTest = async_test(name);
242 xhrTest.step(function () {
243 var xhr = new XMLHttpRequest();
244 /* on purpose wrong method "gett" instead of "get" was used */
245 xhr.open("gett", URI, true);
246 xhr.onreadystatechange = xhrTest.step_func(function (ev) {
247 if (xhr.readyState !== 4 && xhr.status === 501) {
248 assert_true(xhr.response === expected_response,
249 "[" + xhr.status + " error, response:[" + xhr.response + "] " + "]");
250
251 xhrTest.done();
252 }
253 if (xhr.readyState === 4 && xhr.status === 200) {
254 assert_true(false,
255 "[Should get 501 but got 200 OK, "
256 +"file found while it should not find it, "
257 +" non existing 'gett' method used");
258 }
259 });
260 xhr.send();
261 });
262 delete xhrTest;
263 }
264 Get_501_reponse(TC_name + " 501 Method Not Implemented error expected",
265 'resources/ExamPLE/mmY/index.html', "");
266
267
268 /**
269 * 400 Bad Request error - response body MUST be empty
270 *
271 * rules for dereferencing an app: URI =>
272 5. If the URI does not conform to the appuri ABNF, return a
273 [HTTP] 400 Bad Request response and terminate this algorithm.
274 */
275
276 function Get_400_reponse(name, URI, expected_response) {
277 var xhrTest = async_test(name);
278 xhrTest.step(function () {
279 var xhr = new XMLHttpRequest();
280 //alert(URI);
281 xhr.open("GET", URI, true);
282 xhr.onreadystatechange = xhrTest.step_func(function (ev) {
283 if (xhr.readyState !== 4 && xhr.status === 400) {
284 assert_true(xhr.response === expected_response,
285 "[" + xhr.status + " error, response:[" + xhr.response + "] " + "]");
286
287 xhrTest.done();
288 }
289 if (xhr.readyState === 4 && xhr.status === 200) {
290 assert_true(false,
291 "[Should get 400 but got 200 OK, "
292 +"file found while it should not find it, "
293 +"since no specific file requested]");
294 }
295 });
296 xhr.send();
297 });
298 delete xhrTest;
299 }
300 Get_400_reponse(TC_name + " 400 Method Not Implemented error expected, no path",
301 tmp_domain, "");
302 Get_400_reponse(TC_name + " 400 Method Not Implemented error expected, different domain with no path",
303 ChangeHostIfEqCurrent("app://f15a6d20-cefa-13e5-1972-800e20d19a76"), "");
304
305
306 /**
307 * 403 Forbidden error - response body MUST be empty
308 *
309 * rules for dereferencing an app: URI =>
310 6. If the URI uses the scheme 'app', but the authority does not match
311 the one assigned to this document, return a [HTTP] 403 Forbidden
312 response and terminate this algorithm
313 (i.e., prevent inter-application content access).
314 */
315
316 function Get_403_reponse(name, URI, expected_response) {
317 var xhrTest = async_test(name);
318 xhrTest.step(function () {
319 /* Change if URI host is the same as current application host */
320 URI = ChangeHostIfEqCurrent(URI);
321 var xhr = new XMLHttpRequest();
322 xhr.open("GET", URI, true);
323 xhr.onreadystatechange = xhrTest.step_func(function (ev) {
324 if (xhr.readyState === 4 && xhr.status === 200) {
325 assert_true(false, "[403 error expected, got: 200 OK instead]");
326 }
327 if (xhr.readyState !== 4 && xhr.status === 403) {
328 assert_true(xhr.response === expected_response, "["
329 + xhr.status + " error, response:[" + xhr.response + "] "
330 + "]");
331 xhrTest.done();
332 }
333 });
334 xhr.send();
335 });
336 }
337 Get_403_reponse(TC_name + " Access to restricted URI - 403 Forbidden error expected",
338 window.location.protocol + "//f15a6d20-cefa-13e5-1972-800e20d19a76/" + 'resources/ExamPLE/mmY/index.html', "");
339
340
341 /**
342 * 404 Not Found error - response body MUST be empty
343 *
344 * rules for dereferencing an app: URI =>
345 9. If potential-file is not found at the given path inside the container,
346 return a [HTTP] 404 Not Found response.
347 */
348
349 TC_name = "Test: 6.4 Dereferencing and retrieval of files from a container";
350
351 var CompareResponseBodytests = [ /* scheme: [TC name, URI, expected_response]*/
352 [TC_name + " 404 Not Found error expected",
353 'resources/ImaGes/~t/%7b!a%7d/~sth11.png', ""]
354 ];
355
356 CompareResponseBodytests.forEach(function (data, i) {
357 var name = data[0];
358 var URI = data[1];
359 var expected_response = data[2];
360 var xhrTest = async_test(name);
361 var xhr;
362 xhrTest.step(function () {
363 xhr = new XMLHttpRequest();
364 xhr.open("GET", URI, true);
365 xhr.onreadystatechange = xhrTest.step_func(function (ev) {
366 if (xhr.readyState !== 4 && xhr.status === 404) {
367 assert_true(xhr.response === expected_response,
368 "[" + xhr.status + " error, response:[" + xhr.response + "] " + "]");
369 xhrTest.done();
370 }
371 if (xhr.readyState === 4 && xhr.status === 200) {
372 assert_true(false, "[404 error expected, got: 200 OK instead]");
373 }
374 });
375 xhr.send();
376 });
377 delete xhrTest, xhr;
378 });
379 delete CompareResponseBodytests;
380
381
382
383 } else {
384 document.getElementById("logs").innerHTML =
385 "This is a test suite for app protocol only. Test aborted due to current protocol "
386 + window.location.protocol;
387 }
388
389 </script>
390 </body>
391</html>
392
393
394