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