// Copyright 2019 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.

#include "chrome/browser/ash/crostini/crostini_package_service.h"

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/ash/crostini/crostini_test_helper.h"
#include "chrome/browser/ash/crostini/crostini_util.h"
#include "chrome/browser/ash/file_manager/path_util.h"
#include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
#include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/dbus/cicerone/cicerone_client.h"
#include "chromeos/dbus/cicerone/fake_cicerone_client.h"
#include "chromeos/dbus/concierge/concierge_client.h"
#include "chromeos/dbus/concierge/fake_concierge_client.h"
#include "chromeos/dbus/cros_disks/cros_disks_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/seneschal/fake_seneschal_client.h"
#include "chromeos/dbus/seneschal/seneschal_client.h"
#include "chromeos/dbus/vm_applications/apps.pb.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_task_environment.h"
#include "storage/browser/file_system/external_mount_points.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace crostini {

namespace {

using ::chromeos::DBusMethodCallback;
using ::chromeos::DBusThreadManager;
using ::chromeos::FakeCiceroneClient;
using ::chromeos::FakeConciergeClient;
using ::chromeos::FakeSeneschalClient;
using ::testing::_;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::MakeMatcher;
using ::testing::Matcher;
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;
using ::testing::UnorderedElementsAre;
using ::vm_tools::cicerone::InstallLinuxPackageProgressSignal;
using ::vm_tools::cicerone::InstallLinuxPackageRequest;
using ::vm_tools::cicerone::InstallLinuxPackageResponse;
using ::vm_tools::cicerone::LinuxPackageInfoRequest;
using ::vm_tools::cicerone::LinuxPackageInfoResponse;
using ::vm_tools::cicerone::PendingAppListUpdatesSignal;
using ::vm_tools::cicerone::UninstallPackageOwningFileRequest;
using ::vm_tools::cicerone::UninstallPackageOwningFileResponse;
using ::vm_tools::cicerone::UninstallPackageProgressSignal;
using ::vm_tools::seneschal::SharePathResponse;

// IDs, etc of apps that are always registered during tests.
// These are on the default VM / default container.
constexpr char kDefaultAppFileId[] = "default_file_id";
constexpr char kDefaultAppName[] = "The Default";
constexpr char16_t kDefaultAppName16[] = u"The Default";
constexpr char kSecondAppFileId[] = "second_file_id";
constexpr char kSecondAppName[] = "Another Fine App";
constexpr char16_t kSecondAppName16[] = u"Another Fine App";
constexpr char kThirdAppFileId[] = "third_file_id";
constexpr char kThirdAppName[] = "Yet Another App";
constexpr char16_t kThirdAppName16[] = u"Yet Another App";
// Different VM name, but container name is the default.
constexpr char kDifferentVmAppFileId[] = "different_vm_app";
constexpr char kDifferentVmAppName[] = "I'm in a VM!";
constexpr char16_t kDifferentVmAppName16[] = u"I'm in a VM!";
constexpr char kDifferentVmApp2FileId[] = "different_vm_app_2";
constexpr char kDifferentVmApp2Name[] = "I'm in a VM also";
constexpr char16_t kDifferentVmApp2Name16[] = u"I'm in a VM also";
constexpr char kDifferentVmVmName[] = "second_vm_name";
// Default VM name, but container name is different.
constexpr char kDifferentContainerAppFileId[] = "different_container_app";
constexpr char kDifferentContainerAppName[] =
    "Just Over The Container Boundary";
constexpr char16_t kDifferentContainerAppName16[] =
    u"Just Over The Container Boundary";
constexpr char kDifferentContainerApp2FileId[] = "different_container_app_2";
constexpr char kDifferentContainerApp2Name[] = "Severe Lack of Containers";
constexpr char16_t kDifferentContainerApp2Name16[] =
    u"Severe Lack of Containers";
constexpr char kDifferentContainerContainerName[] = "second_container_name";
constexpr char kPackageFilePath[] = "/tmp/nethack.deb";
constexpr char kPackageFileContainerPath[] =
    "/mnt/chromeos/MyFiles/tmp/nethack.deb";

// Callback for RunUntilUninstallRequestMade.
void CaptureUninstallRequestParametersAndQuitLoop(
    base::RepeatingClosure quit_closure,
    UninstallPackageOwningFileRequest* request_output,
    DBusMethodCallback<UninstallPackageOwningFileResponse>* callback_output,
    const UninstallPackageOwningFileRequest& request_input,
    DBusMethodCallback<UninstallPackageOwningFileResponse> callback_input) {
  *request_output = request_input;
  if (callback_output != nullptr) {
    *callback_output = std::move(callback_input);
  }
  std::move(quit_closure).Run();
}

// Run until |fake_cicerone_client_|'s UninstallPackageOwningFile is called.
// |request| and |callback| are filled in with the parameters to
// CiceroneClient::UninstallPackageOwningFile.
void RunUntilUninstallRequestMade(
    FakeCiceroneClient* fake_cicerone_client,
    UninstallPackageOwningFileRequest* request,
    DBusMethodCallback<UninstallPackageOwningFileResponse>* callback) {
  base::RunLoop run_loop;
  fake_cicerone_client->SetOnUninstallPackageOwningFileCallback(
      base::BindRepeating(&CaptureUninstallRequestParametersAndQuitLoop,
                          run_loop.QuitClosure(), base::Unretained(request),
                          base::Unretained(callback)));
  run_loop.Run();

  // Callback isn't valid after end of function.
  fake_cicerone_client->SetOnUninstallPackageOwningFileCallback(
      base::NullCallback());
}

// Callback used for InstallLinuxPackage
void ExpectedCrostiniResult(base::OnceClosure quit,
                            CrostiniResult expected,
                            CrostiniResult result) {
  EXPECT_EQ(expected, result);
  std::move(quit).Run();
}

// Callback used for GetLinuxPackageInfo.
void RecordPackageInfoResult(LinuxPackageInfo* record_location,
                             const LinuxPackageInfo& result) {
  *record_location = result;
}

class CrostiniPackageServiceTest : public testing::Test {
 public:
  CrostiniPackageServiceTest()
      : kDefaultAppId(CrostiniTestHelper::GenerateAppId(kDefaultAppFileId)),
        kSecondAppId(CrostiniTestHelper::GenerateAppId(kSecondAppFileId)),
        kThirdAppId(CrostiniTestHelper::GenerateAppId(kThirdAppFileId)),
        kDifferentVmAppId(
            CrostiniTestHelper::GenerateAppId(kDifferentVmAppFileId,
                                              kDifferentVmVmName,
                                              kCrostiniDefaultContainerName)),
        kDifferentVmApp2Id(
            CrostiniTestHelper::GenerateAppId(kDifferentVmApp2FileId,
                                              kDifferentVmVmName,
                                              kCrostiniDefaultContainerName)),
        kDifferentContainerAppId(CrostiniTestHelper::GenerateAppId(
            kDifferentContainerAppFileId,
            kCrostiniDefaultVmName,
            kDifferentContainerContainerName)),
        kDifferentContainerApp2Id(CrostiniTestHelper::GenerateAppId(
            kDifferentContainerApp2FileId,
            kCrostiniDefaultVmName,
            kDifferentContainerContainerName)) {}

