chromium/chrome/browser/ash/policy/skyvault/skyvault_test_base.cc

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/policy/skyvault/skyvault_test_base.h"

#include <string>

#include "base/base_paths.h"
#include "base/check.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/test/test_future.h"
#include "chrome/browser/ash/file_manager/path_util.h"
#include "chrome/browser/ash/file_manager/volume_manager.h"
#include "chrome/browser/ash/policy/skyvault/local_files_migration_constants.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "storage/browser/file_system/external_mount_points.h"

namespace policy::local_user_files {

base::FilePath GetTestFilePath(const std::string& file_name) {
  // Get the path to file manager's test data directory.
  base::FilePath source_dir;
  CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &source_dir));
  base::FilePath test_data_dir = source_dir.AppendASCII("chrome")
                                     .AppendASCII("test")
                                     .AppendASCII("data")
                                     .AppendASCII("chromeos")
                                     .AppendASCII("file_manager");
  return test_data_dir.Append(base::FilePath::FromUTF8Unsafe(file_name));
}

void SkyvaultTestBase::TearDown() {
  InProcessBrowserTest::TearDown();
  storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
}

void SkyvaultTestBase::SetUpMyFiles() {
  my_files_dir_ = GetMyFilesPath(browser()->profile());
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_TRUE(base::CreateDirectory(my_files_dir_));
  }
  std::string mount_point_name =
      file_manager::util::GetDownloadsMountPointName(profile());
  storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
      mount_point_name);
  CHECK(storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
      mount_point_name, storage::kFileSystemTypeLocal,
      storage::FileSystemMountOption(), my_files_dir_));
  file_manager::VolumeManager::Get(profile())
      ->RegisterDownloadsDirectoryForTesting(my_files_dir_);
}

base::FilePath SkyvaultTestBase::CreateTestDir(
    const std::string& test_dir_name,
    const base::FilePath& parent_dir) {
  const base::FilePath dir_path = parent_dir.AppendASCII(test_dir_name);
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    CHECK(base::CreateDirectory(dir_path));
    CHECK(base::PathExists(dir_path));
  }

  return dir_path;
}

base::FilePath SkyvaultTestBase::CopyTestFile(
    const std::string& test_file_name,
    const base::FilePath& parent_dir) {
  const base::FilePath copied_file_path =
      parent_dir.AppendASCII(test_file_name);

  const base::FilePath test_file_path = GetTestFilePath(test_file_name);
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    CHECK(base::CopyFile(test_file_path, copied_file_path));
    CHECK(base::PathExists(copied_file_path));
  }

  return copied_file_path;
}

void SkyvaultOneDriveTest::SetUpODFS() {
  provided_file_system_ =
      file_manager::test::MountFakeProvidedFileSystemOneDrive(profile());
}

void SkyvaultOneDriveTest::CheckPathExistsOnODFS(const base::FilePath& path) {
  ASSERT_TRUE(provided_file_system_);
  base::test::TestFuture<
      std::unique_ptr<ash::file_system_provider::EntryMetadata>,
      base::File::Error>
      future;
  provided_file_system_->GetMetadata(path, {}, future.GetCallback());
  EXPECT_EQ(base::File::Error::FILE_OK, future.Get<base::File::Error>());
}

void SkyvaultOneDriveTest::CheckPathNotFoundOnODFS(const base::FilePath& path) {
  ASSERT_TRUE(provided_file_system_);
  base::test::TestFuture<
      std::unique_ptr<ash::file_system_provider::EntryMetadata>,
      base::File::Error>
      future;
  provided_file_system_->GetMetadata(path, {}, future.GetCallback());
  EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND,
            future.Get<base::File::Error>());
}

SkyvaultGoogleDriveTest::SkyvaultGoogleDriveTest() {
  EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
  drive_mount_point_ = temp_dir_.GetPath().Append("drivefs");
  drive_root_dir_ = drive_mount_point_.AppendASCII("root");
}

SkyvaultGoogleDriveTest::~SkyvaultGoogleDriveTest() = default;

void SkyvaultGoogleDriveTest::SetUpInProcessBrowserTestFixture() {
  // Setup drive integration service.
  create_drive_integration_service_ = base::BindRepeating(
      &SkyvaultGoogleDriveTest::CreateDriveIntegrationService,
      base::Unretained(this));
  service_factory_for_test_ = std::make_unique<
      drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>(
      &create_drive_integration_service_);
}

