signed_in_devices_api_unittest.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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 <string> 6 7#include <vector> 8 9#include "base/guid.h" 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_function_test_utils.h" 15#include "chrome/browser/extensions/test_extension_prefs.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/browser/sync/glue/device_info.h" 18#include "chrome/browser/sync/profile_sync_service_factory.h" 19#include "chrome/browser/sync/profile_sync_service_mock.h" 20#include "chrome/common/extensions/extension.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" 24#include "testing/gmock/include/gmock/gmock.h" 25#include "testing/gtest/include/gtest/gtest.h" 26 27using extensions::Extension; 28using extensions::TestExtensionPrefs; 29using browser_sync::DeviceInfo; 30using testing::Return; 31 32namespace extensions { 33 34namespace utils = extension_function_test_utils; 35 36TEST(SignedInDevicesAPITest, GetSignedInDevices) { 37 ProfileSyncServiceMock pss_mock; 38 base::MessageLoop message_loop_; 39 TestExtensionPrefs extension_prefs( 40 message_loop_.message_loop_proxy().get()); 41 42 // Add a couple of devices and make sure we get back public ids for them. 43 std::string extension_name = "test"; 44 scoped_refptr<Extension> extension_test = 45 extension_prefs.AddExtension(extension_name); 46 47 DeviceInfo device_info1( 48 base::GenerateGUID(), 49 "abc Device", "XYZ v1", "XYZ SyncAgent v1", 50 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); 51 52 DeviceInfo device_info2( 53 base::GenerateGUID(), 54 "def Device", "XYZ v2", "XYZ SyncAgent v2", 55 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); 56 57 std::vector<DeviceInfo*> devices; 58 devices.push_back(&device_info1); 59 devices.push_back(&device_info2); 60 61 EXPECT_CALL(pss_mock, GetAllSignedInDevicesMock()). 62 WillOnce(Return(&devices)); 63 64 ScopedVector<DeviceInfo> output1 = GetAllSignedInDevices( 65 extension_test.get()->id(), 66 &pss_mock, 67 extension_prefs.prefs()); 68 69 std::string public_id1 = device_info1.public_id(); 70 std::string public_id2 = device_info2.public_id(); 71 72 EXPECT_FALSE(public_id1.empty()); 73 EXPECT_FALSE(public_id2.empty()); 74 EXPECT_NE(public_id1, public_id2); 75 76 // Now clear output1 so its destructor will not destroy the pointers for 77 // |device_info1| and |device_info2|. 78 output1.weak_clear(); 79 80 // Add a third device and make sure the first 2 ids are retained and a new 81 // id is generated for the third device. 82 DeviceInfo device_info3( 83 base::GenerateGUID(), 84 "def Device", "jkl v2", "XYZ SyncAgent v2", 85 sync_pb::SyncEnums_DeviceType_TYPE_LINUX); 86 87 devices.push_back(&device_info3); 88 89 EXPECT_CALL(pss_mock, GetAllSignedInDevicesMock()). 90 WillOnce(Return(&devices)); 91 92 ScopedVector<DeviceInfo> output2 = GetAllSignedInDevices( 93 extension_test.get()->id(), 94 &pss_mock, 95 extension_prefs.prefs()); 96 97 EXPECT_EQ(device_info1.public_id(), public_id1); 98 EXPECT_EQ(device_info2.public_id(), public_id2); 99 100 std::string public_id3 = device_info3.public_id(); 101 EXPECT_FALSE(public_id3.empty()); 102 EXPECT_NE(public_id3, public_id1); 103 EXPECT_NE(public_id3, public_id2); 104 105 // Now clear output2 so that its destructor does not destroy the 106 // |DeviceInfo| pointers. 107 output2.weak_clear(); 108} 109 110class ProfileSyncServiceMockForExtensionTests: 111 public ProfileSyncServiceMock { 112 public: 113 ProfileSyncServiceMockForExtensionTests() {} 114 ~ProfileSyncServiceMockForExtensionTests() {} 115 MOCK_METHOD0(Shutdown, void()); 116}; 117 118BrowserContextKeyedService* CreateProfileSyncServiceMock( 119 content::BrowserContext* profile) { 120 return new ProfileSyncServiceMockForExtensionTests(); 121} 122 123class 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 155DeviceInfo* 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 163std::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 172void 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 181base::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 191TEST_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 233} // namespace extensions 234