chromium/chrome/browser/apps/app_service/publishers/crostini_apps_unittest.cc

// Copyright 2022 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/apps/app_service/publishers/crostini_apps.h"

#include <vector>

#include "base/memory/raw_ptr.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/ash/crostini/crostini_test_helper.h"
#include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/ash/components/dbus/cicerone/cicerone_client.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/cpp/app_update.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace apps {

class CrostiniAppsTest : public testing::Test {
 public:
  CrostiniAppsTest()
      : task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD) {}

  crostini::CrostiniTestHelper* test_helper() { return test_helper_.get(); }

  AppServiceProxy* app_service_proxy() { return app_service_proxy_; }

  TestingProfile* profile() { return profile_.get(); }

  void SetUp() override {
    ash::CiceroneClient::InitializeFake();
    profile_ = std::make_unique<TestingProfile>();
    app_service_proxy_ = AppServiceProxyFactory::GetForProfile(profile_.get());
    web_app::test::AwaitStartWebAppProviderAndSubsystems(profile_.get());
    test_helper_ =
        std::make_unique<crostini::CrostiniTestHelper>(profile_.get());
    test_helper()->ReInitializeAppServiceIntegration();
  }

  void TearDown() override {
    test_helper_.reset();
    profile_.reset();
    ash::CiceroneClient::Shutdown();
  }

  // Adds a test Crostini app and returns its app_id.
  std::string AddCrostiniApp(std::string desktop_file_id,
                             std::string app_name) {
    vm_tools::apps::App app;
    app.set_desktop_file_id(desktop_file_id);
    vm_tools::apps::App::LocaleString::Entry* entry =
        app.mutable_name()->add_values();
    entry->set_locale(std::string());
    entry->set_value(app_name);
    test_helper()->AddApp(app);
    return crostini::CrostiniTestHelper::GenerateAppId(
        app.desktop_file_id(), crostini::kCrostiniDefaultVmName,
        crostini::kCrostiniDefaultContainerName);
  }

 private:
  content::BrowserTaskEnvironment task_environment_;
  std::unique_ptr<TestingProfile> profile_;
  std::unique_ptr<crostini::CrostiniTestHelper> test_helper_;
  raw_ptr<AppServiceProxy, DanglingUntriaged> app_service_proxy_ = nullptr;
};

TEST_F(CrostiniAppsTest, AppReadinessUpdatesWhenCrostiniDisabled) {
  // Install a Crostini app.
  const std::string app_id = AddCrostiniApp("desktop_file_id", "app_name");

  // Check that the app is ready.
  apps::Readiness readiness_before = Readiness::kUnknown;
  app_service_proxy()->AppRegistryCache().ForOneApp(
      app_id, [&readiness_before](const AppUpdate& update) {
        readiness_before = update.Readiness();
      });
  ASSERT_EQ(readiness_before, Readiness::kReady);

  // Disable Crostini. This call uninstalls all Crostini apps.
  guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile())
      ->ClearApplicationList(guest_os::VmType::TERMINA,
                             crostini::kCrostiniDefaultVmName, "");

  // Check that the app is now disabled.
  apps::Readiness readiness_after;
  app_service_proxy()->AppRegistryCache().ForOneApp(
      app_id, [&readiness_after](const AppUpdate& update) {
        readiness_after = update.Readiness();
      });
  ASSERT_EQ(readiness_after, Readiness::kUninstalledByUser);
}

}  // namespace apps