OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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. | |
4 | |
5 'use strict'; | |
6 | |
7 /** | |
8 * @type {number} | |
9 */ | |
10 var fileSystemId = 0; | |
11 | |
12 /** | |
13 * @type {?DOMFileSystem} | |
14 */ | |
15 var fileSystem = null; | |
16 | |
17 /** | |
18 * Map of opened files, from a <code>openRequestId</code> to <code>filePath | |
19 * </code>. | |
20 * @type {Object.<number, string>} | |
21 */ | |
22 var openedFiles = {}; | |
23 | |
24 /** | |
25 * @type {Object} | |
26 * @const | |
27 */ | |
28 var TESTING_ROOT = Object.freeze({ | |
29 isDirectory: true, | |
30 name: '', | |
31 size: 0, | |
32 modificationTime: new Date(2014, 4, 28, 10, 39, 15) | |
33 }); | |
34 | |
35 /** | |
36 * Testing contents for files. | |
37 * @type {string} | |
38 * @const | |
39 */ | |
40 var TESTING_TEXT = 'I have a basket full of fruits.'; | |
41 | |
42 /** | |
43 * Metadata of a healthy file used to read contents from. | |
44 * @type {Object} | |
45 * @const | |
46 */ | |
47 var TESTING_TIRAMISU_FILE = Object.freeze({ | |
48 isDirectory: false, | |
49 name: 'tiramisu.txt', | |
50 size: TESTING_TEXT.length, | |
51 modificationTime: new Date(2014, 1, 25, 7, 36, 12) | |
52 }); | |
53 | |
54 /** | |
55 * Metadata of a broken file used to read contents from. | |
56 * @type {Object} | |
57 * @const | |
58 */ | |
59 var TESTING_BROKEN_TIRAMISU_FILE = Object.freeze({ | |
60 isDirectory: false, | |
61 name: 'broken-tiramisu.txt', | |
62 size: TESTING_TEXT.length, | |
63 modificationTime: new Date(2014, 1, 25, 7, 36, 12) | |
64 }); | |
65 | |
66 /** | |
67 * Returns metadata for the requested entry. | |
68 * | |
69 * To successfully acquire a DirectoryEntry, or even a DOMFileSystem, this event | |
70 * must be implemented and return correct values. | |
71 * | |
72 * @param {number} inFileSystemId ID of the file system. | |
73 * @param {string} entryPath Path of the requested entry. | |
74 * @param {function(Object)} onSuccess Success callback with metadata passed | |
75 * an argument. | |
76 * @param {function(string)} onError Error callback with an error code. | |
77 */ | |
78 function onGetMetadataRequested( | |
79 inFileSystemId, entryPath, onSuccess, onError) { | |
80 if (inFileSystemId != fileSystemId) { | |
81 onError('SECURITY_ERROR'); // enum ProviderError. | |
82 return; | |
83 } | |
84 | |
85 if (entryPath == '/') { | |
86 onSuccess(TESTING_ROOT); | |
87 return; | |
88 } | |
89 | |
90 if (entryPath == '/' + TESTING_TIRAMISU_FILE.name) { | |
91 onSuccess(TESTING_TIRAMISU_FILE); | |
92 return; | |
93 } | |
94 | |
95 if (entryPath == '/' + TESTING_BROKEN_TIRAMISU_FILE.name) { | |
96 onSuccess(TESTING_BROKEN_TIRAMISU_FILE); | |
97 return; | |
98 } | |
99 | |
100 onError('NOT_FOUND'); // enum ProviderError. | |
101 } | |
102 | |
103 /** | |
104 * Requests opening a file at <code>filePath</code>. Further file operations | |
105 * will be associated with the <code>requestId</code> | |
106 * | |
107 * @param {number} inFileSystemId ID of the file system. | |
108 * @param {number} requestId ID of the opening request. Used later for reading. | |
109 * @param {string} filePath Path of the file to be opened. | |
110 * @param {string} mode Mode, either reading or writing. | |
111 * @param {boolean} create True to create if doesn't exist. | |
112 * @param {function()} onSuccess Success callback. | |
113 * @param {function(string)} onError Error callback. | |
114 */ | |
115 function onOpenFileRequested( | |
116 inFileSystemId, requestId, filePath, mode, create, onSuccess, onError) { | |
117 if (inFileSystemId != fileSystemId || mode != 'READ' || create) { | |
118 onError('SECURITY_ERROR'); // enum ProviderError. | |
119 return; | |
120 } | |
121 | |
122 if (filePath == '/' + TESTING_TIRAMISU_FILE.name || | |
123 filePath == '/' + TESTING_BROKEN_TIRAMISU_FILE.name) { | |
124 openedFiles[requestId] = filePath; | |
125 onSuccess(); | |
126 } else { | |
127 onError('NOT_FOUND'); // enum ProviderError. | |
128 } | |
129 } | |
130 | |
131 /** | |
132 * Requests closing a file previously opened with <code>openRequestId</code>. | |
133 * | |
134 * @param {number} inFileSystemId ID of the file system. | |
135 * @param {number} openRequestId ID of the request used to open the file. | |
136 * @param {function()} onSuccess Success callback. | |
137 * @param {function(string)} onError Error callback. | |
138 */ | |
139 function onCloseFileRequested( | |
140 inFileSystemId, openRequestId, onSuccess, onError) { | |
141 if (inFileSystemId != fileSystemId || !openedFiles[openRequestId]) { | |
142 onError('SECURITY_ERROR'); // enum ProviderError. | |
143 return; | |
144 } | |
145 | |
146 delete openedFiles[requestId]; | |
147 onSuccess(); | |
148 } | |
149 | |
150 /** | |
151 * Requests reading contents of a file, previously opened with <code> | |
152 * openRequestId</code>. | |
153 * | |
154 * @param {number} inFileSystemId ID of the file system. | |
155 * @param {number} openRequestId ID of the request used to open the file. | |
156 * @param {number} offset Offset of the file. | |
157 * @param {number} length Number of bytes to read. | |
158 * @param {function(string, boolean)} onSuccess Success callback with a chunk | |
hirono
2014/05/20 04:03:07
function(string, boolean) -> function(ArrayBuffer,
mtomasz
2014/05/20 04:39:36
Done.
| |
159 * of data, and information if more data will be provided later. | |
160 * @param {function(string)} onError Error callback. | |
161 */ | |
162 function onReadFileRequested( | |
163 inFileSystemId, openRequestId, offset, length, onSuccess, onError) { | |
164 var filePath = openedFiles[openRequestId]; | |
165 if (inFileSystemId != fileSystemId || !filePath) { | |
166 onError('SECURITY_ERROR'); // enum ProviderError. | |
167 return; | |
168 } | |
169 | |
170 if (filePath == '/' + TESTING_TIRAMISU_FILE.name) { | |
171 var textToSend = TESTING_TEXT.substr(offset, length); | |
172 var textToSendInChunks = textToSend.split(/(?= )/); | |
173 | |
174 textToSendInChunks.forEach(function(item, index) { | |
175 // Convert item (string) to an ArrayBuffer. | |
176 var reader = new FileReader(); | |
177 | |
178 reader.onload = function(e) { | |
179 onSuccess( | |
180 e.target.result, | |
181 index < textToSendInChunks.length - 1 /* has_next */); | |
182 }; | |
183 | |
184 reader.readAsArrayBuffer(new Blob([item])); | |
185 }); | |
186 return; | |
187 } | |
188 | |
189 if (filePath == '/' + TESTING_BROKEN_TIRAMISU_FILE.name) { | |
190 onError('ACCESS_DENIED'); // enum ProviderError. | |
191 return; | |
192 } | |
193 | |
194 onError('INVALID_OPERATION'); // enum ProviderError. | |
195 } | |
196 | |
197 /** | |
198 * Sets up the tests. Called once per all test cases. In case of a failure, | |
199 * the callback is not called. | |
200 * | |
201 * @param {function()} callback Success callback. | |
202 */ | |
203 function setUp(callback) { | |
204 chrome.fileSystemProvider.mount('chocolate.zip', function(id) { | |
205 fileSystemId = id; | |
206 chrome.fileSystemProvider.onGetMetadataRequested.addListener( | |
207 onGetMetadataRequested); | |
208 chrome.fileSystemProvider.onOpenFileRequested.addListener( | |
209 onOpenFileRequested); | |
210 chrome.fileSystemProvider.onReadFileRequested.addListener( | |
211 onReadFileRequested); | |
212 var volumeId = | |
213 'provided:' + chrome.runtime.id + '-' + fileSystemId + '-user'; | |
214 | |
215 chrome.fileBrowserPrivate.requestFileSystem( | |
216 volumeId, | |
217 function(inFileSystem) { | |
218 chrome.test.assertTrue(!!inFileSystem); | |
219 | |
220 fileSystem = inFileSystem; | |
221 callback(); | |
222 }); | |
223 }, function() { | |
224 chrome.test.fail(); | |
225 }); | |
226 } | |
227 | |
228 /** | |
229 * Runs all of the test cases, one by one. | |
230 */ | |
231 function runTests() { | |
232 chrome.test.runTests([ | |
233 // Read contents of the /tiramisu.txt file. This file exists, so it should | |
234 // succeed. | |
235 function readFileSuccess() { | |
236 var onTestSuccess = chrome.test.callbackPass(); | |
237 fileSystem.root.getFile( | |
238 TESTING_TIRAMISU_FILE.name, | |
239 {create: false}, | |
240 function(fileEntry) { | |
241 fileEntry.file(function(file) { | |
242 var fileReader = new FileReader(); | |
243 fileReader.onload = function(e) { | |
244 var text = fileReader.result; | |
245 chrome.test.assertEq(TESTING_TEXT, text); | |
246 onTestSuccess(); | |
247 }; | |
248 fileReader.onerror = function(e) { | |
249 chrome.test.fail(fileReader.error.name); | |
250 }; | |
251 fileReader.readAsText(file); | |
252 }, | |
253 function(error) { | |
254 chrome.test.fail(error.name); | |
255 }); | |
256 }, | |
257 function(error) { | |
258 chrome.test.fail(error.name); | |
259 }); | |
260 }, | |
261 // Read contents of a file file, but with an error on the way. This should | |
262 // result in an error. | |
263 function readEntriesError() { | |
264 var onTestSuccess = chrome.test.callbackPass(); | |
265 fileSystem.root.getFile( | |
266 TESTING_BROKEN_TIRAMISU_FILE.name, | |
267 {create: false}, | |
268 function(fileEntry) { | |
269 fileEntry.file(function(file) { | |
270 var fileReader = new FileReader(); | |
271 fileReader.onload = function(e) { | |
272 chrome.test.fail(); | |
273 }; | |
274 fileReader.onerror = function(e) { | |
275 chrome.test.assertEq('NotReadableError', fileReader.error.name); | |
276 onTestSuccess(); | |
277 }; | |
278 fileReader.readAsText(file); | |
279 }, | |
280 function(error) { | |
281 chrome.test.fail(); | |
282 }); | |
283 }, | |
284 function(error) { | |
285 chrome.test.fail(error.name); | |
286 }); | |
287 } | |
288 ]); | |
289 } | |
290 | |
291 // Setup and run all of the test cases. | |
292 setUp(runTests); | |
OLD | NEW |