'use strict';
/**
- * @type {DOMFileSystem}
- */
-var fileSystem = null;
-
-/**
* Map of opened files, from a <code>openRequestId</code> to <code>filePath
* </code>.
* @type {Object.<number, string>}
var openedFiles = {};
/**
- * @type {string}
- * @const
- */
-var FILE_SYSTEM_ID = 'chocolate-id';
-
-/**
- * @type {Object}
- * @const
- */
-var TESTING_ROOT = Object.freeze({
- isDirectory: true,
- name: '',
- size: 0,
- modificationTime: new Date(2014, 4, 28, 10, 39, 15)
-});
-
-/**
* Testing contents for files.
* @type {string}
* @const
});
/**
- * Gets volume information for the provided file system.
- *
- * @param {string} fileSystemId Id of the provided file system.
- * @param {function(Object)} callback Callback to be called on result, with the
- * volume information object in case of success, or null if not found.
- */
-function getVolumeInfo(fileSystemId, callback) {
- chrome.fileBrowserPrivate.getVolumeMetadataList(function(volumeList) {
- for (var i = 0; i < volumeList.length; i++) {
- if (volumeList[i].extensionId == chrome.runtime.id &&
- volumeList[i].fileSystemId == fileSystemId) {
- callback(volumeList[i]);
- return;
- }
- }
- callback(null);
- });
-}
-
-/**
- * Returns metadata for the requested entry.
- *
- * To successfully acquire a DirectoryEntry, or even a DOMFileSystem, this event
- * must be implemented and return correct values.
- *
- * @param {GetMetadataRequestedOptions} options Options.
- * @param {function(Object)} onSuccess Success callback with metadata passed
- * an argument.
- * @param {function(string)} onError Error callback with an error code.
- */
-function onGetMetadataRequested(options, onSuccess, onError) {
- if (options.fileSystemId != FILE_SYSTEM_ID) {
- onError('SECURITY'); // enum ProviderError.
- return;
- }
-
- if (options.entryPath == '/') {
- onSuccess(TESTING_ROOT);
- return;
- }
-
- if (options.entryPath == '/' + TESTING_TIRAMISU_FILE.name) {
- onSuccess(TESTING_TIRAMISU_FILE);
- return;
- }
-
- if (options.entryPath == '/' + TESTING_BROKEN_TIRAMISU_FILE.name) {
- onSuccess(TESTING_BROKEN_TIRAMISU_FILE);
- return;
- }
-
- onError('NOT_FOUND'); // enum ProviderError.
-}
-
-/**
- * Requests opening a file at <code>filePath</code>. Further file operations
- * will be associated with the <code>requestId</code>
- *
- * @param {OpenFileRequestedOptions} options Options.
- * @param {function()} onSuccess Success callback.
- * @param {function(string)} onError Error callback.
- */
-function onOpenFileRequested(options, onSuccess, onError) {
- if (options.fileSystemId != FILE_SYSTEM_ID || options.mode != 'READ' ||
- options.create) {
- onError('SECURITY'); // enum ProviderError.
- return;
- }
-
- if (options.filePath == '/' + TESTING_TIRAMISU_FILE.name ||
- options.filePath == '/' + TESTING_BROKEN_TIRAMISU_FILE.name) {
- openedFiles[options.requestId] = options.filePath;
- onSuccess();
- } else {
- onError('NOT_FOUND'); // enum ProviderError.
- }
-}
-
-/**
- * Requests closing a file previously opened with <code>openRequestId</code>.
- *
- * @param {CloseFileRequestedOptions} options Options.
- * @param {function()} onSuccess Success callback.
- * @param {function(string)} onError Error callback.
+ * Metadata of a broken file used to read contents from, but it simulates
+ * a very long read, in order to verify the aborting mechanism.
+ * @type {Object}
+ * @const
*/
-function onCloseFileRequested(options, onSuccess, onError) {
- if (options.fileSystemId != FILE_SYSTEM_ID ||
- !openedFiles[options.openRequestId]) {
- onError('SECURITY'); // enum ProviderError.
- return;
- }
-
- delete openedFiles[options.openRequestId];
- onSuccess();
-}
+var TESTING_VANILLA_FOR_ABORT_FILE = Object.freeze({
+ isDirectory: false,
+ name: 'vanilla.txt',
+ size: TESTING_TEXT.length,
+ modificationTime: new Date(2014, 1, 25, 7, 36, 12)
+});
/**
* Requests reading contents of a file, previously opened with <code>
* @param {function(string)} onError Error callback.
*/
function onReadFileRequested(options, onSuccess, onError) {
- var filePath = openedFiles[options.openRequestId];
- if (options.fileSystemId != FILE_SYSTEM_ID || !filePath) {
+ var filePath = test_util.openedFiles[options.openRequestId];
+ if (options.fileSystemId != test_util.FILE_SYSTEM_ID || !filePath) {
onError('SECURITY'); // enum ProviderError.
return;
}
return;
}
+ if (filePath == '/' + TESTING_VANILLA_FOR_ABORT_FILE.name) {
+ // Do nothing. This simulates a very slow read.
+ return;
+ }
+
if (filePath == '/' + TESTING_BROKEN_TIRAMISU_FILE.name) {
onError('ACCESS_DENIED'); // enum ProviderError.
return;
* @param {function()} callback Success callback.
*/
function setUp(callback) {
- chrome.fileSystemProvider.mount(
- {fileSystemId: FILE_SYSTEM_ID, displayName: 'chocolate.zip'},
- function() {
- chrome.fileSystemProvider.onGetMetadataRequested.addListener(
- onGetMetadataRequested);
- chrome.fileSystemProvider.onOpenFileRequested.addListener(
- onOpenFileRequested);
- chrome.fileSystemProvider.onReadFileRequested.addListener(
- onReadFileRequested);
- var volumeId =
- 'provided:' + chrome.runtime.id + '-' + FILE_SYSTEM_ID + '-user';
-
- getVolumeInfo(FILE_SYSTEM_ID, function(volumeInfo) {
- chrome.test.assertTrue(!!volumeInfo);
- chrome.fileBrowserPrivate.requestFileSystem(
- volumeInfo.volumeId,
- function(inFileSystem) {
- chrome.test.assertTrue(!!inFileSystem);
-
- fileSystem = inFileSystem;
- callback();
- });
- });
- },
- function() {
- chrome.test.fail();
- });
+ chrome.fileSystemProvider.onGetMetadataRequested.addListener(
+ test_util.onGetMetadataRequestedDefault);
+ chrome.fileSystemProvider.onOpenFileRequested.addListener(
+ test_util.onOpenFileRequested);
+ chrome.fileSystemProvider.onCloseFileRequested.addListener(
+ test_util.onCloseFileRequested);
+
+ test_util.defaultMetadata['/' + TESTING_TIRAMISU_FILE.name] =
+ TESTING_TIRAMISU_FILE;
+ test_util.defaultMetadata['/' + TESTING_BROKEN_TIRAMISU_FILE.name] =
+ TESTING_BROKEN_TIRAMISU_FILE;
+ test_util.defaultMetadata['/' + TESTING_VANILLA_FOR_ABORT_FILE.name] =
+ TESTING_VANILLA_FOR_ABORT_FILE;
+
+ chrome.fileSystemProvider.onReadFileRequested.addListener(
+ onReadFileRequested);
+
+ test_util.mountFileSystem(callback);
}
/**
// succeed.
function readFileSuccess() {
var onTestSuccess = chrome.test.callbackPass();
- fileSystem.root.getFile(
+ test_util.fileSystem.root.getFile(
TESTING_TIRAMISU_FILE.name,
{create: false},
function(fileEntry) {
chrome.test.fail(error.name);
});
},
- // Read contents of a file file, but with an error on the way. This should
+
+ // Read contents of a file, but with an error on the way. This should
// result in an error.
function readEntriesError() {
var onTestSuccess = chrome.test.callbackPass();
- fileSystem.root.getFile(
+ test_util.fileSystem.root.getFile(
TESTING_BROKEN_TIRAMISU_FILE.name,
{create: false},
function(fileEntry) {
fileReader.readAsText(file);
},
function(error) {
- chrome.test.fail();
+ chrome.test.fail(error.name);
+ });
+ },
+ function(error) {
+ chrome.test.fail(error.name);
+ });
+ },
+
+ // Abort reading a file with a registered abort handler. Should result in a
+ // gracefully terminated reading operation.
+ function abortReadingSuccess() {
+ var onTestSuccess = chrome.test.callbackPass();
+
+ var onAbortRequested = function(options, onSuccess, onError) {
+ chrome.fileSystemProvider.onAbortRequested.removeListener(
+ onAbortRequested);
+ onSuccess();
+ onTestSuccess();
+ };
+
+ chrome.fileSystemProvider.onAbortRequested.addListener(
+ onAbortRequested);
+
+ test_util.fileSystem.root.getFile(
+ TESTING_VANILLA_FOR_ABORT_FILE.name,
+ {create: false, exclusive: false},
+ function(fileEntry) {
+ fileEntry.file(function(file) {
+ var hadAbort = false;
+ var fileReader = new FileReader();
+ fileReader.onload = function(e) {
+ if (!hadAbort) {
+ chrome.test.fail(
+ 'Unexpectedly finished writing, despite aborting.');
+ return;
+ }
+ chrome.test.fail();
+ };
+ fileReader.onerror = function(e) {
+ chrome.test.assertEq(
+ 'AbortError', fileReader.error.name);
+ };
+ fileReader.readAsText(file);
+ setTimeout(function() {
+ // Abort the operation after it's started.
+ fileReader.abort();
+ }, 0);
+ },
+ function(error) {
+ chrome.test.fail(error.name);
});
},
function(error) {