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.
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/values.h"
13 #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h"
14 #include "chrome/browser/extensions/extension_api_unittest.h"
15 #include "chrome/browser/extensions/test_extension_prefs.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/sync/profile_sync_service_factory.h"
18 #include "chrome/browser/sync/profile_sync_service_mock.h"
19 #include "chrome/common/pref_names.h"
20 #include "components/sync_driver/device_info.h"
21 #include "extensions/common/extension.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using sync_driver::DeviceInfo;
26 using sync_driver::DeviceInfoTracker;
27 using testing::Return;
29 namespace extensions {
31 class MockDeviceInfoTracker : public DeviceInfoTracker {
33 virtual ~MockDeviceInfoTracker() {}
35 virtual scoped_ptr<DeviceInfo> GetDeviceInfo(
36 const std::string& client_id) const OVERRIDE {
38 return scoped_ptr<DeviceInfo>();
41 static DeviceInfo* CloneDeviceInfo(const DeviceInfo* device_info) {
42 return new DeviceInfo(device_info->guid(),
43 device_info->client_name(),
44 device_info->chrome_version(),
45 device_info->sync_user_agent(),
46 device_info->device_type(),
47 device_info->signin_scoped_device_id());
50 virtual ScopedVector<DeviceInfo> GetAllDeviceInfo() const OVERRIDE {
51 ScopedVector<DeviceInfo> list;
53 for (std::vector<const DeviceInfo*>::const_iterator iter = devices_.begin();
54 iter != devices_.end();
56 list.push_back(CloneDeviceInfo(*iter));
62 virtual void AddObserver(Observer* observer) OVERRIDE { NOTREACHED(); }
64 virtual void RemoveObserver(Observer* observer) OVERRIDE { NOTREACHED(); }
66 void Add(const DeviceInfo* device) { devices_.push_back(device); }
69 // DeviceInfo stored here are not owned.
70 std::vector<const DeviceInfo*> devices_;
73 TEST(SignedInDevicesAPITest, GetSignedInDevices) {
74 TestingProfile profile;
75 MockDeviceInfoTracker device_tracker;
76 base::MessageLoop message_loop_;
77 TestExtensionPrefs extension_prefs(
78 message_loop_.message_loop_proxy().get());
80 // Add a couple of devices and make sure we get back public ids for them.
81 std::string extension_name = "test";
82 scoped_refptr<Extension> extension_test =
83 extension_prefs.AddExtension(extension_name);
85 DeviceInfo device_info1(base::GenerateGUID(),
89 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
92 DeviceInfo device_info2(base::GenerateGUID(),
96 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
99 device_tracker.Add(&device_info1);
100 device_tracker.Add(&device_info2);
102 ScopedVector<DeviceInfo> output1 = GetAllSignedInDevices(
103 extension_test.get()->id(), &device_tracker, extension_prefs.prefs());
105 std::string public_id1 = output1[0]->public_id();
106 std::string public_id2 = output1[1]->public_id();
108 EXPECT_FALSE(public_id1.empty());
109 EXPECT_FALSE(public_id2.empty());
110 EXPECT_NE(public_id1, public_id2);
112 // Add a third device and make sure the first 2 ids are retained and a new
113 // id is generated for the third device.
114 DeviceInfo device_info3(base::GenerateGUID(),
118 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
121 device_tracker.Add(&device_info3);
123 ScopedVector<DeviceInfo> output2 = GetAllSignedInDevices(
124 extension_test.get()->id(), &device_tracker, extension_prefs.prefs());
126 EXPECT_EQ(output2[0]->public_id(), public_id1);
127 EXPECT_EQ(output2[1]->public_id(), public_id2);
129 std::string public_id3 = output2[2]->public_id();
130 EXPECT_FALSE(public_id3.empty());
131 EXPECT_NE(public_id3, public_id1);
132 EXPECT_NE(public_id3, public_id2);
135 class ProfileSyncServiceMockForExtensionTests:
136 public ProfileSyncServiceMock {
138 explicit ProfileSyncServiceMockForExtensionTests(Profile* p)
139 : ProfileSyncServiceMock(p) {}
140 ~ProfileSyncServiceMockForExtensionTests() {}
142 MOCK_METHOD0(Shutdown, void());
143 MOCK_CONST_METHOD0(GetDeviceInfoTracker, DeviceInfoTracker*());
146 KeyedService* CreateProfileSyncServiceMock(content::BrowserContext* profile) {
147 return new ProfileSyncServiceMockForExtensionTests(
148 Profile::FromBrowserContext(profile));
151 class ExtensionSignedInDevicesTest : public ExtensionApiUnittest {
153 virtual void SetUp() {
154 ExtensionApiUnittest::SetUp();
156 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
157 profile(), CreateProfileSyncServiceMock);
161 std::string GetPublicId(const base::DictionaryValue* dictionary) {
162 std::string public_id;
163 if (!dictionary->GetString("id", &public_id)) {
164 ADD_FAILURE() << "Not able to find public id in the dictionary";
170 void VerifyDictionaryWithDeviceInfo(const base::DictionaryValue* actual_value,
171 DeviceInfo* device_info) {
172 std::string public_id = GetPublicId(actual_value);
173 device_info->set_public_id(public_id);
175 scoped_ptr<base::DictionaryValue> expected_value(device_info->ToValue());
176 EXPECT_TRUE(expected_value->Equals(actual_value));
179 base::DictionaryValue* GetDictionaryFromList(int index,
180 base::ListValue* value) {
181 base::DictionaryValue* dictionary;
182 if (!value->GetDictionary(index, &dictionary)) {
183 ADD_FAILURE() << "Expected a list of dictionaries";
189 TEST_F(ExtensionSignedInDevicesTest, GetAll) {
190 ProfileSyncServiceMockForExtensionTests* pss_mock =
191 static_cast<ProfileSyncServiceMockForExtensionTests*>(
192 ProfileSyncServiceFactory::GetForProfile(profile()));
193 MockDeviceInfoTracker device_tracker;
195 DeviceInfo device_info1(base::GenerateGUID(),
199 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
202 DeviceInfo device_info2(base::GenerateGUID(),
206 sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
209 device_tracker.Add(&device_info1);
210 device_tracker.Add(&device_info2);
212 EXPECT_CALL(*pss_mock, GetDeviceInfoTracker())
213 .WillOnce(Return(&device_tracker));
215 EXPECT_CALL(*pss_mock, Shutdown());
217 scoped_ptr<base::ListValue> result(RunFunctionAndReturnList(
218 new SignedInDevicesGetFunction(), "[null]"));
220 // Ensure dictionary matches device info.
221 VerifyDictionaryWithDeviceInfo(GetDictionaryFromList(0, result.get()),
223 VerifyDictionaryWithDeviceInfo(GetDictionaryFromList(1, result.get()),
226 // Ensure public ids are set and unique.
227 std::string public_id1 = GetPublicId(GetDictionaryFromList(0, result.get()));
228 std::string public_id2 = GetPublicId(GetDictionaryFromList(1, result.get()));
230 EXPECT_FALSE(public_id1.empty());
231 EXPECT_FALSE(public_id2.empty());
232 EXPECT_NE(public_id1, public_id2);
235 TEST_F(ExtensionSignedInDevicesTest, DeviceInfoTrackerNotInitialized) {
236 ProfileSyncServiceMockForExtensionTests* pss_mock =
237 static_cast<ProfileSyncServiceMockForExtensionTests*>(
238 ProfileSyncServiceFactory::GetForProfile(profile()));
240 EXPECT_CALL(*pss_mock, GetDeviceInfoTracker())
241 .WillOnce(Return((DeviceInfoTracker*)NULL));
242 EXPECT_CALL(*pss_mock, Shutdown());
244 ScopedVector<DeviceInfo> output = GetAllSignedInDevices(
245 extension()->id(), profile());
247 EXPECT_TRUE(output.empty());
250 } // namespace extensions