#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h"
#include <memory>
#include <string>
#include <string_view>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/version.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h"
#include "chrome/browser/ui/views/web_apps/isolated_web_apps/test_isolated_web_app_installer_model_observer.h"
#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_source.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_storage_location.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_trust_checker.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
#include "chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_metadata.h"
#include "chrome/browser/web_applications/isolated_web_apps/test/test_signed_web_bundle_builder.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/fake_web_app_ui_manager.h"
#include "chrome/browser/web_applications/test/fake_web_contents_manager.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_icon_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_ui_manager.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_task_environment.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/manifest/manifest.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ash_pref_names.h"
#include "base/values.h"
#include "chrome/browser/ui/views/web_apps/isolated_web_apps/pref_observer.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/app_restore/full_restore_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/extensions/extension_keeplist_chromeos.h"
#include "chrome/browser/web_applications/app_service/test/loopback_crosapi_app_service_proxy.h"
#include "chromeos/crosapi/mojom/prefs.mojom.h"
#include "chromeos/lacros/lacros_service.h"
#endif
namespace web_app {
namespace {
_;
AllOf;
AnyNumber;
Exactly;
ExplainMatchResult;
Field;
Invoke;
Property;
VariantWith;
Step;
constexpr std::string_view kIconPath = …;
MATCHER_P3(WithMetadata, app_id, app_name, version, "") { … }
IsolatedWebAppUrlInfo CreateAndWriteTestBundle(
const base::FilePath& bundle_path,
const std::string& version) { … }
SignedWebBundleMetadata CreateMetadata(const std::u16string& app_name,
const std::string& version) { … }
blink::mojom::ManifestPtr CreateDefaultManifest(const GURL& iwa_url,
const base::Version version) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
std::unique_ptr<KeyedService> NullServiceFactory(content::BrowserContext*) {
return nullptr;
}
#endif
class MockView : public IsolatedWebAppInstallerView { … };
class FakeIsolatedWebAppsEnabledPrefObserver
: public IsolatedWebAppsEnabledPrefObserver { … };
}
class IsolatedWebAppInstallerViewControllerTest : public ::testing::Test { … };
TEST_F(IsolatedWebAppInstallerViewControllerTest,
ValidBundleTransitionsToShowMetadataScreen) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
InvalidBundleShowsErrorDialog) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
OutdatedBundleShowsAlreadyInstalledDialog) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
NewerBundleShowsAlreadyInstalledDialog) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
InstallButtonLaunchesConfirmationDialog) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
ConfirmationDialogMovesToInstallScreen) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
SuccessfulInstallationMovesToSuccessScreen) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest, CanLaunchAppAfterInstall) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
InstallationErrorShowsErrorDialog) { … }
TEST_F(IsolatedWebAppInstallerViewControllerTest,
InstallationErrorRetryRestartsFlow) { … }
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(IsolatedWebAppInstallerViewControllerTest,
ChangingPrefToFalseDisablesInstaller) {
base::FilePath bundle_path = CreateBundlePath("test_bundle.swbn");
IsolatedWebAppUrlInfo url_info = CreateAndWriteTestBundle(bundle_path, "1.0");
SetTrustedWebBundleIdsForTesting({url_info.web_bundle_id()});
MockIconAndPageState(url_info);
IsolatedWebAppInstallerModel model{IwaSourceBundleProdMode(bundle_path)};
auto pref_observer =
std::make_unique<FakeIsolatedWebAppsEnabledPrefObserver>(true);
FakeIsolatedWebAppsEnabledPrefObserver* raw_pref_observer =
pref_observer.get();
IsolatedWebAppInstallerViewController controller(
profile(), fake_provider(), &model, std::move(pref_observer));
testing::StrictMock<MockView> view;
controller.SetViewForTesting(&view);
EXPECT_CALL(view, UpdateGetMetadataProgress(_)).Times(AnyNumber());
EXPECT_CALL(view, ShowGetMetadataScreen());
EXPECT_CALL(
view, ShowMetadataScreen(WithMetadata("hoealecpbefphiclhampllbdbdpfmfpi",
u"test app name", "7.7.7")));
controller.Start(base::DoNothing(), base::DoNothing());
TestIsolatedWebAppInstallerModelObserver model_observer(&model);
model_observer.WaitForStepChange(Step::kShowMetadata);
EXPECT_CALL(view, ShowDisabledScreen());
raw_pref_observer->UpdatePref(false);
model_observer.WaitForStepChange(Step::kDisabled);
}
TEST_F(IsolatedWebAppInstallerViewControllerTest,
ChangingPrefToTrueRestartsInstaller) {
base::FilePath bundle_path = CreateBundlePath("test_bundle.swbn");
IsolatedWebAppUrlInfo url_info = CreateAndWriteTestBundle(bundle_path, "1.0");
SetTrustedWebBundleIdsForTesting({url_info.web_bundle_id()});
MockIconAndPageState(url_info);
IsolatedWebAppInstallerModel model{IwaSourceBundleProdMode(bundle_path)};
auto pref_observer =
std::make_unique<FakeIsolatedWebAppsEnabledPrefObserver>(false);
FakeIsolatedWebAppsEnabledPrefObserver* raw_pref_observer =
pref_observer.get();
IsolatedWebAppInstallerViewController controller(
profile(), fake_provider(), &model, std::move(pref_observer));
testing::StrictMock<MockView> view;
controller.SetViewForTesting(&view);
EXPECT_CALL(view, ShowDisabledScreen());
controller.Start(base::DoNothing(), base::DoNothing());
TestIsolatedWebAppInstallerModelObserver model_observer(&model);
model_observer.WaitForStepChange(Step::kDisabled);
ASSERT_EQ(model.step(), Step::kDisabled);
EXPECT_CALL(view, UpdateGetMetadataProgress(_)).Times(AnyNumber());
EXPECT_CALL(view, ShowGetMetadataScreen());
EXPECT_CALL(
view, ShowMetadataScreen(WithMetadata("hoealecpbefphiclhampllbdbdpfmfpi",
u"test app name", "7.7.7")));
raw_pref_observer->UpdatePref(true);
model_observer.WaitForStepChange(Step::kShowMetadata);
}
#endif
}