mirror of
https://github.com/roytam1/UXP.git
synced 2026-06-23 08:49:05 +00:00
a299eaa965
This is effectively a back-out of the following patches from Bug 1274959 except we add comments and test coverage: - Part 1 which made the DirectoryListingTask include symlinks in the results as exposed by Directory.getFilesAndDirectories. - Part 3 which made GetFilesHelper include symlinks in the results. Test coverage for getFilesAndDirectories is provided by dom/filesystem/tests/test_basic.html by way of changes to its included file dom/filesystem/tests/filesystem_commons.js and changes to the createTreeFile helper in dom/filesystem/tests/script_fileList.js. Test coverage for GetFilesHelper is provided by dom/filesystem/tests/test_webkitdirectory.html and changes to the createTestFile helper in dom/filesystem/tests/script_fileList.js. Commenting out either of the `isLink` test in the relevant C++ code will cause the given tests to fail on non-windows platforms.
279 lines
9.5 KiB
HTML
279 lines
9.5 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Test for webkitdirectory and webkitRelativePath</title>
|
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
</head>
|
|
|
|
<body>
|
|
<input id="inputFileWebkitDirectory" type="file" webkitdirectory></input>
|
|
<input id="inputFileWebkitDirectoryAndDirectory" type="file" webkitdirectory allowdirs></input>
|
|
<input id="inputFileWebkitFile" type="file"></input>
|
|
<input id="inputFileDirectory" type="file" allowdirs></input>
|
|
<input id="inputFileDirectoryChange" type="file" webkitdirectory></input>
|
|
|
|
<script type="application/javascript;version=1.7">
|
|
|
|
// Populate the given input type=file `aInputFile`'s `files` attribute by:
|
|
// - loading `script_fileList.js` in the parent process
|
|
// - telling it to generate the "test" template directory pattern which will
|
|
// create "foo.txt", "subdir/bar.txt", and if symlinks are available on the
|
|
// platform, "symlink.txt" which will be a symlink to "foo.txt". (Note that
|
|
// we explicitly expect the symlink to be filtered out if generated, and
|
|
// during the enhancement of the test we verified the file was created on
|
|
// linux by running the test before fixing the GetFilesHelper logic to filter
|
|
// the symlink out and verifying the subsequent `test_fileList` check failed.)
|
|
// - Triggering the mock file picker with the base directory of the "test"
|
|
// template directory.
|
|
//
|
|
// It's expected that `test_fileList` will be used after this step completes in
|
|
// order to validate the results.
|
|
function populateInputFile(aInputFile) {
|
|
var url = SimpleTest.getTestFileURL("script_fileList.js");
|
|
var script = SpecialPowers.loadChromeScript(url);
|
|
|
|
var MockFilePicker = SpecialPowers.MockFilePicker;
|
|
MockFilePicker.init(window, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeOpen);
|
|
|
|
function onOpened(message) {
|
|
MockFilePicker.useDirectory(message.dir);
|
|
|
|
var input = document.getElementById(aInputFile);
|
|
input.setAttribute('data-name', message.name);
|
|
input.addEventListener('change', function change() {
|
|
input.removeEventListener('change', change);
|
|
MockFilePicker.cleanup();
|
|
script.destroy();
|
|
next();
|
|
});
|
|
|
|
input.click();
|
|
}
|
|
|
|
script.addMessageListener("dir.opened", onOpened);
|
|
script.sendAsyncMessage("dir.open", { path: 'test' });
|
|
}
|
|
|
|
function checkFile(file, fileList, dirName) {
|
|
for (var i = 0; i < fileList.length; ++i) {
|
|
ok(fileList[i] instanceof File, "We want just files.");
|
|
if (fileList[i].name == file.name) {
|
|
is(fileList[i].webkitRelativePath, dirName + file.path, "Path matches");
|
|
return;
|
|
}
|
|
}
|
|
|
|
ok(false, "File not found.");
|
|
}
|
|
|
|
// Validate the contents of the given input type=file `aInputFile`'s' `files`
|
|
// property against the expected list of files `aWhat`.
|
|
function test_fileList(aInputFile, aWhat) {
|
|
var input = document.getElementById(aInputFile);
|
|
var fileList = input.files;
|
|
|
|
if (aWhat == null) {
|
|
is(fileList, null, "We want a null fileList for " + aInputFile);
|
|
next();
|
|
return;
|
|
}
|
|
|
|
is(fileList.length, aWhat.length, "We want just " + aWhat.length + " elements for " + aInputFile);
|
|
for (var i = 0; i < aWhat.length; ++i) {
|
|
checkFile(aWhat[i], fileList, input.dataset.name);
|
|
}
|
|
|
|
next();
|
|
}
|
|
|
|
// Verify that we can explicitly select a symlink and it will not be filtered
|
|
// out. This is really a verification that GetFileHelper's file-handling logic
|
|
// https://searchfox.org/mozilla-central/rev/065102493dfc49234120c37fc6a334a5b1d86d9e/dom/filesystem/GetFilesHelper.cpp#81-86
|
|
// does not proactively take an action to filter out a selected symlink.
|
|
//
|
|
// This is a glass box test that is not entirely realistic for our actual system
|
|
// file pickers but does reflect what will happen in the drag-and-drop case
|
|
// for `HTMLInputElement::MozSetDndFilesAndDirectories` and this helps ensure
|
|
// that future implementation changes will behave as expected. Specifically,
|
|
// the presence of webkitdirectory will result in the file picker using
|
|
// `modeGetFolder` which will only allow selection of a directory and forbid
|
|
// file selection.
|
|
//
|
|
// This test explicitly does not validate HTMLInputElement's non-webkitdirectory
|
|
// file selection mechanism because it does not involve GetFileHelper.
|
|
async function test_individualSymlink(aInputFile) {
|
|
const input = document.getElementById(aInputFile);
|
|
|
|
// -- Create the symlink and get a `File` instance pointing at it.
|
|
const url = SimpleTest.getTestFileURL("script_fileList.js");
|
|
const script = SpecialPowers.loadChromeScript(url);
|
|
|
|
let opened = new Promise(resolve => script.addMessageListener("symlink.opened", resolve));
|
|
script.sendAsyncMessage("symlink.open", {});
|
|
let { dir, file: symlinkFile } = await opened;
|
|
info(`symlink.open provided dir: ${dir}`)
|
|
|
|
// -- Have the picker pick it
|
|
var MockFilePicker = SpecialPowers.MockFilePicker;
|
|
MockFilePicker.init(window, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeOpen);
|
|
|
|
MockFilePicker.displayDirectory = dir;
|
|
let pickerShown = new Promise(resolve => {
|
|
MockFilePicker.showCallback = function() {
|
|
// This is where we are diverging from a realistic scenario in order to get
|
|
// the expected coverage.
|
|
MockFilePicker.setFiles([symlinkFile]);
|
|
resolve();
|
|
}
|
|
});
|
|
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
|
|
|
let changeEvent = waitForEvent(input, "change");
|
|
|
|
input.click();
|
|
|
|
await pickerShown;
|
|
await changeEvent;
|
|
|
|
MockFilePicker.cleanup();
|
|
script.destroy();
|
|
|
|
// -- Verify that we see the symlink.
|
|
let fileList = input.files;
|
|
is(fileList.length, 1, "There should be 1 file.");
|
|
is(fileList[0].name, "symlink.txt", "The file should be the symlink.");
|
|
next();
|
|
}
|
|
|
|
function test_webkitdirectory_attribute() {
|
|
var a = document.createElement("input");
|
|
a.setAttribute("type", "file");
|
|
|
|
ok("webkitdirectory" in a, "HTMLInputElement.webkitdirectory exists");
|
|
|
|
ok(!a.hasAttribute("webkitdirectory"), "No webkitdirectory DOM attribute by default");
|
|
ok(!a.webkitdirectory, "No webkitdirectory attribute by default");
|
|
|
|
a.webkitdirectory = true;
|
|
|
|
ok(a.hasAttribute("webkitdirectory"), "Webkitdirectory DOM attribute is set");
|
|
ok(a.webkitdirectory, "Webkitdirectory attribute is set");
|
|
|
|
next();
|
|
}
|
|
|
|
function test_changeDataWhileWorking() {
|
|
var url = SimpleTest.getTestFileURL("script_fileList.js");
|
|
var script = SpecialPowers.loadChromeScript(url);
|
|
|
|
var MockFilePicker = SpecialPowers.MockFilePicker;
|
|
MockFilePicker.init(window, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeOpen);
|
|
|
|
// Let's start retrieving the root nsIFile object
|
|
new Promise(function(resolve) {
|
|
function onOpened(message) {
|
|
script.removeMessageListener("dir.opened", onOpened);
|
|
resolve(message.dir);
|
|
}
|
|
|
|
script.addMessageListener("dir.opened", onOpened);
|
|
script.sendAsyncMessage("dir.open", { path: 'root' });
|
|
})
|
|
|
|
// input.click() pointing to the root dir
|
|
.then(function(aDir) {
|
|
MockFilePicker.cleanup();
|
|
MockFilePicker.init(window, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeOpen);
|
|
MockFilePicker.useDirectory(aDir);
|
|
var input = document.getElementById("inputFileDirectoryChange");
|
|
input.click();
|
|
})
|
|
|
|
// Before onchange, let's take the 'test' directory
|
|
.then(function() {
|
|
return new Promise(function(resolve) {
|
|
function onOpened(message) {
|
|
script.removeMessageListener("dir.opened", onOpened);
|
|
script.destroy();
|
|
resolve(message.dir);
|
|
}
|
|
|
|
script.addMessageListener("dir.opened", onOpened);
|
|
script.sendAsyncMessage("dir.open", { path: 'test' });
|
|
});
|
|
})
|
|
|
|
// Now let's click again and wait for onchange.
|
|
.then(function(aDir) {
|
|
return new Promise(function(resolve) {
|
|
MockFilePicker.cleanup();
|
|
MockFilePicker.init(window, "A Mock File Picker", SpecialPowers.Ci.nsIFilePicker.modeOpen);
|
|
MockFilePicker.useDirectory(aDir);
|
|
|
|
var input = document.getElementById("inputFileDirectoryChange");
|
|
input.addEventListener('change', function() {
|
|
MockFilePicker.cleanup();
|
|
resolve();
|
|
});
|
|
|
|
input.click();
|
|
})
|
|
})
|
|
|
|
.then(function() {
|
|
test_fileList('inputFileWebkitDirectory', testDirData);
|
|
});
|
|
}
|
|
|
|
function test_setup() {
|
|
SpecialPowers.pushPrefEnv({"set": [["dom.input.dirpicker", true],
|
|
["dom.filesystem.pathcheck.disabled", true],
|
|
["dom.webkitBlink.dirPicker.enabled", true]]}, next);
|
|
}
|
|
|
|
var testDirData = [ { name: 'foo.txt', path: '/foo.txt' },
|
|
{ name: 'bar.txt', path: '/subdir/bar.txt' }];
|
|
|
|
var tests = [
|
|
test_setup,
|
|
|
|
function() { populateInputFile('inputFileWebkitDirectory'); },
|
|
function() { populateInputFile('inputFileWebkitDirectoryAndDirectory'); },
|
|
function() { populateInputFile('inputFileDirectory'); },
|
|
|
|
function() { test_fileList('inputFileWebkitDirectory', testDirData) },
|
|
function() { test_fileList('inputFileWebkitDirectoryAndDirectory', testDirData) },
|
|
function() { test_fileList('inputFileDirectory', null); },
|
|
|
|
function() {
|
|
#ifdef XP_WIN // Symlinks are not available on Windows and so will not be created.
|
|
info("Skipping individual symlink check on Windows and Android.");
|
|
next();
|
|
return;
|
|
#endif
|
|
test_individualSymlink("inputFileWebkitFile").catch(err => ok(false, `Problem in symlink case: ${err}`));
|
|
},
|
|
|
|
|
|
test_webkitdirectory_attribute,
|
|
|
|
test_changeDataWhileWorking,
|
|
];
|
|
|
|
function next() {
|
|
if (!tests.length) {
|
|
SimpleTest.finish();
|
|
return;
|
|
}
|
|
|
|
var test = tests.shift();
|
|
test();
|
|
}
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
next();
|
|
</script>
|
|
</body>
|
|
</html>
|