Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: chrome/test/data/file_manager/unit_tests/file_operation_manager_unittest.js

Issue 460963002: Files.app: Add more unit tests for FileOperationManager class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/test/data/file_manager/unit_tests/mocks/mock_entry.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 'use strict'; 4 'use strict';
5 5
6 /** 6 /**
7 * Mock of chrome.runtime. 7 * Mock of chrome.runtime.
8 * @type {Object} 8 * @type {Object}
9 * @const 9 * @const
10 */ 10 */
(...skipping 23 matching lines...) Expand all
34 */ 34 */
35 chrome.fileBrowserPrivate = { 35 chrome.fileBrowserPrivate = {
36 onCopyProgress: { 36 onCopyProgress: {
37 addListener: function(callback) { 37 addListener: function(callback) {
38 chrome.fileBrowserPrivate.onCopyProgress.listener_ = callback; 38 chrome.fileBrowserPrivate.onCopyProgress.listener_ = callback;
39 }, 39 },
40 removeListener: function() { 40 removeListener: function() {
41 chrome.fileBrowserPrivate.onCopyProgress.listener_ = null; 41 chrome.fileBrowserPrivate.onCopyProgress.listener_ = null;
42 }, 42 },
43 listener_: null 43 listener_: null
44 },
45 startCopy: function(source, destination, newName, callback) {
46 var id = 1;
47 var events = [
48 'begin_copy_entry',
49 'progress',
50 'end_copy_entry',
51 'success'
52 ].map(function(type) {
53 return [id, {type: type, sourceUrl: source, destinationUrl: destination}];
54 });
55 var sendEvent = function(index) {
56 // Call the function asynchronously.
57 return Promise.resolve().then(function() {
58 chrome.fileBrowserPrivate.onCopyProgress.listener_.apply(
59 null, events[index]);
60 if (index + 1 < events.length)
61 return sendEvent(index + 1);
62 else
63 return null;
64 }.bind(this));
65 }.bind(this);
66 callback(id);
67 sendEvent(0).catch(function(error) {
68 console.log(error.stack || error);
69 window.onerror();
70 });
71 } 44 }
72 }; 45 };
73 46
74 /** 47 /**
75 * Reports the result of promise to the test system. 48 * Reports the result of promise to the test system.
76 * @param {Promise} promise Promise to be fulfilled or rejected. 49 * @param {Promise} promise Promise to be fulfilled or rejected.
77 * @param {function(boolean:hasError)} callback Callback to be passed true on 50 * @param {function(boolean:hasError)} callback Callback to be passed true on
78 * error. 51 * error.
79 */ 52 */
80 function reportPromise(promise, callback) { 53 function reportPromise(promise, callback) {
81 promise.then( 54 promise.then(
82 callback.bind(null, false), 55 callback.bind(null, false),
83 function(error) { 56 function(error) {
84 if (error instanceof FileOperationManager.Error) { 57 if (error instanceof FileOperationManager.Error) {
85 console.log('FileOperationManager.Error: code=' + error.code); 58 console.error('FileOperationManager.Error: code=' + error.code);
86 } else { 59 } else {
87 console.log(error.stack || error.name || error); 60 console.error(error.stack || error.name || error);
88 } 61 }
89 callback(true); 62 callback(true);
90 }); 63 });
91 } 64 }
92 65
93 /** 66 /**
67 * Size of directory.
68 * @type {number}
69 * @const
70 */
71 var DIRECTORY_SIZE = -1;
72
73 /**
74 * Creates test file system.
75 * @param {string} id File system ID.
76 * @param {Object.<string, number>} entries Map of entries' paths and their
77 * size. If the size is equals to DIRECTORY_SIZE, the entry is derectory.
78 */
79 function createTestFileSystem(id, entries) {
80 var fileSystem = new TestFileSystem(id);
81 for (var path in entries) {
82 if (entries[path] === DIRECTORY_SIZE) {
83 fileSystem.entries[path] = new MockDirectoryEntry(fileSystem, path);
84 } else {
85 fileSystem.entries[path] =
86 new MockFileEntry(fileSystem, path, {size: entries[path]});
87 }
88 }
89 return fileSystem;
90 }
91
92 /**
93 * Resolves URL on the file system.
94 * @param {FakeFileSystem} fileSystem Fake file system.
95 * @param {string} url URL.
96 * @param {function(MockEntry)} success Success callback.
97 * @param {function()} failure Failure callback.
98 */
99 function resolveTestFileSystemURL(fileSystem, url, success, failure) {
100 for (var name in fileSystem.entries) {
101 var entry = fileSystem.entries[name];
102 if (entry.toURL() == url) {
103 success(entry);
104 return;
105 }
106 }
107 failure();
108 }
109
110 /**
111 * Waits for events until 'success'.
112 * @param {FileOperationManager} fileOperationManager File operation manager.
113 * @return {Promise} Promise to be fulfilled with an event list.
114 */
115 function waitForEvents(fileOperationManager) {
116 return new Promise(function(fulfill) {
117 var events = [];
118 fileOperationManager.addEventListener('copy-progress', function(event) {
119 events.push(event);
120 if (event.reason === 'SUCCESS')
121 fulfill(events);
122 });
123 fileOperationManager.addEventListener('entry-changed', function(event) {
124 events.push(event);
125 });
126 fileOperationManager.addEventListener('delete', function(event) {
127 events.push(event);
128 if (event.reason === 'SUCCESS')
129 fulfill(events);
130 });
131 });
132 }
133
134 /**
94 * Test target. 135 * Test target.
95 * @type {FileOperationManager} 136 * @type {FileOperationManager}
96 */ 137 */
97 var fileOperationManager; 138 var fileOperationManager;
98 139
99 /** 140 /**
100 * Initializes the test environment. 141 * Initializes the test environment.
101 */ 142 */
102 function setUp() { 143 function setUp() {
103 fileOperationManager = new FileOperationManager(); 144 fileOperationManager = new FileOperationManager();
104 } 145 }
105 146
106 /** 147 /**
107 * Tests the fileOperationUtil.resolvePath function. 148 * Tests the fileOperationUtil.resolvePath function.
108 * @param {function(boolean:hasError)} callback Callback to be passed true on 149 * @param {function(boolean:hasError)} callback Callback to be passed true on
109 * error. 150 * error.
110 */ 151 */
111 function testResolvePath(callback) { 152 function testResolvePath(callback) {
112 var fileEntry = new MockFileEntry('testVolume', '/file', {}); 153 var fileSystem = createTestFileSystem('testVolume', {
113 var directoryEntry = new MockDirectoryEntry('testVolume', '/directory', {}); 154 '/': DIRECTORY_SIZE,
114 var root = new MockDirectoryEntry('testVolume', '/', { 155 '/file': 10,
115 '/file': fileEntry, 156 '/directory': DIRECTORY_SIZE
116 '/directory': directoryEntry
117 }); 157 });
158 var root = fileSystem.root;
118 var rootPromise = fileOperationUtil.resolvePath(root, '/'); 159 var rootPromise = fileOperationUtil.resolvePath(root, '/');
119 var filePromise = fileOperationUtil.resolvePath(root, '/file'); 160 var filePromise = fileOperationUtil.resolvePath(root, '/file');
120 var directoryPromise = fileOperationUtil.resolvePath(root, '/directory'); 161 var directoryPromise = fileOperationUtil.resolvePath(root, '/directory');
121 var errorPromise = fileOperationUtil.resolvePath(root, '/not_found').then( 162 var errorPromise = fileOperationUtil.resolvePath(root, '/not_found').then(
122 function() { 163 function() { assertTrue(false, 'The NOT_FOUND error is not reported.'); },
123 assertTrue(false, 'The NOT_FOUND error is not reported.'); 164 function(error) { return error.name; });
124 },
125 function(error) {
126 assertEquals('NotFoundError', error.name);
127 });
128 reportPromise(Promise.all([ 165 reportPromise(Promise.all([
129 rootPromise, 166 rootPromise,
130 filePromise, 167 filePromise,
131 directoryPromise, 168 directoryPromise,
132 errorPromise 169 errorPromise
133 ]).then(function(results) { 170 ]).then(function(results) {
134 assertArrayEquals([ 171 assertArrayEquals([
135 root, 172 fileSystem.entries['/'],
136 fileEntry, 173 fileSystem.entries['/file'],
137 directoryEntry, 174 fileSystem.entries['/directory'],
138 undefined 175 'NotFoundError'
139 ], results); 176 ], results);
140 }), callback); 177 }), callback);
141 } 178 }
142 179
143 /** 180 /**
144 * Tests the fileOperationUtil.deduplicatePath 181 * Tests the fileOperationUtil.deduplicatePath
145 * @param {function(boolean:hasError)} callback Callback to be passed true on 182 * @param {function(boolean:hasError)} callback Callback to be passed true on
146 * error. 183 * error.
147 */ 184 */
148 function testDeduplicatePath(callback) { 185 function testDeduplicatePath(callback) {
149 var directoryEntry1 = new MockDirectoryEntry('testVolume', '/directory', {}); 186 var fileSystem1 = createTestFileSystem('testVolume', {'/': DIRECTORY_SIZE});
150 var directoryEntry2 = new MockDirectoryEntry( 187 var fileSystem2 = createTestFileSystem('testVolume', {
151 'testVolume', 188 '/': DIRECTORY_SIZE,
152 '/directory', 189 '/file.txt': 10
153 {'file.txt': new MockFileEntry('testVolume', '/file.txt', {})}); 190 });
154 var directoryEntry3 = new MockDirectoryEntry( 191 var fileSystem3 = createTestFileSystem('testVolume', {
155 'testVolume', 192 '/': DIRECTORY_SIZE,
156 '/directory', 193 '/file.txt': 10,
157 { 194 '/file (1).txt': 10,
158 'file.txt': new MockFileEntry('testVolume', '/file.txt', {}), 195 '/file (2).txt': 10,
159 'file (1).txt': new MockFileEntry('testVolume', '/file (1).txt', {}), 196 '/file (3).txt': 10,
160 'file (2).txt': new MockFileEntry('testVolume', '/file (2).txt', {}), 197 '/file (4).txt': 10,
161 'file (3).txt': new MockFileEntry('testVolume', '/file (3).txt', {}), 198 '/file (5).txt': 10,
162 'file (4).txt': new MockFileEntry('testVolume', '/file (4).txt', {}), 199 '/file (6).txt': 10,
163 'file (5).txt': new MockFileEntry('testVolume', '/file (5).txt', {}), 200 '/file (7).txt': 10,
164 'file (6).txt': new MockFileEntry('testVolume', '/file (6).txt', {}), 201 '/file (8).txt': 10,
165 'file (7).txt': new MockFileEntry('testVolume', '/file (7).txt', {}), 202 '/file (9).txt': 10,
166 'file (8).txt': new MockFileEntry('testVolume', '/file (8).txt', {}), 203 });
167 'file (9).txt': new MockFileEntry('testVolume', '/file (9).txt', {})
168 });
169 204
170 var nonExistingPromise = 205 var nonExistingPromise =
171 fileOperationUtil.deduplicatePath(directoryEntry1, 'file.txt'). 206 fileOperationUtil.deduplicatePath(fileSystem1.root, 'file.txt').
172 then(function(path) { 207 then(function(path) {
173 assertEquals('file.txt', path); 208 assertEquals('file.txt', path);
174 }); 209 });
175 var existingPathPromise = 210 var existingPathPromise =
176 fileOperationUtil.deduplicatePath(directoryEntry2, 'file.txt'). 211 fileOperationUtil.deduplicatePath(fileSystem2.root, 'file.txt').
177 then(function(path) { 212 then(function(path) {
178 assertEquals('file (1).txt', path); 213 assertEquals('file (1).txt', path);
179 }); 214 });
180 var failedPromise = 215 var failedPromise =
181 fileOperationUtil.deduplicatePath(directoryEntry3, 'file.txt'). 216 fileOperationUtil.deduplicatePath(fileSystem3.root, 'file.txt').
182 then(function() { 217 then(function() {
183 assertTrue(false, 'FileOperationManager.Error is not reported.'); 218 assertTrue(false, 'FileOperationManager.Error is not reported.');
184 }, function(error) { 219 }, function(error) {
185 assertTrue(error instanceof FileOperationManager.Error); 220 assertTrue(error instanceof FileOperationManager.Error);
186 assertEquals(util.FileOperationErrorType.TARGET_EXISTS, error.code); 221 assertEquals(util.FileOperationErrorType.TARGET_EXISTS, error.code);
187 }); 222 });
188 223
189 var testPromise = Promise.all([ 224 var testPromise = Promise.all([
190 nonExistingPromise, 225 nonExistingPromise,
191 existingPathPromise, 226 existingPathPromise,
192 failedPromise 227 failedPromise
193 ]); 228 ]);
194 reportPromise(testPromise, callback); 229 reportPromise(testPromise, callback);
195 } 230 }
196 231
197 /** 232 /**
198 * Tests the fileOperationUtil.paste. 233 * Tests the fileOperationUtil.paste.
234 * @param {function(boolean:hasError)} callback Callback to be passed true on
235 * error.
199 */ 236 */
200 function testCopy(callback) { 237 function testCopy(callback) {
201 // Prepare entries and their resolver. 238 // Prepare entries and their resolver.
202 var sourceEntries = 239 var fileSystem = createTestFileSystem('testVolume', {
203 [new MockFileEntry('testVolume', '/test.txt', {size: 10})]; 240 '/': DIRECTORY_SIZE,
204 var targetEntry = new MockDirectoryEntry('testVolume', '/', {}); 241 '/test.txt': 10,
205 window.webkitResolveLocalFileSystemURL = function(url, success, failure) { 242 });
206 if (url === sourceEntries[0].toURL()) 243 window.webkitResolveLocalFileSystemURL =
207 success(sourceEntries[0]); 244 resolveTestFileSystemURL.bind(null, fileSystem);
208 else if (url === targetEntry.toURL()) 245
209 success(targetEntry); 246 chrome.fileBrowserPrivate.startCopy =
210 else 247 function(source, destination, newName, callback) {
211 failure(); 248 var makeStatus = function(type) {
212 }; 249 return {type: type, sourceUrl: source, destinationUrl: destination};
250 };
251 callback(1);
252 var listener = chrome.fileBrowserPrivate.onCopyProgress.listener_;
253 listener(1, makeStatus('begin_copy_entry'));
254 listener(1, makeStatus('progress'));
255 var newPath = joinPath('/', newName);
256 fileSystem.entries[newPath] =
257 fileSystem.entries['/test.txt'].clone(newPath);
258 listener(1, makeStatus('end_copy_entry'));
259 listener(1, makeStatus('success'));
260 };
213 261
214 // Observing manager's events. 262 // Observing manager's events.
215 var eventsPromise = new Promise(function(fulfill) { 263 var eventsPromise = waitForEvents(fileOperationManager);
216 var events = [];
217 fileOperationManager.addEventListener('copy-progress', function(event) {
218 events.push(event);
219 if (event.reason === 'SUCCESS')
220 fulfill(events);
221 });
222 fileOperationManager.addEventListener('entry-changed', function(event) {
223 events.push(event);
224 });
225 });
226 264
227 // Verify the events. 265 // Verify the events.
228 reportPromise(eventsPromise.then(function(events) { 266 reportPromise(eventsPromise.then(function(events) {
229 var firstEvent = events[0]; 267 var firstEvent = events[0];
230 assertEquals('BEGIN', firstEvent.reason); 268 assertEquals('BEGIN', firstEvent.reason);
231 assertEquals(1, firstEvent.status.numRemainingItems); 269 assertEquals(1, firstEvent.status.numRemainingItems);
232 assertEquals(0, firstEvent.status.processedBytes); 270 assertEquals(0, firstEvent.status.processedBytes);
233 assertEquals(1, firstEvent.status.totalBytes); 271 assertEquals(1, firstEvent.status.totalBytes);
234 272
235 var lastEvent = events[events.length - 1]; 273 var lastEvent = events[events.length - 1];
236 assertEquals('SUCCESS', lastEvent.reason); 274 assertEquals('SUCCESS', lastEvent.reason);
237 assertEquals(0, lastEvent.status.numRemainingItems); 275 assertEquals(0, lastEvent.status.numRemainingItems);
238 assertEquals(10, lastEvent.status.processedBytes); 276 assertEquals(10, lastEvent.status.processedBytes);
239 assertEquals(10, lastEvent.status.totalBytes); 277 assertEquals(10, lastEvent.status.totalBytes);
278
279 assertTrue(events.some(function(event) {
280 return event.type === 'entry-changed' &&
281 event.kind === util.EntryChangedKind.CREATED &&
282 event.entry.fullPath === '/test (1).txt';
283 }));
284
285 assertFalse(events.some(function(event) {
286 return event.type === 'delete';
287 }));
240 }), callback); 288 }), callback);
241 289
242 fileOperationManager.paste(sourceEntries, targetEntry, false); 290 fileOperationManager.paste(
291 [fileSystem.entries['/test.txt']],
292 fileSystem.entries['/'],
293 false);
243 } 294 }
295
296 /**
297 * Tests the fileOperationUtil.paste for move.
298 * @param {function(boolean:hasError)} callback Callback to be passed true on
299 * error.
300 */
301 function testMove(callback) {
302 // Prepare entries and their resolver.
303 var fileSystem = createTestFileSystem('testVolume', {
304 '/': DIRECTORY_SIZE,
305 '/directory': DIRECTORY_SIZE,
306 '/test.txt': 10,
307 });
308 window.webkitResolveLocalFileSystemURL =
309 resolveTestFileSystemURL.bind(null, fileSystem);
310
311 // Observing manager's events.
312 var eventsPromise = waitForEvents(fileOperationManager);
313
314 // Verify the events.
315 reportPromise(eventsPromise.then(function(events) {
316 var firstEvent = events[0];
317 assertEquals('BEGIN', firstEvent.reason);
318 assertEquals(1, firstEvent.status.numRemainingItems);
319 assertEquals(0, firstEvent.status.processedBytes);
320 assertEquals(1, firstEvent.status.totalBytes);
321
322 var lastEvent = events[events.length - 1];
323 assertEquals('SUCCESS', lastEvent.reason);
324 assertEquals(0, lastEvent.status.numRemainingItems);
325 assertEquals(1, lastEvent.status.processedBytes);
326 assertEquals(1, lastEvent.status.totalBytes);
327
328 assertTrue(events.some(function(event) {
329 return event.type === 'entry-changed' &&
330 event.kind === util.EntryChangedKind.DELETED &&
331 event.entry.fullPath === '/test.txt';
332 }));
333
334 assertTrue(events.some(function(event) {
335 return event.type === 'entry-changed' &&
336 event.kind === util.EntryChangedKind.CREATED &&
337 event.entry.fullPath === '/directory/test.txt';
338 }));
339
340 assertFalse(events.some(function(event) {
341 return event.type === 'delete';
342 }));
343 }), callback);
344
345 fileOperationManager.paste(
346 [fileSystem.entries['/test.txt']],
347 fileSystem.entries['/directory'],
348 true);
349 }
350
351 /**
352 * Tests the fileOperationUtil.deleteEntries.
353 * @param {function(boolean:hasError)} callback Callback to be passed true on
354 * error.
355 */
356 function testDelete(callback) {
357 // Prepare entries and their resolver.
358 var fileSystem = createTestFileSystem('testVolume', {
359 '/': DIRECTORY_SIZE,
360 '/test.txt': 10,
361 });
362 window.webkitResolveLocalFileSystemURL =
363 resolveTestFileSystemURL.bind(null, fileSystem);
364
365 // Observing manager's events.
366 reportPromise(waitForEvents(fileOperationManager).then(function(events) {
367 assertEquals('delete', events[0].type);
368 assertEquals('BEGIN', events[0].reason);
369 assertEquals(10, events[0].totalBytes);
370 assertEquals(0, events[0].processedBytes);
371
372 var lastEvent = events[events.length - 1];
373 assertEquals('delete', lastEvent.type);
374 assertEquals('SUCCESS', lastEvent.reason);
375 assertEquals(10, lastEvent.totalBytes);
376 assertEquals(10, lastEvent.processedBytes);
377
378 assertFalse(events.some(function(event) {
379 return event.type === 'copy-progress';
380 }));
381 }), callback);
382
383 fileOperationManager.deleteEntries([fileSystem.entries['/test.txt']]);
384 }
385
386 /**
387 * Tests the fileOperationUtil.zipSelection.
388 * @param {function(boolean:hasError)} callback Callback to be passed true on
389 * error.
390 */
391 function testZip(callback) {
392 // Prepare entries and their resolver.
393 var fileSystem = createTestFileSystem('testVolume', {
394 '/': DIRECTORY_SIZE,
395 '/test.txt': 10,
396 });
397 window.webkitResolveLocalFileSystemURL =
398 resolveTestFileSystemURL.bind(null, fileSystem);
399 chrome.fileBrowserPrivate.zipSelection =
400 function(parentURL, sources, newName, success, error) {
401 var newPath = joinPath('/', newName);
402 var newEntry = new MockFileEntry(fileSystem, newPath, {size: 10});
403 fileSystem.entries[newPath] = newEntry;
404 success(newEntry);
405 };
406
407 // Observing manager's events.
408 reportPromise(waitForEvents(fileOperationManager).then(function(events) {
409 assertEquals('copy-progress', events[0].type);
410 assertEquals('BEGIN', events[0].reason);
411 assertEquals(1, events[0].status.totalBytes);
412 assertEquals(0, events[0].status.processedBytes);
413
414 var lastEvent = events[events.length - 1];
415 assertEquals('copy-progress', lastEvent.type);
416 assertEquals('SUCCESS', lastEvent.reason);
417 assertEquals(10, lastEvent.status.totalBytes);
418 assertEquals(10, lastEvent.status.processedBytes);
419
420 assertFalse(events.some(function(event) {
421 return event.type === 'delete';
422 }));
423
424 assertTrue(events.some(function(event) {
425 return event.type === 'entry-changed' &&
426 event.entry.fullPath === '/test.zip';
427 }));
428 }), callback);
429
430 fileOperationManager.zipSelection(
431 fileSystem.entries['/'],
432 [fileSystem.entries['/test.txt']]);
433 }
OLDNEW
« no previous file with comments | « no previous file | chrome/test/data/file_manager/unit_tests/mocks/mock_entry.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698