forked from mirrors/gecko-dev
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35919 --HG-- extra : source : afa5bd771feba466ba7670c58f3d93233a14e202
247 lines
7 KiB
JavaScript
247 lines
7 KiB
JavaScript
/* -*- 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;
|
|
|
|
XPCOMUtils.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");
|
|
|
|
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 *
|
|
*********/
|
|
|
|
XPCOMUtils.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^/");
|
|
}
|