Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc

Issue 783083002: Add support for child accounts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove CrOS for now Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 #include <vector>
7
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/values.h"
13 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
14 #include "chrome/browser/supervised_user/child_accounts/family_info_fetcher.h"
15 #include "net/url_request/test_url_fetcher_factory.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 const char kAccountId[] = "user@gmail.com";
21 const char kDifferentAccountId[] = "some_other_user@gmail.com";
22 const int kFamilyInfoFetcherURLFetcherID = 0;
23
24 bool operator==(const FamilyInfoFetcher::FamilyProfile& family1,
25 const FamilyInfoFetcher::FamilyProfile& family2) {
26 return family1.id == family2.id &&
27 family1.name == family2.name;
28 }
29
30 bool operator==(const FamilyInfoFetcher::FamilyMember& account1,
31 const FamilyInfoFetcher::FamilyMember& account2) {
32 return account1.obfuscated_gaia_id == account2.obfuscated_gaia_id &&
33 account1.role == account2.role &&
34 account1.display_name == account2.display_name &&
35 account1.email == account2.email &&
36 account1.profile_url == account2.profile_url &&
37 account1.profile_image_url == account2.profile_image_url;
38 }
39
40 namespace {
41
42 std::string BuildGetFamilyProfileResponse(
43 const FamilyInfoFetcher::FamilyProfile& family) {
44 base::DictionaryValue dict;
45 base::DictionaryValue* family_dict = new base::DictionaryValue;
46 family_dict->SetStringWithoutPathExpansion("familyId", family.id);
47 base::DictionaryValue* profile_dict = new base::DictionaryValue;
48 profile_dict->SetStringWithoutPathExpansion("name", family.name);
49 family_dict->SetWithoutPathExpansion("profile", profile_dict);
50 dict.SetWithoutPathExpansion("family", family_dict);
51 std::string result;
52 base::JSONWriter::Write(&dict, &result);
53 return result;
54 }
55
56 std::string BuildEmptyGetFamilyProfileResponse() {
57 base::DictionaryValue dict;
58 base::DictionaryValue* family_dict = new base::DictionaryValue;
59 dict.SetWithoutPathExpansion("family", family_dict);
60 std::string result;
61 base::JSONWriter::Write(&dict, &result);
62 return result;
63 }
64
65 std::string BuildGetFamilyMembersResponse(
66 const std::vector<FamilyInfoFetcher::FamilyMember>& members) {
67 base::DictionaryValue dict;
68 base::ListValue* list = new base::ListValue;
69 for (size_t i = 0; i < members.size(); i++) {
70 const FamilyInfoFetcher::FamilyMember& member = members[i];
71 base::DictionaryValue* member_dict = new base::DictionaryValue;
72 member_dict->SetStringWithoutPathExpansion("userId",
73 member.obfuscated_gaia_id);
74 member_dict->SetStringWithoutPathExpansion(
75 "role", FamilyInfoFetcher::RoleToString(member.role));
76 if (!member.display_name.empty() ||
77 !member.email.empty() ||
78 !member.profile_url.empty() ||
79 !member.profile_image_url.empty()) {
80 base::DictionaryValue* profile_dict = new base::DictionaryValue;
81 if (!member.display_name.empty())
82 profile_dict->SetStringWithoutPathExpansion("displayName",
83 member.display_name);
84 if (!member.email.empty())
85 profile_dict->SetStringWithoutPathExpansion("email",
86 member.email);
87 if (!member.profile_url.empty())
88 profile_dict->SetStringWithoutPathExpansion("profileUrl",
89 member.profile_url);
90 if (!member.profile_image_url.empty())
91 profile_dict->SetStringWithoutPathExpansion("profileImageUrl",
92 member.profile_image_url);
93
94 member_dict->SetWithoutPathExpansion("profile", profile_dict);
95 }
96 list->Append(member_dict);
97 }
98 dict.SetWithoutPathExpansion("members", list);
99 std::string result;
100 base::JSONWriter::Write(&dict, &result);
101 return result;
102 }
103
104 } // namespace
105
106 class FamilyInfoFetcherTest : public testing::Test,
107 public FamilyInfoFetcher::Consumer {
108 public:
109 FamilyInfoFetcherTest()
110 : request_context_(new net::TestURLRequestContextGetter(
111 base::MessageLoopProxy::current())),
112 fetcher_(this, kAccountId, &token_service_, request_context_.get()) {
113 }
114
115 MOCK_METHOD1(OnGetFamilyProfileSuccess,
116 void(const FamilyInfoFetcher::FamilyProfile& family));
117 MOCK_METHOD1(OnGetFamilyMembersSuccess,
118 void(const std::vector<FamilyInfoFetcher::FamilyMember>&
119 members));
120 MOCK_METHOD1(OnFailure, void(FamilyInfoFetcher::ErrorCode error));
121
122 protected:
123 void IssueRefreshToken() {
124 token_service_.UpdateCredentials(kAccountId, "refresh_token");
125 }
126
127 void IssueRefreshTokenForDifferentAccount() {
128 token_service_.UpdateCredentials(kDifferentAccountId, "refresh_token");
129 }
130
131 void IssueAccessToken() {
132 token_service_.IssueAllTokensForAccount(
133 kAccountId,
134 "access_token",
135 base::Time::Now() + base::TimeDelta::FromHours(1));
136 }
137
138 net::TestURLFetcher* GetURLFetcher() {
139 net::TestURLFetcher* url_fetcher =
140 url_fetcher_factory_.GetFetcherByID(
141 kFamilyInfoFetcherURLFetcherID);
142 EXPECT_TRUE(url_fetcher);
143 return url_fetcher;
144 }
145
146 void SendResponse(net::URLRequestStatus::Status status,
147 const std::string& response) {
148 net::TestURLFetcher* url_fetcher = GetURLFetcher();
149 url_fetcher->set_status(net::URLRequestStatus(status, 0));
150 url_fetcher->set_response_code(net::HTTP_OK);
151 url_fetcher->SetResponseString(response);
152 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
153 }
154
155 void SendValidGetFamilyProfileResponse(
156 const FamilyInfoFetcher::FamilyProfile& family) {
157 SendResponse(net::URLRequestStatus::SUCCESS,
158 BuildGetFamilyProfileResponse(family));
159 }
160
161 void SendValidGetFamilyMembersResponse(
162 const std::vector<FamilyInfoFetcher::FamilyMember>& members) {
163 SendResponse(net::URLRequestStatus::SUCCESS,
164 BuildGetFamilyMembersResponse(members));
165 }
166
167 void SendInvalidGetFamilyProfileResponse() {
168 SendResponse(net::URLRequestStatus::SUCCESS,
169 BuildEmptyGetFamilyProfileResponse());
170 }
171
172 void SendFailedResponse() {
173 SendResponse(net::URLRequestStatus::CANCELED, std::string());
174 }
175
176 base::MessageLoop message_loop_;
177 FakeProfileOAuth2TokenService token_service_;
178 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
179 net::TestURLFetcherFactory url_fetcher_factory_;
180 FamilyInfoFetcher fetcher_;
181 };
182
183
184 TEST_F(FamilyInfoFetcherTest, GetFamilyProfileSuccess) {
185 IssueRefreshToken();
186
187 fetcher_.StartGetFamilyProfile();
188
189 // Since a refresh token is already available, we should immediately get a
190 // request for an access token.
191 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
192
193 IssueAccessToken();
194
195 FamilyInfoFetcher::FamilyProfile family("test", "My Test Family");
196 EXPECT_CALL(*this, OnGetFamilyProfileSuccess(family));
197 SendValidGetFamilyProfileResponse(family);
198 }
199
200 TEST_F(FamilyInfoFetcherTest, GetFamilyMembersSuccess) {
201 IssueRefreshToken();
202
203 fetcher_.StartGetFamilyMembers();
204
205 // Since a refresh token is already available, we should immediately get a
206 // request for an access token.
207 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
208
209 IssueAccessToken();
210
211 std::vector<FamilyInfoFetcher::FamilyMember> members;
212 members.push_back(
213 FamilyInfoFetcher::FamilyMember("someObfuscatedGaiaId",
214 FamilyInfoFetcher::HEAD_OF_HOUSEHOLD,
215 "Homer Simpson",
216 "homer@simpson.com",
217 "http://profile.url/homer",
218 "http://profile.url/homer/image"));
219 members.push_back(
220 FamilyInfoFetcher::FamilyMember("anotherObfuscatedGaiaId",
221 FamilyInfoFetcher::PARENT,
222 "Marge Simpson",
223 std::string(),
224 "http://profile.url/marge",
225 std::string()));
226 members.push_back(
227 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId3",
228 FamilyInfoFetcher::CHILD,
229 "Lisa Simpson",
230 "lisa@gmail.com",
231 std::string(),
232 "http://profile.url/lisa/image"));
233 members.push_back(
234 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId4",
235 FamilyInfoFetcher::CHILD,
236 "Bart Simpson",
237 "bart@bart.bart",
238 std::string(),
239 std::string()));
240 members.push_back(
241 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId5",
242 FamilyInfoFetcher::MEMBER,
243 std::string(),
244 std::string(),
245 std::string(),
246 std::string()));
247
248 EXPECT_CALL(*this, OnGetFamilyMembersSuccess(members));
249 SendValidGetFamilyMembersResponse(members);
250 }
251
252
253 TEST_F(FamilyInfoFetcherTest, SuccessAfterWaitingForRefreshToken) {
254 fetcher_.StartGetFamilyProfile();
255
256 // Since there is no refresh token yet, we should not get a request for an
257 // access token at this point.
258 EXPECT_EQ(0U, token_service_.GetPendingRequests().size());
259
260 IssueRefreshToken();
261
262 // Now there is a refresh token and we should have got a request for an
263 // access token.
264 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
265
266 IssueAccessToken();
267
268 FamilyInfoFetcher::FamilyProfile family("test", "My Test Family");
269 EXPECT_CALL(*this, OnGetFamilyProfileSuccess(family));
270 SendValidGetFamilyProfileResponse(family);
271 }
272
273 TEST_F(FamilyInfoFetcherTest, NoRefreshToken) {
274 fetcher_.StartGetFamilyProfile();
275
276 IssueRefreshTokenForDifferentAccount();
277
278 // Credentials for a different user should be ignored, i.e. not result in a
279 // request for an access token.
280 EXPECT_EQ(0U, token_service_.GetPendingRequests().size());
281
282 // After all refresh tokens have been loaded, there is still no token for our
283 // user, so we expect a token error.
284 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::TOKEN_ERROR));
285 token_service_.IssueAllRefreshTokensLoaded();
286 }
287
288 TEST_F(FamilyInfoFetcherTest, GetTokenFailure) {
289 IssueRefreshToken();
290
291 fetcher_.StartGetFamilyProfile();
292
293 // On failure to get an access token we expect a token error.
294 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::TOKEN_ERROR));
295 token_service_.IssueErrorForAllPendingRequestsForAccount(
296 kAccountId,
297 GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
298 }
299
300 TEST_F(FamilyInfoFetcherTest, InvalidResponse) {
301 IssueRefreshToken();
302
303 fetcher_.StartGetFamilyProfile();
304
305 IssueAccessToken();
306
307 // Invalid response data should result in a service error.
308 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::SERVICE_ERROR));
309 SendInvalidGetFamilyProfileResponse();
310 }
311
312 TEST_F(FamilyInfoFetcherTest, FailedResponse) {
313 IssueRefreshToken();
314
315 fetcher_.StartGetFamilyProfile();
316
317 IssueAccessToken();
318
319 // Failed API call should result in a network error.
320 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::NETWORK_ERROR));
321 SendFailedResponse();
322 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698