  void SetUp() override {
    DBusThreadManager::Initialize();

    chromeos::CiceroneClient::InitializeFake();
    chromeos::ConciergeClient::InitializeFake();
    chromeos::SeneschalClient::InitializeFake();
    fake_cicerone_client_ = chromeos::FakeCiceroneClient::Get();
    ASSERT_TRUE(fake_cicerone_client_);
    fake_seneschal_client_ = chromeos::FakeSeneschalClient::Get();
    ASSERT_TRUE(fake_seneschal_client_);

    task_environment_ = std::make_unique<content::BrowserTaskEnvironment>(
        base::test::TaskEnvironment::MainThreadType::UI,
        base::test::TaskEnvironment::ThreadPoolExecutionMode::ASYNC,
        content::BrowserTaskEnvironment::REAL_IO_THREAD);
    profile_ = std::make_unique<TestingProfile>(
        base::FilePath("/home/chronos/u-0123456789abcdef"));
    crostini_test_helper_ =
        std::make_unique<CrostiniTestHelper>(profile_.get());
    notification_display_service_tester_ =
        std::make_unique<NotificationDisplayServiceTester>(profile_.get());
    notification_display_service_ =
        static_cast<StubNotificationDisplayService*>(
            NotificationDisplayServiceFactory::GetForProfile(profile_.get()));
    ASSERT_TRUE(notification_display_service_);
    service_ = std::make_unique<CrostiniPackageService>(profile_.get());
    storage::ExternalMountPoints* mount_points =
        storage::ExternalMountPoints::GetSystemInstance();
    ASSERT_TRUE(mount_points);
    std::string mount_point_name =
        file_manager::util::GetDownloadsMountPointName(profile_.get());
    mount_points->RegisterFileSystem(
        mount_point_name, storage::kFileSystemTypeLocal,
        storage::FileSystemMountOption(),
        file_manager::util::GetDownloadsFolderForProfile(profile_.get()));
    package_file_url_ = mount_points->CreateExternalFileSystemURL(
        url::Origin(), mount_point_name, base::FilePath(kPackageFilePath));

    auto* crostini_manager = CrostiniManager::GetForProfile(profile_.get());
    ASSERT_TRUE(crostini_manager);
    crostini_manager->set_skip_restart_for_testing();
    crostini_manager->AddRunningVmForTesting(kDifferentVmVmName);

    CreateDefaultAppRegistration();
    CreateSecondAppRegistration();
    CreateThirdAppRegistration();
    CreateDifferentVmAppRegistration();
    CreateDifferentContainerAppRegistration();
  }

  void TearDown() override {
    // Complete all CrostiniManager queued tasks before deleting it.
    base::RunLoop().RunUntilIdle();
    storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
        file_manager::util::GetDownloadsMountPointName(profile_.get()));
    service_.reset();
    notification_display_service_tester_.reset();
    crostini_test_helper_.reset();
    profile_.reset();
    task_environment_.reset();
    chromeos::SeneschalClient::Shutdown();
    chromeos::ConciergeClient::Shutdown();
    chromeos::CiceroneClient::Shutdown();
    DBusThreadManager::Shutdown();
  }

 protected:
  const std::string kDefaultAppId;  // App_id for app with kDefaultAppFileId.
  const std::string kSecondAppId;   // App_id for app with kSecondAppFileId.
  const std::string kThirdAppId;    // App_id for app with kThirdAppFileId.
  const std::string kDifferentVmAppId;          // App_id for app with
                                                // kDifferentVmAppFileId.
  const std::string kDifferentVmApp2Id;         // App_id for app with
                                                // kDifferentVmApp2FileId.
  const std::string kDifferentContainerAppId;   // App_id for app with
                                                // kDifferentContainerAppFileId.
  const std::string kDifferentContainerApp2Id;  // App_id for app with
                                                // kDifferentContainerApp2FileId
  const ContainerId kDifferentContainerId =
      ContainerId(kDifferentVmVmName, kDifferentContainerContainerName);
  storage::FileSystemURL package_file_url_;

  UninstallPackageProgressSignal MakeUninstallSignal(
      const UninstallPackageOwningFileRequest& request) {
    UninstallPackageProgressSignal signal;
    signal.set_vm_name(request.vm_name());
    signal.set_container_name(request.container_name());
    signal.set_owner_id(request.owner_id());
    return signal;
  }

  InstallLinuxPackageProgressSignal MakeInstallSignal(
      const InstallLinuxPackageRequest& request) {
    InstallLinuxPackageProgressSignal signal;
    signal.set_vm_name(request.vm_name());
    signal.set_container_name(request.container_name());
    signal.set_owner_id(request.owner_id());
    return signal;
  }

  void SendAppListUpdateSignal(const ContainerId& container_id, int count) {
    PendingAppListUpdatesSignal signal;
    signal.set_vm_name(container_id.vm_name);
    signal.set_container_name(container_id.container_name);
    signal.set_count(count);
    fake_cicerone_client_->NotifyPendingAppListUpdates(signal);
  }

  // Closes the notification as if the user had clicked 'close'.
  void CloseNotification(const message_center::Notification& notification) {
    notification_display_service_->RemoveNotification(
        NotificationHandler::Type::TRANSIENT, notification.id(),
        true /*by_user*/, false /*silent*/);
  }

  // Start an uninstall and then sent a single uninstall signal with the given
  // status and (optional) progress. If |request_out| is not nullptr, the
  // request sent by the service will be copied to |*request_out|.
  void StartAndSignalUninstall(
      UninstallPackageProgressSignal::Status signal_status,
      int progress_percent = 0,
      const char* const expected_desktop_file_id = kDefaultAppFileId,
      UninstallPackageOwningFileRequest* request_out = nullptr) {
    UninstallPackageOwningFileRequest request;
    DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
    RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
    EXPECT_EQ(request.desktop_file_id(), expected_desktop_file_id);

    // It's illegal to send a signal unless the response was STARTED. So assume
    // that any test calling this function wants us to give a STARTED response.
    UninstallPackageOwningFileResponse response;
    response.set_status(UninstallPackageOwningFileResponse::STARTED);
    std::move(callback).Run(response);

    UninstallPackageProgressSignal signal = MakeUninstallSignal(request);
    signal.set_status(signal_status);
    switch (signal_status) {
      case UninstallPackageProgressSignal::UNINSTALLING:
        signal.set_progress_percent(progress_percent);
        break;
      case UninstallPackageProgressSignal::FAILED:
        signal.set_failure_details("Oh no not again");
        break;
      case UninstallPackageProgressSignal::SUCCEEDED:
        break;
      default:
        NOTREACHED();
    }
    fake_cicerone_client_->UninstallPackageProgress(signal);

    if (request_out != nullptr) {
      *request_out = request;
    }
  }

  // Start an install and then sent a single install signal with the given
  // status and (optional) progress.
  void StartAndSignalInstall(
      InstallLinuxPackageProgressSignal::Status signal_status,
      int progress_percent = 0) {
    base::RunLoop().RunUntilIdle();

    InstallLinuxPackageProgressSignal signal = MakeInstallSignal(
        fake_cicerone_client_->get_most_recent_install_linux_package_request());
    signal.set_status(signal_status);
    switch (signal_status) {
      case InstallLinuxPackageProgressSignal::DOWNLOADING:
      case InstallLinuxPackageProgressSignal::INSTALLING:
        signal.set_progress_percent(progress_percent);
        break;

      case InstallLinuxPackageProgressSignal::FAILED:
        signal.set_failure_details("Wouldn't be prudent");
        break;

      case InstallLinuxPackageProgressSignal::SUCCEEDED:
        break;

      default:
        NOTREACHED();
    }
    fake_cicerone_client_->InstallLinuxPackageProgress(signal);
  }

  FakeCiceroneClient* fake_cicerone_client_ = nullptr;
  FakeSeneschalClient* fake_seneschal_client_ = nullptr;

