Commit f129fcdb authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Commit Bot

Fix crostini DirectoryItem type when using My Files

DirectoryItem created without a specific NavigationModelItem defaults
to SubDirectoryItem. Change DirectoryItem to check if entry has a
NavigationModelItem to generate the appropriate derived "item" type
from DirectoryItem. In particular, crostini will generate FakeItem.
This fixes issue where crostini wouldn't mount because the trigger
to mount is on FakeItem.

Change FakeItem to have updateSharedStatusIcon as no-op, since it
doesn't have a shared state. This fixes an error where DirectoryItem
calls updateSharedStatusIcon on its sub-items, before FakeItem was
used only as top-level so nobody was calling updateSharedStatusIcon.

Change DirectoryTree to call EntryList to update its sub-directories
since those sub-directories are usually volumes that need to update
themselves.

Add test createFolderNestedDownloads to check that EntryListItem call
to updateSubDirectories doesn't have to be recursive.

Change SubDirectoryItem to add "volume-type-for-testing" in test to
fix tests using this selector when running with My Files enabled if
the item is a volume.

Bug: 857335
Cq-Include-Trybots: luci.chromium.try:closure_compilation
Change-Id: I8a579b9c754143d9ba8322aba9014e82a3ac1757
Reviewed-on: https://chromium-review.googlesource.com/1133616
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574811}
parent 9dc77681
......@@ -198,6 +198,7 @@ WRAPPED_INSTANTIATE_TEST_CASE_P(
TestCase("selectCreateFolderDownloads"),
TestCase("createFolderDownloads").InGuestMode(),
TestCase("createFolderDownloads"),
TestCase("createFolderNestedDownloads"),
TestCase("createFolderDrive"),
TestCase("createFolderDrive").EnableDriveFs()));
......
......@@ -209,6 +209,7 @@ DirectoryItem.prototype = {
DirectoryItem.prototype.updateSubElementsFromList = function(recursive) {
var index = 0;
var tree = this.parentTree_;
var item;
while (this.entries_[index]) {
var currentEntry = this.entries_[index];
var currentElement = this.items[index];
......@@ -217,7 +218,14 @@ DirectoryItem.prototype.updateSubElementsFromList = function(recursive) {
currentEntry) || '';
if (index >= this.items.length) {
var item = new SubDirectoryItem(label, currentEntry, this, tree);
// If currentEntry carries its navigationModel we generate an item
// accordingly. Used for Crostini when displayed within My Files.
if (currentEntry.navigationModel) {
item = DirectoryTree.createDirectoryItem(
currentEntry.navigationModel, tree);
} else {
item = new SubDirectoryItem(label, currentEntry, this, tree);
}
this.add(item);
index++;
} else if (util.isSameEntry(currentEntry, currentElement.entry)) {
......@@ -237,7 +245,14 @@ DirectoryItem.prototype.updateSubElementsFromList = function(recursive) {
}
index++;
} else if (currentEntry.toURL() < currentElement.entry.toURL()) {
var item = new SubDirectoryItem(label, currentEntry, this, tree);
// If currentEntry carries its navigationModel we generate an item
// accordingly. Used for Crostini when displayed within My Files.
if (currentEntry.navigationModel) {
item = DirectoryTree.createDirectoryItem(
currentEntry.navigationModel, tree);
} else {
item = new SubDirectoryItem(label, currentEntry, this, tree);
}
this.addAt(item, index);
index++;
} else if (currentEntry.toURL() > currentElement.entry.toURL()) {
......@@ -556,6 +571,10 @@ function SubDirectoryItem(label, dirEntry, parentDirItem, tree) {
var location = tree.volumeManager.getLocationInfo(item.entry);
if (location && location.rootType && location.isRootEntry) {
icon.setAttribute('volume-type-icon', location.rootType);
if (window.IN_TEST && location.volumeInfo) {
item.setAttribute(
'volume-type-for-testing', location.volumeInfo.volumeType);
}
} else {
icon.setAttribute('file-type-icon', 'folder');
item.updateSharedStatusIcon();
......@@ -677,7 +696,7 @@ EntryListItem.prototype.updateSubDirectories = function(
if (this.entry && this.entry.children) {
for (let childEntry of this.entry.children) {
if (childEntry instanceof VolumeEntry) {
// For VolumeEntry we wan't to display its root.
// For VolumeEntry we want to display its root.
this.entries_.push(childEntry.rootEntry);
} else {
this.entries_.push(childEntry);
......@@ -1359,6 +1378,11 @@ FakeItem.prototype.updateSubDirectories = function(
return opt_successCallback && opt_successCallback();
};
/**
* FakeItem doesn't really have shared status/icon so we define here as no-op.
*/
FakeItem.prototype.updateSharedStatusIcon = function() {};
////////////////////////////////////////////////////////////////////////////////
// DirectoryTree
......@@ -1572,14 +1596,20 @@ DirectoryTree.prototype.updateSubElementsFromList = function(recursive) {
// Starts with TOP_SECTION so first section doesn't get the separator line.
var previousSection = NavigationSection.TOP;
while (modelIndex < this.dataModel.length) {
const currentItem = this.items[itemIndex];
if (itemIndex < this.items.length &&
this.items[itemIndex].modelItem === this.dataModel.item(modelIndex)) {
var modelItem = this.items[itemIndex].modelItem;
currentItem.modelItem === this.dataModel.item(modelIndex)) {
var modelItem = currentItem.modelItem;
if (previousSection !== modelItem.section)
this.items[itemIndex].setAttribute('section-start', previousSection);
currentItem.setAttribute('section-start', previousSection);
previousSection = modelItem.section;
if (recursive && this.items[itemIndex] instanceof VolumeItem)
this.items[itemIndex].updateSubDirectories(true);
if (recursive && currentItem instanceof VolumeItem)
currentItem.updateSubDirectories(true);
// EntryListItem can contain volumes that might have been updated: ask
// them to re-draw. It only needs to update the first level of children,
// so it doesn't need to be recursive.
if (currentItem instanceof EntryListItem)
currentItem.updateSubDirectories(false);
} else {
var modelItem = this.dataModel.item(modelIndex);
if (modelItem) {
......
......@@ -53,12 +53,16 @@ function selectFirstListItem(windowId) {
* @param {string} windowId ID of the target window.
* @param {string} path Initial path.
* @param {Array<TestEntryInfo>} initialEntrySet Initial set of entries.
* @param {string} rootLabel label path's root.
* @return {Promise} Promise to be fulfilled on success.
*/
function createNewFolder(windowId, path, initialEntrySet) {
function createNewFolder(windowId, path, initialEntrySet, rootLabel) {
var caller = getCaller();
return Promise.resolve(
).then(function() {
return Promise.resolve()
.then(function() {
return navigateWithDirectoryTree(windowId, path, rootLabel);
})
.then(function() {
// Push Ctrl + E.
return remoteCall.callRemoteTestUtil(
'fakeKeyDown', windowId,
......@@ -165,7 +169,7 @@ testcase.selectCreateFolderDownloads = function() {
}).then(function() {
return remoteCall.waitForElement(windowId, '#detail-table');
}).then(function() {
return createNewFolder(windowId, PATH, BASIC_LOCAL_ENTRY_SET);
return createNewFolder(windowId, '', BASIC_LOCAL_ENTRY_SET, 'Downloads');
});
testPromise(promise);
......@@ -182,7 +186,27 @@ testcase.createFolderDownloads = function() {
}).then(function() {
return remoteCall.waitForElement(windowId, '#detail-table');
}).then(function() {
return createNewFolder(windowId, PATH, BASIC_LOCAL_ENTRY_SET);
return createNewFolder(windowId, '', BASIC_LOCAL_ENTRY_SET, 'Downloads');
});
testPromise(promise);
};
testcase.createFolderNestedDownloads = function() {
var PATH = RootPath.DOWNLOADS;
const expectedPhotosInitialSet = [];
var windowId = null;
var promise = new Promise(function(callback) {
setupAndWaitUntilReady(null, PATH, callback);
}).then(function(results) {
windowId = results.windowId;
return expandRoot(windowId, TREEITEM_DOWNLOADS);
}).then(function() {
return remoteCall.waitForElement(windowId, '#detail-table');
}).then(function() {
return createNewFolder(
windowId, '/photos', expectedPhotosInitialSet, 'Downloads');
});
testPromise(promise);
......@@ -199,7 +223,7 @@ testcase.createFolderDrive = function() {
}).then(function() {
return remoteCall.waitForElement(windowId, '#detail-table');
}).then(function() {
return createNewFolder(windowId, PATH, BASIC_DRIVE_ENTRY_SET);
return createNewFolder(windowId, '', BASIC_DRIVE_ENTRY_SET, 'My Drive');
});
testPromise(promise);
......
......@@ -105,7 +105,7 @@ function expandDirectoryTreeForInternal_(windowId, components, index) {
/**
* Navigates to specified directory on Download volume by using directory tree.
*/
function navigateWithDirectoryTree(windowId, path) {
function navigateWithDirectoryTree(windowId, path, rootLabel) {
return expandDirectoryTreeFor(windowId, path).then(function() {
// Select target path.
return remoteCall.callRemoteTestUtil('fakeMouseClick', windowId,
......@@ -113,7 +113,7 @@ function navigateWithDirectoryTree(windowId, path) {
}).then(function() {
// Wait until the Files app is navigated to the path.
return remoteCall.waitUntilCurrentDirectoryIsChanged(
windowId, `/Downloads${path}`);
windowId, `/${rootLabel}${path}`);
});
}
......@@ -144,7 +144,8 @@ function clickDirectoryTreeContextMenuItem(windowId, path, id) {
*/
function navigateToDestinationDirectoryAndTestPaste(windowId) {
// Navigates to destination directory.
return navigateWithDirectoryTree(windowId, '/destination').then(function() {
return navigateWithDirectoryTree(windowId, '/destination', 'Downloads')
.then(function() {
// Confirm files before paste.
return remoteCall.waitForFiles(windowId, ITEMS_IN_DEST_DIR_BEFORE_PASTE,
{ignoreLastModifiedTime: true});
......@@ -188,7 +189,7 @@ function renameDirectoryFromDirectoryTreeSuccessCase(useKeyboardShortcut) {
var windowId;
return setupForDirectoryTreeContextMenuTest().then(function(id) {
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
return renamePhotosDirectoryTo(windowId, 'New photos', useKeyboardShortcut);
}).then(function() {
......@@ -205,7 +206,7 @@ function renameDirectoryFromDirectoryTreeAndConfirmAlertDialog(newName) {
var windowId;
return setupForDirectoryTreeContextMenuTest().then(function(id) {
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
return renamePhotosDirectoryTo(windowId, newName, false);
}).then(function() {
......@@ -224,7 +225,7 @@ function createDirectoryFromDirectoryTree(
windowId = id;
if (changeCurrentDirectory)
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
else
return expandDownloadVolumeInDirectoryTree(windowId);
}).then(function() {
......@@ -254,7 +255,7 @@ function createDirectoryFromDirectoryTree(
windowId, changeCurrentDirectory ? '/Downloads/photos' : '/Downloads');
}).then(function() {
// Confirm that new directory is actually created by navigating to it.
return navigateWithDirectoryTree(windowId, '/photos/test');
return navigateWithDirectoryTree(windowId, '/photos/test', 'Downloads');
});
}
......@@ -265,7 +266,7 @@ testcase.dirCopyWithContextMenu = function() {
var windowId;
testPromise(setupForDirectoryTreeContextMenuTest().then(function(id) {
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
return clickDirectoryTreeContextMenuItem(windowId, '/photos', 'copy');
}).then(function() {
......@@ -280,7 +281,7 @@ testcase.dirCopyWithKeyboard = function() {
var windowId;
testPromise(setupForDirectoryTreeContextMenuTest().then(function(id) {
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
// Press Ctrl+C.
return remoteCall.callRemoteTestUtil('fakeKeyDown', windowId,
......@@ -312,7 +313,7 @@ testcase.dirCutWithContextMenu = function() {
var windowId;
testPromise(setupForDirectoryTreeContextMenuTest().then(function(id) {
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
return clickDirectoryTreeContextMenuItem(windowId, '/photos', 'cut');
}).then(function() {
......@@ -331,7 +332,7 @@ testcase.dirCutWithKeyboard = function() {
var windowId;
testPromise(setupForDirectoryTreeContextMenuTest().then(function(id) {
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
// Press Ctrl+X.
return remoteCall.callRemoteTestUtil('fakeKeyDown', windowId,
......@@ -371,12 +372,12 @@ testcase.dirPasteWithContextMenu = function() {
testPromise(setupForDirectoryTreeContextMenuTest().then(function(id) {
// Copy photos directory as a test data.
windowId = id;
return navigateWithDirectoryTree(windowId, '/photos');
return navigateWithDirectoryTree(windowId, '/photos', 'Downloads');
}).then(function() {
return remoteCall.callRemoteTestUtil('fakeKeyDown', windowId,
['body', 'c', 'U+0043' /* c */, true /* ctrl */, false, false]);
}).then(function() {
return navigateWithDirectoryTree(windowId, '/destination');
return navigateWithDirectoryTree(windowId, '/destination', 'Downloads');
}).then(function() {
// Confirm files before paste.
return remoteCall.waitForFiles(windowId, ITEMS_IN_DEST_DIR_BEFORE_PASTE,
......
......@@ -12,7 +12,7 @@ testcase.showMyFiles = function() {
'Recent: FakeItem',
'My Files: EntryListItem',
'Downloads: SubDirectoryItem',
'Linux Files: SubDirectoryItem',
'Linux Files: FakeItem',
'Google Drive: DriveVolumeItem',
'My Drive: SubDirectoryItem',
'Shared with me: SubDirectoryItem',
......
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