Unwind the URL-based experiment IDs.
[chromium-blink-merge.git] / chrome / browser / signin / easy_unlock_app_manager_unittest.cc
blob416c910fdf3a8dd7d2266f8cfb7c87ea74c0d6c0
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/signin/easy_unlock_app_manager.h"
7 #include <string>
9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "chrome/browser/extensions/component_loader.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/test_extension_system.h"
15 #include "chrome/common/extensions/api/easy_unlock_private.h"
16 #include "chrome/common/extensions/api/screenlock_private.h"
17 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/proximity_auth/switches.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "extensions/browser/event_router.h"
22 #include "extensions/browser/extension_prefs.h"
23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/browser/extension_registry_observer.h"
25 #include "extensions/browser/process_manager.h"
26 #include "extensions/browser/process_manager_factory.h"
27 #include "extensions/common/api/app_runtime.h"
28 #include "extensions/common/extension.h"
29 #include "grit/browser_resources.h"
30 #include "testing/gtest/include/gtest/gtest.h"
32 #if defined(OS_CHROMEOS)
33 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
34 #include "chrome/browser/chromeos/settings/cros_settings.h"
35 #include "chrome/browser/chromeos/settings/device_settings_service.h"
36 #endif
38 namespace easy_unlock_private_api = extensions::api::easy_unlock_private;
39 namespace screenlock_private_api = extensions::api::screenlock_private;
40 namespace app_runtime_api = extensions::core_api::app_runtime;
42 namespace {
44 // Sets |*value| to true, also verifying that the value was not previously set.
45 // Used in tests for verifying that a callback was called.
46 void VerifyFalseAndSetToTrue(bool* value) {
47 EXPECT_FALSE(*value);
48 *value = true;
51 // A ProcessManager that doesn't create background host pages.
52 class TestProcessManager : public extensions::ProcessManager {
53 public:
54 explicit TestProcessManager(content::BrowserContext* context)
55 : extensions::ProcessManager(
56 context,
57 context,
58 extensions::ExtensionRegistry::Get(context)) {}
59 ~TestProcessManager() override {}
61 // ProcessManager overrides:
62 bool CreateBackgroundHost(const extensions::Extension* extension,
63 const GURL& url) override {
64 return false;
67 private:
68 DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
71 KeyedService* CreateTestProcessManager(content::BrowserContext* context) {
72 return new TestProcessManager(context);
75 // Observes extension registry for unload and load events (in that order) of an
76 // extension with the provided extension id.
77 // Used to determine if an extension was reloaded.
78 class ExtensionReloadTracker : public extensions::ExtensionRegistryObserver {
79 public:
80 ExtensionReloadTracker(Profile* profile, const std::string& extension_id)
81 : profile_(profile),
82 extension_id_(extension_id),
83 unloaded_(false),
84 loaded_(false) {
85 extensions::ExtensionRegistry::Get(profile)->AddObserver(this);
88 ~ExtensionReloadTracker() override {
89 extensions::ExtensionRegistry::Get(profile_)->RemoveObserver(this);
92 // extension::ExtensionRegistryObserver implementation:
93 void OnExtensionLoaded(content::BrowserContext* browser_context,
94 const extensions::Extension* extension) override {
95 ASSERT_FALSE(loaded_);
96 ASSERT_EQ(extension_id_, extension->id());
97 loaded_ = true;
100 void OnExtensionUnloaded(
101 content::BrowserContext* browser_context,
102 const extensions::Extension* extension,
103 extensions::UnloadedExtensionInfo::Reason reason) override {
104 ASSERT_FALSE(unloaded_);
105 ASSERT_EQ(extension_id_, extension->id());
106 unloaded_ = true;
109 // Whether the extensino was unloaded and loaded during |this| lifetime.
110 bool HasReloaded() const { return loaded_ && unloaded_; }
112 private:
113 Profile* profile_;
114 std::string extension_id_;
115 bool unloaded_;
116 bool loaded_;
118 DISALLOW_COPY_AND_ASSIGN(ExtensionReloadTracker);
121 // Consumes events dispatched from test event router.
122 class EasyUnlockAppEventConsumer {
123 public:
124 explicit EasyUnlockAppEventConsumer(Profile* profile)
125 : user_updated_count_(0u),
126 auth_attempted_count_(0u),
127 app_launched_count_(0u) {}
129 ~EasyUnlockAppEventConsumer() {}
131 // Processes event for test event router.
132 // It returns whether the event is expected to be dispatched during tests and
133 // whether it's well formed.
134 bool ConsumeEvent(const std::string& event_name, base::ListValue* args) {
135 if (event_name == easy_unlock_private_api::OnUserInfoUpdated::kEventName)
136 return ConsumeUserInfoUpdated(args);
138 if (event_name == screenlock_private_api::OnAuthAttempted::kEventName)
139 return ConsumeAuthAttempted(args);
141 if (event_name == app_runtime_api::OnLaunched::kEventName)
142 return ConsumeLaunched(args);
144 LOG(ERROR) << "Unexpected event: " << event_name;
145 return false;
148 // Information about encountered events:
149 size_t user_updated_count() const { return user_updated_count_; }
150 size_t auth_attempted_count() const { return auth_attempted_count_; }
151 size_t app_launched_count() const { return app_launched_count_; }
153 // The data carried by the last UserInfoUpdated event:
154 std::string user_id() const { return user_id_; }
155 bool user_logged_in() const { return user_logged_in_; }
156 bool user_data_ready() const { return user_data_ready_; }
158 private:
159 // Processes easyUnlockPrivate.onUserInfoUpdated event.
160 bool ConsumeUserInfoUpdated(base::ListValue* args) {
161 if (!args) {
162 LOG(ERROR) << "No argument list for onUserInfoUpdated event.";
163 return false;
166 if (args->GetSize() != 1u) {
167 LOG(ERROR) << "Invalid argument list size for onUserInfoUpdated event: "
168 << args->GetSize() << " expected: " << 1u;
169 return false;
172 base::DictionaryValue* user_info;
173 if (!args->GetDictionary(0u, &user_info) || !user_info) {
174 LOG(ERROR) << "Unabled to get event argument as dictionary for "
175 << "onUserInfoUpdated event.";
176 return false;
179 EXPECT_TRUE(user_info->GetString("userId", &user_id_));
180 EXPECT_TRUE(user_info->GetBoolean("loggedIn", &user_logged_in_));
181 EXPECT_TRUE(user_info->GetBoolean("dataReady", &user_data_ready_));
183 ++user_updated_count_;
184 return true;
187 // Processes screenlockPrivate.onAuthAttempted event.
188 bool ConsumeAuthAttempted(base::ListValue* args) {
189 if (!args) {
190 LOG(ERROR) << "No argument list for onAuthAttempted event";
191 return false;
194 if (args->GetSize() != 2u) {
195 LOG(ERROR) << "Invalid argument list size for onAuthAttempted event: "
196 << args->GetSize() << " expected: " << 2u;
197 return false;
200 std::string auth_type;
201 if (!args->GetString(0u, &auth_type)) {
202 LOG(ERROR) << "Unable to get first argument as string for "
203 << "onAuthAttempted event.";
204 return false;
207 EXPECT_EQ("userClick", auth_type);
208 ++auth_attempted_count_;
209 return true;
212 // Processes app.runtime.onLaunched event.
213 bool ConsumeLaunched(base::ListValue* args) {
214 ++app_launched_count_;
215 return true;
218 size_t user_updated_count_;
219 size_t auth_attempted_count_;
220 size_t app_launched_count_;
222 std::string user_id_;
223 bool user_logged_in_;
224 bool user_data_ready_;
226 DISALLOW_COPY_AND_ASSIGN(EasyUnlockAppEventConsumer);
229 // Event router injected into extension system for the tests. It redirects
230 // events to EasyUnlockAppEventConsumer.
231 class TestEventRouter : public extensions::EventRouter {
232 public:
233 TestEventRouter(Profile* profile,
234 extensions::ExtensionPrefs* extension_prefs,
235 EasyUnlockAppEventConsumer* event_consumer)
236 : extensions::EventRouter(profile, extension_prefs),
237 event_consumer_(event_consumer) {}
239 ~TestEventRouter() override {}
241 // extensions::EventRouter implementation:
242 void BroadcastEvent(scoped_ptr<extensions::Event> event) override {
243 ASSERT_EQ(screenlock_private_api::OnAuthAttempted::kEventName,
244 event->event_name);
245 EXPECT_TRUE(event_consumer_->ConsumeEvent(event->event_name,
246 event->event_args.get()));
249 void DispatchEventToExtension(const std::string& extension_id,
250 scoped_ptr<extensions::Event> event) override {
251 ASSERT_EQ(extension_misc::kEasyUnlockAppId, extension_id);
252 EXPECT_TRUE(event_consumer_->ConsumeEvent(event->event_name,
253 event->event_args.get()));
256 private:
257 EasyUnlockAppEventConsumer* event_consumer_;
259 DISALLOW_COPY_AND_ASSIGN(TestEventRouter);
262 class EasyUnlockAppManagerTest : public testing::Test {
263 public:
264 EasyUnlockAppManagerTest()
265 : event_consumer_(&profile_),
266 command_line_(base::CommandLine::NO_PROGRAM) {}
267 ~EasyUnlockAppManagerTest() override {}
269 void SetUp() override {
270 base::CommandLine::ForCurrentProcess()->AppendSwitch(
271 proximity_auth::switches::kForceLoadEasyUnlockAppInTests);
272 extensions::ExtensionSystem* extension_system = SetUpExtensionSystem();
273 app_manager_ =
274 EasyUnlockAppManager::Create(extension_system, IDR_EASY_UNLOCK_MANIFEST,
275 GetAppPath()).Pass();
278 protected:
279 void SetExtensionSystemReady() {
280 extensions::TestExtensionSystem* test_extension_system =
281 static_cast<extensions::TestExtensionSystem*>(
282 extensions::ExtensionSystem::Get(&profile_));
283 test_extension_system->SetReady();
284 base::RunLoop().RunUntilIdle();
287 base::FilePath GetAppPath() {
288 return extensions::ExtensionPrefs::Get(&profile_)
289 ->install_directory()
290 .AppendASCII("easy_unlock");
293 private:
294 // Initializes test extension system.
295 extensions::ExtensionSystem* SetUpExtensionSystem() {
296 extensions::TestExtensionSystem* test_extension_system =
297 static_cast<extensions::TestExtensionSystem*>(
298 extensions::ExtensionSystem::Get(&profile_));
299 extension_service_ = test_extension_system->CreateExtensionService(
300 &command_line_, base::FilePath() /* install_directory */,
301 false /* autoupdate_enabled */);
302 test_extension_system->CreateLazyBackgroundTaskQueue();
304 extensions::ProcessManagerFactory::GetInstance()->SetTestingFactory(
305 &profile_, &CreateTestProcessManager);
307 scoped_ptr<extensions::EventRouter> event_router(new TestEventRouter(
308 &profile_, extensions::ExtensionPrefs::Get(&profile_),
309 &event_consumer_));
310 event_router_ = event_router.get();
311 test_extension_system->SetEventRouter(event_router.Pass());
313 return test_extension_system;
316 protected:
317 scoped_ptr<EasyUnlockAppManager> app_manager_;
319 // Needed by extension system.
320 content::TestBrowserThreadBundle thread_bundle_;
322 #if defined(OS_CHROMEOS)
323 // Cros settings and device settings are needed when creating user manager.
324 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
325 chromeos::ScopedTestCrosSettings test_cros_settings_;
326 // Needed for creating ExtensionService.
327 chromeos::ScopedTestUserManager test_user_manager_;
328 #endif
330 TestingProfile profile_;
332 EasyUnlockAppEventConsumer event_consumer_;
333 ExtensionService* extension_service_;
334 extensions::EventRouter* event_router_;
336 base::CommandLine command_line_;
338 private:
339 DISALLOW_COPY_AND_ASSIGN(EasyUnlockAppManagerTest);
342 TEST_F(EasyUnlockAppManagerTest, LoadAppWhenNotLoaded) {
343 SetExtensionSystemReady();
345 // Sanity check for the test: the easy unlock app should not be loaded at
346 // this point.
347 ASSERT_FALSE(extension_service_->GetExtensionById(
348 extension_misc::kEasyUnlockAppId, true));
350 app_manager_->LoadApp();
352 ASSERT_TRUE(extension_service_->GetExtensionById(
353 extension_misc::kEasyUnlockAppId, false));
354 EXPECT_TRUE(
355 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
358 TEST_F(EasyUnlockAppManagerTest, LoadAppWhenAlreadyLoaded) {
359 SetExtensionSystemReady();
361 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
362 GetAppPath());
364 app_manager_->LoadApp();
366 ASSERT_TRUE(extension_service_->GetExtensionById(
367 extension_misc::kEasyUnlockAppId, false));
370 TEST_F(EasyUnlockAppManagerTest, LoadAppPreviouslyDisabled) {
371 SetExtensionSystemReady();
373 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
374 GetAppPath());
375 extension_service_->DisableExtension(extension_misc::kEasyUnlockAppId,
376 extensions::Extension::DISABLE_RELOAD);
378 ASSERT_TRUE(extension_service_->GetExtensionById(
379 extension_misc::kEasyUnlockAppId, true));
380 ASSERT_FALSE(
381 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
383 app_manager_->LoadApp();
385 ASSERT_TRUE(extension_service_->GetExtensionById(
386 extension_misc::kEasyUnlockAppId, false));
389 TEST_F(EasyUnlockAppManagerTest, ReloadApp) {
390 SetExtensionSystemReady();
392 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
393 GetAppPath());
395 ExtensionReloadTracker reload_tracker(&profile_,
396 extension_misc::kEasyUnlockAppId);
397 ASSERT_FALSE(reload_tracker.HasReloaded());
399 app_manager_->ReloadApp();
401 EXPECT_TRUE(reload_tracker.HasReloaded());
402 EXPECT_TRUE(extension_service_->GetExtensionById(
403 extension_misc::kEasyUnlockAppId, false));
406 TEST_F(EasyUnlockAppManagerTest, ReloadAppDisabled) {
407 SetExtensionSystemReady();
409 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
410 GetAppPath());
411 extension_service_->DisableExtension(extension_misc::kEasyUnlockAppId,
412 extensions::Extension::DISABLE_RELOAD);
413 ExtensionReloadTracker reload_tracker(&profile_,
414 extension_misc::kEasyUnlockAppId);
415 ASSERT_FALSE(reload_tracker.HasReloaded());
417 app_manager_->ReloadApp();
419 EXPECT_FALSE(reload_tracker.HasReloaded());
420 EXPECT_TRUE(extension_service_->GetExtensionById(
421 extension_misc::kEasyUnlockAppId, true));
422 EXPECT_FALSE(
423 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
426 TEST_F(EasyUnlockAppManagerTest, DisableApp) {
427 SetExtensionSystemReady();
429 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
430 GetAppPath());
431 EXPECT_TRUE(extension_service_->GetExtensionById(
432 extension_misc::kEasyUnlockAppId, false));
434 app_manager_->DisableAppIfLoaded();
436 EXPECT_TRUE(extension_service_->GetExtensionById(
437 extension_misc::kEasyUnlockAppId, true));
438 EXPECT_FALSE(
439 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
442 TEST_F(EasyUnlockAppManagerTest, DisableAppWhenNotLoaded) {
443 SetExtensionSystemReady();
445 EXPECT_FALSE(extension_service_->GetExtensionById(
446 extension_misc::kEasyUnlockAppId, true));
448 app_manager_->DisableAppIfLoaded();
450 EXPECT_FALSE(extension_service_->GetExtensionById(
451 extension_misc::kEasyUnlockAppId, true));
453 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
454 GetAppPath());
455 EXPECT_TRUE(extension_service_->GetExtensionById(
456 extension_misc::kEasyUnlockAppId, false));
459 TEST_F(EasyUnlockAppManagerTest, EnsureReady) {
460 bool ready = false;
461 app_manager_->EnsureReady(base::Bind(&VerifyFalseAndSetToTrue, &ready));
463 base::RunLoop().RunUntilIdle();
464 ASSERT_FALSE(ready);
466 SetExtensionSystemReady();
467 ASSERT_TRUE(ready);
470 TEST_F(EasyUnlockAppManagerTest, EnsureReadyAfterExtesionSystemReady) {
471 SetExtensionSystemReady();
473 bool ready = false;
474 app_manager_->EnsureReady(base::Bind(&VerifyFalseAndSetToTrue, &ready));
476 base::RunLoop().RunUntilIdle();
477 ASSERT_TRUE(ready);
480 TEST_F(EasyUnlockAppManagerTest, LaunchSetup) {
481 SetExtensionSystemReady();
483 ASSERT_EQ(0u, event_consumer_.app_launched_count());
485 app_manager_->LoadApp();
486 app_manager_->LaunchSetup();
488 EXPECT_EQ(1u, event_consumer_.app_launched_count());
491 TEST_F(EasyUnlockAppManagerTest, LaunchSetupWhenDisabled) {
492 SetExtensionSystemReady();
494 ASSERT_EQ(0u, event_consumer_.app_launched_count());
496 app_manager_->LoadApp();
497 app_manager_->DisableAppIfLoaded();
499 app_manager_->LaunchSetup();
501 EXPECT_EQ(0u, event_consumer_.app_launched_count());
504 TEST_F(EasyUnlockAppManagerTest, LaunchSetupWhenNotLoaded) {
505 SetExtensionSystemReady();
507 ASSERT_EQ(0u, event_consumer_.app_launched_count());
509 app_manager_->LaunchSetup();
511 EXPECT_EQ(0u, event_consumer_.app_launched_count());
514 TEST_F(EasyUnlockAppManagerTest, SendUserUpdated) {
515 SetExtensionSystemReady();
517 app_manager_->LoadApp();
518 event_router_->AddLazyEventListener(
519 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
520 extension_misc::kEasyUnlockAppId);
522 ASSERT_EQ(0u, event_consumer_.user_updated_count());
524 EXPECT_TRUE(app_manager_->SendUserUpdatedEvent("user", true /* logged_in */,
525 false /* data_ready */));
527 EXPECT_EQ(1u, event_consumer_.user_updated_count());
529 EXPECT_EQ("user", event_consumer_.user_id());
530 EXPECT_TRUE(event_consumer_.user_logged_in());
531 EXPECT_FALSE(event_consumer_.user_data_ready());
534 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedInvertedFlags) {
535 SetExtensionSystemReady();
537 app_manager_->LoadApp();
538 event_router_->AddLazyEventListener(
539 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
540 extension_misc::kEasyUnlockAppId);
542 ASSERT_EQ(0u, event_consumer_.user_updated_count());
544 EXPECT_TRUE(app_manager_->SendUserUpdatedEvent("user", false /* logged_in */,
545 true /* data_ready */));
547 EXPECT_EQ(1u, event_consumer_.user_updated_count());
549 EXPECT_EQ("user", event_consumer_.user_id());
550 EXPECT_FALSE(event_consumer_.user_logged_in());
551 EXPECT_TRUE(event_consumer_.user_data_ready());
554 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedNoRegisteredListeners) {
555 SetExtensionSystemReady();
557 app_manager_->LoadApp();
559 ASSERT_EQ(0u, event_consumer_.user_updated_count());
561 EXPECT_FALSE(app_manager_->SendUserUpdatedEvent("user", true, true));
562 EXPECT_EQ(0u, event_consumer_.user_updated_count());
565 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedAppDisabled) {
566 SetExtensionSystemReady();
568 app_manager_->LoadApp();
569 event_router_->AddLazyEventListener(
570 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
571 extension_misc::kEasyUnlockAppId);
572 app_manager_->DisableAppIfLoaded();
574 ASSERT_EQ(0u, event_consumer_.user_updated_count());
576 EXPECT_FALSE(app_manager_->SendUserUpdatedEvent("user", true, true));
577 EXPECT_EQ(0u, event_consumer_.user_updated_count());
580 TEST_F(EasyUnlockAppManagerTest, SendAuthAttempted) {
581 SetExtensionSystemReady();
583 app_manager_->LoadApp();
584 event_router_->AddLazyEventListener(
585 screenlock_private_api::OnAuthAttempted::kEventName,
586 extension_misc::kEasyUnlockAppId);
588 ASSERT_EQ(0u, event_consumer_.user_updated_count());
590 EXPECT_TRUE(app_manager_->SendAuthAttemptEvent());
591 EXPECT_EQ(1u, event_consumer_.auth_attempted_count());
594 TEST_F(EasyUnlockAppManagerTest, SendAuthAttemptedNoRegisteredListeners) {
595 SetExtensionSystemReady();
597 app_manager_->LoadApp();
599 ASSERT_EQ(0u, event_consumer_.auth_attempted_count());
601 EXPECT_FALSE(app_manager_->SendAuthAttemptEvent());
602 EXPECT_EQ(0u, event_consumer_.auth_attempted_count());
605 TEST_F(EasyUnlockAppManagerTest, SendAuthAttemptedAppDisabled) {
606 SetExtensionSystemReady();
608 app_manager_->LoadApp();
609 event_router_->AddLazyEventListener(
610 screenlock_private_api::OnAuthAttempted::kEventName,
611 extension_misc::kEasyUnlockAppId);
612 app_manager_->DisableAppIfLoaded();
614 ASSERT_EQ(0u, event_consumer_.auth_attempted_count());
616 EXPECT_FALSE(app_manager_->SendAuthAttemptEvent());
617 EXPECT_EQ(0u, event_consumer_.auth_attempted_count());
620 } // namespace