Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013 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. | |
| 4 | |
| 5 #include "chrome/browser/extensions/api/identity/identity_event_router.h" | |
| 6 | |
| 7 #include <map> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/command_line.h" | |
| 12 #include "base/files/file_path.h" | |
| 13 #include "base/path_service.h" | |
| 14 #include "base/stl_util.h" | |
| 15 #include "base/strings/stringprintf.h" | |
| 16 #include "base/values.h" | |
| 17 #include "chrome/browser/extensions/event_router.h" | |
| 18 #include "chrome/browser/extensions/extension_service.h" | |
| 19 #include "chrome/browser/extensions/extension_system.h" | |
| 20 #include "chrome/browser/extensions/extension_system_factory.h" | |
| 21 #include "chrome/browser/extensions/test_extension_service.h" | |
| 22 #include "chrome/browser/extensions/test_extension_system.h" | |
| 23 #include "chrome/browser/profiles/profile.h" | |
| 24 #include "chrome/common/chrome_paths.h" | |
| 25 #include "chrome/common/extensions/api/identity.h" | |
| 26 #include "chrome/common/extensions/extension.h" | |
| 27 #include "chrome/common/extensions/extension_builder.h" | |
| 28 #include "chrome/common/extensions/extension_set.h" | |
| 29 #include "chrome/common/extensions/permissions/api_permission.h" | |
| 30 #include "chrome/common/extensions/permissions/permissions_data.h" | |
| 31 #include "chrome/common/extensions/value_builder.h" | |
| 32 #include "chrome/test/base/testing_profile.h" | |
| 33 #include "content/public/test/mock_render_process_host.h" | |
| 34 #include "content/public/test/test_browser_thread_bundle.h" | |
| 35 #include "testing/gtest/include/gtest/gtest.h" | |
| 36 | |
| 37 namespace { | |
| 38 | |
| 39 struct EventInfo { | |
| 40 std::string user_id; | |
| 41 std::string email; | |
| 42 bool is_signed_in; | |
| 43 }; | |
| 44 | |
| 45 class FakeEventRouter : public extensions::EventRouter { | |
| 46 public: | |
| 47 explicit FakeEventRouter(Profile* profile) : EventRouter(profile, NULL) {} | |
| 48 | |
| 49 virtual void DispatchEventToExtension( | |
| 50 const std::string& extension_id, | |
| 51 scoped_ptr<extensions::Event> event) OVERRIDE { | |
| 52 EventInfo event_info; | |
| 53 base::DictionaryValue* event_object = NULL; | |
| 54 EXPECT_TRUE(event->event_args->GetDictionary(0, &event_object)); | |
| 55 EXPECT_TRUE(event_object->GetString("id", &event_info.user_id)); | |
| 56 event_object->GetString("email", &event_info.email); | |
| 57 | |
| 58 EXPECT_TRUE(event->event_args->GetBoolean(1, &event_info.is_signed_in)); | |
| 59 | |
| 60 EXPECT_FALSE(ContainsKey(extension_id_to_event_, extension_id)); | |
| 61 extension_id_to_event_[extension_id] = event_info; | |
| 62 } | |
| 63 | |
| 64 size_t GetEventCount() { | |
| 65 return extension_id_to_event_.size(); | |
| 66 } | |
| 67 | |
| 68 bool ContainsExtensionId(const std::string extension_id) { | |
| 69 return ContainsKey(extension_id_to_event_, extension_id); | |
| 70 } | |
| 71 | |
| 72 const EventInfo& GetEventInfo(const std::string extension_id) { | |
| 73 return extension_id_to_event_[extension_id]; | |
| 74 } | |
| 75 | |
| 76 private: | |
| 77 std::map<std::string, EventInfo> extension_id_to_event_; | |
|
not at google - send to devlin
2013/10/16 16:49:37
with a map you lose ordering + repetition, right?
Michael Courage
2013/10/16 20:24:53
Line 60 forbids repetition of any kind. FakeEventR
| |
| 78 | |
| 79 DISALLOW_COPY_AND_ASSIGN(FakeEventRouter); | |
| 80 }; | |
| 81 | |
| 82 class FakeExtensionService : public TestExtensionService { | |
| 83 public: | |
| 84 FakeExtensionService() {} | |
| 85 virtual ~FakeExtensionService() {} | |
| 86 | |
| 87 virtual const ExtensionSet* extensions() const OVERRIDE { | |
| 88 return &extensions_; | |
| 89 } | |
| 90 | |
| 91 virtual void AddExtension(const extensions::Extension* extension) OVERRIDE { | |
| 92 extensions_.Insert(extension); | |
| 93 } | |
| 94 | |
| 95 private: | |
| 96 ExtensionSet extensions_; | |
| 97 }; | |
| 98 | |
| 99 class FakeExtensionSystem : public extensions::TestExtensionSystem { | |
| 100 public: | |
| 101 explicit FakeExtensionSystem(Profile* profile) | |
| 102 : extensions::TestExtensionSystem(profile) {} | |
| 103 | |
| 104 virtual extensions::EventRouter* event_router() OVERRIDE { | |
| 105 return fake_event_router(); | |
| 106 } | |
| 107 | |
| 108 virtual ExtensionService* extension_service() OVERRIDE { | |
| 109 ExtensionServiceInterface* as_interface = | |
| 110 static_cast<ExtensionServiceInterface*>(&fake_extension_service_); | |
| 111 return static_cast<ExtensionService*>(as_interface); | |
| 112 } | |
| 113 | |
| 114 FakeEventRouter* fake_event_router() { | |
| 115 if (!fake_event_router_) | |
| 116 fake_event_router_.reset(new FakeEventRouter(profile_)); | |
| 117 return fake_event_router_.get(); | |
| 118 } | |
| 119 | |
| 120 private: | |
| 121 FakeExtensionService fake_extension_service_; | |
| 122 scoped_ptr<FakeEventRouter> fake_event_router_; | |
| 123 | |
| 124 DISALLOW_COPY_AND_ASSIGN(FakeExtensionSystem); | |
| 125 }; | |
| 126 | |
| 127 BrowserContextKeyedService* BuildFakeExtensionSystem( | |
| 128 content::BrowserContext* profile) { | |
| 129 return new FakeExtensionSystem(static_cast<Profile*>(profile)); | |
| 130 } | |
| 131 | |
| 132 } // namespace | |
| 133 | |
| 134 namespace extensions { | |
| 135 | |
| 136 class IdentityEventRouterTest : public testing::Test { | |
| 137 public: | |
| 138 IdentityEventRouterTest() | |
| 139 : test_profile_(new TestingProfile()), | |
| 140 identity_event_router_(test_profile_.get()), | |
| 141 extension_counter_(0) {} | |
| 142 | |
| 143 virtual void SetUp() OVERRIDE { | |
| 144 fake_extension_system_ = static_cast<FakeExtensionSystem*>( | |
| 145 ExtensionSystemFactory::GetInstance()->SetTestingFactoryAndUse( | |
| 146 test_profile_.get(), &BuildFakeExtensionSystem)); | |
| 147 } | |
| 148 | |
| 149 FakeEventRouter* fake_event_router() { | |
| 150 return fake_extension_system_->fake_event_router(); | |
| 151 } | |
| 152 | |
| 153 Profile* profile() { | |
| 154 return test_profile_.get(); | |
| 155 } | |
| 156 | |
| 157 protected: | |
| 158 scoped_refptr<const Extension> CreateExtension(bool has_email_permission) { | |
| 159 ListBuilder permissions; | |
| 160 if (has_email_permission) | |
| 161 permissions.Append("identity.email"); | |
| 162 | |
| 163 std::string id = base::StringPrintf("id.%d", extension_counter_++); | |
| 164 scoped_refptr<const Extension> extension = ExtensionBuilder() | |
| 165 .SetID(id) | |
| 166 .SetManifest(DictionaryBuilder() | |
| 167 .Set("name", "Extension with ID " + id) | |
| 168 .Set("version", "1.0") | |
| 169 .Set("manifest_version", 2) | |
| 170 .Set("permissions", permissions)) | |
| 171 .Build(); | |
| 172 fake_extension_system_->extension_service()->AddExtension(extension.get()); | |
| 173 fake_event_router()->AddEventListener( | |
| 174 api::identity::OnSignInChanged::kEventName, NULL, extension->id()); | |
| 175 return extension; | |
| 176 } | |
| 177 | |
| 178 scoped_ptr<TestingProfile> test_profile_; | |
| 179 IdentityEventRouter identity_event_router_; | |
| 180 FakeExtensionSystem* fake_extension_system_; | |
| 181 content::TestBrowserThreadBundle thread_bundle_; | |
| 182 int extension_counter_; | |
| 183 }; | |
| 184 | |
| 185 TEST_F(IdentityEventRouterTest, SignInNoListeners) { | |
| 186 identity_event_router_.DispatchSignInEvent( | |
| 187 "test_user_id", "test_email", true); | |
| 188 EXPECT_EQ(0ul, fake_event_router()->GetEventCount()); | |
| 189 } | |
| 190 | |
| 191 TEST_F(IdentityEventRouterTest, SignInNoEmailListener) { | |
| 192 scoped_refptr<const Extension> ext = CreateExtension(false); | |
|
not at google - send to devlin
2013/10/16 16:49:37
for what it's worth: the scoped_refptr<> here (and
Michael Courage
2013/10/16 20:24:53
Done.
| |
| 193 identity_event_router_.DispatchSignInEvent( | |
| 194 "test_user_id", "test_email", true); | |
| 195 EXPECT_EQ(1ul, fake_event_router()->GetEventCount()); | |
| 196 EXPECT_TRUE(fake_event_router()->ContainsExtensionId(ext->id())); | |
| 197 EXPECT_EQ("test_user_id", | |
| 198 fake_event_router()->GetEventInfo(ext->id()).user_id); | |
| 199 EXPECT_TRUE(fake_event_router()->GetEventInfo(ext->id()).email.empty()); | |
| 200 EXPECT_TRUE(fake_event_router()->GetEventInfo(ext->id()).is_signed_in); | |
| 201 } | |
| 202 | |
| 203 TEST_F(IdentityEventRouterTest, SignInWithEmailListener) { | |
| 204 scoped_refptr<const Extension> ext = CreateExtension(true); | |
| 205 identity_event_router_.DispatchSignInEvent( | |
| 206 "test_user_id", "test_email", true); | |
| 207 EXPECT_EQ(1ul, fake_event_router()->GetEventCount()); | |
| 208 EXPECT_TRUE(fake_event_router()->ContainsExtensionId(ext->id())); | |
| 209 EXPECT_EQ("test_user_id", | |
| 210 fake_event_router()->GetEventInfo(ext->id()).user_id); | |
| 211 EXPECT_EQ("test_email", fake_event_router()->GetEventInfo(ext->id()).email); | |
| 212 EXPECT_TRUE(fake_event_router()->GetEventInfo(ext->id()).is_signed_in); | |
| 213 } | |
| 214 | |
| 215 TEST_F(IdentityEventRouterTest, SignInMultipleListeners) { | |
| 216 typedef std::vector<scoped_refptr<const Extension> > ExtensionVector; | |
| 217 ExtensionVector with_email; | |
| 218 ExtensionVector no_email; | |
| 219 | |
| 220 for (int i = 0; i < 3; i++) | |
| 221 with_email.push_back(CreateExtension(true)); | |
| 222 | |
| 223 for (int i = 0; i < 2; i++) | |
| 224 no_email.push_back(CreateExtension(false)); | |
| 225 | |
| 226 identity_event_router_.DispatchSignInEvent( | |
| 227 "test_user_id", "test_email", true); | |
| 228 | |
| 229 EXPECT_EQ(with_email.size() + no_email.size(), | |
| 230 fake_event_router()->GetEventCount()); | |
| 231 | |
| 232 for (ExtensionVector::const_iterator it = with_email.begin(); | |
| 233 it != with_email.end(); | |
| 234 ++it) { | |
| 235 EXPECT_TRUE(fake_event_router()->ContainsExtensionId((*it)->id())); | |
| 236 EXPECT_EQ("test_user_id", | |
| 237 fake_event_router()->GetEventInfo((*it)->id()).user_id); | |
| 238 EXPECT_EQ("test_email", | |
| 239 fake_event_router()->GetEventInfo((*it)->id()).email); | |
| 240 EXPECT_TRUE(fake_event_router()->GetEventInfo((*it)->id()).is_signed_in); | |
| 241 } | |
| 242 | |
| 243 for (ExtensionVector::const_iterator it = no_email.begin(); | |
| 244 it != no_email.end(); | |
| 245 ++it) { | |
| 246 EXPECT_TRUE(fake_event_router()->ContainsExtensionId((*it)->id())); | |
| 247 EXPECT_EQ("test_user_id", | |
| 248 fake_event_router()->GetEventInfo((*it)->id()).user_id); | |
| 249 EXPECT_TRUE(fake_event_router()->GetEventInfo((*it)->id()).email.empty()); | |
| 250 EXPECT_TRUE(fake_event_router()->GetEventInfo((*it)->id()).is_signed_in); | |
| 251 } | |
| 252 } | |
| 253 | |
| 254 TEST_F(IdentityEventRouterTest, SignInWithTwoListenersOnOneExtension) { | |
| 255 scoped_refptr<const Extension> ext = CreateExtension(true); | |
| 256 | |
| 257 scoped_ptr<content::MockRenderProcessHost> fake_render_process( | |
| 258 new content::MockRenderProcessHost(profile())); | |
| 259 fake_event_router()->AddEventListener( | |
| 260 api::identity::OnSignInChanged::kEventName, | |
| 261 fake_render_process.get(), | |
| 262 ext->id()); | |
| 263 | |
| 264 identity_event_router_.DispatchSignInEvent( | |
| 265 "test_user_id", "test_email", true); | |
| 266 EXPECT_EQ(1ul, fake_event_router()->GetEventCount()); | |
| 267 EXPECT_TRUE(fake_event_router()->ContainsExtensionId(ext->id())); | |
| 268 EXPECT_EQ("test_user_id", | |
| 269 fake_event_router()->GetEventInfo(ext->id()).user_id); | |
| 270 EXPECT_EQ("test_email", fake_event_router()->GetEventInfo(ext->id()).email); | |
| 271 EXPECT_TRUE(fake_event_router()->GetEventInfo(ext->id()).is_signed_in); | |
| 272 | |
| 273 fake_event_router()->RemoveEventListener( | |
| 274 api::identity::OnSignInChanged::kEventName, | |
| 275 fake_render_process.get(), | |
| 276 ext->id()); | |
| 277 } | |
| 278 | |
| 279 TEST_F(IdentityEventRouterTest, SignOut) { | |
| 280 scoped_refptr<const Extension> ext = CreateExtension(false); | |
| 281 identity_event_router_.DispatchSignInEvent( | |
| 282 "test_user_id", "test_email", false); | |
| 283 EXPECT_EQ(1ul, fake_event_router()->GetEventCount()); | |
| 284 EXPECT_TRUE(fake_event_router()->ContainsExtensionId(ext->id())); | |
| 285 EXPECT_EQ("test_user_id", | |
| 286 fake_event_router()->GetEventInfo(ext->id()).user_id); | |
| 287 EXPECT_TRUE(fake_event_router()->GetEventInfo(ext->id()).email.empty()); | |
| 288 EXPECT_FALSE(fake_event_router()->GetEventInfo(ext->id()).is_signed_in); | |
| 289 } | |
| 290 | |
| 291 } // namespace extensions | |
| OLD | NEW |