  std::unique_ptr<content::BrowserTaskEnvironment> task_environment_;
  std::unique_ptr<TestingProfile> profile_;
  std::unique_ptr<CrostiniTestHelper> crostini_test_helper_;
  std::unique_ptr<NotificationDisplayServiceTester>
      notification_display_service_tester_;
  StubNotificationDisplayService* notification_display_service_;
  std::unique_ptr<CrostiniPackageService> service_;

 private:
  // Helper to set up an App proto with a single name.
  vm_tools::apps::App BasicApp(const std::string& desktop_file_id,
                               const std::string& name,
                               const std::string& package_id) {
    vm_tools::apps::App app;
    app.set_desktop_file_id(desktop_file_id);
    app.mutable_name()->add_values()->set_value(name);
    app.set_no_display(false);
    app.set_package_id(package_id);
    return app;
  }

  // Create a registration in GuestOsRegistryService for an app with app_id
  // kDefaultAppId and desktop file ID kDefaultAppFileId.
  void CreateDefaultAppRegistration() {
    auto app = BasicApp(kDefaultAppFileId, kDefaultAppName, "123-thing");
    crostini_test_helper_->AddApp(app);
  }

  // Create a registration in GuestOsRegistryService for an app with app_id
  // kSecondAppId and desktop file ID kSecondAppFileId.
  void CreateSecondAppRegistration() {
    auto app = BasicApp(kSecondAppFileId, kSecondAppName, "abc-another");
    crostini_test_helper_->AddApp(app);
  }

  // Create a registration in GuestOsRegistryService for an app with app_id
  // kThirdAppId and desktop file ID kThirdAppFileId.
  void CreateThirdAppRegistration() {
    auto app = BasicApp(kThirdAppFileId, kThirdAppName, "yanpi");
    crostini_test_helper_->AddApp(app);
  }

  // Create a registration in GuestOsRegistryService for apps with app_id
  // kDifferentVmAppId and kDifferentVmApp2Id inside kDifferentVmVmName.
  void CreateDifferentVmAppRegistration() {
    // CrostiniTestHelper doesn't directly allow apps to be added for VMs other
    // than the default VM.
    vm_tools::apps::ApplicationList app_list;
    app_list.set_vm_name(kDifferentVmVmName);
    app_list.set_container_name(kCrostiniDefaultContainerName);
    *app_list.add_apps() =
        BasicApp(kDifferentVmAppFileId, kDifferentVmAppName, "pack5");
    *app_list.add_apps() =
        BasicApp(kDifferentVmApp2FileId, kDifferentVmApp2Name, "pack5-2");
    guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile_.get())
        ->UpdateApplicationList(app_list);
  }

  // Create a registration in GuestOsRegistryService for apps with app_id
  // kDifferentContainerAppId and kDifferentContainerApp2Id inside
  // kDifferentContainerContainerName.
  void CreateDifferentContainerAppRegistration() {
    // CrostiniTestHelper doesn't directly allow apps to be added for containers
    // other than the default container.
    vm_tools::apps::ApplicationList app_list;
    app_list.set_vm_name(kCrostiniDefaultVmName);
    app_list.set_container_name(kDifferentContainerContainerName);
    *app_list.add_apps() = BasicApp(kDifferentContainerAppFileId,
                                    kDifferentContainerAppName, "pack7");
    *app_list.add_apps() = BasicApp(kDifferentContainerApp2FileId,
                                    kDifferentContainerApp2Name, "pack7-2");
    guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile_.get())
        ->UpdateApplicationList(app_list);
  }
};

// A way of referring to one of the various app ids in parameters.
enum KnownApp {
  DEFAULT_APP,
  SECOND_APP,
  THIRD_APP,
  DIFFERENT_VM,
  DIFFERENT_VM_2,
  DIFFERENT_CONTAINER,
  DIFFERENT_CONTAINER_2
};

// Returns the app name for one of the known apps.
std::u16string GetAppName(KnownApp app) {
  switch (app) {
    case DEFAULT_APP:
      return kDefaultAppName16;
    case SECOND_APP:
      return kSecondAppName16;
    case THIRD_APP:
      return kThirdAppName16;
    case DIFFERENT_VM:
      return kDifferentVmAppName16;
    case DIFFERENT_VM_2:
      return kDifferentVmApp2Name16;
    case DIFFERENT_CONTAINER:
      return kDifferentContainerAppName16;
    case DIFFERENT_CONTAINER_2:
      return kDifferentContainerApp2Name16;
    default:
      NOTREACHED();
  }
}

// This is a wrapper around message_center::Notification, allowing us to print
// them nicely. Otherwise, UnorderedElementsAre has failures that look like
// Actual: { 680-byte object <68-98 31-13 AC-7F 00-00 00-00 00-00 AB-AB AB-AB
//           80-AC 97-F1 06-23 00-00 1C-00 00-00 00-00 00-00 20-00 00-00 00-00
//           00-80 80-49 9F-F1 06-23 00-00 0B-00 00-00 00-00 00-00 10-00 00-00
//           00-00 00-80 ... 00-00 00-00 00-00 00-00 D2-67 19-FF 00-00 00-00
//           00-75 59-F1 00-00 00-00 03-00 00-00 AB-AB AB-AB E0-40 92-F1 06-23
//           00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00
//           00-00 00-00> }
class PrintableNotification {
 public:
  explicit PrintableNotification(const message_center::Notification& base)
      : display_source_(base.display_source()),
        title_(base.title()),
        message_(base.message()),
        progress_(base.progress()) {}

  const std::u16string& display_source() const { return display_source_; }
  const std::u16string& title() const { return title_; }
  const std::u16string& message() const { return message_; }
  int progress() const { return progress_; }

 private:
  const std::u16string display_source_;
  const std::u16string title_;
  const std::u16string message_;
  const int progress_;
};

std::ostream& operator<<(std::ostream& os,
                         const PrintableNotification& notification) {
  os << "source: \"" << notification.display_source() << "\", title: \""
     << notification.title() << "\", message: \"" << notification.message()
     << "\", progress: " << notification.progress();
  return os;
}

// Short-named conversion functions to avoid adding more noise than necessary
// to EXPECT_THAT calls.
PrintableNotification Printable(const message_center::Notification& base) {
  return PrintableNotification(base);
}

std::vector<PrintableNotification> Printable(
    const std::vector<message_center::Notification>& base) {
  std::vector<PrintableNotification> result;
  result.reserve(base.size());
  for (const message_center::Notification& base_notification : base) {
    result.push_back(PrintableNotification(base_notification));
  }
  return result;
}

class NotificationMatcher : public MatcherInterface<PrintableNotification> {
 public:
  NotificationMatcher(const std::u16string& expected_source,
                      const std::u16string& expected_title,
                      const std::u16string& expected_message)
      : expected_source_(expected_source),
        expected_title_(expected_title),
        check_message_(true),
        expected_message_(expected_message),
        check_progress_(false),
        expected_progress_(-1) {}
  NotificationMatcher(const std::u16string& expected_source,
                      const std::u16string& expected_title,
                      int expected_progress)
      : expected_source_(expected_source),
        expected_title_(expected_title),
        check_message_(false),
        expected_message_(),
        check_progress_(true),
        expected_progress_(expected_progress) {}

