<!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>



