Commit 367235e1 authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

Support /.files-by-id/<id> prefixes for shared with me in LocationLine.

LocationLine assumes DRIVE_OTHER entries will be of the form
/other/path/to/file. With DriveFS, they are instead of the form
/.files-by-id/<id>/path/to/file. Support correct breadcrumbs for
directories within shared with me by treating /.files-by-id/<id> as the
prefix instead of /other when the path starts with that pattern.

Bug: 854481
Tbr: slangley@chromium.org
Change-Id: I91b55c6fbae3458b4f0f4599fc969b3c1b1fa2e8
Reviewed-on: https://chromium-review.googlesource.com/1245343
Commit-Queue: Sam McNally <sammc@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594948}
parent 0e18cb68
...@@ -116,7 +116,7 @@ struct AddEntriesMessage { ...@@ -116,7 +116,7 @@ struct AddEntriesMessage {
enum EntryType { FILE, DIRECTORY, TEAM_DRIVE }; enum EntryType { FILE, DIRECTORY, TEAM_DRIVE };
// Represents whether an entry appears in 'Share with Me' or not. // Represents whether an entry appears in 'Share with Me' or not.
enum SharedOption { NONE, SHARED }; enum SharedOption { NONE, SHARED, SHARED_WITH_ME, NESTED_SHARED_WITH_ME };
// The actual AddEntriesMessage contents. // The actual AddEntriesMessage contents.
...@@ -278,6 +278,10 @@ struct AddEntriesMessage { ...@@ -278,6 +278,10 @@ struct AddEntriesMessage {
SharedOption* option) { SharedOption* option) {
if (value == "shared") if (value == "shared")
*option = SHARED; *option = SHARED;
else if (value == "sharedWithMe")
*option = SHARED_WITH_ME;
else if (value == "nestedSharedWithMe")
*option = NESTED_SHARED_WITH_ME;
else if (value == "none") else if (value == "none")
*option = NONE; *option = NONE;
else else
...@@ -685,12 +689,16 @@ class DriveTestVolume : public TestVolume { ...@@ -685,12 +689,16 @@ class DriveTestVolume : public TestVolume {
case AddEntriesMessage::FILE: case AddEntriesMessage::FILE:
CreateFile(entry.source_file_name, parent_entry->resource_id(), CreateFile(entry.source_file_name, parent_entry->resource_id(),
target_name, entry.mime_type, target_name, entry.mime_type,
entry.shared_option == AddEntriesMessage::SHARED, entry.shared_option == AddEntriesMessage::SHARED ||
entry.shared_option == AddEntriesMessage::SHARED_WITH_ME,
entry.last_modified_time, file_capabilities); entry.last_modified_time, file_capabilities);
break; break;
case AddEntriesMessage::DIRECTORY: case AddEntriesMessage::DIRECTORY:
CreateDirectory(parent_entry->resource_id(), target_name, CreateDirectory(
entry.last_modified_time, file_capabilities); parent_entry->resource_id(), target_name, entry.last_modified_time,
entry.shared_option == AddEntriesMessage::SHARED ||
entry.shared_option == AddEntriesMessage::SHARED_WITH_ME,
file_capabilities);
break; break;
case AddEntriesMessage::TEAM_DRIVE: case AddEntriesMessage::TEAM_DRIVE:
CreateTeamDrive(entry.team_drive_name, team_drive_capabilities); CreateTeamDrive(entry.team_drive_name, team_drive_capabilities);
...@@ -716,6 +724,7 @@ class DriveTestVolume : public TestVolume { ...@@ -716,6 +724,7 @@ class DriveTestVolume : public TestVolume {
const std::string& parent_id, const std::string& parent_id,
const std::string& target_name, const std::string& target_name,
const base::Time& modification_time, const base::Time& modification_time,
bool shared_with_me,
const google_apis::FileResourceCapabilities& capabilities) { const google_apis::FileResourceCapabilities& capabilities) {
google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
...@@ -740,6 +749,11 @@ class DriveTestVolume : public TestVolume { ...@@ -740,6 +749,11 @@ class DriveTestVolume : public TestVolume {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_TRUE(error == google_apis::HTTP_SUCCESS); ASSERT_TRUE(error == google_apis::HTTP_SUCCESS);
ASSERT_TRUE(entry); ASSERT_TRUE(entry);
if (shared_with_me) {
ASSERT_EQ(google_apis::HTTP_SUCCESS,
fake_drive_service_->SetFileAsSharedWithMe(entry->file_id()));
}
} }
// Creates a test file with the given spec. // Creates a test file with the given spec.
...@@ -837,13 +851,15 @@ class DriveFsTestVolume : public DriveTestVolume { ...@@ -837,13 +851,15 @@ class DriveFsTestVolume : public DriveTestVolume {
const base::FilePath target_path = GetTargetPathForTestEntry(entry); const base::FilePath target_path = GetTargetPathForTestEntry(entry);
entries_.insert(std::make_pair(target_path, entry)); entries_.insert(std::make_pair(target_path, entry));
fake_drivefs_->SetMetadata(
GetRelativeDrivePathForTestEntry(entry), entry.mime_type,
base::FilePath(entry.target_path).BaseName().value(), entry.pinned,
entry.shared_option == AddEntriesMessage::SharedOption::SHARED ||
entry.shared_option ==
AddEntriesMessage::SharedOption::SHARED_WITH_ME);
switch (entry.type) { switch (entry.type) {
case AddEntriesMessage::FILE: { case AddEntriesMessage::FILE: {
fake_drivefs_->SetMetadata(
GetRelativeDrivePathForTestEntry(entry), entry.mime_type,
base::FilePath(entry.target_path).BaseName().value(), entry.pinned,
entry.shared_option == AddEntriesMessage::SharedOption::SHARED);
if (entry.source_file_name.empty()) { if (entry.source_file_name.empty()) {
ASSERT_EQ(0, base::WriteFile(target_path, "", 0)); ASSERT_EQ(0, base::WriteFile(target_path, "", 0));
break; break;
...@@ -908,7 +924,8 @@ class DriveFsTestVolume : public DriveTestVolume { ...@@ -908,7 +924,8 @@ class DriveFsTestVolume : public DriveTestVolume {
// Update the modified time of parent directories because they may be // Update the modified time of parent directories because they may be
// also affected by the update of child items. // also affected by the update of child items.
if (path.DirName() != GetTeamDriveGrandRoot() && if (path.DirName() != GetTeamDriveGrandRoot() &&
path.DirName() != GetMyDrivePath()) { path.DirName() != GetMyDrivePath() &&
path.DirName() != GetSharedWithMePath()) {
const auto it = entries_.find(path.DirName()); const auto it = entries_.find(path.DirName());
if (it == entries_.end()) if (it == entries_.end())
return false; return false;
...@@ -921,14 +938,24 @@ class DriveFsTestVolume : public DriveTestVolume { ...@@ -921,14 +938,24 @@ class DriveFsTestVolume : public DriveTestVolume {
base::FilePath GetTargetPathForTestEntry( base::FilePath GetTargetPathForTestEntry(
const AddEntriesMessage::TestEntryInfo& entry) { const AddEntriesMessage::TestEntryInfo& entry) {
const base::FilePath target_path = const base::FilePath target_path =
entry.team_drive_name.empty() GetTargetBasePathForTestEntry(entry).Append(entry.target_path);
? GetMyDrivePath().Append(entry.target_path)
: GetTeamDrivePath(entry.team_drive_name).Append(entry.target_path);
if (entry.name_text != entry.target_path) if (entry.name_text != entry.target_path)
return target_path.DirName().Append(entry.name_text); return target_path.DirName().Append(entry.name_text);
return target_path; return target_path;
} }
base::FilePath GetTargetBasePathForTestEntry(
const AddEntriesMessage::TestEntryInfo& entry) {
if (entry.shared_option == AddEntriesMessage::SHARED_WITH_ME ||
entry.shared_option == AddEntriesMessage::NESTED_SHARED_WITH_ME) {
return GetSharedWithMePath();
}
if (!entry.team_drive_name.empty()) {
return GetTeamDrivePath(entry.team_drive_name);
}
return GetMyDrivePath();
}
base::FilePath GetRelativeDrivePathForTestEntry( base::FilePath GetRelativeDrivePathForTestEntry(
const AddEntriesMessage::TestEntryInfo& entry) { const AddEntriesMessage::TestEntryInfo& entry) {
const base::FilePath target_path = GetTargetPathForTestEntry(entry); const base::FilePath target_path = GetTargetPathForTestEntry(entry);
...@@ -945,6 +972,10 @@ class DriveFsTestVolume : public DriveTestVolume { ...@@ -945,6 +972,10 @@ class DriveFsTestVolume : public DriveTestVolume {
return mount_path().Append("team_drives"); return mount_path().Append("team_drives");
} }
base::FilePath GetSharedWithMePath() {
return mount_path().Append(".files-by-id/123");
}
base::FilePath GetTeamDrivePath(const std::string& team_drive_name) { base::FilePath GetTeamDrivePath(const std::string& team_drive_name) {
return GetTeamDriveGrandRoot().Append(team_drive_name); return GetTeamDriveGrandRoot().Append(team_drive_name);
} }
...@@ -1208,6 +1239,11 @@ void FileManagerBrowserTestBase::OnCommand(const std::string& name, ...@@ -1208,6 +1239,11 @@ void FileManagerBrowserTestBase::OnCommand(const std::string& name,
return; return;
} }
if (name == "getDriveFsEnabled") {
*output = IsDriveFsTest() ? "true" : "false";
return;
}
if (name == "getRootPaths") { if (name == "getRootPaths") {
// Obtain the root paths. // Obtain the root paths.
const auto downloads_root = util::GetDownloadsMountPointName(profile()); const auto downloads_root = util::GetDownloadsMountPointName(profile());
......
...@@ -120,7 +120,9 @@ class FakeDriveFs::SearchQuery : public mojom::SearchQuery { ...@@ -120,7 +120,9 @@ class FakeDriveFs::SearchQuery : public mojom::SearchQuery {
static std::vector<drivefs::mojom::QueryItemPtr> SearchFiles( static std::vector<drivefs::mojom::QueryItemPtr> SearchFiles(
const base::FilePath& mount_path) { const base::FilePath& mount_path) {
std::vector<drivefs::mojom::QueryItemPtr> results; std::vector<drivefs::mojom::QueryItemPtr> results;
base::FileEnumerator walker(mount_path, true, base::FileEnumerator::FILES); base::FileEnumerator walker(
mount_path, true,
base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
for (auto file = walker.Next(); !file.empty(); file = walker.Next()) { for (auto file = walker.Next(); !file.empty(); file = walker.Next()) {
auto item = drivefs::mojom::QueryItem::New(); auto item = drivefs::mojom::QueryItem::New();
item->path = base::FilePath("/"); item->path = base::FilePath("/");
...@@ -157,29 +159,26 @@ class FakeDriveFs::SearchQuery : public mojom::SearchQuery { ...@@ -157,29 +159,26 @@ class FakeDriveFs::SearchQuery : public mojom::SearchQuery {
void OnComplete() { void OnComplete() {
if (--pending_callbacks_ == 0) { if (--pending_callbacks_ == 0) {
if (!query_.empty() || available_offline_ || shared_with_me_) { // Filter out non-matching results.
// Filter out non-matching results. base::EraseIf(results_, [=](const auto& item_ptr) {
base::EraseIf(results_, [=](const auto& item_ptr) { if (!item_ptr->metadata) {
const base::FilePath path = item_ptr->path;
const drivefs::mojom::FileMetadata* metadata =
item_ptr->metadata.get();
if (!query_.empty()) {
return base::ToLowerASCII(path.BaseName().value()).find(query_) ==
std::string::npos;
}
if (available_offline_) {
if (metadata && metadata->available_offline)
return false;
if (metadata &&
metadata->type == mojom::FileMetadata::Type::kHosted)
return false;
}
if (shared_with_me_ && metadata) {
return !metadata->shared;
}
return true; return true;
}); }
} const base::FilePath path = item_ptr->path;
const drivefs::mojom::FileMetadata* metadata = item_ptr->metadata.get();
if (!query_.empty()) {
return base::ToLowerASCII(path.BaseName().value()).find(query_) ==
std::string::npos;
}
if (available_offline_) {
return !metadata->available_offline &&
metadata->type != mojom::FileMetadata::Type::kHosted;
}
if (shared_with_me_) {
return !metadata->shared;
}
return false;
});
std::move(callback_).Run(drive::FileError::FILE_ERROR_OK, std::move(callback_).Run(drive::FileError::FILE_ERROR_OK,
{std::move(results_)}); {std::move(results_)});
......
...@@ -1563,6 +1563,19 @@ google_apis::DriveApiErrorCode FakeDriveService::GetFileVisibility( ...@@ -1563,6 +1563,19 @@ google_apis::DriveApiErrorCode FakeDriveService::GetFileVisibility(
return HTTP_SUCCESS; return HTTP_SUCCESS;
} }
google_apis::DriveApiErrorCode FakeDriveService::SetFileAsSharedWithMe(
const std::string& resource_id) {
DCHECK(thread_checker_.CalledOnValidThread());
EntryInfo* entry = FindEntryByResourceId(resource_id);
if (!entry)
return HTTP_NOT_FOUND;
entry->change_resource.mutable_file()->set_shared_with_me_date(
base::Time::Now());
return HTTP_SUCCESS;
}
void FakeDriveService::AddChangeObserver(ChangeObserver* change_observer) { void FakeDriveService::AddChangeObserver(ChangeObserver* change_observer) {
change_observers_.AddObserver(change_observer); change_observers_.AddObserver(change_observer);
} }
......
...@@ -332,6 +332,9 @@ class FakeDriveService : public DriveServiceInterface { ...@@ -332,6 +332,9 @@ class FakeDriveService : public DriveServiceInterface {
const std::string& resource_id, const std::string& resource_id,
google_apis::drive::FileVisibility* visibility); google_apis::drive::FileVisibility* visibility);
google_apis::DriveApiErrorCode SetFileAsSharedWithMe(
const std::string& resource_id);
void AddChangeObserver(ChangeObserver* observer); void AddChangeObserver(ChangeObserver* observer);
void RemoveChangeObserver(ChangeObserver* observer); void RemoveChangeObserver(ChangeObserver* observer);
......
...@@ -89,8 +89,13 @@ LocationLine.prototype.getComponents_ = function(entry) { ...@@ -89,8 +89,13 @@ LocationLine.prototype.getComponents_ = function(entry) {
} }
if (locationInfo.rootType === VolumeManagerCommon.RootType.DRIVE_OTHER) { if (locationInfo.rootType === VolumeManagerCommon.RootType.DRIVE_OTHER) {
// When target path is a shared directory, volume should be shared with me. // When target path is a shared directory, volume should be shared with me.
displayRootUrl = this.replaceRootName_(displayRootUrl, '/other'); const match = entry.fullPath.match(/\/\.files-by-id\/\d+\//);
displayRootFullPath = '/other'; if (match) {
displayRootFullPath = match[0];
} else {
displayRootFullPath = '/other';
}
displayRootUrl = this.replaceRootName_(displayRootUrl, displayRootFullPath);
var sharedWithMeFakeEntry = locationInfo.volumeInfo.fakeEntries[ var sharedWithMeFakeEntry = locationInfo.volumeInfo.fakeEntries[
VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME]; VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME];
components.push(new LocationLine.PathComponent( components.push(new LocationLine.PathComponent(
......
...@@ -119,10 +119,20 @@ testcase.driveOpenSidebarOffline = function() { ...@@ -119,10 +119,20 @@ testcase.driveOpenSidebarOffline = function() {
* "shared-with-me" should be shown. * "shared-with-me" should be shown.
*/ */
testcase.driveOpenSidebarSharedWithMe = function() { testcase.driveOpenSidebarSharedWithMe = function() {
var appId; let appId;
let isDriveFsEnabled;
StepsRunner.run([ StepsRunner.run([
function() { function() {
setupAndWaitUntilReady(null, RootPath.DRIVE, this.next); sendTestMessage({name: 'getDriveFsEnabled'}).then(this.next);
},
function(result) {
isDriveFsEnabled = result === 'true';
setupAndWaitUntilReady(
null, RootPath.DRIVE, this.next, [], BASIC_DRIVE_ENTRY_SET.concat([
ENTRIES.sharedDirectory,
ENTRIES.sharedDirectoryFile,
]));
}, },
// Click the icon of the Shared With Me volume. // Click the icon of the Shared With Me volume.
function(results) { function(results) {
...@@ -132,17 +142,45 @@ testcase.driveOpenSidebarSharedWithMe = function() { ...@@ -132,17 +142,45 @@ testcase.driveOpenSidebarSharedWithMe = function() {
appId, appId,
['drive_shared_with_me'], this.next); ['drive_shared_with_me'], this.next);
}, },
// Wait until the file list is updated. // Wait until the breadcrumb path is updated.
function(result) { function(result) {
chrome.test.assertFalse(!result); chrome.test.assertFalse(!result);
remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length). remoteCall.waitUntilCurrentDirectoryIsChanged(appId, '/Shared with me')
then(this.next); .then(this.next);
}, },
// Verify the file list. // Verify the file list.
function(actualFilesAfter) { function() {
chrome.test.assertEq( remoteCall
TestEntryInfo.getExpectedRows(SHARED_WITH_ME_ENTRY_SET).sort(), .waitForFiles(
actualFilesAfter); appId,
TestEntryInfo.getExpectedRows(
SHARED_WITH_ME_ENTRY_SET.concat([ENTRIES.sharedDirectory])))
.then(this.next);
},
// Navigate to the directory within Shared with me.
function() {
remoteCall.callRemoteTestUtil('openFile', appId, ['Shared Directory'])
.then(this.next);
},
// Wait until the breadcrumb path is updated.
function(result) {
chrome.test.assertFalse(!result);
remoteCall
.waitUntilCurrentDirectoryIsChanged(
appId,
isDriveFsEnabled ? '/Shared with me/Shared Directory' :
'/My Drive/Shared Directory')
.then(this.next);
},
// Verify the file list.
function() {
remoteCall
.waitForFiles(
appId,
TestEntryInfo.getExpectedRows([ENTRIES.sharedDirectoryFile]))
.then(this.next);
},
function() {
checkIfNoErrorsOccured(this.next); checkIfNoErrorsOccured(this.next);
} }
]); ]);
......
...@@ -209,7 +209,9 @@ var EntryType = Object.freeze({ ...@@ -209,7 +209,9 @@ var EntryType = Object.freeze({
*/ */
var SharedOption = Object.freeze({ var SharedOption = Object.freeze({
NONE: 'none', NONE: 'none',
SHARED: 'shared' SHARED: 'shared',
SHARED_WITH_ME: 'sharedWithMe',
NESTED_SHARED_WITH_ME: 'nestedSharedWithMe',
}); });
/** /**
...@@ -818,4 +820,26 @@ var ENTRIES = { ...@@ -818,4 +820,26 @@ var ENTRIES = {
sizeText: '51 bytes', sizeText: '51 bytes',
typeText: 'Plain text' typeText: 'Plain text'
}), }),
sharedDirectory: new TestEntryInfo({
type: EntryType.DIRECTORY,
targetPath: 'Shared Directory',
sharedOption: SharedOption.SHARED_WITH_ME,
lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
nameText: 'Shared Directory',
sizeText: '--',
typeText: 'Folder'
}),
sharedDirectoryFile: new TestEntryInfo({
type: EntryType.FILE,
sourceFileName: 'text.txt',
targetPath: 'Shared Directory/file.txt',
mimeType: 'text/plain',
sharedOption: SharedOption.NESTED_SHARED_WITH_ME,
lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
nameText: 'file.txt',
sizeText: '51 bytes',
typeText: 'Plain text'
}),
}; };
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