#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager.h"
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/to_vector.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/values_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/test/test_timeouts.h"
#include "base/test/values_test_util.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/version.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.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_apply_update_command.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_update_discovery_task.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
#include "chrome/browser/web_applications/isolated_web_apps/iwa_identity_validator.h"
#include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_constants.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_database_factory.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/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/test/web_app_test_observers.h"
#include "chrome/browser/web_applications/web_app_command_scheduler.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_contents/web_contents_manager.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/nacl/common/buildflags.h"
#include "components/web_package/signed_web_bundles/ed25519_public_key.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "components/webapps/browser/uninstall_result_code.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/common/content_features.h"
#include "net/http/http_status_code.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"
#if BUILDFLAG(ENABLE_NACL)
#include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
#include "components/nacl/browser/nacl_browser.h"
#endif
namespace web_app {
namespace {
ToVector;
DictionaryHasValue;
ValueIs;
_;
AllOf;
Each;
ElementsAre;
Eq;
ExplainMatchResult;
Field;
Ge;
Invoke;
IsEmpty;
IsFalse;
IsTrue;
Le;
Ne;
NiceMock;
NotNull;
Optional;
Property;
SizeIs;
VariantWith;
WithArg;
blink::mojom::ManifestPtr CreateDefaultManifest(const GURL& application_url,
std::u16string_view short_name,
const base::Version& version) { … }
MATCHER_P(IsDict, dict_matcher, "") { … }
class MockCommandScheduler : public WebAppCommandScheduler { … };
#if BUILDFLAG(ENABLE_NACL)
class ScopedNaClBrowserDelegate {
public:
~ScopedNaClBrowserDelegate() { nacl::NaClBrowser::ClearAndDeleteDelegate(); }
void Init(ProfileManager* profile_manager) {
nacl::NaClBrowser::SetDelegate(
std::make_unique<NaClBrowserDelegateImpl>(profile_manager));
}
};
#endif
class IsolatedWebAppUpdateManagerTest : public WebAppTest { … };
class IsolatedWebAppUpdateManagerDevModeUpdateTest
: public IsolatedWebAppUpdateManagerTest { … };
TEST_F(IsolatedWebAppUpdateManagerDevModeUpdateTest,
DiscoversLocalDevModeUpdate) { … }
class IsolatedWebAppUpdateManagerUpdateTest
: public IsolatedWebAppUpdateManagerTest { … };
class IsolatedWebAppUpdateManagerUpdateMockTimeTest
: public IsolatedWebAppUpdateManagerUpdateTest { … };
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(IsolatedWebAppUpdateManagerUpdateMockTimeTest,
DiscoversAndPreparesUpdateOfPolicyInstalledApps) {
IsolatedWebAppUrlInfo non_installed_url_info =
IsolatedWebAppUrlInfo::CreateFromSignedWebBundleId(
*web_package::SignedWebBundleId::Create(
"5tkrnsmftl4ggvvdkfth3piainqragus2qbhf7rlz2a3wo3rh4wqaaic"));
IsolatedWebAppUrlInfo dev_bundle_url_info =
IsolatedWebAppUrlInfo::CreateFromSignedWebBundleId(
*web_package::SignedWebBundleId::Create(
"aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic"));
IsolatedWebAppUrlInfo dev_proxy_url_info =
IsolatedWebAppUrlInfo::CreateFromSignedWebBundleId(
web_package::SignedWebBundleId::CreateRandomForProxyMode());
test::InstallDummyWebApp(profile(), "non-iwa", GURL("https://a"));
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed iwa 1",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
AddDummyIsolatedAppToRegistry(
profile(), dev_proxy_url_info.origin().GetURL(),
"installed iwa 2 (dev mode proxy)",
WebApp::IsolationData(IwaStorageProxy{dev_proxy_url_info.origin()},
base::Version("1.0.0")),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
AddDummyIsolatedAppToRegistry(
profile(), dev_bundle_url_info.origin().GetURL(),
"installed iwa 3 (unowned bundle)",
WebApp::IsolationData(IwaStorageUnownedBundle{base::FilePath()},
base::Version("1.0.0")),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
AddDummyIsolatedAppToRegistry(
profile(), GURL("isolated-app://b"), "installed iwa 4",
WebApp::IsolationData(
IwaStorageOwnedBundle{"", false},
base::Version("1.0.0")),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 1);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()},
{non_installed_url_info, "https://example.com/update_manifest.json"},
{dev_bundle_url_info, "https://example.com/update_manifest.json"},
{dev_proxy_url_info, "https://example.com/update_manifest.json"}});
task_environment()->FastForwardBy(
*update_manager().GetNextUpdateDiscoveryTimeForTesting() -
base::TimeTicks::Now());
task_environment()->RunUntilIdle();
EXPECT_THAT(
fake_provider().registrar_unsafe().GetAppById(
iwa_info1_->url_info.app_id()),
test::IwaIs(Eq("installed iwa 1"),
test::IsolationDataIs(Eq(iwa_info1_->installed_location),
Eq(iwa_info1_->installed_version),
_,
test::PendingUpdateInfoIs(
UpdateLocationMatcher(profile()),
Eq(base::Version("2.0.0")),
_),
_)));
EXPECT_THAT(
UpdateDiscoveryLog(),
UnorderedElementsAre(IsDict(DictionaryHasValue(
"result", base::Value("Success::kUpdateFoundAndDryRunSuccessful")))));
EXPECT_THAT(UpdateApplyLog(), IsEmpty());
fake_provider().Shutdown();
ChromeBrowsingDataRemoverDelegateFactory::GetForProfile(profile())
->Shutdown();
}
#endif
TEST_F(IsolatedWebAppUpdateManagerUpdateMockTimeTest,
MaybeDiscoverUpdatesForApp) { … }
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(IsolatedWebAppUpdateManagerUpdateMockTimeTest, DiscoverUpdatesNow) {
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed iwa 1",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 1);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()}});
task_environment()->FastForwardBy(base::Hours(1));
auto old_update_discovery_time =
update_manager().GetNextUpdateDiscoveryTimeForTesting();
EXPECT_THAT(old_update_discovery_time.has_value(), IsTrue());
EXPECT_THAT(update_manager().DiscoverUpdatesNow(), Eq(1ul));
EXPECT_THAT(update_manager().GetNextUpdateDiscoveryTimeForTesting(),
AllOf(Ne(old_update_discovery_time), Ge(base::TimeTicks::Now())));
task_environment()->RunUntilIdle();
EXPECT_THAT(
fake_provider().registrar_unsafe().GetAppById(
iwa_info1_->url_info.app_id()),
test::IwaIs(Eq("installed iwa 1"),
test::IsolationDataIs(Eq(iwa_info1_->installed_location),
Eq(iwa_info1_->installed_version),
_,
test::PendingUpdateInfoIs(
UpdateLocationMatcher(profile()),
Eq(base::Version("2.0.0")),
_),
_)));
EXPECT_THAT(
UpdateDiscoveryLog(),
UnorderedElementsAre(IsDict(DictionaryHasValue(
"result", base::Value("Success::kUpdateFoundAndDryRunSuccessful")))));
EXPECT_THAT(UpdateApplyLog(), IsEmpty());
fake_provider().Shutdown();
ChromeBrowsingDataRemoverDelegateFactory::GetForProfile(profile())
->Shutdown();
}
TEST_F(IsolatedWebAppUpdateManagerUpdateTest,
ApplysUpdatesAfterWindowIsClosed) {
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed app",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 1);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()}});
update_manager().DiscoverUpdatesNow();
task_environment()->RunUntilIdle();
EXPECT_THAT(
fake_provider().registrar_unsafe().GetAppById(
iwa_info1_->url_info.app_id()),
test::IwaIs(Eq("installed app"),
test::IsolationDataIs(Eq(iwa_info1_->installed_location),
Eq(iwa_info1_->installed_version),
_,
test::PendingUpdateInfoIs(
UpdateLocationMatcher(profile()),
Eq(iwa_info1_->update_version),
_),
_)));
EXPECT_THAT(
UpdateDiscoveryLog(),
UnorderedElementsAre(IsDict(DictionaryHasValue(
"result", base::Value("Success::kUpdateFoundAndDryRunSuccessful")))));
EXPECT_THAT(UpdateApplyLog(), IsEmpty());
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 0);
task_environment()->RunUntilIdle();
EXPECT_THAT(UpdateApplyLog(), UnorderedElementsAre(IsDict(DictionaryHasValue(
"result", base::Value("Success")))));
EXPECT_THAT(fake_provider().registrar_unsafe().GetAppById(
iwa_info1_->url_info.app_id()),
test::IwaIs(iwa_info1_->update_app_name,
test::IsolationDataIs(
UpdateLocationMatcher(profile()),
Eq(iwa_info1_->update_version),
_,
Eq(std::nullopt),
_)));
}
TEST_F(IsolatedWebAppUpdateManagerUpdateTest,
ApplysUpdatesWithHigherPriorityThanUpdateDiscovery) {
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed app 1",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
AddDummyIsolatedAppToRegistry(
profile(), iwa_info2_->url_info.origin().GetURL(), "installed app 2",
WebApp::IsolationData(iwa_info2_->installed_location,
iwa_info2_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()},
{iwa_info2_->url_info, iwa_info2_->update_manifest_url.spec()}});
update_manager().DiscoverUpdatesNow();
task_environment()->RunUntilIdle();
{
auto update_discovery_log = UpdateDiscoveryLog();
auto update_apply_log = UpdateApplyLog();
EXPECT_THAT(
update_discovery_log,
UnorderedElementsAre(
IsDict(DictionaryHasValue(
"result",
base::Value("Success::kUpdateFoundAndDryRunSuccessful"))),
IsDict(DictionaryHasValue(
"result",
base::Value("Success::kUpdateFoundAndDryRunSuccessful")))));
EXPECT_THAT(
update_apply_log,
UnorderedElementsAre(
IsDict(DictionaryHasValue("result", base::Value("Success"))),
IsDict(DictionaryHasValue("result", base::Value("Success")))));
std::vector<base::Value*> times(
{update_discovery_log[0].GetDict().Find("start_time"),
update_discovery_log[0].GetDict().Find("end_time"),
update_apply_log[0].GetDict().Find("start_time"),
update_apply_log[0].GetDict().Find("end_time"),
update_discovery_log[1].GetDict().Find("start_time"),
update_discovery_log[1].GetDict().Find("end_time"),
update_apply_log[1].GetDict().Find("start_time"),
update_apply_log[1].GetDict().Find("end_time")});
EXPECT_THAT(base::ranges::is_sorted(times, {},
[](base::Value* value) {
return *base::ValueToTime(value);
}),
IsTrue())
<< base::JoinString(ToVector(times, &base::Value::DebugString), "");
}
EXPECT_THAT(fake_provider().registrar_unsafe().GetAppById(
iwa_info1_->url_info.app_id()),
test::IwaIs(iwa_info1_->update_app_name,
test::IsolationDataIs(
UpdateLocationMatcher(profile()),
Eq(iwa_info1_->update_version),
_,
Eq(std::nullopt),
_)));
EXPECT_THAT(fake_provider().registrar_unsafe().GetAppById(
iwa_info2_->url_info.app_id()),
test::IwaIs(iwa_info2_->update_app_name,
test::IsolationDataIs(
UpdateLocationMatcher(profile()),
Eq(iwa_info2_->update_version),
_,
Eq(std::nullopt),
_)));
}
TEST_F(IsolatedWebAppUpdateManagerUpdateTest,
StopsNonStartedUpdateDiscoveryTasksIfIwaIsUninstalled) {
profile_url_loader_factory().ClearResponses();
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed app 1",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
AddDummyIsolatedAppToRegistry(
profile(), iwa_info2_->url_info.origin().GetURL(), "installed app 2",
WebApp::IsolationData(iwa_info2_->installed_location,
iwa_info2_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()},
{iwa_info2_->url_info, iwa_info2_->update_manifest_url.spec()}});
update_manager().DiscoverUpdatesNow();
task_environment()->RunUntilIdle();
ASSERT_THAT(profile_url_loader_factory().NumPending(), Eq(1));
EXPECT_THAT(UpdateDiscoveryTasks(), SizeIs(2));
EXPECT_THAT(UpdateDiscoveryLog(), IsEmpty());
GURL pending_url =
profile_url_loader_factory().GetPendingRequest(0)->request.url;
IwaInfo* iwa_to_keep;
IwaInfo* iwa_to_uninstall;
if (pending_url == iwa_info1_->update_manifest_url) {
iwa_to_keep = &*iwa_info1_;
iwa_to_uninstall = &*iwa_info2_;
} else if (pending_url == iwa_info2_->update_manifest_url) {
iwa_to_keep = &*iwa_info2_;
iwa_to_uninstall = &*iwa_info1_;
} else {
FAIL() << "Unexpected pending request for: " << pending_url;
}
EXPECT_THAT(UninstallPolicyInstalledIwa(iwa_to_uninstall->url_info.app_id()),
Eq(webapps::UninstallResultCode::kAppRemoved));
EXPECT_THAT(UpdateDiscoveryTasks(),
UnorderedElementsAre(IsDict(DictionaryHasValue(
"app_id", base::Value(iwa_to_keep->url_info.app_id())))));
EXPECT_THAT(UpdateDiscoveryLog(), IsEmpty());
fake_provider().Shutdown();
ChromeBrowsingDataRemoverDelegateFactory::GetForProfile(profile())
->Shutdown();
}
TEST_F(IsolatedWebAppUpdateManagerUpdateTest,
DISABLED_StopsWaitingIfIwaIsUninstalled) {
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed app",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 1);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()}});
update_manager().DiscoverUpdatesNow();
task_environment()->RunUntilIdle();
EXPECT_THAT(
UpdateDiscoveryLog(),
UnorderedElementsAre(IsDict(DictionaryHasValue(
"result", base::Value("Success::kUpdateFoundAndDryRunSuccessful")))));
EXPECT_THAT(UpdateApplyWaiters(),
UnorderedElementsAre(IsDict(DictionaryHasValue(
"app_id", base::Value(iwa_info1_->url_info.app_id())))));
EXPECT_THAT(UninstallPolicyInstalledIwa(iwa_info1_->url_info.app_id()),
Eq(webapps::UninstallResultCode::kAppRemoved));
EXPECT_THAT(UpdateApplyWaiters(), IsEmpty());
EXPECT_THAT(UpdateApplyTasks(), IsEmpty());
EXPECT_THAT(UpdateApplyLog(), IsEmpty());
fake_provider().Shutdown();
ChromeBrowsingDataRemoverDelegateFactory::GetForProfile(profile())
->Shutdown();
}
TEST_F(IsolatedWebAppUpdateManagerUpdateTest,
DISABLED_StopsNonStartedUpdateApplyTasksIfIwaIsUninstalled) {
AddDummyIsolatedAppToRegistry(
profile(), iwa_info1_->url_info.origin().GetURL(), "installed app 1",
WebApp::IsolationData(iwa_info1_->installed_location,
iwa_info1_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
AddDummyIsolatedAppToRegistry(
profile(), iwa_info2_->url_info.origin().GetURL(), "installed app 2",
WebApp::IsolationData(iwa_info2_->installed_location,
iwa_info2_->installed_version),
webapps::WebappInstallSource::IWA_EXTERNAL_POLICY);
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 1);
fake_ui_manager().SetNumWindowsForApp(iwa_info2_->url_info.app_id(), 1);
SetIwaForceInstallPolicy(
{{iwa_info1_->url_info, iwa_info1_->update_manifest_url.spec()},
{iwa_info2_->url_info, iwa_info2_->update_manifest_url.spec()}});
update_manager().DiscoverUpdatesNow();
task_environment()->RunUntilIdle();
EXPECT_THAT(
UpdateDiscoveryLog(),
UnorderedElementsAre(
IsDict(DictionaryHasValue(
"result",
base::Value("Success::kUpdateFoundAndDryRunSuccessful"))),
IsDict(DictionaryHasValue(
"result",
base::Value("Success::kUpdateFoundAndDryRunSuccessful")))));
EXPECT_THAT(UpdateApplyWaiters(),
UnorderedElementsAre(
IsDict(DictionaryHasValue(
"app_id", base::Value(iwa_info1_->url_info.app_id()))),
IsDict(DictionaryHasValue(
"app_id", base::Value(iwa_info2_->url_info.app_id())))));
base::test::TestFuture<IsolatedWebAppUrlInfo> future;
EXPECT_CALL(mock_command_scheduler(),
ApplyPendingIsolatedWebAppUpdate(_, _, _, _, _))
.WillOnce(WithArg<0>(Invoke(
&future, &base::test::TestFuture<IsolatedWebAppUrlInfo>::SetValue)));
fake_ui_manager().SetNumWindowsForApp(iwa_info1_->url_info.app_id(), 0);
fake_ui_manager().SetNumWindowsForApp(iwa_info2_->url_info.app_id(), 0);
webapps::AppId iwa_to_keep = future.Take().app_id();
EXPECT_THAT(UpdateApplyTasks(), SizeIs(2));
EXPECT_THAT(UpdateApplyLog(), IsEmpty());
IwaInfo* iwa_to_uninstall;
if (iwa_to_keep == iwa_info1_->url_info.app_id()) {
iwa_to_uninstall = &*iwa_info2_;
} else if (iwa_to_keep == iwa_info2_->url_info.app_id()) {
iwa_to_uninstall = &*iwa_info1_;
} else {
FAIL() << "Unexpected IWA app id: " << iwa_to_keep;
}
EXPECT_THAT(UninstallPolicyInstalledIwa(iwa_to_uninstall->url_info.app_id()),
Eq(webapps::UninstallResultCode::kAppRemoved));
EXPECT_THAT(UpdateApplyTasks(),
UnorderedElementsAre(IsDict(
DictionaryHasValue("app_id", base::Value(iwa_to_keep)))));
EXPECT_THAT(UpdateApplyLog(), IsEmpty());
fake_provider().Shutdown();
ChromeBrowsingDataRemoverDelegateFactory::GetForProfile(profile())
->Shutdown();
}
#endif
class IsolatedWebAppUpdateManagerUpdateApplyOnStartupTest
: public IsolatedWebAppUpdateManagerUpdateTest { … };
TEST_F(IsolatedWebAppUpdateManagerUpdateApplyOnStartupTest,
SchedulesPendingUpdateApplyTasks) { … }
class IsolatedWebAppUpdateManagerDiscoveryTimerTest
: public IsolatedWebAppUpdateManagerTest { … };
TEST_F(IsolatedWebAppUpdateManagerDiscoveryTimerTest,
DoesNotStartUpdateDiscoveryIfNoIwaIsInstalled) { … }
TEST_F(IsolatedWebAppUpdateManagerDiscoveryTimerTest,
StartsUpdateDiscoveryTimerWithJitter) { … }
TEST_F(IsolatedWebAppUpdateManagerDiscoveryTimerTest,
RunsUpdateDiscoveryWhileIwaIsInstalled) { … }
struct FeatureFlagParam { … };
class IsolatedWebAppUpdateManagerFeatureFlagTest
: public IsolatedWebAppUpdateManagerTest,
public ::testing::WithParamInterface<FeatureFlagParam> { … };
TEST_P(IsolatedWebAppUpdateManagerFeatureFlagTest,
DoesUpdateDiscoveryIfFeatureFlagsAreEnabled) { … }
INSTANTIATE_TEST_SUITE_P(…);
}
TEST_F(IsolatedWebAppUpdateManagerUpdateTest, UpdateDiscoveryTaskSuccess) { … }
TEST_F(IsolatedWebAppUpdateManagerUpdateTest, UpdateDiscoveryTaskFails) { … }
TEST_F(IsolatedWebAppUpdateManagerUpdateTest, UpdateApplyTaskSuccess) { … }
TEST_F(IsolatedWebAppUpdateManagerUpdateTest, UpdateApplyTaskFails) { … }
}