Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / supervised_user / child_accounts / family_info_fetcher_unittest.cc
blobdb2800fd903c9f2bc3d97338a091e411fb5004a0
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.
5 #include <string>
6 #include <vector>
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/thread_task_runner_handle.h"
12 #include "base/values.h"
13 #include "chrome/browser/supervised_user/child_accounts/family_info_fetcher.h"
14 #include "components/signin/core/browser/fake_profile_oauth2_token_service.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"
20 const char kAccountId[] = "user@gmail.com";
21 const char kDifferentAccountId[] = "some_other_user@gmail.com";
22 const int kFamilyInfoFetcherURLFetcherID = 0;
24 bool operator==(const FamilyInfoFetcher::FamilyProfile& family1,
25 const FamilyInfoFetcher::FamilyProfile& family2) {
26 return family1.id == family2.id &&
27 family1.name == family2.name;
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;
40 namespace {
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;
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;
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);
94 member_dict->SetWithoutPathExpansion("profile", profile_dict);
96 list->Append(member_dict);
98 dict.SetWithoutPathExpansion("members", list);
99 std::string result;
100 base::JSONWriter::Write(dict, &result);
101 return result;
104 } // namespace
106 class FamilyInfoFetcherTest : public testing::Test,
107 public FamilyInfoFetcher::Consumer {
108 public:
109 FamilyInfoFetcherTest()
110 : request_context_(new net::TestURLRequestContextGetter(
111 base::ThreadTaskRunnerHandle::Get())),
112 fetcher_(this, kAccountId, &token_service_, request_context_.get()) {}
114 MOCK_METHOD1(OnGetFamilyProfileSuccess,
115 void(const FamilyInfoFetcher::FamilyProfile& family));
116 MOCK_METHOD1(OnGetFamilyMembersSuccess,
117 void(const std::vector<FamilyInfoFetcher::FamilyMember>&
118 members));
119 MOCK_METHOD1(OnFailure, void(FamilyInfoFetcher::ErrorCode error));
121 protected:
122 void IssueRefreshToken() {
123 token_service_.UpdateCredentials(kAccountId, "refresh_token");
126 void IssueRefreshTokenForDifferentAccount() {
127 token_service_.UpdateCredentials(kDifferentAccountId, "refresh_token");
130 void IssueAccessToken() {
131 token_service_.IssueAllTokensForAccount(
132 kAccountId,
133 "access_token",
134 base::Time::Now() + base::TimeDelta::FromHours(1));
137 net::TestURLFetcher* GetURLFetcher() {
138 net::TestURLFetcher* url_fetcher =
139 url_fetcher_factory_.GetFetcherByID(
140 kFamilyInfoFetcherURLFetcherID);
141 EXPECT_TRUE(url_fetcher);
142 return url_fetcher;
145 void SendResponse(net::URLRequestStatus::Status status,
146 const std::string& response) {
147 net::TestURLFetcher* url_fetcher = GetURLFetcher();
148 url_fetcher->set_status(net::URLRequestStatus(status, 0));
149 url_fetcher->set_response_code(net::HTTP_OK);
150 url_fetcher->SetResponseString(response);
151 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
154 void SendValidGetFamilyProfileResponse(
155 const FamilyInfoFetcher::FamilyProfile& family) {
156 SendResponse(net::URLRequestStatus::SUCCESS,
157 BuildGetFamilyProfileResponse(family));
160 void SendValidGetFamilyMembersResponse(
161 const std::vector<FamilyInfoFetcher::FamilyMember>& members) {
162 SendResponse(net::URLRequestStatus::SUCCESS,
163 BuildGetFamilyMembersResponse(members));
166 void SendInvalidGetFamilyProfileResponse() {
167 SendResponse(net::URLRequestStatus::SUCCESS,
168 BuildEmptyGetFamilyProfileResponse());
171 void SendFailedResponse() {
172 SendResponse(net::URLRequestStatus::CANCELED, std::string());
175 base::MessageLoop message_loop_;
176 FakeProfileOAuth2TokenService token_service_;
177 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
178 net::TestURLFetcherFactory url_fetcher_factory_;
179 FamilyInfoFetcher fetcher_;
183 TEST_F(FamilyInfoFetcherTest, GetFamilyProfileSuccess) {
184 IssueRefreshToken();
186 fetcher_.StartGetFamilyProfile();
188 // Since a refresh token is already available, we should immediately get a
189 // request for an access token.
190 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
192 IssueAccessToken();
194 FamilyInfoFetcher::FamilyProfile family("test", "My Test Family");
195 EXPECT_CALL(*this, OnGetFamilyProfileSuccess(family));
196 SendValidGetFamilyProfileResponse(family);
199 TEST_F(FamilyInfoFetcherTest, GetFamilyMembersSuccess) {
200 IssueRefreshToken();
202 fetcher_.StartGetFamilyMembers();
204 // Since a refresh token is already available, we should immediately get a
205 // request for an access token.
206 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
208 IssueAccessToken();
210 std::vector<FamilyInfoFetcher::FamilyMember> members;
211 members.push_back(
212 FamilyInfoFetcher::FamilyMember("someObfuscatedGaiaId",
213 FamilyInfoFetcher::HEAD_OF_HOUSEHOLD,
214 "Homer Simpson",
215 "homer@simpson.com",
216 "http://profile.url/homer",
217 "http://profile.url/homer/image"));
218 members.push_back(
219 FamilyInfoFetcher::FamilyMember("anotherObfuscatedGaiaId",
220 FamilyInfoFetcher::PARENT,
221 "Marge Simpson",
222 std::string(),
223 "http://profile.url/marge",
224 std::string()));
225 members.push_back(
226 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId3",
227 FamilyInfoFetcher::CHILD,
228 "Lisa Simpson",
229 "lisa@gmail.com",
230 std::string(),
231 "http://profile.url/lisa/image"));
232 members.push_back(
233 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId4",
234 FamilyInfoFetcher::CHILD,
235 "Bart Simpson",
236 "bart@bart.bart",
237 std::string(),
238 std::string()));
239 members.push_back(
240 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId5",
241 FamilyInfoFetcher::MEMBER,
242 std::string(),
243 std::string(),
244 std::string(),
245 std::string()));
247 EXPECT_CALL(*this, OnGetFamilyMembersSuccess(members));
248 SendValidGetFamilyMembersResponse(members);
252 TEST_F(FamilyInfoFetcherTest, SuccessAfterWaitingForRefreshToken) {
253 fetcher_.StartGetFamilyProfile();
255 // Since there is no refresh token yet, we should not get a request for an
256 // access token at this point.
257 EXPECT_EQ(0U, token_service_.GetPendingRequests().size());
259 IssueRefreshToken();
261 // Now there is a refresh token and we should have got a request for an
262 // access token.
263 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
265 IssueAccessToken();
267 FamilyInfoFetcher::FamilyProfile family("test", "My Test Family");
268 EXPECT_CALL(*this, OnGetFamilyProfileSuccess(family));
269 SendValidGetFamilyProfileResponse(family);
272 TEST_F(FamilyInfoFetcherTest, NoRefreshToken) {
273 fetcher_.StartGetFamilyProfile();
275 IssueRefreshTokenForDifferentAccount();
277 // Credentials for a different user should be ignored, i.e. not result in a
278 // request for an access token.
279 EXPECT_EQ(0U, token_service_.GetPendingRequests().size());
281 // After all refresh tokens have been loaded, there is still no token for our
282 // user, so we expect a token error.
283 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::TOKEN_ERROR));
284 token_service_.LoadCredentials("");
287 TEST_F(FamilyInfoFetcherTest, GetTokenFailure) {
288 IssueRefreshToken();
290 fetcher_.StartGetFamilyProfile();
292 // On failure to get an access token we expect a token error.
293 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::TOKEN_ERROR));
294 token_service_.IssueErrorForAllPendingRequestsForAccount(
295 kAccountId,
296 GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
299 TEST_F(FamilyInfoFetcherTest, InvalidResponse) {
300 IssueRefreshToken();
302 fetcher_.StartGetFamilyProfile();
304 IssueAccessToken();
306 // Invalid response data should result in a service error.
307 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::SERVICE_ERROR));
308 SendInvalidGetFamilyProfileResponse();
311 TEST_F(FamilyInfoFetcherTest, FailedResponse) {
312 IssueRefreshToken();
314 fetcher_.StartGetFamilyProfile();
316 IssueAccessToken();
318 // Failed API call should result in a network error.
319 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::NETWORK_ERROR));
320 SendFailedResponse();