[Cleanup] Used scoped pointers in KeyedServiceFactory's SetTestingFactory functions.
[chromium-blink-merge.git] / chrome / browser / signin / easy_unlock_app_manager_unittest.cc
blob89bf24b0ed95ba4ca34c0052185c9d8e18950372
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/event_router_factory.h"
23 #include "extensions/browser/extension_prefs.h"
24 #include "extensions/browser/extension_registry.h"
25 #include "extensions/browser/extension_registry_observer.h"
26 #include "extensions/browser/process_manager.h"
27 #include "extensions/browser/process_manager_factory.h"
28 #include "extensions/common/api/app_runtime.h"
29 #include "extensions/common/extension.h"
30 #include "grit/browser_resources.h"
31 #include "testing/gtest/include/gtest/gtest.h"
33 #if defined(OS_CHROMEOS)
34 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
35 #include "chrome/browser/chromeos/settings/cros_settings.h"
36 #include "chrome/browser/chromeos/settings/device_settings_service.h"
37 #endif
39 namespace easy_unlock_private_api = extensions::api::easy_unlock_private;
40 namespace screenlock_private_api = extensions::api::screenlock_private;
41 namespace app_runtime_api = extensions::core_api::app_runtime;
43 namespace {
45 // Sets |*value| to true, also verifying that the value was not previously set.
46 // Used in tests for verifying that a callback was called.
47 void VerifyFalseAndSetToTrue(bool* value) {
48 EXPECT_FALSE(*value);
49 *value = true;
52 // A ProcessManager that doesn't create background host pages.
53 class TestProcessManager : public extensions::ProcessManager {
54 public:
55 explicit TestProcessManager(content::BrowserContext* context)
56 : extensions::ProcessManager(
57 context,
58 context,
59 extensions::ExtensionRegistry::Get(context)) {}
60 ~TestProcessManager() override {}
62 // ProcessManager overrides:
63 bool CreateBackgroundHost(const extensions::Extension* extension,
64 const GURL& url) override {
65 return false;
68 private:
69 DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
72 scoped_ptr<KeyedService> CreateTestProcessManager(
73 content::BrowserContext* context) {
74 return make_scoped_ptr(new TestProcessManager(context));
77 // Observes extension registry for unload and load events (in that order) of an
78 // extension with the provided extension id.
79 // Used to determine if an extension was reloaded.
80 class ExtensionReloadTracker : public extensions::ExtensionRegistryObserver {
81 public:
82 ExtensionReloadTracker(Profile* profile, const std::string& extension_id)
83 : profile_(profile),
84 extension_id_(extension_id),
85 unloaded_(false),
86 loaded_(false) {
87 extensions::ExtensionRegistry::Get(profile)->AddObserver(this);
90 ~ExtensionReloadTracker() override {
91 extensions::ExtensionRegistry::Get(profile_)->RemoveObserver(this);
94 // extension::ExtensionRegistryObserver implementation:
95 void OnExtensionLoaded(content::BrowserContext* browser_context,
96 const extensions::Extension* extension) override {
97 ASSERT_FALSE(loaded_);
98 ASSERT_EQ(extension_id_, extension->id());
99 loaded_ = true;
102 void OnExtensionUnloaded(
103 content::BrowserContext* browser_context,
104 const extensions::Extension* extension,
105 extensions::UnloadedExtensionInfo::Reason reason) override {
106 ASSERT_FALSE(unloaded_);
107 ASSERT_EQ(extension_id_, extension->id());
108 unloaded_ = true;
111 // Whether the extensino was unloaded and loaded during |this| lifetime.
112 bool HasReloaded() const { return loaded_ && unloaded_; }
114 private:
115 Profile* profile_;
116 std::string extension_id_;
117 bool unloaded_;
118 bool loaded_;
120 DISALLOW_COPY_AND_ASSIGN(ExtensionReloadTracker);
123 // Consumes events dispatched from test event router.
124 class EasyUnlockAppEventConsumer {
125 public:
126 explicit EasyUnlockAppEventConsumer(Profile* profile)
127 : user_updated_count_(0u),
128 auth_attempted_count_(0u),
129 app_launched_count_(0u) {}
131 ~EasyUnlockAppEventConsumer() {}
133 // Processes event for test event router.
134 // It returns whether the event is expected to be dispatched during tests and
135 // whether it's well formed.
136 bool ConsumeEvent(const std::string& event_name, base::ListValue* args) {
137 if (event_name == easy_unlock_private_api::OnUserInfoUpdated::kEventName)
138 return ConsumeUserInfoUpdated(args);
140 if (event_name == screenlock_private_api::OnAuthAttempted::kEventName)
141 return ConsumeAuthAttempted(args);
143 if (event_name == app_runtime_api::OnLaunched::kEventName)
144 return ConsumeLaunched(args);
146 LOG(ERROR) << "Unexpected event: " << event_name;
147 return false;
150 // Information about encountered events:
151 size_t user_updated_count() const { return user_updated_count_; }
152 size_t auth_attempted_count() const { return auth_attempted_count_; }
153 size_t app_launched_count() const { return app_launched_count_; }
155 // The data carried by the last UserInfoUpdated event:
156 std::string user_id() const { return user_id_; }
157 bool user_logged_in() const { return user_logged_in_; }
158 bool user_data_ready() const { return user_data_ready_; }
160 private:
161 // Processes easyUnlockPrivate.onUserInfoUpdated event.
162 bool ConsumeUserInfoUpdated(base::ListValue* args) {
163 if (!args) {
164 LOG(ERROR) << "No argument list for onUserInfoUpdated event.";
165 return false;
168 if (args->GetSize() != 1u) {
169 LOG(ERROR) << "Invalid argument list size for onUserInfoUpdated event: "
170 << args->GetSize() << " expected: " << 1u;
171 return false;
174 base::DictionaryValue* user_info;
175 if (!args->GetDictionary(0u, &user_info) || !user_info) {
176 LOG(ERROR) << "Unabled to get event argument as dictionary for "
177 << "onUserInfoUpdated event.";
178 return false;
181 EXPECT_TRUE(user_info->GetString("userId", &user_id_));
182 EXPECT_TRUE(user_info->GetBoolean("loggedIn", &user_logged_in_));
183 EXPECT_TRUE(user_info->GetBoolean("dataReady", &user_data_ready_));
185 ++user_updated_count_;
186 return true;
189 // Processes screenlockPrivate.onAuthAttempted event.
190 bool ConsumeAuthAttempted(base::ListValue* args) {
191 if (!args) {
192 LOG(ERROR) << "No argument list for onAuthAttempted event";
193 return false;
196 if (args->GetSize() != 2u) {
197 LOG(ERROR) << "Invalid argument list size for onAuthAttempted event: "
198 << args->GetSize() << " expected: " << 2u;
199 return false;
202 std::string auth_type;
203 if (!args->GetString(0u, &auth_type)) {
204 LOG(ERROR) << "Unable to get first argument as string for "
205 << "onAuthAttempted event.";
206 return false;
209 EXPECT_EQ("userClick", auth_type);
210 ++auth_attempted_count_;
211 return true;
214 // Processes app.runtime.onLaunched event.
215 bool ConsumeLaunched(base::ListValue* args) {
216 ++app_launched_count_;
217 return true;
220 size_t user_updated_count_;
221 size_t auth_attempted_count_;
222 size_t app_launched_count_;
224 std::string user_id_;
225 bool user_logged_in_;
226 bool user_data_ready_;
228 DISALLOW_COPY_AND_ASSIGN(EasyUnlockAppEventConsumer);
231 // Event router injected into extension system for the tests. It redirects
232 // events to EasyUnlockAppEventConsumer.
233 class TestEventRouter : public extensions::EventRouter {
234 public:
235 TestEventRouter(Profile* profile, extensions::ExtensionPrefs* extension_prefs)
236 : extensions::EventRouter(profile, extension_prefs) {}
238 ~TestEventRouter() override {}
240 // extensions::EventRouter implementation:
241 void BroadcastEvent(scoped_ptr<extensions::Event> event) override {
242 ASSERT_EQ(screenlock_private_api::OnAuthAttempted::kEventName,
243 event->event_name);
244 EXPECT_TRUE(event_consumer_->ConsumeEvent(event->event_name,
245 event->event_args.get()));
248 void DispatchEventToExtension(const std::string& extension_id,
249 scoped_ptr<extensions::Event> event) override {
250 ASSERT_EQ(extension_misc::kEasyUnlockAppId, extension_id);
251 EXPECT_TRUE(event_consumer_->ConsumeEvent(event->event_name,
252 event->event_args.get()));
255 void set_event_consumer(EasyUnlockAppEventConsumer* event_consumer) {
256 event_consumer_ = event_consumer;
259 private:
260 EasyUnlockAppEventConsumer* event_consumer_;
262 DISALLOW_COPY_AND_ASSIGN(TestEventRouter);
265 // TestEventRouter factory function
266 scoped_ptr<KeyedService> TestEventRouterFactoryFunction(
267 content::BrowserContext* context) {
268 return make_scoped_ptr(
269 new TestEventRouter(static_cast<Profile*>(context),
270 extensions::ExtensionPrefs::Get(context)));
273 class EasyUnlockAppManagerTest : public testing::Test {
274 public:
275 EasyUnlockAppManagerTest()
276 : event_consumer_(&profile_),
277 command_line_(base::CommandLine::NO_PROGRAM) {}
278 ~EasyUnlockAppManagerTest() override {}
280 void SetUp() override {
281 base::CommandLine::ForCurrentProcess()->AppendSwitch(
282 proximity_auth::switches::kForceLoadEasyUnlockAppInTests);
283 extensions::ExtensionSystem* extension_system = SetUpExtensionSystem();
284 app_manager_ =
285 EasyUnlockAppManager::Create(extension_system, IDR_EASY_UNLOCK_MANIFEST,
286 GetAppPath()).Pass();
289 protected:
290 void SetExtensionSystemReady() {
291 extensions::TestExtensionSystem* test_extension_system =
292 static_cast<extensions::TestExtensionSystem*>(
293 extensions::ExtensionSystem::Get(&profile_));
294 test_extension_system->SetReady();
295 base::RunLoop().RunUntilIdle();
298 base::FilePath GetAppPath() {
299 return extensions::ExtensionPrefs::Get(&profile_)
300 ->install_directory()
301 .AppendASCII("easy_unlock");
304 private:
305 // Initializes test extension system.
306 extensions::ExtensionSystem* SetUpExtensionSystem() {
307 extensions::TestExtensionSystem* test_extension_system =
308 static_cast<extensions::TestExtensionSystem*>(
309 extensions::ExtensionSystem::Get(&profile_));
310 extension_service_ = test_extension_system->CreateExtensionService(
311 &command_line_, base::FilePath() /* install_directory */,
312 false /* autoupdate_enabled */);
314 extensions::ProcessManagerFactory::GetInstance()->SetTestingFactory(
315 &profile_, &CreateTestProcessManager);
317 event_router_ = static_cast<TestEventRouter*>(
318 extensions::EventRouterFactory::GetInstance()->SetTestingFactoryAndUse(
319 &profile_, &TestEventRouterFactoryFunction));
320 event_router_->set_event_consumer(&event_consumer_);
322 extension_service_->component_loader()->
323 set_ignore_whitelist_for_testing(true);
325 return test_extension_system;
328 protected:
329 scoped_ptr<EasyUnlockAppManager> app_manager_;
331 // Needed by extension system.
332 content::TestBrowserThreadBundle thread_bundle_;
334 #if defined(OS_CHROMEOS)
335 // Cros settings and device settings are needed when creating user manager.
336 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
337 chromeos::ScopedTestCrosSettings test_cros_settings_;
338 // Needed for creating ExtensionService.
339 chromeos::ScopedTestUserManager test_user_manager_;
340 #endif
342 TestingProfile profile_;
344 EasyUnlockAppEventConsumer event_consumer_;
345 ExtensionService* extension_service_;
346 TestEventRouter* event_router_;
348 base::CommandLine command_line_;
350 private:
351 DISALLOW_COPY_AND_ASSIGN(EasyUnlockAppManagerTest);
354 TEST_F(EasyUnlockAppManagerTest, LoadAppWhenNotLoaded) {
355 SetExtensionSystemReady();
357 // Sanity check for the test: the easy unlock app should not be loaded at
358 // this point.
359 ASSERT_FALSE(extension_service_->GetExtensionById(
360 extension_misc::kEasyUnlockAppId, true));
362 app_manager_->LoadApp();
364 ASSERT_TRUE(extension_service_->GetExtensionById(
365 extension_misc::kEasyUnlockAppId, false));
366 EXPECT_TRUE(
367 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
370 TEST_F(EasyUnlockAppManagerTest, LoadAppWhenAlreadyLoaded) {
371 SetExtensionSystemReady();
373 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
374 GetAppPath());
376 app_manager_->LoadApp();
378 ASSERT_TRUE(extension_service_->GetExtensionById(
379 extension_misc::kEasyUnlockAppId, false));
382 TEST_F(EasyUnlockAppManagerTest, LoadAppPreviouslyDisabled) {
383 SetExtensionSystemReady();
385 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
386 GetAppPath());
387 extension_service_->DisableExtension(extension_misc::kEasyUnlockAppId,
388 extensions::Extension::DISABLE_RELOAD);
390 ASSERT_TRUE(extension_service_->GetExtensionById(
391 extension_misc::kEasyUnlockAppId, true));
392 ASSERT_FALSE(
393 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
395 app_manager_->LoadApp();
397 ASSERT_TRUE(extension_service_->GetExtensionById(
398 extension_misc::kEasyUnlockAppId, false));
401 TEST_F(EasyUnlockAppManagerTest, ReloadApp) {
402 SetExtensionSystemReady();
404 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
405 GetAppPath());
407 ExtensionReloadTracker reload_tracker(&profile_,
408 extension_misc::kEasyUnlockAppId);
409 ASSERT_FALSE(reload_tracker.HasReloaded());
411 app_manager_->ReloadApp();
413 EXPECT_TRUE(reload_tracker.HasReloaded());
414 EXPECT_TRUE(extension_service_->GetExtensionById(
415 extension_misc::kEasyUnlockAppId, false));
418 TEST_F(EasyUnlockAppManagerTest, ReloadAppDisabled) {
419 SetExtensionSystemReady();
421 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
422 GetAppPath());
423 extension_service_->DisableExtension(extension_misc::kEasyUnlockAppId,
424 extensions::Extension::DISABLE_RELOAD);
425 ExtensionReloadTracker reload_tracker(&profile_,
426 extension_misc::kEasyUnlockAppId);
427 ASSERT_FALSE(reload_tracker.HasReloaded());
429 app_manager_->ReloadApp();
431 EXPECT_FALSE(reload_tracker.HasReloaded());
432 EXPECT_TRUE(extension_service_->GetExtensionById(
433 extension_misc::kEasyUnlockAppId, true));
434 EXPECT_FALSE(
435 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
438 TEST_F(EasyUnlockAppManagerTest, DisableApp) {
439 SetExtensionSystemReady();
441 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
442 GetAppPath());
443 EXPECT_TRUE(extension_service_->GetExtensionById(
444 extension_misc::kEasyUnlockAppId, false));
446 app_manager_->DisableAppIfLoaded();
448 EXPECT_TRUE(extension_service_->GetExtensionById(
449 extension_misc::kEasyUnlockAppId, true));
450 EXPECT_FALSE(
451 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
454 TEST_F(EasyUnlockAppManagerTest, DisableAppWhenNotLoaded) {
455 SetExtensionSystemReady();
457 EXPECT_FALSE(extension_service_->GetExtensionById(
458 extension_misc::kEasyUnlockAppId, true));
460 app_manager_->DisableAppIfLoaded();
462 EXPECT_FALSE(extension_service_->GetExtensionById(
463 extension_misc::kEasyUnlockAppId, true));
465 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
466 GetAppPath());
467 EXPECT_TRUE(extension_service_->GetExtensionById(
468 extension_misc::kEasyUnlockAppId, false));
471 TEST_F(EasyUnlockAppManagerTest, EnsureReady) {
472 bool ready = false;
473 app_manager_->EnsureReady(base::Bind(&VerifyFalseAndSetToTrue, &ready));
475 base::RunLoop().RunUntilIdle();
476 ASSERT_FALSE(ready);
478 SetExtensionSystemReady();
479 ASSERT_TRUE(ready);
482 TEST_F(EasyUnlockAppManagerTest, EnsureReadyAfterExtesionSystemReady) {
483 SetExtensionSystemReady();
485 bool ready = false;
486 app_manager_->EnsureReady(base::Bind(&VerifyFalseAndSetToTrue, &ready));
488 base::RunLoop().RunUntilIdle();
489 ASSERT_TRUE(ready);
492 TEST_F(EasyUnlockAppManagerTest, LaunchSetup) {
493 SetExtensionSystemReady();
495 ASSERT_EQ(0u, event_consumer_.app_launched_count());
497 app_manager_->LoadApp();
498 app_manager_->LaunchSetup();
500 EXPECT_EQ(1u, event_consumer_.app_launched_count());
503 TEST_F(EasyUnlockAppManagerTest, LaunchSetupWhenDisabled) {
504 SetExtensionSystemReady();
506 ASSERT_EQ(0u, event_consumer_.app_launched_count());
508 app_manager_->LoadApp();
509 app_manager_->DisableAppIfLoaded();
511 app_manager_->LaunchSetup();
513 EXPECT_EQ(0u, event_consumer_.app_launched_count());
516 TEST_F(EasyUnlockAppManagerTest, LaunchSetupWhenNotLoaded) {
517 SetExtensionSystemReady();
519 ASSERT_EQ(0u, event_consumer_.app_launched_count());
521 app_manager_->LaunchSetup();
523 EXPECT_EQ(0u, event_consumer_.app_launched_count());
526 TEST_F(EasyUnlockAppManagerTest, SendUserUpdated) {
527 SetExtensionSystemReady();
529 app_manager_->LoadApp();
530 event_router_->AddLazyEventListener(
531 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
532 extension_misc::kEasyUnlockAppId);
534 ASSERT_EQ(0u, event_consumer_.user_updated_count());
536 EXPECT_TRUE(app_manager_->SendUserUpdatedEvent("user", true /* logged_in */,
537 false /* data_ready */));
539 EXPECT_EQ(1u, event_consumer_.user_updated_count());
541 EXPECT_EQ("user", event_consumer_.user_id());
542 EXPECT_TRUE(event_consumer_.user_logged_in());
543 EXPECT_FALSE(event_consumer_.user_data_ready());
546 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedInvertedFlags) {
547 SetExtensionSystemReady();
549 app_manager_->LoadApp();
550 event_router_->AddLazyEventListener(
551 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
552 extension_misc::kEasyUnlockAppId);
554 ASSERT_EQ(0u, event_consumer_.user_updated_count());
556 EXPECT_TRUE(app_manager_->SendUserUpdatedEvent("user", false /* logged_in */,
557 true /* data_ready */));
559 EXPECT_EQ(1u, event_consumer_.user_updated_count());
561 EXPECT_EQ("user", event_consumer_.user_id());
562 EXPECT_FALSE(event_consumer_.user_logged_in());
563 EXPECT_TRUE(event_consumer_.user_data_ready());
566 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedNoRegisteredListeners) {
567 SetExtensionSystemReady();
569 app_manager_->LoadApp();
571 ASSERT_EQ(0u, event_consumer_.user_updated_count());
573 EXPECT_FALSE(app_manager_->SendUserUpdatedEvent("user", true, true));
574 EXPECT_EQ(0u, event_consumer_.user_updated_count());
577 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedAppDisabled) {
578 SetExtensionSystemReady();
580 app_manager_->LoadApp();
581 event_router_->AddLazyEventListener(
582 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
583 extension_misc::kEasyUnlockAppId);
584 app_manager_->DisableAppIfLoaded();
586 ASSERT_EQ(0u, event_consumer_.user_updated_count());
588 EXPECT_FALSE(app_manager_->SendUserUpdatedEvent("user", true, true));
589 EXPECT_EQ(0u, event_consumer_.user_updated_count());
592 TEST_F(EasyUnlockAppManagerTest, SendAuthAttempted) {
593 SetExtensionSystemReady();
595 app_manager_->LoadApp();
596 event_router_->AddLazyEventListener(
597 screenlock_private_api::OnAuthAttempted::kEventName,
598 extension_misc::kEasyUnlockAppId);
600 ASSERT_EQ(0u, event_consumer_.user_updated_count());
602 EXPECT_TRUE(app_manager_->SendAuthAttemptEvent());
603 EXPECT_EQ(1u, event_consumer_.auth_attempted_count());
606 TEST_F(EasyUnlockAppManagerTest, SendAuthAttemptedNoRegisteredListeners) {
607 SetExtensionSystemReady();
609 app_manager_->LoadApp();
611 ASSERT_EQ(0u, event_consumer_.auth_attempted_count());
613 EXPECT_FALSE(app_manager_->SendAuthAttemptEvent());
614 EXPECT_EQ(0u, event_consumer_.auth_attempted_count());
617 TEST_F(EasyUnlockAppManagerTest, SendAuthAttemptedAppDisabled) {
618 SetExtensionSystemReady();
620 app_manager_->LoadApp();
621 event_router_->AddLazyEventListener(
622 screenlock_private_api::OnAuthAttempted::kEventName,
623 extension_misc::kEasyUnlockAppId);
624 app_manager_->DisableAppIfLoaded();
626 ASSERT_EQ(0u, event_consumer_.auth_attempted_count());
628 EXPECT_FALSE(app_manager_->SendAuthAttemptEvent());
629 EXPECT_EQ(0u, event_consumer_.auth_attempted_count());
632 } // namespace