  bool MatchAndExplain(PrintableNotification notification,
                       MatchResultListener* listener) const override {
    bool has_mismatch = false;
    if (notification.display_source() != expected_source_) {
      *listener << "notification source: " << notification.display_source()
                << "\ndoes not equal expected source: " << expected_source_;
      has_mismatch = true;
    }
    if (notification.title() != expected_title_) {
      if (has_mismatch) {
        *listener << "\nand\n";
      }
      *listener << "notification title: " << notification.title()
                << "\ndoes not equal expected title: " << expected_title_;
      has_mismatch = true;
    }
    if (check_message_ && (notification.message() != expected_message_)) {
      if (has_mismatch) {
        *listener << "\nand\n";
      }
      *listener << "notification message: " << notification.message()
                << "\ndoes not equal expected message: " << expected_message_;
      has_mismatch = true;
    }
    if (check_progress_ && (notification.progress() != expected_progress_)) {
      if (has_mismatch) {
        *listener << "\nand\n";
      }
      *listener << "notification progress: " << notification.progress()
                << "\ndoes not equal expected progress: " << expected_progress_;
      has_mismatch = true;
    }
    return !has_mismatch;
  }

  void DescribeTo(std::ostream* os) const override {
    *os << "has notification source \"" << expected_source_ << "\" and title \""
        << expected_title_ << "\"";
    if (check_message_) {
      *os << " and message \"" << expected_message_ << "\"";
    }
    if (check_progress_) {
      *os << " and progress " << expected_progress_;
    }
  }

  void DescribeNegationTo(std::ostream* os) const override {
    *os << "does not have notification source \"" << expected_source_
        << "\" or does not have title \"" << expected_title_ << "\"";
    if (check_message_) {
      *os << " or does not have message \"" << expected_message_ << "\"";
    }
    if (check_progress_) {
      *os << " or does not have progress " << expected_progress_;
    }
  }

 private:
  const std::u16string expected_source_;
  const std::u16string expected_title_;
  const bool check_message_;
  const std::u16string expected_message_;
  const bool check_progress_;
  const int expected_progress_;
};

Matcher<PrintableNotification> IsUninstallSuccessNotification(
    KnownApp app = DEFAULT_APP) {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringFUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_COMPLETED_TITLE,
          GetAppName(app)),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_COMPLETED_MESSAGE)));
}

Matcher<PrintableNotification> IsUninstallFailedNotification(
    KnownApp app = DEFAULT_APP) {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringFUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_ERROR_TITLE,
          GetAppName(app)),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_ERROR_MESSAGE)));
}

Matcher<PrintableNotification> IsUninstallProgressNotification(
    int expected_progress,
    KnownApp app = DEFAULT_APP) {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringFUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_IN_PROGRESS_TITLE,
          GetAppName(app)),
      expected_progress));
}

Matcher<PrintableNotification> IsUninstallWaitingForAppListNotification(
    KnownApp app = DEFAULT_APP) {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringFUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_IN_PROGRESS_TITLE,
          GetAppName(app)),
      -1));
}

Matcher<PrintableNotification> IsUninstallQueuedNotification(
    KnownApp app = DEFAULT_APP) {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringFUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_QUEUED_TITLE,
          GetAppName(app)),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_APPLICATION_UNINSTALL_NOTIFICATION_QUEUED_MESSAGE)));
}

Matcher<PrintableNotification> IsInstallProgressNotification(
    int expected_progress) {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_IN_PROGRESS_TITLE),
      expected_progress));
}

Matcher<PrintableNotification> IsInstallWaitingForAppListNotification() {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_IN_PROGRESS_TITLE),
      -1));
}

Matcher<PrintableNotification> IsInstallSuccessNotification() {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_COMPLETED_TITLE),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_COMPLETED_MESSAGE)));
}

Matcher<PrintableNotification> IsInstallFailedNotification() {
  return MakeMatcher(new NotificationMatcher(
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_DISPLAY_SOURCE),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_ERROR_TITLE),
      l10n_util::GetStringUTF16(
          IDS_CROSTINI_PACKAGE_INSTALL_NOTIFICATION_ERROR_MESSAGE)));
}

TEST_F(CrostiniPackageServiceTest, BasicUninstallMakesValidUninstallRequest) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_EQ(request.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
}

TEST_F(CrostiniPackageServiceTest, DifferentVmMakesValidUninstallRequest) {
  service_->QueueUninstallApplication(kDifferentVmAppId);

  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_EQ(request.vm_name(), kDifferentVmVmName);
  EXPECT_EQ(request.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.desktop_file_id(), kDifferentVmAppFileId);
}

TEST_F(CrostiniPackageServiceTest,
       DifferentContainerMakesValidUninstallRequest) {
  service_->QueueUninstallApplication(kDifferentContainerAppId);

  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_EQ(request.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request.container_name(), kDifferentContainerContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.desktop_file_id(), kDifferentContainerAppFileId);
}

TEST_F(CrostiniPackageServiceTest, BasicUninstallDisplaysNotification) {
  service_->QueueUninstallApplication(kDefaultAppId);
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       FailedUninstallResponseDisplaysFailedNotification) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);

  // Tell service the uninstall failed.
  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::FAILED);
  response.set_failure_reason("I prefer not to");
  std::move(callback).Run(response);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       BlockedUninstallResponseDisplaysFailedNotification) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);

  // Tell service the uninstall failed.
  UninstallPackageOwningFileResponse response;
  response.set_status(
      UninstallPackageOwningFileResponse::BLOCKING_OPERATION_IN_PROGRESS);
  response.set_failure_reason("Hahaha NO");
  std::move(callback).Run(response);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       FailedUninstallSignalDisplaysFailedNotification) {
  service_->QueueUninstallApplication(kDefaultAppId);

  StartAndSignalUninstall(UninstallPackageProgressSignal::FAILED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallDisplaysProgressNotificationBeforeResponse) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallDisplaysProgressNotificationBeforeSignal) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback).Run(response);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallDisplaysProgressNotificationAfterProgressSignal) {
  service_->QueueUninstallApplication(kDefaultAppId);

  StartAndSignalUninstall(UninstallPackageProgressSignal::UNINSTALLING,
                          23 /*progress_percent*/);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(23)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallDisplaysSuccessNotificationAfterProgressThenSuccess) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  StartAndSignalUninstall(UninstallPackageProgressSignal::UNINSTALLING,
                          50 /*progress_percent*/, kDefaultAppFileId, &request);

  UninstallPackageProgressSignal signal_success = MakeUninstallSignal(request);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallDisplaysFailureNotificationAfterProgressThenFailure) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  StartAndSignalUninstall(UninstallPackageProgressSignal::UNINSTALLING,
                          50 /*progress_percent*/, kDefaultAppFileId, &request);

  UninstallPackageProgressSignal signal_failure = MakeUninstallSignal(request);
  signal_failure.set_status(UninstallPackageProgressSignal::FAILED);
  signal_failure.set_failure_details("I prefer not to");
  fake_cicerone_client_->UninstallPackageProgress(signal_failure);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest, SecondUninstallDisplaysQueuedNotification) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallQueuedNotification(SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, SecondUninstallStartsWhenFirstCompletes) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallProgressNotification(0, SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, SecondUninstallStartsWhenFirstFails) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  StartAndSignalUninstall(UninstallPackageProgressSignal::FAILED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification(DEFAULT_APP),
                           IsUninstallProgressNotification(0, SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, DuplicateUninstallSucceeds) {
  // Use three uninstalls as a regression test for crbug.com/1015341
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  StartAndSignalUninstall(UninstallPackageProgressSignal::UNINSTALLING,
                          50 /*progress_percent*/, kDefaultAppFileId, &request);

  crostini_test_helper_->RemoveApp(0);

  UninstallPackageProgressSignal signal_success = MakeUninstallSignal(request);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(DEFAULT_APP)));
}

