diff options
Diffstat (limited to 'netwerk/test/httpserver/test/test_default_index_handler.js')
-rw-r--r-- | netwerk/test/httpserver/test/test_default_index_handler.js | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/netwerk/test/httpserver/test/test_default_index_handler.js b/netwerk/test/httpserver/test/test_default_index_handler.js new file mode 100644 index 0000000000..efa02cb6e3 --- /dev/null +++ b/netwerk/test/httpserver/test/test_default_index_handler.js @@ -0,0 +1,248 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// checks for correct output with the default index handler, mostly to do +// escaping checks -- highly dependent on the default index handler output +// format + +var srv, dir, gDirEntries; + +ChromeUtils.defineLazyGetter(this, "BASE_URL", function () { + return "http://localhost:" + srv.identity.primaryPort + "/"; +}); + +function run_test() { + createTestDirectory(); + + srv = createServer(); + srv.registerDirectory("/", dir); + + var nameDir = do_get_file("data/name-scheme/"); + srv.registerDirectory("/bar/", nameDir); + + srv.start(-1); + + function done() { + do_test_pending(); + destroyTestDirectory(); + srv.stop(function () { + do_test_finished(); + }); + } + + runHttpTests(tests, done); +} + +function createTestDirectory() { + dir = Services.dirsvc.get("TmpD", Ci.nsIFile); + dir.append("index_handler_test_" + Math.random()); + dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o744); + + // populate with test directories, files, etc. + // Files must be in expected order of display on the index page! + + var files = []; + + makeFile("aa_directory", true, dir, files); + makeFile("Ba_directory", true, dir, files); + makeFile("bb_directory", true, dir, files); + makeFile("foo", true, dir, files); + makeFile("a_file", false, dir, files); + makeFile("B_file", false, dir, files); + makeFile("za'z", false, dir, files); + makeFile("zb&z", false, dir, files); + makeFile("zc<q", false, dir, files); + makeFile('zd"q', false, dir, files); + makeFile("ze%g", false, dir, files); + makeFile("zf%200h", false, dir, files); + makeFile("zg>m", false, dir, files); + + gDirEntries = [files]; + + var subdir = dir.clone(); + subdir.append("foo"); + + files = []; + + makeFile("aa_dir", true, subdir, files); + makeFile("b_dir", true, subdir, files); + makeFile("AA_file.txt", false, subdir, files); + makeFile("test.txt", false, subdir, files); + + gDirEntries.push(files); +} + +function destroyTestDirectory() { + dir.remove(true); +} + +/** *********** + * UTILITIES * + *************/ + +/** Verifies data in bytes for the trailing-caret path above. */ +function hiddenDataCheck(bytes, uri, path) { + var data = String.fromCharCode.apply(null, bytes); + + var parser = new DOMParser(); + + // Note: the index format isn't XML -- it's actually HTML -- but we require + // the index format also be valid XML, albeit XML without namespaces, + // XML declarations, etc. Doing this simplifies output checking. + try { + var doc = parser.parseFromString(data, "application/xml"); + } catch (e) { + do_throw("document failed to parse as XML"); + } + + var body = doc.documentElement.getElementsByTagName("body"); + Assert.equal(body.length, 1); + body = body[0]; + + // header + var header = body.getElementsByTagName("h1"); + Assert.equal(header.length, 1); + + Assert.equal(header[0].textContent, path); + + // files + var lst = body.getElementsByTagName("ol"); + Assert.equal(lst.length, 1); + var items = lst[0].getElementsByTagName("li"); + + var top = Services.io.newURI(uri); + + // N.B. No ERROR_IF_SEE_THIS.txt^ file! + var dirEntries = [ + { name: "file.txt", isDirectory: false }, + { name: "SHOULD_SEE_THIS.txt^", isDirectory: false }, + ]; + + for (var i = 0; i < items.length; i++) { + var link = items[i].childNodes[0]; + var f = dirEntries[i]; + + var sep = f.isDirectory ? "/" : ""; + + Assert.equal(link.textContent, f.name + sep); + + uri = Services.io.newURI(link.getAttribute("href"), null, top); + Assert.equal(decodeURIComponent(uri.pathQueryRef), path + f.name + sep); + } +} + +/** + * Verifies data in bytes (an array of bytes) represents an index page for the + * given URI and path, which should be a page listing the given directory + * entries, in order. + * + * @param bytes + * array of bytes representing the index page's contents + * @param uri + * string which is the URI of the index page + * @param path + * the path portion of uri + * @param dirEntries + * sorted (in the manner the directory entries should be sorted) array of + * objects, each of which has a name property (whose value is the file's name, + * without / if it's a directory) and an isDirectory property (with expected + * value) + */ +function dataCheck(bytes, uri, path, dirEntries) { + var data = String.fromCharCode.apply(null, bytes); + + var parser = new DOMParser(); + + // Note: the index format isn't XML -- it's actually HTML -- but we require + // the index format also be valid XML, albeit XML without namespaces, + // XML declarations, etc. Doing this simplifies output checking. + try { + var doc = parser.parseFromString(data, "application/xml"); + } catch (e) { + do_throw("document failed to parse as XML"); + } + + var body = doc.documentElement.getElementsByTagName("body"); + Assert.equal(body.length, 1); + body = body[0]; + + // header + var header = body.getElementsByTagName("h1"); + Assert.equal(header.length, 1); + + Assert.equal(header[0].textContent, path); + + // files + var lst = body.getElementsByTagName("ol"); + Assert.equal(lst.length, 1); + var items = lst[0].getElementsByTagName("li"); + var top = Services.io.newURI(uri); + + for (var i = 0; i < items.length; i++) { + var link = items[i].childNodes[0]; + var f = dirEntries[i]; + + var sep = f.isDirectory ? "/" : ""; + + Assert.equal(link.textContent, f.name + sep); + + uri = Services.io.newURI(link.getAttribute("href"), null, top); + Assert.equal(decodeURIComponent(uri.pathQueryRef), path + f.name + sep); + } +} + +/** + * Create a file/directory with the given name underneath parentDir, and + * append an object with name/isDirectory properties to lst corresponding + * to it if the file/directory could be created. + */ +function makeFile(name, isDirectory, parentDir, lst) { + var type = Ci.nsIFile[isDirectory ? "DIRECTORY_TYPE" : "NORMAL_FILE_TYPE"]; + var file = parentDir.clone(); + + try { + file.append(name); + file.create(type, 0o755); + lst.push({ name, isDirectory }); + } catch (e) { + /* OS probably doesn't like file name, skip */ + } +} + +/** ******* + * TESTS * + *********/ + +ChromeUtils.defineLazyGetter(this, "tests", function () { + return [ + new Test(BASE_URL, null, start, stopRootDirectory), + new Test(BASE_URL + "foo/", null, start, stopFooDirectory), + new Test( + BASE_URL + "bar/folder^/", + null, + start, + stopTrailingCaretDirectory + ), + ]; +}); + +// check top-level directory listing +function start(ch) { + Assert.equal(ch.getResponseHeader("Content-Type"), "text/html;charset=utf-8"); +} +function stopRootDirectory(ch, status, data) { + dataCheck(data, BASE_URL, "/", gDirEntries[0]); +} + +// check non-top-level, too +function stopFooDirectory(ch, status, data) { + dataCheck(data, BASE_URL + "foo/", "/foo/", gDirEntries[1]); +} + +// trailing-caret leaf with hidden files +function stopTrailingCaretDirectory(ch, status, data) { + hiddenDataCheck(data, BASE_URL + "bar/folder^/", "/bar/folder^/"); +} |