Chromium Code Reviews| 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 |