TEST_F(CrostiniPackageServiceTest,
       AfterSecondInstallStartsProgressAppliesToSecond) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  // Uninstall the first.
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  // Start uninstalling the second
  StartAndSignalUninstall(UninstallPackageProgressSignal::UNINSTALLING,
                          46 /*progress_percent*/, kSecondAppFileId);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallProgressNotification(46, SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, BothUninstallsEventuallyComplete) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  // Uninstall the first.
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  // Uninstall the second.
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED,
                          0 /*progress_percent*/, kSecondAppFileId);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, QueuedUninstallsProcessedInFifoOrder) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);
  service_->QueueUninstallApplication(kThirdAppId);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallQueuedNotification(SECOND_APP),
                           IsUninstallQueuedNotification(THIRD_APP)));

  // Finish the first; second should start.
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallProgressNotification(0, SECOND_APP),
                           IsUninstallQueuedNotification(THIRD_APP)));

  // Finish the second, third should start.
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED,
                          0 /*progress_percent*/, kSecondAppFileId);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(SECOND_APP),
                           IsUninstallProgressNotification(0, THIRD_APP)));

  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED,
                          0 /*progress_percent*/, kThirdAppFileId);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(SECOND_APP),
                           IsUninstallSuccessNotification(THIRD_APP)));
}

TEST_F(CrostiniPackageServiceTest, UninstallNotificationWaitsForAppListUpdate) {
  service_->QueueUninstallApplication(kDefaultAppId);

  SendAppListUpdateSignal(ContainerId::GetDefault(), 1);

  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallWaitingForAppListNotification(DEFAULT_APP)));

  SendAppListUpdateSignal(ContainerId::GetDefault(), 0);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallNotificationDoesntWaitForAppListUpdate) {
  service_->QueueUninstallApplication(kDefaultAppId);

  SendAppListUpdateSignal(ContainerId::GetDefault(), 0);

  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP)));

  SendAppListUpdateSignal(ContainerId::GetDefault(), 1);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallNotificationAppListUpdatesAreVmSpecific) {
  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;

  service_->QueueUninstallApplication(kDefaultAppId);
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  UninstallPackageProgressSignal signal_progress = MakeUninstallSignal(request);
  signal_progress.set_status(UninstallPackageProgressSignal::SUCCEEDED);

  service_->QueueUninstallApplication(kDifferentVmAppId);
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  UninstallPackageProgressSignal signal_progress2 =
      MakeUninstallSignal(request);
  signal_progress2.set_status(UninstallPackageProgressSignal::SUCCEEDED);

  SendAppListUpdateSignal(
      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress2);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallSuccessNotification(DEFAULT_APP),
          IsUninstallWaitingForAppListNotification(DIFFERENT_VM)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallNotificationAppListUpdatesFromUnknownContainersAreIgnored) {
  service_->QueueUninstallApplication(kDefaultAppId);

  SendAppListUpdateSignal(
      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);

  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP)));
}

TEST_F(CrostiniPackageServiceTest, UninstallNotificationFailsOnVmShutdown) {
  // Use two apps to ensure one is queued up.
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  base::RunLoop run_loop;
  CrostiniManager::GetForProfile(profile_.get())
      ->StopVm(kCrostiniDefaultVmName,
               base::BindOnce(
                   [](base::OnceClosure quit, crostini::CrostiniResult) {
                     std::move(quit).Run();
                   },
                   run_loop.QuitClosure()));
  run_loop.Run();

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification(DEFAULT_APP),
                           IsUninstallFailedNotification(SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, ClosingSuccessNotificationWorks) {
  service_->QueueUninstallApplication(kDefaultAppId);
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 1U);
  EXPECT_THAT(Printable(notifications[0]), IsUninstallSuccessNotification());
  CloseNotification(notifications[0]);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      IsEmpty());
}

TEST_F(CrostiniPackageServiceTest, ClosingFailureNotificationWorks) {
  service_->QueueUninstallApplication(kDefaultAppId);
  StartAndSignalUninstall(UninstallPackageProgressSignal::FAILED);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 1U);
  EXPECT_THAT(Printable(notifications[0]), IsUninstallFailedNotification());
  CloseNotification(notifications[0]);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      IsEmpty());
}

TEST_F(CrostiniPackageServiceTest,
       ClosedInProgressNotificationDoesNotReopenOnProgress) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback).Run(response);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 1U);
  EXPECT_THAT(Printable(notifications[0]), IsUninstallProgressNotification(0));
  CloseNotification(notifications[0]);

  UninstallPackageProgressSignal signal_progress = MakeUninstallSignal(request);
  signal_progress.set_status(UninstallPackageProgressSignal::UNINSTALLING);
  signal_progress.set_progress_percent(50);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      IsEmpty());
}

TEST_F(CrostiniPackageServiceTest,
       ClosedInProgressNotificationReopensOnSuccess) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback).Run(response);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 1U);
  EXPECT_THAT(Printable(notifications[0]), IsUninstallProgressNotification(0));
  CloseNotification(notifications[0]);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      IsEmpty());

  UninstallPackageProgressSignal signal_success = MakeUninstallSignal(request);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       ClosedInProgressNotificationReopensOnFailure) {
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback).Run(response);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 1U);
  EXPECT_THAT(Printable(notifications[0]), IsUninstallProgressNotification(0));
  CloseNotification(notifications[0]);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      IsEmpty());

  UninstallPackageProgressSignal signal_failure = MakeUninstallSignal(request);
  signal_failure.set_status(UninstallPackageProgressSignal::FAILED);
  signal_failure.set_failure_details("I prefer not to");
  fake_cicerone_client_->UninstallPackageProgress(signal_failure);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       ClosedQueuedNotificationDoesNotReopenOnProgress) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 2U);
  EXPECT_THAT(Printable(notifications[1]),
              IsUninstallQueuedNotification(SECOND_APP));
  CloseNotification(notifications[1]);

  // Complete Uninstall 1
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  // Uninstall 2 is now started, but we don't see a notification.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP)));
}

TEST_F(CrostiniPackageServiceTest,
       ClosedQueuedNotificationDoesNotReopenOnFurtherProgress) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 2U);
  EXPECT_THAT(Printable(notifications[1]),
              IsUninstallQueuedNotification(SECOND_APP));
  CloseNotification(notifications[1]);

  // Complete Uninstall 1
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  // Start Uninstall 2
  StartAndSignalUninstall(UninstallPackageProgressSignal::UNINSTALLING,
                          50 /*progress_percent*/, kSecondAppFileId);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP)));
}

TEST_F(CrostiniPackageServiceTest,
       ClosedQueuedNotificationReopensOnCompletion) {
  service_->QueueUninstallApplication(kDefaultAppId);
  service_->QueueUninstallApplication(kSecondAppId);

  std::vector<message_center::Notification> notifications =
      notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(notifications.size(), 2U);
  EXPECT_THAT(Printable(notifications[1]),
              IsUninstallQueuedNotification(SECOND_APP));
  CloseNotification(notifications[1]);

  // Complete Uninstall 1
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);

  // Complete Uninstall 2
  StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED,
                          0 /*progress_percent*/, kSecondAppFileId);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(SECOND_APP)));
}

