Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / test / data / file_manager / unit_tests / file_operation_manager_unittest.js
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 'use strict';
5
6 /**
7  * Mock of chrome.runtime.
8  * @type {Object}
9  * @const
10  */
11 chrome.runtime = {
12   lastError: null
13 };
14
15 /**
16  * Mock of chrome.power.
17  * @type {Object}
18  * @const
19  */
20 chrome.power = {
21   requestKeepAwake: function() {
22     chrome.power.keepAwakeRequested = true;
23   },
24   releaseKeepAwake: function() {
25     chrome.power.keepAwakeRequested = false;
26   },
27   keepAwakeRequested: false
28 };
29
30 /**
31  * Mock of chrome.fileManagerPrivate.
32  * @type {Object}
33  * @const
34  */
35 chrome.fileManagerPrivate = {
36   onCopyProgress: {
37     addListener: function(callback) {
38       chrome.fileManagerPrivate.onCopyProgress.listener_ = callback;
39     },
40     removeListener: function() {
41       chrome.fileManagerPrivate.onCopyProgress.listener_ = null;
42     },
43     listener_: null
44   }
45 };
46
47 /**
48  * Reports the result of promise to the test system.
49  * @param {Promise} promise Promise to be fulfilled or rejected.
50  * @param {function(boolean:hasError)} callback Callback to be passed true on
51  *     error.
52  */
53 function reportPromise(promise, callback) {
54   promise.then(
55       callback.bind(null, false),
56       function(error) {
57         if (error instanceof FileOperationManager.Error) {
58           console.error('FileOperationManager.Error: code=' + error.code);
59         } else {
60           console.error(error.stack || error.name || error);
61         }
62         callback(true);
63       });
64 }
65
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('entries-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 /**
135  * Test target.
136  * @type {FileOperationManager}
137  */
138 var fileOperationManager;
139
140 /**
141  * Initializes the test environment.
142  */
143 function setUp() {
144   fileOperationManager = new FileOperationManager();
145 }
146
147 /**
148  * Tests the fileOperationUtil.resolvePath function.
149  * @param {function(boolean:hasError)} callback Callback to be passed true on
150  *     error.
151  */
152 function testResolvePath(callback) {
153   var fileSystem = createTestFileSystem('testVolume', {
154     '/': DIRECTORY_SIZE,
155     '/file': 10,
156     '/directory': DIRECTORY_SIZE
157   });
158   var root = fileSystem.root;
159   var rootPromise = fileOperationUtil.resolvePath(root, '/');
160   var filePromise = fileOperationUtil.resolvePath(root, '/file');
161   var directoryPromise = fileOperationUtil.resolvePath(root, '/directory');
162   var errorPromise = fileOperationUtil.resolvePath(root, '/not_found').then(
163       function() { assertTrue(false, 'The NOT_FOUND error is not reported.'); },
164       function(error) { return error.name; });
165   reportPromise(Promise.all([
166     rootPromise,
167     filePromise,
168     directoryPromise,
169     errorPromise
170   ]).then(function(results) {
171     assertArrayEquals([
172       fileSystem.entries['/'],
173       fileSystem.entries['/file'],
174       fileSystem.entries['/directory'],
175       'NotFoundError'
176     ], results);
177   }), callback);
178 }
179
180 /**
181  * Tests the fileOperationUtil.deduplicatePath
182  * @param {function(boolean:hasError)} callback Callback to be passed true on
183  *     error.
184  */
185 function testDeduplicatePath(callback) {
186   var fileSystem1 = createTestFileSystem('testVolume', {'/': DIRECTORY_SIZE});
187   var fileSystem2 = createTestFileSystem('testVolume', {
188     '/': DIRECTORY_SIZE,
189     '/file.txt': 10
190   });
191   var fileSystem3 = createTestFileSystem('testVolume', {
192     '/': DIRECTORY_SIZE,
193     '/file.txt': 10,
194     '/file (1).txt': 10,
195     '/file (2).txt': 10,
196     '/file (3).txt': 10,
197     '/file (4).txt': 10,
198     '/file (5).txt': 10,
199     '/file (6).txt': 10,
200     '/file (7).txt': 10,
201     '/file (8).txt': 10,
202     '/file (9).txt': 10,
203   });
204
205   var nonExistingPromise =
206       fileOperationUtil.deduplicatePath(fileSystem1.root, 'file.txt').
207       then(function(path) {
208         assertEquals('file.txt', path);
209       });
210   var existingPathPromise =
211       fileOperationUtil.deduplicatePath(fileSystem2.root, 'file.txt').
212       then(function(path) {
213         assertEquals('file (1).txt', path);
214       });
215   var failedPromise =
216       fileOperationUtil.deduplicatePath(fileSystem3.root, 'file.txt').
217       then(function() {
218         assertTrue(false, 'FileOperationManager.Error is not reported.');
219       }, function(error) {
220         assertTrue(error instanceof FileOperationManager.Error);
221         assertEquals(util.FileOperationErrorType.TARGET_EXISTS, error.code);
222       });
223
224   var testPromise = Promise.all([
225     nonExistingPromise,
226     existingPathPromise,
227     failedPromise
228   ]);
229   reportPromise(testPromise, callback);
230 }
231
232 /**
233  * Tests the fileOperationUtil.paste.
234  * @param {function(boolean:hasError)} callback Callback to be passed true on
235  *     error.
236  */
237 function testCopy(callback) {
238   // Prepare entries and their resolver.
239   var fileSystem = createTestFileSystem('testVolume', {
240     '/': DIRECTORY_SIZE,
241     '/test.txt': 10,
242   });
243   window.webkitResolveLocalFileSystemURL =
244       resolveTestFileSystemURL.bind(null, fileSystem);
245
246   chrome.fileManagerPrivate.startCopy =
247       function(source, destination, newName, callback) {
248         var makeStatus = function(type) {
249           return {type: type, sourceUrl: source, destinationUrl: destination};
250         };
251         callback(1);
252         var listener = chrome.fileManagerPrivate.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       };
261
262   // Observing manager's events.
263   var eventsPromise = waitForEvents(fileOperationManager);
264
265   // Verify the events.
266   reportPromise(eventsPromise.then(function(events) {
267     var firstEvent = events[0];
268     assertEquals('BEGIN', firstEvent.reason);
269     assertEquals(1, firstEvent.status.numRemainingItems);
270     assertEquals(0, firstEvent.status.processedBytes);
271     assertEquals(1, firstEvent.status.totalBytes);
272
273     var lastEvent = events[events.length - 1];
274     assertEquals('SUCCESS', lastEvent.reason);
275     assertEquals(0, lastEvent.status.numRemainingItems);
276     assertEquals(10, lastEvent.status.processedBytes);
277     assertEquals(10, lastEvent.status.totalBytes);
278
279     assertTrue(events.some(function(event) {
280       return event.type === 'entries-changed' &&
281           event.kind === util.EntryChangedKind.CREATED &&
282           event.entries[0].fullPath === '/test (1).txt';
283     }));
284
285     assertFalse(events.some(function(event) {
286       return event.type === 'delete';
287     }));
288   }), callback);
289
290   fileOperationManager.paste(
291       [fileSystem.entries['/test.txt']],
292       fileSystem.entries['/'],
293       false);
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 === 'entries-changed' &&
330           event.kind === util.EntryChangedKind.DELETED &&
331           event.entries[0].fullPath === '/test.txt';
332     }));
333
334     assertTrue(events.some(function(event) {
335       return event.type === 'entries-changed' &&
336           event.kind === util.EntryChangedKind.CREATED &&
337           event.entries[0].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.fileManagerPrivate.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 === 'entries-changed' &&
426           event.entries[0].fullPath === '/test.zip';
427     }));
428   }), callback);
429
430   fileOperationManager.zipSelection(
431       fileSystem.entries['/'],
432       [fileSystem.entries['/test.txt']]);
433 }