OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/guid.h" | 9 #include "base/guid.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/prefs/pref_service.h" |
| 12 #include "base/values.h" |
11 #include "chrome/browser/extensions/api/signedin_devices/signedin_devices_api.h" | 13 #include "chrome/browser/extensions/api/signedin_devices/signedin_devices_api.h" |
| 14 #include "chrome/browser/extensions/extension_function_test_utils.h" |
12 #include "chrome/browser/extensions/test_extension_prefs.h" | 15 #include "chrome/browser/extensions/test_extension_prefs.h" |
| 16 #include "chrome/browser/profiles/profile.h" |
13 #include "chrome/browser/sync/glue/device_info.h" | 17 #include "chrome/browser/sync/glue/device_info.h" |
| 18 #include "chrome/browser/sync/profile_sync_service_factory.h" |
14 #include "chrome/browser/sync/profile_sync_service_mock.h" | 19 #include "chrome/browser/sync/profile_sync_service_mock.h" |
15 #include "chrome/common/extensions/extension.h" | 20 #include "chrome/common/extensions/extension.h" |
16 #include "chrome/common/extensions/extension_manifest_constants.h" | 21 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 22 #include "chrome/common/pref_names.h" |
| 23 #include "chrome/test/base/browser_with_test_window_test.h" |
17 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
19 | 26 |
20 using extensions::Extension; | 27 using extensions::Extension; |
21 using extensions::TestExtensionPrefs; | 28 using extensions::TestExtensionPrefs; |
22 using browser_sync::DeviceInfo; | 29 using browser_sync::DeviceInfo; |
23 using testing::Return; | 30 using testing::Return; |
24 | 31 |
25 namespace extensions { | 32 namespace extensions { |
26 | 33 |
| 34 namespace utils = extension_function_test_utils; |
| 35 |
27 TEST(SignedinDevicesAPITest, GetSignedInDevices) { | 36 TEST(SignedinDevicesAPITest, GetSignedInDevices) { |
28 ProfileSyncServiceMock pss_mock; | 37 ProfileSyncServiceMock pss_mock; |
29 base::MessageLoop message_loop_; | 38 base::MessageLoop message_loop_; |
30 TestExtensionPrefs extension_prefs( | 39 TestExtensionPrefs extension_prefs( |
31 message_loop_.message_loop_proxy().get()); | 40 message_loop_.message_loop_proxy().get()); |
32 | 41 |
33 // Add a couple of devices and make sure we get back public ids for them. | 42 // Add a couple of devices and make sure we get back public ids for them. |
34 std::string extension_name = "test"; | 43 std::string extension_name = "test"; |
35 scoped_refptr<Extension> extension_test = | 44 scoped_refptr<Extension> extension_test = |
36 extension_prefs.AddExtension(extension_name); | 45 extension_prefs.AddExtension(extension_name); |
37 | 46 |
38 DeviceInfo device_info1( | 47 DeviceInfo device_info1( |
39 base::GenerateGUID(), | 48 base::GenerateGUID(), |
40 "abc Device", "XYZ v1", "XYZ SyncAgent v1", | 49 "abc Device", "XYZ v1", "XYZ SyncAgent v1", |
41 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); | 50 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); |
42 | 51 |
43 DeviceInfo device_info2( | 52 DeviceInfo device_info2( |
44 base::GenerateGUID(), | 53 base::GenerateGUID(), |
45 "def Device", "XYZ v2", "XYZ SyncAgent v2", | 54 "def Device", "XYZ v2", "XYZ SyncAgent v2", |
46 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); | 55 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); |
47 | 56 |
48 std::vector<DeviceInfo*> devices; | 57 std::vector<DeviceInfo*> devices; |
49 devices.push_back(&device_info1); | 58 devices.push_back(&device_info1); |
50 devices.push_back(&device_info2); | 59 devices.push_back(&device_info2); |
51 | 60 |
52 EXPECT_CALL(pss_mock, GetAllSignedInDevicesMock()). | 61 EXPECT_CALL(pss_mock, GetAllSignedinDevicesMock()). |
53 WillOnce(Return(&devices)); | 62 WillOnce(Return(&devices)); |
54 | 63 |
55 ScopedVector<DeviceInfo> output1 = GetAllSignedInDevices( | 64 ScopedVector<DeviceInfo> output1 = GetAllSignedinDevices( |
56 extension_test.get()->id(), | 65 extension_test.get()->id(), |
57 &pss_mock, | 66 &pss_mock, |
58 extension_prefs.prefs()); | 67 extension_prefs.prefs()); |
59 | 68 |
60 std::string public_id1 = device_info1.public_id(); | 69 std::string public_id1 = device_info1.public_id(); |
61 std::string public_id2 = device_info2.public_id(); | 70 std::string public_id2 = device_info2.public_id(); |
62 | 71 |
63 EXPECT_FALSE(public_id1.empty()); | 72 EXPECT_FALSE(public_id1.empty()); |
64 EXPECT_FALSE(public_id2.empty()); | 73 EXPECT_FALSE(public_id2.empty()); |
65 EXPECT_NE(public_id1, public_id2); | 74 EXPECT_NE(public_id1, public_id2); |
66 | 75 |
67 // Now clear output1 so its destructor will not destroy the pointers for | 76 // Now clear output1 so its destructor will not destroy the pointers for |
68 // |device_info1| and |device_info2|. | 77 // |device_info1| and |device_info2|. |
69 output1.weak_clear(); | 78 output1.weak_clear(); |
70 | 79 |
71 // Add a third device and make sure the first 2 ids are retained and a new | 80 // Add a third device and make sure the first 2 ids are retained and a new |
72 // id is generated for the third device. | 81 // id is generated for the third device. |
73 DeviceInfo device_info3( | 82 DeviceInfo device_info3( |
74 base::GenerateGUID(), | 83 base::GenerateGUID(), |
75 "def Device", "jkl v2", "XYZ SyncAgent v2", | 84 "def Device", "jkl v2", "XYZ SyncAgent v2", |
76 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); | 85 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); |
77 | 86 |
78 devices.push_back(&device_info3); | 87 devices.push_back(&device_info3); |
79 | 88 |
80 EXPECT_CALL(pss_mock, GetAllSignedInDevicesMock()). | 89 EXPECT_CALL(pss_mock, GetAllSignedinDevicesMock()). |
81 WillOnce(Return(&devices)); | 90 WillOnce(Return(&devices)); |
82 | 91 |
83 ScopedVector<DeviceInfo> output2 = GetAllSignedInDevices( | 92 ScopedVector<DeviceInfo> output2 = GetAllSignedinDevices( |
84 extension_test.get()->id(), | 93 extension_test.get()->id(), |
85 &pss_mock, | 94 &pss_mock, |
86 extension_prefs.prefs()); | 95 extension_prefs.prefs()); |
87 | 96 |
88 EXPECT_EQ(device_info1.public_id(), public_id1); | 97 EXPECT_EQ(device_info1.public_id(), public_id1); |
89 EXPECT_EQ(device_info2.public_id(), public_id2); | 98 EXPECT_EQ(device_info2.public_id(), public_id2); |
90 | 99 |
91 std::string public_id3 = device_info3.public_id(); | 100 std::string public_id3 = device_info3.public_id(); |
92 EXPECT_FALSE(public_id3.empty()); | 101 EXPECT_FALSE(public_id3.empty()); |
93 EXPECT_NE(public_id3, public_id1); | 102 EXPECT_NE(public_id3, public_id1); |
94 EXPECT_NE(public_id3, public_id2); | 103 EXPECT_NE(public_id3, public_id2); |
95 | 104 |
96 // Now clear output2 so that its destructor does not destroy the | 105 // Now clear output2 so that its destructor does not destroy the |
97 // |DeviceInfo| pointers. | 106 // |DeviceInfo| pointers. |
98 output2.weak_clear(); | 107 output2.weak_clear(); |
99 } | 108 } |
100 | 109 |
| 110 class ProfileSyncServiceMockForExtensionTests: |
| 111 public ProfileSyncServiceMock { |
| 112 public: |
| 113 ProfileSyncServiceMockForExtensionTests() {} |
| 114 ~ProfileSyncServiceMockForExtensionTests() {} |
| 115 MOCK_METHOD0(Shutdown, void()); |
| 116 }; |
| 117 |
| 118 BrowserContextKeyedService* CreateProfileSyncServiceMock( |
| 119 content::BrowserContext* profile) { |
| 120 return new ProfileSyncServiceMockForExtensionTests(); |
| 121 } |
| 122 |
| 123 class ExtensionSignedinDevicesTest : public BrowserWithTestWindowTest { |
| 124 public: |
| 125 virtual void SetUp() { |
| 126 BrowserWithTestWindowTest::SetUp(); |
| 127 |
| 128 ProfileSyncServiceFactory::GetInstance()->SetTestingFactory( |
| 129 profile(), CreateProfileSyncServiceMock); |
| 130 |
| 131 extension_ = utils::CreateEmptyExtensionWithLocation( |
| 132 extensions::Manifest::UNPACKED); |
| 133 |
| 134 } |
| 135 |
| 136 base::Value* RunFunctionWithExtension( |
| 137 UIThreadExtensionFunction* function, |
| 138 const std::string& args) { |
| 139 scoped_refptr<UIThreadExtensionFunction> delete_function(function); |
| 140 function->set_extension(extension_.get()); |
| 141 return utils::RunFunctionAndReturnSingleResult(function, args, browser()); |
| 142 } |
| 143 |
| 144 base::ListValue* RunFunctionAndReturnList( |
| 145 UIThreadExtensionFunction* function, |
| 146 const std::string& args) { |
| 147 base::Value* result = RunFunctionWithExtension(function, args); |
| 148 return result ? utils::ToList(result) : NULL; |
| 149 } |
| 150 |
| 151 protected: |
| 152 scoped_refptr<extensions::Extension> extension_; |
| 153 }; |
| 154 |
| 155 DeviceInfo* CreateDeviceInfo(const DeviceInfo& device_info) { |
| 156 return new DeviceInfo(device_info.guid(), |
| 157 device_info.client_name(), |
| 158 device_info.chrome_version(), |
| 159 device_info.sync_user_agent(), |
| 160 device_info.device_type()); |
| 161 } |
| 162 |
| 163 std::string GetPublicId(const base::DictionaryValue* dictionary) { |
| 164 std::string public_id; |
| 165 if (!dictionary->GetString("id", &public_id)) { |
| 166 ADD_FAILURE() << "Not able to find public id in the dictionary"; |
| 167 } |
| 168 |
| 169 return public_id; |
| 170 } |
| 171 |
| 172 void VerifyDictionaryWithDeviceInfo(const base::DictionaryValue* actual_value, |
| 173 DeviceInfo* device_info) { |
| 174 std::string public_id = GetPublicId(actual_value); |
| 175 device_info->set_public_id(public_id); |
| 176 |
| 177 scoped_ptr<base::DictionaryValue> expected_value(device_info->ToValue()); |
| 178 EXPECT_TRUE(expected_value->Equals(actual_value)); |
| 179 } |
| 180 |
| 181 base::DictionaryValue* GetDictionaryFromList(int index, |
| 182 base::ListValue* value) { |
| 183 base::DictionaryValue* dictionary; |
| 184 if (!value->GetDictionary(index, &dictionary)) { |
| 185 ADD_FAILURE() << "Expected a list of dictionaries"; |
| 186 return NULL; |
| 187 } |
| 188 return dictionary; |
| 189 } |
| 190 |
| 191 TEST_F(ExtensionSignedinDevicesTest, GetAll) { |
| 192 ProfileSyncServiceMockForExtensionTests* pss_mock = |
| 193 static_cast<ProfileSyncServiceMockForExtensionTests*>( |
| 194 ProfileSyncServiceFactory::GetForProfile(profile())); |
| 195 |
| 196 DeviceInfo device_info1( |
| 197 base::GenerateGUID(), |
| 198 "abc Device", "XYZ v1", "XYZ SyncAgent v1", |
| 199 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); |
| 200 |
| 201 DeviceInfo device_info2( |
| 202 base::GenerateGUID(), |
| 203 "def Device", "XYZ v2", "XYZ SyncAgent v2", |
| 204 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); |
| 205 |
| 206 std::vector<DeviceInfo*> devices; |
| 207 devices.push_back(CreateDeviceInfo(device_info1)); |
| 208 devices.push_back(CreateDeviceInfo(device_info2)); |
| 209 |
| 210 EXPECT_CALL(*pss_mock, GetAllSignedinDevicesMock()). |
| 211 WillOnce(Return(&devices)); |
| 212 |
| 213 EXPECT_CALL(*pss_mock, Shutdown()); |
| 214 |
| 215 scoped_ptr<base::ListValue> result(RunFunctionAndReturnList( |
| 216 new SignedinDevicesGetFunction(), "[null]")); |
| 217 |
| 218 // Ensure dictionary matches device info. |
| 219 VerifyDictionaryWithDeviceInfo(GetDictionaryFromList(0, result.get()), |
| 220 &device_info1); |
| 221 VerifyDictionaryWithDeviceInfo(GetDictionaryFromList(1, result.get()), |
| 222 &device_info2); |
| 223 |
| 224 // Ensure public ids are set and unique. |
| 225 std::string public_id1 = GetPublicId(GetDictionaryFromList(0, result.get())); |
| 226 std::string public_id2 = GetPublicId(GetDictionaryFromList(1, result.get())); |
| 227 |
| 228 EXPECT_FALSE(public_id1.empty()); |
| 229 EXPECT_FALSE(public_id2.empty()); |
| 230 EXPECT_NE(public_id1, public_id2); |
| 231 } |
| 232 |
101 } // namespace extensions | 233 } // namespace extensions |
OLD | NEW |