TEST_F(CrostiniPackageServiceTest, UninstallsOnDifferentVmsDoNotInterfere) {
  service_->QueueUninstallApplication(kDefaultAppId);
  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  EXPECT_EQ(request.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);

  service_->QueueUninstallApplication(kDifferentVmAppId);
  UninstallPackageOwningFileRequest request_different_vm;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback_different_vm;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request_different_vm,
                               &callback_different_vm);
  EXPECT_EQ(request_different_vm.vm_name(), kDifferentVmVmName);
  EXPECT_EQ(request_different_vm.desktop_file_id(), kDifferentVmAppFileId);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallProgressNotification(0, DIFFERENT_VM)));

  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback).Run(response);
  UninstallPackageProgressSignal signal_progress = MakeUninstallSignal(request);
  signal_progress.set_status(UninstallPackageProgressSignal::UNINSTALLING);
  signal_progress.set_progress_percent(60);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(60, DEFAULT_APP),
                           IsUninstallProgressNotification(0, DIFFERENT_VM)));

  std::move(callback_different_vm).Run(response);
  signal_progress = MakeUninstallSignal(request_different_vm);
  signal_progress.set_status(UninstallPackageProgressSignal::UNINSTALLING);
  signal_progress.set_progress_percent(40);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(60, DEFAULT_APP),
                           IsUninstallProgressNotification(40, DIFFERENT_VM)));

  UninstallPackageProgressSignal signal_success =
      MakeUninstallSignal(request_different_vm);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(60, DEFAULT_APP),
                           IsUninstallSuccessNotification(DIFFERENT_VM)));

  UninstallPackageProgressSignal signal_failure = MakeUninstallSignal(request);
  signal_failure.set_status(UninstallPackageProgressSignal::FAILED);
  signal_failure.set_failure_details("Nope");
  fake_cicerone_client_->UninstallPackageProgress(signal_failure);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallFailedNotification(DEFAULT_APP),
                           IsUninstallSuccessNotification(DIFFERENT_VM)));
}

TEST_F(CrostiniPackageServiceTest, UninstallsOnDifferentVmsHaveSeparateQueues) {
  service_->QueueUninstallApplication(kDefaultAppId);
  UninstallPackageOwningFileRequest request_default;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback_default;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request_default,
                               &callback_default);
  EXPECT_EQ(request_default.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request_default.desktop_file_id(), kDefaultAppFileId);

  service_->QueueUninstallApplication(kDifferentVmAppId);
  UninstallPackageOwningFileRequest request_different_vm;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback_different_vm;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request_different_vm,
                               &callback_different_vm);
  EXPECT_EQ(request_different_vm.vm_name(), kDifferentVmVmName);
  EXPECT_EQ(request_different_vm.desktop_file_id(), kDifferentVmAppFileId);

  service_->QueueUninstallApplication(kSecondAppId);
  service_->QueueUninstallApplication(kDifferentVmApp2Id);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallProgressNotification(0, DIFFERENT_VM),
                           IsUninstallQueuedNotification(SECOND_APP),
                           IsUninstallQueuedNotification(DIFFERENT_VM_2)));

  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::FAILED);
  std::move(callback_different_vm).Run(response);

  // Even though kSecondAppId was queued first, kDifferentVmApp2Id is moved
  // to progress state, because it's on a different queue.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallFailedNotification(DIFFERENT_VM),
                           IsUninstallQueuedNotification(SECOND_APP),
                           IsUninstallProgressNotification(0, DIFFERENT_VM_2)));

  UninstallPackageOwningFileRequest request_different_vm_2;
  DBusMethodCallback<UninstallPackageOwningFileResponse>
      callback_different_vm_2;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request_different_vm_2,
                               &callback_different_vm_2);
  EXPECT_EQ(request_different_vm_2.vm_name(), kDifferentVmVmName);
  EXPECT_EQ(request_different_vm_2.desktop_file_id(), kDifferentVmApp2FileId);
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback_different_vm_2).Run(response);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallFailedNotification(DIFFERENT_VM),
                           IsUninstallQueuedNotification(SECOND_APP),
                           IsUninstallProgressNotification(0, DIFFERENT_VM_2)));

  UninstallPackageProgressSignal signal_success =
      MakeUninstallSignal(request_different_vm_2);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  // Even though the task finished on VM 2, SECOND_APP does not start
  // uninstalling because it is on a different queue.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallProgressNotification(0, DEFAULT_APP),
                           IsUninstallFailedNotification(DIFFERENT_VM),
                           IsUninstallQueuedNotification(SECOND_APP),
                           IsUninstallSuccessNotification(DIFFERENT_VM_2)));

  std::move(callback_default).Run(response);
  signal_success = MakeUninstallSignal(request_default);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  // Only when the uninstall on the default VM is done does SECOND_APP start
  // uninstalling.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsUninstallSuccessNotification(DEFAULT_APP),
                           IsUninstallFailedNotification(DIFFERENT_VM),
                           IsUninstallProgressNotification(0, SECOND_APP),
                           IsUninstallSuccessNotification(DIFFERENT_VM_2)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallsOnDifferentContainersDoNotInterfere) {
  service_->QueueUninstallApplication(kDefaultAppId);
  UninstallPackageOwningFileRequest request;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, &callback);
  EXPECT_EQ(request.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);

  service_->QueueUninstallApplication(kDifferentContainerAppId);
  UninstallPackageOwningFileRequest request_different_container;
  DBusMethodCallback<UninstallPackageOwningFileResponse>
      callback_different_container;
  RunUntilUninstallRequestMade(fake_cicerone_client_,
                               &request_different_container,
                               &callback_different_container);
  EXPECT_EQ(request_different_container.container_name(),
            kDifferentContainerContainerName);
  EXPECT_EQ(request_different_container.desktop_file_id(),
            kDifferentContainerAppFileId);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(0, DEFAULT_APP),
          IsUninstallProgressNotification(0, DIFFERENT_CONTAINER)));

  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback).Run(response);
  UninstallPackageProgressSignal signal_progress = MakeUninstallSignal(request);
  signal_progress.set_status(UninstallPackageProgressSignal::UNINSTALLING);
  signal_progress.set_progress_percent(60);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(60, DEFAULT_APP),
          IsUninstallProgressNotification(0, DIFFERENT_CONTAINER)));

  std::move(callback_different_container).Run(response);
  signal_progress = MakeUninstallSignal(request_different_container);
  signal_progress.set_status(UninstallPackageProgressSignal::UNINSTALLING);
  signal_progress.set_progress_percent(40);
  fake_cicerone_client_->UninstallPackageProgress(signal_progress);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(60, DEFAULT_APP),
          IsUninstallProgressNotification(40, DIFFERENT_CONTAINER)));

  UninstallPackageProgressSignal signal_success =
      MakeUninstallSignal(request_different_container);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(60, DEFAULT_APP),
          IsUninstallSuccessNotification(DIFFERENT_CONTAINER)));

  UninstallPackageProgressSignal signal_failure = MakeUninstallSignal(request);
  signal_failure.set_status(UninstallPackageProgressSignal::FAILED);
  signal_failure.set_failure_details("Nope");
  fake_cicerone_client_->UninstallPackageProgress(signal_failure);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallFailedNotification(DEFAULT_APP),
          IsUninstallSuccessNotification(DIFFERENT_CONTAINER)));
}

