Support SizeClassIdiom on iOS7.
[chromium-blink-merge.git] / chrome / browser / signin / easy_unlock_app_manager_unittest.cc
blob8ae5b87c664fb9a9c8a24d5b101446b0bea3cbe3
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/api/screenlock_private/screenlock_private_api.h"
13 #include "chrome/browser/extensions/component_loader.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/test_extension_system.h"
16 #include "chrome/common/extensions/api/easy_unlock_private.h"
17 #include "chrome/common/extensions/api/screenlock_private.h"
18 #include "chrome/common/extensions/extension_constants.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/proximity_auth/switches.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "extensions/browser/event_router.h"
23 #include "extensions/browser/event_router_factory.h"
24 #include "extensions/browser/extension_prefs.h"
25 #include "extensions/browser/extension_registry.h"
26 #include "extensions/browser/extension_registry_observer.h"
27 #include "extensions/browser/process_manager.h"
28 #include "extensions/browser/process_manager_factory.h"
29 #include "extensions/common/api/app_runtime.h"
30 #include "extensions/common/extension.h"
31 #include "grit/browser_resources.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 #if defined(OS_CHROMEOS)
35 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
36 #include "chrome/browser/chromeos/settings/cros_settings.h"
37 #include "chrome/browser/chromeos/settings/device_settings_service.h"
38 #endif
40 namespace easy_unlock_private_api = extensions::api::easy_unlock_private;
41 namespace screenlock_private_api = extensions::api::screenlock_private;
42 namespace app_runtime_api = extensions::api::app_runtime;
44 namespace {
46 // Sets |*value| to true, also verifying that the value was not previously set.
47 // Used in tests for verifying that a callback was called.
48 void VerifyFalseAndSetToTrue(bool* value) {
49 EXPECT_FALSE(*value);
50 *value = true;
53 // A ProcessManager that doesn't create background host pages.
54 class TestProcessManager : public extensions::ProcessManager {
55 public:
56 explicit TestProcessManager(content::BrowserContext* context)
57 : extensions::ProcessManager(
58 context,
59 context,
60 extensions::ExtensionRegistry::Get(context)) {}
61 ~TestProcessManager() override {}
63 // ProcessManager overrides:
64 bool CreateBackgroundHost(const extensions::Extension* extension,
65 const GURL& url) override {
66 return false;
69 private:
70 DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
73 scoped_ptr<KeyedService> CreateTestProcessManager(
74 content::BrowserContext* context) {
75 return make_scoped_ptr(new TestProcessManager(context));
78 scoped_ptr<KeyedService> CreateScreenlockPrivateEventRouter(
79 content::BrowserContext* context) {
80 return make_scoped_ptr(new extensions::ScreenlockPrivateEventRouter(context));
83 // Observes extension registry for unload and load events (in that order) of an
84 // extension with the provided extension id.
85 // Used to determine if an extension was reloaded.
86 class ExtensionReloadTracker : public extensions::ExtensionRegistryObserver {
87 public:
88 ExtensionReloadTracker(Profile* profile, const std::string& extension_id)
89 : profile_(profile),
90 extension_id_(extension_id),
91 unloaded_(false),
92 loaded_(false) {
93 extensions::ExtensionRegistry::Get(profile)->AddObserver(this);
96 ~ExtensionReloadTracker() override {
97 extensions::ExtensionRegistry::Get(profile_)->RemoveObserver(this);
100 // extension::ExtensionRegistryObserver implementation:
101 void OnExtensionLoaded(content::BrowserContext* browser_context,
102 const extensions::Extension* extension) override {
103 ASSERT_FALSE(loaded_);
104 ASSERT_EQ(extension_id_, extension->id());
105 loaded_ = true;
108 void OnExtensionUnloaded(
109 content::BrowserContext* browser_context,
110 const extensions::Extension* extension,
111 extensions::UnloadedExtensionInfo::Reason reason) override {
112 ASSERT_FALSE(unloaded_);
113 ASSERT_EQ(extension_id_, extension->id());
114 unloaded_ = true;
117 // Whether the extensino was unloaded and loaded during |this| lifetime.
118 bool HasReloaded() const { return loaded_ && unloaded_; }
120 private:
121 Profile* profile_;
122 std::string extension_id_;
123 bool unloaded_;
124 bool loaded_;
126 DISALLOW_COPY_AND_ASSIGN(ExtensionReloadTracker);
129 // Consumes events dispatched from test event router.
130 class EasyUnlockAppEventConsumer {
131 public:
132 explicit EasyUnlockAppEventConsumer(Profile* profile)
133 : user_updated_count_(0u),
134 auth_attempted_count_(0u),
135 app_launched_count_(0u) {}
137 ~EasyUnlockAppEventConsumer() {}
139 // Processes event for test event router.
140 // It returns whether the event is expected to be dispatched during tests and
141 // whether it's well formed.
142 bool ConsumeEvent(const std::string& event_name, base::ListValue* args) {
143 if (event_name == easy_unlock_private_api::OnUserInfoUpdated::kEventName)
144 return ConsumeUserInfoUpdated(args);
146 if (event_name == screenlock_private_api::OnAuthAttempted::kEventName)
147 return ConsumeAuthAttempted(args);
149 if (event_name == app_runtime_api::OnLaunched::kEventName)
150 return ConsumeLaunched(args);
152 LOG(ERROR) << "Unexpected event: " << event_name;
153 return false;
156 // Information about encountered events:
157 size_t user_updated_count() const { return user_updated_count_; }
158 size_t auth_attempted_count() const { return auth_attempted_count_; }
159 size_t app_launched_count() const { return app_launched_count_; }
161 // The data carried by the last UserInfoUpdated event:
162 std::string user_id() const { return user_id_; }
163 bool user_logged_in() const { return user_logged_in_; }
164 bool user_data_ready() const { return user_data_ready_; }
166 private:
167 // Processes easyUnlockPrivate.onUserInfoUpdated event.
168 bool ConsumeUserInfoUpdated(base::ListValue* args) {
169 if (!args) {
170 LOG(ERROR) << "No argument list for onUserInfoUpdated event.";
171 return false;
174 if (args->GetSize() != 1u) {
175 LOG(ERROR) << "Invalid argument list size for onUserInfoUpdated event: "
176 << args->GetSize() << " expected: " << 1u;
177 return false;
180 base::DictionaryValue* user_info;
181 if (!args->GetDictionary(0u, &user_info) || !user_info) {
182 LOG(ERROR) << "Unabled to get event argument as dictionary for "
183 << "onUserInfoUpdated event.";
184 return false;
187 EXPECT_TRUE(user_info->GetString("userId", &user_id_));
188 EXPECT_TRUE(user_info->GetBoolean("loggedIn", &user_logged_in_));
189 EXPECT_TRUE(user_info->GetBoolean("dataReady", &user_data_ready_));
191 ++user_updated_count_;
192 return true;
195 // Processes screenlockPrivate.onAuthAttempted event.
196 bool ConsumeAuthAttempted(base::ListValue* args) {
197 if (!args) {
198 LOG(ERROR) << "No argument list for onAuthAttempted event";
199 return false;
202 if (args->GetSize() != 2u) {
203 LOG(ERROR) << "Invalid argument list size for onAuthAttempted event: "
204 << args->GetSize() << " expected: " << 2u;
205 return false;
208 std::string auth_type;
209 if (!args->GetString(0u, &auth_type)) {
210 LOG(ERROR) << "Unable to get first argument as string for "
211 << "onAuthAttempted event.";
212 return false;
215 EXPECT_EQ("userClick", auth_type);
216 ++auth_attempted_count_;
217 return true;
220 // Processes app.runtime.onLaunched event.
221 bool ConsumeLaunched(base::ListValue* args) {
222 ++app_launched_count_;
223 return true;
226 size_t user_updated_count_;
227 size_t auth_attempted_count_;
228 size_t app_launched_count_;
230 std::string user_id_;
231 bool user_logged_in_;
232 bool user_data_ready_;
234 DISALLOW_COPY_AND_ASSIGN(EasyUnlockAppEventConsumer);
237 // Event router injected into extension system for the tests. It redirects
238 // events to EasyUnlockAppEventConsumer.
239 class TestEventRouter : public extensions::EventRouter {
240 public:
241 TestEventRouter(Profile* profile, extensions::ExtensionPrefs* extension_prefs)
242 : extensions::EventRouter(profile, extension_prefs) {}
244 ~TestEventRouter() override {}
246 // extensions::EventRouter implementation:
247 void BroadcastEvent(scoped_ptr<extensions::Event> event) override {
248 ASSERT_EQ(screenlock_private_api::OnAuthAttempted::kEventName,
249 event->event_name);
250 EXPECT_TRUE(event_consumer_->ConsumeEvent(event->event_name,
251 event->event_args.get()));
254 void DispatchEventToExtension(const std::string& extension_id,
255 scoped_ptr<extensions::Event> event) override {
256 ASSERT_EQ(extension_misc::kEasyUnlockAppId, extension_id);
257 EXPECT_TRUE(event_consumer_->ConsumeEvent(event->event_name,
258 event->event_args.get()));
261 void set_event_consumer(EasyUnlockAppEventConsumer* event_consumer) {
262 event_consumer_ = event_consumer;
265 private:
266 EasyUnlockAppEventConsumer* event_consumer_;
268 DISALLOW_COPY_AND_ASSIGN(TestEventRouter);
271 // TestEventRouter factory function
272 scoped_ptr<KeyedService> TestEventRouterFactoryFunction(
273 content::BrowserContext* context) {
274 return make_scoped_ptr(
275 new TestEventRouter(static_cast<Profile*>(context),
276 extensions::ExtensionPrefs::Get(context)));
279 class EasyUnlockAppManagerTest : public testing::Test {
280 public:
281 EasyUnlockAppManagerTest()
282 : event_consumer_(&profile_),
283 command_line_(base::CommandLine::NO_PROGRAM) {}
284 ~EasyUnlockAppManagerTest() override {}
286 void SetUp() override {
287 base::CommandLine::ForCurrentProcess()->AppendSwitch(
288 proximity_auth::switches::kForceLoadEasyUnlockAppInTests);
289 extensions::ExtensionSystem* extension_system = SetUpExtensionSystem();
290 app_manager_ =
291 EasyUnlockAppManager::Create(extension_system, IDR_EASY_UNLOCK_MANIFEST,
292 GetAppPath()).Pass();
295 protected:
296 void SetExtensionSystemReady() {
297 extensions::TestExtensionSystem* test_extension_system =
298 static_cast<extensions::TestExtensionSystem*>(
299 extensions::ExtensionSystem::Get(&profile_));
300 test_extension_system->SetReady();
301 base::RunLoop().RunUntilIdle();
304 base::FilePath GetAppPath() {
305 return extensions::ExtensionPrefs::Get(&profile_)
306 ->install_directory()
307 .AppendASCII("easy_unlock");
310 private:
311 // Initializes test extension system.
312 extensions::ExtensionSystem* SetUpExtensionSystem() {
313 extensions::TestExtensionSystem* test_extension_system =
314 static_cast<extensions::TestExtensionSystem*>(
315 extensions::ExtensionSystem::Get(&profile_));
316 extension_service_ = test_extension_system->CreateExtensionService(
317 &command_line_, base::FilePath() /* install_directory */,
318 false /* autoupdate_enabled */);
320 extensions::ProcessManagerFactory::GetInstance()->SetTestingFactory(
321 &profile_, &CreateTestProcessManager);
322 extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()
323 ->SetTestingFactory(&profile_, &CreateScreenlockPrivateEventRouter);
325 event_router_ = static_cast<TestEventRouter*>(
326 extensions::EventRouterFactory::GetInstance()->SetTestingFactoryAndUse(
327 &profile_, &TestEventRouterFactoryFunction));
328 event_router_->set_event_consumer(&event_consumer_);
330 extension_service_->component_loader()->
331 set_ignore_whitelist_for_testing(true);
333 return test_extension_system;
336 protected:
337 scoped_ptr<EasyUnlockAppManager> app_manager_;
339 // Needed by extension system.
340 content::TestBrowserThreadBundle thread_bundle_;
342 #if defined(OS_CHROMEOS)
343 // Cros settings and device settings are needed when creating user manager.
344 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
345 chromeos::ScopedTestCrosSettings test_cros_settings_;
346 // Needed for creating ExtensionService.
347 chromeos::ScopedTestUserManager test_user_manager_;
348 #endif
350 TestingProfile profile_;
352 EasyUnlockAppEventConsumer event_consumer_;
353 ExtensionService* extension_service_;
354 TestEventRouter* event_router_;
356 base::CommandLine command_line_;
358 private:
359 DISALLOW_COPY_AND_ASSIGN(EasyUnlockAppManagerTest);
362 TEST_F(EasyUnlockAppManagerTest, LoadAppWhenNotLoaded) {
363 SetExtensionSystemReady();
365 // Sanity check for the test: the easy unlock app should not be loaded at
366 // this point.
367 ASSERT_FALSE(extension_service_->GetExtensionById(
368 extension_misc::kEasyUnlockAppId, true));
370 app_manager_->LoadApp();
372 ASSERT_TRUE(extension_service_->GetExtensionById(
373 extension_misc::kEasyUnlockAppId, false));
374 EXPECT_TRUE(
375 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
378 TEST_F(EasyUnlockAppManagerTest, LoadAppWhenAlreadyLoaded) {
379 SetExtensionSystemReady();
381 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
382 GetAppPath());
384 app_manager_->LoadApp();
386 ASSERT_TRUE(extension_service_->GetExtensionById(
387 extension_misc::kEasyUnlockAppId, false));
390 TEST_F(EasyUnlockAppManagerTest, LoadAppPreviouslyDisabled) {
391 SetExtensionSystemReady();
393 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
394 GetAppPath());
395 extension_service_->DisableExtension(extension_misc::kEasyUnlockAppId,
396 extensions::Extension::DISABLE_RELOAD);
398 ASSERT_TRUE(extension_service_->GetExtensionById(
399 extension_misc::kEasyUnlockAppId, true));
400 ASSERT_FALSE(
401 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
403 app_manager_->LoadApp();
405 ASSERT_TRUE(extension_service_->GetExtensionById(
406 extension_misc::kEasyUnlockAppId, false));
409 TEST_F(EasyUnlockAppManagerTest, ReloadApp) {
410 SetExtensionSystemReady();
412 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
413 GetAppPath());
415 ExtensionReloadTracker reload_tracker(&profile_,
416 extension_misc::kEasyUnlockAppId);
417 ASSERT_FALSE(reload_tracker.HasReloaded());
419 app_manager_->ReloadApp();
421 EXPECT_TRUE(reload_tracker.HasReloaded());
422 EXPECT_TRUE(extension_service_->GetExtensionById(
423 extension_misc::kEasyUnlockAppId, false));
426 TEST_F(EasyUnlockAppManagerTest, ReloadAppDisabled) {
427 SetExtensionSystemReady();
429 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
430 GetAppPath());
431 extension_service_->DisableExtension(extension_misc::kEasyUnlockAppId,
432 extensions::Extension::DISABLE_RELOAD);
433 ExtensionReloadTracker reload_tracker(&profile_,
434 extension_misc::kEasyUnlockAppId);
435 ASSERT_FALSE(reload_tracker.HasReloaded());
437 app_manager_->ReloadApp();
439 EXPECT_FALSE(reload_tracker.HasReloaded());
440 EXPECT_TRUE(extension_service_->GetExtensionById(
441 extension_misc::kEasyUnlockAppId, true));
442 EXPECT_FALSE(
443 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
446 TEST_F(EasyUnlockAppManagerTest, DisableApp) {
447 SetExtensionSystemReady();
449 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
450 GetAppPath());
451 EXPECT_TRUE(extension_service_->GetExtensionById(
452 extension_misc::kEasyUnlockAppId, false));
454 app_manager_->DisableAppIfLoaded();
456 EXPECT_TRUE(extension_service_->GetExtensionById(
457 extension_misc::kEasyUnlockAppId, true));
458 EXPECT_FALSE(
459 extension_service_->IsExtensionEnabled(extension_misc::kEasyUnlockAppId));
462 TEST_F(EasyUnlockAppManagerTest, DisableAppWhenNotLoaded) {
463 SetExtensionSystemReady();
465 EXPECT_FALSE(extension_service_->GetExtensionById(
466 extension_misc::kEasyUnlockAppId, true));
468 app_manager_->DisableAppIfLoaded();
470 EXPECT_FALSE(extension_service_->GetExtensionById(
471 extension_misc::kEasyUnlockAppId, true));
473 extension_service_->component_loader()->Add(IDR_EASY_UNLOCK_MANIFEST,
474 GetAppPath());
475 EXPECT_TRUE(extension_service_->GetExtensionById(
476 extension_misc::kEasyUnlockAppId, false));
479 TEST_F(EasyUnlockAppManagerTest, EnsureReady) {
480 bool ready = false;
481 app_manager_->EnsureReady(base::Bind(&VerifyFalseAndSetToTrue, &ready));
483 base::RunLoop().RunUntilIdle();
484 ASSERT_FALSE(ready);
486 SetExtensionSystemReady();
487 ASSERT_TRUE(ready);
490 TEST_F(EasyUnlockAppManagerTest, EnsureReadyAfterExtesionSystemReady) {
491 SetExtensionSystemReady();
493 bool ready = false;
494 app_manager_->EnsureReady(base::Bind(&VerifyFalseAndSetToTrue, &ready));
496 base::RunLoop().RunUntilIdle();
497 ASSERT_TRUE(ready);
500 TEST_F(EasyUnlockAppManagerTest, LaunchSetup) {
501 SetExtensionSystemReady();
503 ASSERT_EQ(0u, event_consumer_.app_launched_count());
505 app_manager_->LoadApp();
506 app_manager_->LaunchSetup();
508 EXPECT_EQ(1u, event_consumer_.app_launched_count());
511 TEST_F(EasyUnlockAppManagerTest, LaunchSetupWhenDisabled) {
512 SetExtensionSystemReady();
514 ASSERT_EQ(0u, event_consumer_.app_launched_count());
516 app_manager_->LoadApp();
517 app_manager_->DisableAppIfLoaded();
519 app_manager_->LaunchSetup();
521 EXPECT_EQ(0u, event_consumer_.app_launched_count());
524 TEST_F(EasyUnlockAppManagerTest, LaunchSetupWhenNotLoaded) {
525 SetExtensionSystemReady();
527 ASSERT_EQ(0u, event_consumer_.app_launched_count());
529 app_manager_->LaunchSetup();
531 EXPECT_EQ(0u, event_consumer_.app_launched_count());
534 TEST_F(EasyUnlockAppManagerTest, SendUserUpdated) {
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", true /* logged_in */,
545 false /* data_ready */));
547 EXPECT_EQ(1u, event_consumer_.user_updated_count());
549 EXPECT_EQ("user", event_consumer_.user_id());
550 EXPECT_TRUE(event_consumer_.user_logged_in());
551 EXPECT_FALSE(event_consumer_.user_data_ready());
554 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedInvertedFlags) {
555 SetExtensionSystemReady();
557 app_manager_->LoadApp();
558 event_router_->AddLazyEventListener(
559 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
560 extension_misc::kEasyUnlockAppId);
562 ASSERT_EQ(0u, event_consumer_.user_updated_count());
564 EXPECT_TRUE(app_manager_->SendUserUpdatedEvent("user", false /* logged_in */,
565 true /* data_ready */));
567 EXPECT_EQ(1u, event_consumer_.user_updated_count());
569 EXPECT_EQ("user", event_consumer_.user_id());
570 EXPECT_FALSE(event_consumer_.user_logged_in());
571 EXPECT_TRUE(event_consumer_.user_data_ready());
574 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedNoRegisteredListeners) {
575 SetExtensionSystemReady();
577 app_manager_->LoadApp();
579 ASSERT_EQ(0u, event_consumer_.user_updated_count());
581 EXPECT_FALSE(app_manager_->SendUserUpdatedEvent("user", true, true));
582 EXPECT_EQ(0u, event_consumer_.user_updated_count());
585 TEST_F(EasyUnlockAppManagerTest, SendUserUpdatedAppDisabled) {
586 SetExtensionSystemReady();
588 app_manager_->LoadApp();
589 event_router_->AddLazyEventListener(
590 easy_unlock_private_api::OnUserInfoUpdated::kEventName,
591 extension_misc::kEasyUnlockAppId);
592 app_manager_->DisableAppIfLoaded();
594 ASSERT_EQ(0u, event_consumer_.user_updated_count());
596 EXPECT_FALSE(app_manager_->SendUserUpdatedEvent("user", true, true));
597 EXPECT_EQ(0u, event_consumer_.user_updated_count());
600 TEST_F(EasyUnlockAppManagerTest, SendAuthAttempted) {
601 SetExtensionSystemReady();
603 app_manager_->LoadApp();
604 event_router_->AddLazyEventListener(
605 screenlock_private_api::OnAuthAttempted::kEventName,
606 extension_misc::kEasyUnlockAppId);
608 ASSERT_EQ(0u, event_consumer_.user_updated_count());
610 EXPECT_TRUE(app_manager_->SendAuthAttemptEvent());
611 EXPECT_EQ(1u, event_consumer_.auth_attempted_count());
614 TEST_F(EasyUnlockAppManagerTest, SendAuthAttemptedNoRegisteredListeners) {
615 SetExtensionSystemReady();
617 app_manager_->LoadApp();
619 ASSERT_EQ(0u, event_consumer_.auth_attempted_count());
621 EXPECT_FALSE(app_manager_->SendAuthAttemptEvent());
622 EXPECT_EQ(0u, event_consumer_.auth_attempted_count());
625 TEST_F(EasyUnlockAppManagerTest, SendAuthAttemptedAppDisabled) {
626 SetExtensionSystemReady();
628 app_manager_->LoadApp();
629 event_router_->AddLazyEventListener(
630 screenlock_private_api::OnAuthAttempted::kEventName,
631 extension_misc::kEasyUnlockAppId);
632 app_manager_->DisableAppIfLoaded();
634 ASSERT_EQ(0u, event_consumer_.auth_attempted_count());
636 EXPECT_FALSE(app_manager_->SendAuthAttemptEvent());
637 EXPECT_EQ(0u, event_consumer_.auth_attempted_count());
640 } // namespace