blob: 8b83969bbc15809a248a7d136ca5ac48037c5a9c [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>app:URI compliance tests</title>
<script src='resources/testharness.js'></script>
<script src='resources/testharnessreport.js'></script>
<link rel='stylesheet' href='resource/testharness.css'>
<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>