TEST_F(CrostiniPackageServiceTest,
       UninstallsOnDifferentContainersHaveSeparateQueues) {
  service_->QueueUninstallApplication(kDefaultAppId);
  UninstallPackageOwningFileRequest request_default;
  DBusMethodCallback<UninstallPackageOwningFileResponse> callback_default;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request_default,
                               &callback_default);
  EXPECT_EQ(request_default.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request_default.desktop_file_id(), kDefaultAppFileId);

  service_->QueueUninstallApplication(kDifferentContainerAppId);
  UninstallPackageOwningFileRequest request_different_container;
  DBusMethodCallback<UninstallPackageOwningFileResponse>
      callback_different_container;
  RunUntilUninstallRequestMade(fake_cicerone_client_,
                               &request_different_container,
                               &callback_different_container);
  EXPECT_EQ(request_different_container.container_name(),
            kDifferentContainerContainerName);
  EXPECT_EQ(request_different_container.desktop_file_id(),
            kDifferentContainerAppFileId);

  service_->QueueUninstallApplication(kSecondAppId);
  service_->QueueUninstallApplication(kDifferentContainerApp2Id);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(0, DEFAULT_APP),
          IsUninstallProgressNotification(0, DIFFERENT_CONTAINER),
          IsUninstallQueuedNotification(SECOND_APP),
          IsUninstallQueuedNotification(DIFFERENT_CONTAINER_2)));

  UninstallPackageOwningFileResponse response;
  response.set_status(UninstallPackageOwningFileResponse::FAILED);
  std::move(callback_different_container).Run(response);

  // Even though kSecondAppId was queued first, kDifferentContainerApp2Id is
  // moved to progress state, because it's on a different queue.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(0, DEFAULT_APP),
          IsUninstallFailedNotification(DIFFERENT_CONTAINER),
          IsUninstallQueuedNotification(SECOND_APP),
          IsUninstallProgressNotification(0, DIFFERENT_CONTAINER_2)));

  UninstallPackageOwningFileRequest request_different_container_2;
  DBusMethodCallback<UninstallPackageOwningFileResponse>
      callback_different_container_2;
  RunUntilUninstallRequestMade(fake_cicerone_client_,
                               &request_different_container_2,
                               &callback_different_container_2);
  EXPECT_EQ(request_different_container_2.container_name(),
            kDifferentContainerContainerName);
  EXPECT_EQ(request_different_container_2.desktop_file_id(),
            kDifferentContainerApp2FileId);
  response.set_status(UninstallPackageOwningFileResponse::STARTED);
  std::move(callback_different_container_2).Run(response);
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(0, DEFAULT_APP),
          IsUninstallFailedNotification(DIFFERENT_CONTAINER),
          IsUninstallQueuedNotification(SECOND_APP),
          IsUninstallProgressNotification(0, DIFFERENT_CONTAINER_2)));

  UninstallPackageProgressSignal signal_success =
      MakeUninstallSignal(request_different_container_2);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  // Even though the task finished on container 2, SECOND_APP does not start
  // uninstalling because it is on a different queue.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallProgressNotification(0, DEFAULT_APP),
          IsUninstallFailedNotification(DIFFERENT_CONTAINER),
          IsUninstallQueuedNotification(SECOND_APP),
          IsUninstallSuccessNotification(DIFFERENT_CONTAINER_2)));

  std::move(callback_default).Run(response);
  signal_success = MakeUninstallSignal(request_default);
  signal_success.set_status(UninstallPackageProgressSignal::SUCCEEDED);
  fake_cicerone_client_->UninstallPackageProgress(signal_success);

  // Only when the uninstall on the default container is done does SECOND_APP
  // start uninstalling.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(
          IsUninstallSuccessNotification(DEFAULT_APP),
          IsUninstallFailedNotification(DIFFERENT_CONTAINER),
          IsUninstallProgressNotification(0, SECOND_APP),
          IsUninstallSuccessNotification(DIFFERENT_CONTAINER_2)));
}

TEST_F(CrostiniPackageServiceTest, InstallSendsValidRequest) {
  base::RunLoop run_loop;
  service_->QueueInstallLinuxPackage(
      kDifferentContainerId, package_file_url_,
      base::BindOnce(&ExpectedCrostiniResult, run_loop.QuitClosure(),
                     CrostiniResult::SUCCESS));
  run_loop.Run();

  const vm_tools::cicerone::InstallLinuxPackageRequest& request =
      fake_cicerone_client_->get_most_recent_install_linux_package_request();

  EXPECT_EQ(request.vm_name(), kDifferentVmVmName);
  EXPECT_EQ(request.container_name(), kDifferentContainerContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.file_path(), kPackageFileContainerPath);
}

TEST_F(CrostiniPackageServiceTest, InstallConvertPathFailure) {
  base::RunLoop run_loop;
  service_->QueueInstallLinuxPackage(
      kDifferentContainerId,
      storage::FileSystemURL::CreateForTest(GURL("invalid")),
      base::BindOnce(&ExpectedCrostiniResult, run_loop.QuitClosure(),
                     CrostiniResult::INSTALL_LINUX_PACKAGE_FAILED));
  run_loop.Run();
}

TEST_F(CrostiniPackageServiceTest, InstallDisplaysProgressNotificationOnStart) {
  base::RunLoop run_loop;
  service_->QueueInstallLinuxPackage(
      ContainerId::GetDefault(), package_file_url_,
      base::BindOnce(&ExpectedCrostiniResult, run_loop.QuitClosure(),
                     CrostiniResult::SUCCESS));
  run_loop.Run();

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallProgressNotification(0)));
}

TEST_F(CrostiniPackageServiceTest,
       InstallUpdatesProgressNotificationOnDownloadingSignal) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  StartAndSignalInstall(InstallLinuxPackageProgressSignal::DOWNLOADING,
                        44 /*progress_percent*/);

  // 22 = 44/2
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallProgressNotification(22)));
}

TEST_F(CrostiniPackageServiceTest,
       InstallUpdatesProgressNotificationOnInstallingSignal) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  StartAndSignalInstall(InstallLinuxPackageProgressSignal::INSTALLING,
                        44 /*progress_percent*/);

  // 72 = 44/2 + 50
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallProgressNotification(72)));
}

TEST_F(CrostiniPackageServiceTest,
       InstallDisplaysSuccessNotificationOnSuccessSignal) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  StartAndSignalInstall(InstallLinuxPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       InstallDisplaysFailureNotificationOnFailedSignal) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  StartAndSignalInstall(InstallLinuxPackageProgressSignal::FAILED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest, InstallNotificationWaitsForAppListUpdate) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  base::RunLoop().RunUntilIdle();

  SendAppListUpdateSignal(ContainerId::GetDefault(), 1);

  StartAndSignalInstall(InstallLinuxPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallWaitingForAppListNotification()));

  SendAppListUpdateSignal(ContainerId::GetDefault(), 0);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       InstallNotificationDoesntWaitForAppListUpdate) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  base::RunLoop().RunUntilIdle();

  SendAppListUpdateSignal(ContainerId::GetDefault(), 0);

  StartAndSignalInstall(InstallLinuxPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification()));

  SendAppListUpdateSignal(ContainerId::GetDefault(), 1);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       InstallNotificationAppListUpdatesAreVmSpecific) {
  InstallLinuxPackageRequest request;

  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  request =
      fake_cicerone_client_->get_most_recent_install_linux_package_request();
  InstallLinuxPackageProgressSignal signal_progress =
      MakeInstallSignal(request);
  signal_progress.set_status(InstallLinuxPackageProgressSignal::SUCCEEDED);

  service_->QueueInstallLinuxPackage(
      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName),
      package_file_url_, base::DoNothing());
  request =
      fake_cicerone_client_->get_most_recent_install_linux_package_request();
  InstallLinuxPackageProgressSignal signal_progress2 =
      MakeInstallSignal(request);
  signal_progress2.set_status(InstallLinuxPackageProgressSignal::SUCCEEDED);

  base::RunLoop().RunUntilIdle();

  SendAppListUpdateSignal(
      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
  fake_cicerone_client_->InstallLinuxPackageProgress(signal_progress);
  fake_cicerone_client_->InstallLinuxPackageProgress(signal_progress2);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification(),
                           IsInstallWaitingForAppListNotification()));
}

