Commit 84b63242 authored by Noel Gordon's avatar Noel Gordon Committed by Commit Bot

Closure compile navigation_list_model_unittest

 - remove navigation_list_model_unittest.html
 - add BUILD rules to auto-generate and compile this unittest
 - fix MockFolderShortcutDataModel BUILD rule
   - MockFolderShortcutDataModel depends on ui:array_data_model
 - fix FolderShortcutsDataModel BUILD rule
   - FolderShortcutsDataModel depends on cr:event_target
 - add prefix comments to all test cases
   - test cases should describe their intent
 - fix Closure compile errors

Bug: 910991
Change-Id: I8ba2ad3e917473b83011871d94cf17b80ad64d31
Reviewed-on: https://chromium-review.googlesource.com/c/1356731
Commit-Queue: Noel Gordon <noel@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#613016}
parent 471524ed
......@@ -20,8 +20,7 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ActionsModelTest) {
}
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, NavigationListModelTest) {
RunTest(base::FilePath(
FILE_PATH_LITERAL("foreground/js/navigation_list_model_unittest.html")));
RunGeneratedTest("/foreground/js/navigation_list_model_unittest.html");
}
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileOperationHandlerTest) {
......
......@@ -165,6 +165,7 @@ js_library("mock_folder_shortcut_data_model") {
testonly = true
deps = [
"//ui/file_manager/file_manager/common/js:mock_entry",
"//ui/webui/resources/js/cr/ui:array_data_model",
]
}
......@@ -406,6 +407,7 @@ js_library("folder_shortcuts_data_model") {
"//ui/file_manager/file_manager/common/js:async_util",
"//ui/file_manager/file_manager/common/js:metrics",
"//ui/file_manager/file_manager/common/js:util",
"//ui/webui/resources/js/cr:event_target",
]
}
......@@ -526,6 +528,16 @@ js_library("navigation_list_model") {
]
}
js_unittest("navigation_list_model_unittest") {
deps = [
":mock_folder_shortcut_data_model",
":navigation_list_model",
"//ui/file_manager/base/js:mock_chrome",
"//ui/file_manager/base/js:test_error_reporting",
"//ui/file_manager/file_manager/background/js:mock_volume_manager",
]
}
js_library("progress_center_item_group") {
deps = [
"../../common/js:progress_center_common",
......@@ -699,6 +711,7 @@ js_library("webui_command_extender") {
js_unit_tests("unit_tests") {
deps = [
":file_list_model_unittest",
":navigation_list_model_unittest",
":progress_center_item_group_unittest",
":providers_model_unittest",
":spinner_controller_unittest",
......
......@@ -3,13 +3,14 @@
// found in the LICENSE file.
/**
* Mock class for FolderShortcutDataModel.
* @param {...MockEntry} var_args List of the initial shortcuts.
* Mock FolderShortcutDataModel.
* @param {!Array<MockEntry>} args Array of shortcuts.
*
* @extends {cr.ui.ArrayDataModel}
* @constructor
*/
function MockFolderShortcutDataModel(var_args) {
cr.ui.ArrayDataModel.apply(this, arguments);
function MockFolderShortcutDataModel(...args) {
cr.ui.ArrayDataModel.apply(this, args);
}
MockFolderShortcutDataModel.prototype = {
......
<!DOCTYPE html>
<!-- Copyright 2014 The Chromium Authors. All rights reserved.
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.
-->
<cr-menu id="add-new-services-menu">
</cr-menu>
<script src="../../../../../ui/webui/resources/js/cr.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"></script>
<script src="../../../../../ui/webui/resources/js/load_time_data.js"></script>
<script src="../../common/js/files_app_entry_types.js"></script>
<script src="../../../base/js/volume_manager_types.js"></script>
<script src="../../background/js/volume_info_impl.js"></script>
<script src="../../background/js/volume_info_list_impl.js"></script>
<script src="../../background/js/volume_manager_factory.js"></script>
<script src="../../background/js/volume_manager_impl.js"></script>
<script src="../../background/js/volume_manager_util.js"></script>
<script src="../../background/js/mock_volume_manager.js"></script>
<script src="../../common/js/async_util.js"></script>
<script src="../../common/js/mock_entry.js"></script>
<script src="../../../base/js/test_error_reporting.js"></script>
<script src="../../../base/js/mock_chrome.js"></script>
<script src="../../common/js/unittest_util.js"></script>
<script src="../../common/js/util.js"></script>
<script src="mock_folder_shortcut_data_model.js"></script>
<script src="navigation_list_model.js"></script>
<script src="navigation_list_model_unittest.js"></script>
......@@ -2,13 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/** @type {!MockFileSystem} Simulate the drive file system. */
'use strict';
/**
* Mock Recent fake entry.
* @type {!FilesAppEntry}
*/
const recentFakeEntry =
/** @type {!FilesAppEntry} */ ({toURL: () => 'fake-entry://recent'});
/**
* Drive file system.
* @type {!MockFileSystem}
*/
var drive;
/** @type {!MockFileSystem} Simulate a removable volume. */
/**
* Removable volume file system.
* @type {!MockFileSystem}
*/
var hoge;
// Setup the test components.
function setUp() {
// Mock LoadTimeData strings.
window.loadTimeData.data = {
MY_FILES_VOLUME_ENABLED: false,
MY_FILES_ROOT_LABEL: 'My files',
......@@ -18,154 +35,236 @@ function setUp() {
window.loadTimeData.getString = id => {
return window.loadTimeData.data_[id] || id;
};
// Mock chrome APIs.
new MockCommandLinePrivate();
// Override VolumeInfo.prototype.resolveDisplayRoot to be sync.
VolumeInfoImpl.prototype.resolveDisplayRoot = function(successCallback) {
this.displayRoot_ = this.fileSystem_.root;
successCallback(this.displayRoot_);
return Promise.resolve(this.fileSystem_.root);
};
// TODO(crbug.com/834103): Add integration test for Crostini.
// Create mock file systems.
drive = new MockFileSystem('drive');
hoge = new MockFileSystem('removable:hoge');
}
/**
* Tests model.
*/
function testModel() {
var volumeManager = new MockVolumeManager();
var shortcutListModel = new MockFolderShortcutDataModel(
[new MockFileEntry(drive, '/root/shortcut')]);
var recentItem = new NavigationModelFakeItem(
'recent-label', NavigationModelItemType.RECENT,
{toURL: () => 'fake-entry://recent'});
var model =
new NavigationListModel(volumeManager, shortcutListModel, recentItem);
model.linuxFilesItem = new NavigationModelFakeItem(
'recent-label', NavigationModelItemType.RECENT, recentFakeEntry);
var crostiniFakeItem = new NavigationModelFakeItem(
'linux-files-label', NavigationModelItemType.CROSTINI,
new FakeEntry(
'linux-files-label', VolumeManagerCommon.RootType.CROSTINI));
var model =
new NavigationListModel(volumeManager, shortcutListModel, recentItem);
model.linuxFilesItem = crostiniFakeItem;
assertEquals(4, model.length);
assertEquals('fake-entry://recent', model.item(0).entry.toURL());
assertEquals('/root/shortcut', model.item(1).entry.fullPath);
assertEquals(
'fake-entry://recent', /** @type {!NavigationModelFakeItem} */
(model.item(0)).entry.toURL());
assertEquals(
'/root/shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(1)).entry.fullPath);
assertEquals('My files', model.item(2).label);
assertEquals('drive', model.item(3).volumeInfo.volumeId);
assertEquals(
'drive', /** @type {!NavigationModelVolumeItem} */
(model.item(3)).volumeInfo.volumeId);
// Downloads and Crostini are displayed within My files.
const myFilesEntry = model.item(2).entry;
assertEquals(2, myFilesEntry.getUIChildren().length);
assertEquals('Downloads', myFilesEntry.getUIChildren()[0].name);
assertEquals('linux-files-label', myFilesEntry.getUIChildren()[1].name);
const myFilesItem = /** @type NavigationModelFakeItem */ (model.item(2));
const myFilesEntryList = /** @type {!EntryList} */ (myFilesItem.entry);
assertEquals(2, myFilesEntryList.getUIChildren().length);
assertEquals('Downloads', myFilesEntryList.getUIChildren()[0].name);
assertEquals('linux-files-label', myFilesEntryList.getUIChildren()[1].name);
}
/**
* Tests model with no Recents, Linux files, Play files.
*/
function testNoRecentOrLinuxFiles() {
var volumeManager = new MockVolumeManager();
var shortcutListModel = new MockFolderShortcutDataModel(
[new MockFileEntry(drive, '/root/shortcut')]);
var recentItem = null;
var model =
new NavigationListModel(volumeManager, shortcutListModel, recentItem);
assertEquals(3, model.length);
assertEquals('/root/shortcut', model.item(0).entry.fullPath);
assertEquals(
'/root/shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).entry.fullPath);
assertEquals('My files', model.item(1).label);
assertEquals('drive', model.item(2).volumeInfo.volumeId);
assertEquals(
'drive', /** @type {!NavigationModelVolumeItem} */
(model.item(2)).volumeInfo.volumeId);
}
/**
* Tests adding and removing shortcuts.
*/
function testAddAndRemoveShortcuts() {
var volumeManager = new MockVolumeManager();
var shortcutListModel = new MockFolderShortcutDataModel(
[new MockFileEntry(drive, '/root/shortcut')]);
var recentItem = null;
var model =
new NavigationListModel(volumeManager, shortcutListModel, recentItem);
assertEquals(3, model.length);
// Add a shortcut at the tail, shortcuts are sorted by their label.
shortcutListModel.splice(1, 0, new MockFileEntry(drive, '/root/shortcut2'));
const addShortcut = new MockFileEntry(drive, '/root/shortcut2');
shortcutListModel.splice(1, 0, addShortcut);
assertEquals(4, model.length);
assertEquals('shortcut', model.item(0).label);
assertEquals('shortcut2', model.item(1).label);
assertEquals(
'shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).label);
assertEquals(
'shortcut2', /** @type {!NavigationModelShortcutItem} */
(model.item(1)).label);
// Add a shortcut at the head.
shortcutListModel.splice(0, 0, new MockFileEntry(drive, '/root/hoge'));
const headShortcut = new MockFileEntry(drive, '/root/head');
shortcutListModel.splice(0, 0, headShortcut);
assertEquals(5, model.length);
assertEquals('hoge', model.item(0).label);
assertEquals('shortcut', model.item(1).label);
assertEquals('shortcut2', model.item(2).label);
assertEquals(
'head', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).label);
assertEquals(
'shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(1)).label);
assertEquals(
'shortcut2', /** @type {!NavigationModelShortcutItem} */
(model.item(2)).label);
// Remove the last shortcut.
shortcutListModel.splice(2, 1);
assertEquals(4, model.length);
assertEquals('hoge', model.item(0).label);
assertEquals('shortcut', model.item(1).label);
assertEquals(
'head', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).label);
assertEquals(
'shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(1)).label);
// Remove the first shortcut.
shortcutListModel.splice(0, 1);
assertEquals(3, model.length);
assertEquals('shortcut', model.item(0).label);
assertEquals(
'shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).label);
}
/**
* Tests adding and removing volumes.
*/
function testAddAndRemoveVolumes() {
var volumeManager = new MockVolumeManager();
var shortcutListModel = new MockFolderShortcutDataModel(
[new MockFileEntry(drive, '/root/shortcut')]);
var recentItem = null;
var model =
new NavigationListModel(volumeManager, shortcutListModel, recentItem);
assertEquals(3, model.length);
// Removable volume 'hoge' is mounted.
// Mount removable volume 'hoge'.
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.REMOVABLE, 'removable:hoge'));
assertEquals(4, model.length);
assertEquals('/root/shortcut', model.item(0).entry.fullPath);
assertEquals(
'/root/shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).entry.fullPath);
assertEquals('My files', model.item(1).label);
assertEquals('drive', model.item(2).volumeInfo.volumeId);
assertEquals('removable:hoge', model.item(3).volumeInfo.volumeId);
assertEquals(
'drive', /** @type {!NavigationModelVolumeItem} */
(model.item(2)).volumeInfo.volumeId);
assertEquals(
'removable:hoge', /** @type {!NavigationModelVolumeItem} */
(model.item(3)).volumeInfo.volumeId);
// Removable volume 'fuga' is mounted.
// Mount removable volume 'fuga'.
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.REMOVABLE, 'removable:fuga'));
assertEquals(5, model.length);
assertEquals('/root/shortcut', model.item(0).entry.fullPath);
assertEquals(
'/root/shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).entry.fullPath);
assertEquals('My files', model.item(1).label);
assertEquals('drive', model.item(2).volumeInfo.volumeId);
assertEquals('removable:hoge', model.item(3).volumeInfo.volumeId);
assertEquals('removable:fuga', model.item(4).volumeInfo.volumeId);
assertEquals(
'drive', /** @type {!NavigationModelVolumeItem} */
(model.item(2)).volumeInfo.volumeId);
assertEquals(
'removable:hoge', /** @type {!NavigationModelVolumeItem} */
(model.item(3)).volumeInfo.volumeId);
assertEquals(
'removable:fuga', /** @type {!NavigationModelVolumeItem} */
(model.item(4)).volumeInfo.volumeId);
// A shortcut is created on the 'hoge' volume.
// Create a shortcut on the 'hoge' volume.
shortcutListModel.splice(
1, 0, new MockFileEntry(hoge, '/shortcut2'));
assertEquals(6, model.length);
assertEquals('/root/shortcut', model.item(0).entry.fullPath);
assertEquals('/shortcut2', model.item(1).entry.fullPath);
assertEquals(
'/root/shortcut', /** @type {!NavigationModelShortcutItem} */
(model.item(0)).entry.fullPath);
assertEquals(
'/shortcut2', /** @type {!NavigationModelShortcutItem} */
(model.item(1)).entry.fullPath);
assertEquals('My files', model.item(2).label);
assertEquals('drive', model.item(3).volumeInfo.volumeId);
assertEquals('removable:hoge', model.item(4).volumeInfo.volumeId);
assertEquals('removable:fuga', model.item(5).volumeInfo.volumeId);
assertEquals(
'drive', /** @type {!NavigationModelVolumeItem} */
(model.item(3)).volumeInfo.volumeId);
assertEquals(
'removable:hoge', /** @type {!NavigationModelVolumeItem} */
(model.item(4)).volumeInfo.volumeId);
assertEquals(
'removable:fuga', /** @type {!NavigationModelVolumeItem} */
(model.item(5)).volumeInfo.volumeId);
}
/**
* Checks that orderAndNestItems_ function does the following:
* Tests that orderAndNestItems_ function does the following:
* 1. produces the expected order of volumes.
* 2. manages NavigationSection for the relevant volumes.
* 3. keeps MTP/Archive/Removable volumes on the original order.
*/
function testOrderAndNestItems() {
const volumeManager = new MockVolumeManager();
const shortcutListModel = new MockFolderShortcutDataModel([
new MockFileEntry(drive, '/root/shortcut'),
new MockFileEntry(drive, '/root/shortcut2')
]);
const recentItem = new NavigationModelFakeItem(
'recent-label', NavigationModelItemType.RECENT,
{toURL: () => 'fake-entry://recent'});
const zipVolumeId = 'provided:dmboannefpncccogfdikhmhpmdnddgoe:' +
'~%2FDownloads%2Fazip_file%2Ezip:' +
'096eaa592ea7e8ffb9a27435e50dabd6c809c125';
'recent-label', NavigationModelItemType.RECENT, recentFakeEntry);
// Create different volumes.
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
......@@ -188,7 +287,11 @@ function testOrderAndNestItems() {
VolumeManagerCommon.VolumeType.MEDIA_VIEW, 'media_view:videos_root'));
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.MEDIA_VIEW, 'media_view:audio_root'));
// ZipArchiver mounts zip files as PROVIDED volume type.
// ZipArchiver mounts zip files as a PROVIDED volume type.
const zipVolumeId = 'provided:dmboannefpncccogfdikhmhpmdnddgoe:' +
'~%2FDownloads%2Fazip_file%2Ezip:' +
'096eaa592ea7e8ffb9a27435e50dabd6c809c125';
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.PROVIDED, zipVolumeId));
......@@ -279,41 +382,45 @@ function testOrderAndNestItems() {
assertEquals(NavigationSection.REMOVABLE, model.item(14).section);
const myFilesModel = model.item(6);
// Re-order again.
model.orderAndNestItems_();
// Check if My Files continues on the same position.
// Re-order again: cast to allow calling this private model function.
/** @type {!Object} */ (model).orderAndNestItems_();
// Check if My Files is still in the same position.
assertEquals(NavigationSection.MY_FILES, model.item(6).section);
// Check if My Files model is still the same instance, because DirectoryTree
// expects it to be the same instance to be able to find it on the tree.
assertEquals(myFilesModel, model.item(6));
}
/**
* Tests model with My files enabled.
*/
function testMyFilesVolumeEnabled(callback) {
// Enable My files.
loadTimeData.data_['MY_FILES_VOLUME_ENABLED'] = true;
const volumeManager = new MockVolumeManager();
// Index 1 is Downloads.
// Item 1 of the volume info list should have Downloads volume type.
assertEquals(
VolumeManagerCommon.VolumeType.DOWNLOADS,
volumeManager.volumeInfoList.item(1).volumeType);
// Create a downloads folder inside it.
// Create a downloads folder inside the item.
const downloadsVolume = volumeManager.volumeInfoList.item(1);
downloadsVolume.fileSystem.populate(['/Downloads/']);
/** @type {!MockFileSystem} */ (downloadsVolume.fileSystem).populate([
'/Downloads/'
]);
const shortcutListModel = new MockFolderShortcutDataModel([]);
const recentItem = null;
// Create Android 'Play files' volume.
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.ANDROID_FILES, 'android_files:droid'));
const crostiniFakeItem = new NavigationModelFakeItem(
'linux-files-label', NavigationModelItemType.CROSTINI,
new FakeEntry(
'linux-files-label', VolumeManagerCommon.RootType.CROSTINI));
// Create Android volume.
volumeManager.volumeInfoList.add(MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.ANDROID_FILES, 'android_files:droid'));
// Navigation items built above:
// 1. My files
// -> Play files
......@@ -330,19 +437,21 @@ function testMyFilesVolumeEnabled(callback) {
assertEquals('My Drive', model.item(1).label);
// Android and Crostini are displayed within My files. And there is no
// Downloads volume inside it. Downloads should be a normal folder inside My
// files volume.
const myFilesEntry = model.item(0).entry;
assertEquals(2, myFilesEntry.children_.length);
assertEquals('android_files:droid', myFilesEntry.children_[0].name);
assertEquals('linux-files-label', myFilesEntry.children_[1].name);
const reader = myFilesEntry.createReader();
// Downloads volume inside it. Downloads should be a normal folder inside
// the My files volume.
const myFilesItem = /** @type NavigationModelFakeItem */ (model.item(0));
const myFilesEntryList = /** @type {!EntryList} */ (myFilesItem.entry);
assertEquals(2, myFilesEntryList.getUIChildren().length);
assertEquals('android_files:droid', myFilesEntryList.getUIChildren()[0].name);
assertEquals('linux-files-label', myFilesEntryList.getUIChildren()[1].name);
const reader = myFilesEntryList.createReader();
const foundEntries = [];
reader.readEntries((entries) => {
for (entry of entries)
for (const entry of entries)
foundEntries.push(entry);
});
reportPromise(
waitUntil(() => {
// Wait for Downloads folder to be read from My files volume.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment