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