TEST_F(CrostiniPackageServiceTest,
       InstallNotificationAppListUpdatesFromUnknownContainersAreIgnored) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());

  base::RunLoop().RunUntilIdle();

  SendAppListUpdateSignal(
      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);

  StartAndSignalInstall(InstallLinuxPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification()));
}

TEST_F(CrostiniPackageServiceTest, InstallNotificationFailsOnVmShutdown) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());

  base::RunLoop().RunUntilIdle();

  StartAndSignalInstall(InstallLinuxPackageProgressSignal::INSTALLING);

  base::RunLoop run_loop;
  CrostiniManager::GetForProfile(profile_.get())
      ->StopVm(kCrostiniDefaultVmName,
               base::BindOnce(
                   [](base::OnceClosure quit, crostini::CrostiniResult) {
                     std::move(quit).Run();
                   },
                   run_loop.QuitClosure()));
  run_loop.Run();

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallFailedNotification()));
}

TEST_F(CrostiniPackageServiceTest, UninstallsQueuesBehindStartingUpInstall) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  service_->QueueUninstallApplication(kDefaultAppId);

  // Install doesn't show a notification until it gets a response, but uninstall
  // still shows a queued notification.
  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallProgressNotification(0),
                           IsUninstallQueuedNotification()));
}

TEST_F(CrostiniPackageServiceTest, InstallRunsInFrontOfQueuedUninstall) {
  base::RunLoop run_loop;
  service_->QueueInstallLinuxPackage(
      ContainerId::GetDefault(), package_file_url_,
      base::BindOnce(&ExpectedCrostiniResult, run_loop.QuitClosure(),
                     CrostiniResult::SUCCESS));
  service_->QueueUninstallApplication(kDefaultAppId);
  run_loop.Run();

  // Ensure the install started, not the uninstall.
  const vm_tools::cicerone::InstallLinuxPackageRequest& request =
      fake_cicerone_client_->get_most_recent_install_linux_package_request();
  EXPECT_EQ(request.file_path(), kPackageFileContainerPath);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallProgressNotification(0),
                           IsUninstallQueuedNotification()));
}

TEST_F(CrostiniPackageServiceTest, QueuedUninstallRunsAfterCompletedInstall) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  service_->QueueUninstallApplication(kDefaultAppId);
  StartAndSignalInstall(InstallLinuxPackageProgressSignal::SUCCEEDED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallSuccessNotification(),
                           IsUninstallProgressNotification(0)));
  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_EQ(request.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
}

TEST_F(CrostiniPackageServiceTest,
       QueuedUninstallRunsAfterFailedToStartInstall) {
  InstallLinuxPackageResponse response;
  response.set_status(InstallLinuxPackageResponse::FAILED);
  response.set_failure_reason("No such file");
  fake_cicerone_client_->set_install_linux_package_response(response);
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  service_->QueueUninstallApplication(kDefaultAppId);

  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallFailedNotification(),
                           IsUninstallProgressNotification(0)));

  EXPECT_EQ(request.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
}

TEST_F(CrostiniPackageServiceTest,
       QueuedUninstallRunsAfterFailedInstallSignal) {
  service_->QueueInstallLinuxPackage(ContainerId::GetDefault(),
                                     package_file_url_, base::DoNothing());
  service_->QueueUninstallApplication(kDefaultAppId);
  StartAndSignalInstall(InstallLinuxPackageProgressSignal::FAILED);

  EXPECT_THAT(
      Printable(notification_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT)),
      UnorderedElementsAre(IsInstallFailedNotification(),
                           IsUninstallProgressNotification(0)));
  UninstallPackageOwningFileRequest request;
  RunUntilUninstallRequestMade(fake_cicerone_client_, &request, nullptr);

  EXPECT_EQ(request.vm_name(), kCrostiniDefaultVmName);
  EXPECT_EQ(request.container_name(), kCrostiniDefaultContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.desktop_file_id(), kDefaultAppFileId);
}

TEST_F(CrostiniPackageServiceTest, GetLinuxPackageInfoSendsCorrectRequest) {
  service_->GetLinuxPackageInfo(kDifferentContainerId, package_file_url_,
                                base::DoNothing());

  base::RunLoop().RunUntilIdle();

  const LinuxPackageInfoRequest& request =
      fake_cicerone_client_->get_most_recent_linux_package_info_request();
  EXPECT_EQ(request.vm_name(), kDifferentVmVmName);
  EXPECT_EQ(request.container_name(), kDifferentContainerContainerName);
  EXPECT_EQ(request.owner_id(), CryptohomeIdForProfile(profile_.get()));
  EXPECT_EQ(request.file_path(), kPackageFileContainerPath);
  EXPECT_TRUE(fake_seneschal_client_->share_path_called());
}

TEST_F(CrostiniPackageServiceTest, GetLinuxPackageInfoReturnsInfoOnSuccess) {
  LinuxPackageInfoResponse response;
  response.set_success(true);
  response.set_package_id("nethack;3.6.1;x64;some data");
  response.set_license("ngpl");
  response.set_description("Explore the Dungeon!");
  response.set_project_url("https://www.nethack.org/");
  response.set_size(548422342432);
  response.set_summary("Fight! Run! Win!");
  fake_cicerone_client_->set_linux_package_info_response(response);

  LinuxPackageInfo result;
  service_->GetLinuxPackageInfo(
      kDifferentContainerId, package_file_url_,
      base::BindOnce(&RecordPackageInfoResult, base::Unretained(&result)));

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(result.success);
  EXPECT_EQ(result.name, "nethack");
  EXPECT_EQ(result.version, "3.6.1");
  EXPECT_EQ(result.summary, response.summary());
  EXPECT_EQ(result.description, response.description());
}

TEST_F(CrostiniPackageServiceTest, GetLinuxPackageInfoConvertPathFailure) {
  SharePathResponse response;
  response.set_success(false);
  fake_seneschal_client_->set_share_path_response(response);

  LinuxPackageInfo result;
  service_->GetLinuxPackageInfo(
      kDifferentContainerId,
      storage::FileSystemURL::CreateForTest(GURL("invalid")),
      base::BindOnce(&RecordPackageInfoResult, base::Unretained(&result)));

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(result.success);
  EXPECT_TRUE(base::StartsWith(result.failure_reason, "Invalid package url:",
                               base::CompareCase::SENSITIVE));
}

TEST_F(CrostiniPackageServiceTest, GetLinuxPackageInfoSharePathFailure) {
  SharePathResponse response;
  response.set_success(false);
  fake_seneschal_client_->set_share_path_response(response);

  LinuxPackageInfo result;
  service_->GetLinuxPackageInfo(
      kDifferentContainerId, package_file_url_,
      base::BindOnce(&RecordPackageInfoResult, base::Unretained(&result)));

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(result.success);
  EXPECT_TRUE(base::StartsWith(result.failure_reason, "Error sharing package",
                               base::CompareCase::SENSITIVE));
}

TEST_F(CrostiniPackageServiceTest, GetLinuxPackageInfoReturnsFailureOnFailure) {
  LinuxPackageInfoResponse response;
  response.set_success(false);
  response.set_failure_reason("test failure reason");
  fake_cicerone_client_->set_linux_package_info_response(response);

  LinuxPackageInfo result;
  service_->GetLinuxPackageInfo(
      kDifferentContainerId, package_file_url_,
      base::BindOnce(&RecordPackageInfoResult, base::Unretained(&result)));

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(result.success);
  EXPECT_EQ(result.failure_reason, "test failure reason");
}

}  // namespace

}  // namespace crostini
