1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * This extension provides two file browser handlers: 'ReadOnly' and
7 * 'ReadWrite'. 'ReadOnly' handler handles .xul files and has read-only file
8 * access. 'ReadWrite' handler handles .tiff files and has read-write file
9 * access. The extension does not have persistent background page.
11 * The extension waits until 'ReadWrite' handler is executed and then runs tests
12 * for it. The tests verify that the extension is able to read and write the
13 * handled file. If there is an error before the tests are run,
14 * chrome.test.notifyFail will be called, and further onExecute events will be
17 * 'ReadOnly' handler is ignored by this test extension, but it must be defined
18 * to conform to the expectations of file_browser/handler_test_runner
20 * The handlers are executed by 'file_browser/handler_test_runner' extension.
21 * 'ReadWrite' handler are executed once, and should carry exactly one handled
25 // Initial content of handled files. The content is set in
26 // external_filesystem_apitest.cc.
27 var kInitialTestFileContent = 'This is some test content.';
28 // Content written by write test.
29 var kTextToWrite = ' Yay!';
32 * Asserts that |value| equals |expectedValue|. If the assert fails, current
33 * test fails with |errorMessage|. Otherwise, |callback()| is called.
35 function assertEqAndRunCallback(expectedValue, value, errorMessage, callback) {
36 chrome.test.assertEq(expectedValue, value, errorMessage);
41 * Attempts to read file and asserts that the read success and file content are
42 * as expected (|expectSuccess|, |expectedContent|). On success |callback| is
43 * called, otherwise current test is failed.
45 * @param {FileEntry} entry Entry to be read.
46 * @param {boolean} expectSuccess Whether the read should succeed.
47 * @param {string} expectedContent If the read succeeds, the expected content to
48 * be read from file. If the read fails, it is ignored.
49 * @param {function()} callback Function called if the read ends as defined by
50 * |expectSuccess| and |expectedContent|.
52 function readAndExpectContent(entry, expectSuccess, expectedContent, callback) {
53 var error = 'Reading file \'' + entry.fullPath + '\'.';
54 var reader = new FileReader();
56 reader.onload = function() {
57 chrome.test.assertTrue(expectSuccess, error);
58 assertEqAndRunCallback(expectedContent, reader.result, error, callback);
61 entry.file(reader.readAsText.bind(reader),
62 assertEqAndRunCallback.bind(null,
63 false, expectSuccess, error, callback));
67 * Attempts to write |content| to the end of the |entry| and verifies that the
68 * operation success is as expected. On success |callback| is called, else the
69 * current test is failed.
71 * @param {FileEntry} entry File entry to be read.
72 * @param {string} content String content to be appended to the file.
73 * @param {boolean} expectSuccess Whether the write should succeed.
74 * @param {function()} callback Function called if write ends as defined by
77 function write(entry, content, expectSuccess, callback) {
78 var error = 'Writing to: \'' + entry.fullPath + '\'.';
80 entry.createWriter(function(writer) {
81 writer.onerror = assertEqAndRunCallback.bind(null, expectSuccess, false,
83 writer.onwrite = assertEqAndRunCallback.bind(null, expectSuccess, true,
86 writer.seek(kInitialTestFileContent.length);
87 var blob = new Blob([kTextToWrite], {type: 'text/plain'});
90 assertEqAndRunCallback.bind(null, expectSuccess, false,
91 'Getting writer for: \'' + entry.fullPath + '\'.', callback));
97 * @params {FileEntry} entry File entry for which the test should be run.
98 * @params {boolean} expectSuccess Whether the read should succeed.
100 function readTest(entry, expectSuccess) {
101 readAndExpectContent(entry, expectSuccess, kInitialTestFileContent,
106 * Runs test for a file that is not executed for any handler. Test tries to get
107 * an existing file entry from the |entry|'s filesystem. The file path is
108 * constructed by appending '.foo' to the |entry|'s path (the Chrome part of the
109 * test should ensure that the file exists). The get operation is expected to
112 function getSiblingTest(entry) {
113 var error = 'Got file (\'' + entry.fullPath.concat('.foo') + '\') for which' +
114 'file access was not granted.';
115 entry.filesystem.root.getFile(
116 entry.fullPath.concat('.foo'), {},
117 chrome.test.fail.bind(null, error),
118 chrome.test.succeed);
123 * Attempts to write to the entry. If the write operation ends as expected, the
124 * test verifies new content of the file.
126 * @param {FileEntry} entry Entry to be written.
127 * @param {boolean} expectSuccess Whether the test should succeed.
129 function writeTest(entry, expectSuccess) {
130 var verifyFileContent = function() {
131 var expectedContent = kInitialTestFileContent;
133 expectedContent = expectedContent.concat(kTextToWrite);
135 readAndExpectContent(entry, true, expectedContent, chrome.test.succeed);
138 write(entry, kTextToWrite, expectSuccess, verifyFileContent);
142 * Listens for onExecute events, and runs tests once the event for 'ReadWrite'
143 * handler is received.
145 function executeListener(id, details) {
146 if (id == 'ReadWrite') {
147 var fileEntries = details.entries;
148 if (!fileEntries || fileEntries.length != 1) {
149 chrome.test.notifyFail('Unexpected file entries size.');
153 var entry = fileEntries[0];
155 // Run tests for read-write handler.
156 chrome.test.runTests([
157 function readReadWrite() {
158 readTest(entry, true);
160 function getSilblingReadWrite() {
161 getSiblingTest(entry);
163 function writeReadWrite() {
164 writeTest(entry, true);
167 } else if (id != 'ReadOnly') {
168 chrome.test.notifyFail('Unexpected action id: ' + id);
173 chrome.fileBrowserHandler.onExecute.addListener(executeListener);