void SkyvaultGoogleDriveTest::SetUpOnMainThread() {
  SetDriveConnectionStatusForTesting(ConnectionStatus::kConnected);
  SkyvaultTestBase::SetUpOnMainThread();
}

void SkyvaultGoogleDriveTest::SetUp() {
  InProcessBrowserTest::SetUp();
  // Create the Google Drive root directory
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    EXPECT_TRUE(base::CreateDirectory(drive_root_dir_));
  }
}

void SkyvaultGoogleDriveTest::TearDown() {
  SkyvaultTestBase::TearDown();
  storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
}

void SkyvaultGoogleDriveTest::TearDownOnMainThread() {
  RemoveObservers();
  SkyvaultTestBase::TearDownOnMainThread();
}

void SkyvaultGoogleDriveTest::SetUpObservers() {
  // Subscribe to IOTasks updates to track the copy/move to Drive progress.
  file_manager::VolumeManager::Get(profile())
      ->io_task_controller()
      ->AddObserver(this);
}

void SkyvaultGoogleDriveTest::RemoveObservers() {
  file_manager::VolumeManager::Get(profile())
      ->io_task_controller()
      ->RemoveObserver(this);
}

base::FilePath SkyvaultGoogleDriveTest::SetUpSourceFile(
    const std::string& test_file_name,
    base::FilePath source_path) {
  base::FilePath source_file_path = CopyTestFile(test_file_name, source_path);

  base::FilePath local_relative_path;
  GetMyFilesPath(browser()->profile())
      .AppendRelativePath(source_file_path, &local_relative_path);
  FileInfo info(test_file_name, local_relative_path);
  // Check that the source file exists at the intended source location and is
  // not in Drive.
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    EXPECT_TRUE(base::PathExists(source_file_path));
    CheckPathNotFoundOnDrive(observed_relative_drive_path(info));
  }

  source_files_.emplace(source_file_path, std::move(info));
  return source_file_path;
}

void SkyvaultGoogleDriveTest::CheckPathExistsOnDrive(
    const base::FilePath& path) {
  drive_integration_service()->GetDriveFsInterface()->GetMetadata(
      path, base::BindOnce(&SkyvaultGoogleDriveTest::OnGetMetadataExpectSuccess,
                           base::Unretained(this)));
  base::ScopedAllowBlockingForTesting allow_blocking;
  Wait();
}
void SkyvaultGoogleDriveTest::CheckPathNotFoundOnDrive(
    const base::FilePath& path) {
  drive_integration_service()->GetDriveFsInterface()->GetMetadata(
      path,
      base::BindOnce(&SkyvaultGoogleDriveTest::OnGetMetadataExpectNotFound,
                     base::Unretained(this)));
  base::ScopedAllowBlockingForTesting allow_blocking;
  Wait();
}

void SkyvaultGoogleDriveTest::Wait() {
  base::ScopedAllowBlockingForTesting allow_blocking;
  ASSERT_FALSE(run_loop_);
  run_loop_ = std::make_unique<base::RunLoop>();
  run_loop_->Run();
  run_loop_ = nullptr;
}

void SkyvaultGoogleDriveTest::EndWait() {
  ASSERT_TRUE(run_loop_);
  run_loop_->Quit();
}

DriveIntegrationService* SkyvaultGoogleDriveTest::CreateDriveIntegrationService(
    Profile* profile) {
  base::ScopedAllowBlockingForTesting allow_blocking;
  fake_drivefs_helpers_[profile] =
      std::make_unique<file_manager::test::FakeSimpleDriveFsHelper>(
          profile, drive_mount_point_);
  return new DriveIntegrationService(
      profile, "", drive_mount_point_,
      fake_drivefs_helpers_[profile]->CreateFakeDriveFsListenerFactory());
}

void SkyvaultGoogleDriveTest::OnGetMetadataExpectSuccess(
    drive::FileError error,
    drivefs::mojom::FileMetadataPtr metadata) {
  EXPECT_EQ(drive::FILE_ERROR_OK, error);
  EndWait();
}

void SkyvaultGoogleDriveTest::OnGetMetadataExpectNotFound(
    drive::FileError error,
    drivefs::mojom::FileMetadataPtr metadata) {
  EXPECT_EQ(drive::FILE_ERROR_NOT_FOUND, error);
  EndWait();
}

}  // namespace policy::local_user_files