Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / supervised_user / child_accounts / family_info_fetcher_unittest.cc
blob071902b99391426723ab34f7d6f4c80a8d4e5484
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/base/net_errors.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "net/url_request/url_request_test_util.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 const char kAccountId[] = "user@gmail.com";
22 const char kDifferentAccountId[] = "some_other_user@gmail.com";
23 const int kFamilyInfoFetcherURLFetcherID = 0;
25 bool operator==(const FamilyInfoFetcher::FamilyProfile& family1,
26 const FamilyInfoFetcher::FamilyProfile& family2) {
27 return family1.id == family2.id &&
28 family1.name == family2.name;
31 bool operator==(const FamilyInfoFetcher::FamilyMember& account1,
32 const FamilyInfoFetcher::FamilyMember& account2) {
33 return account1.obfuscated_gaia_id == account2.obfuscated_gaia_id &&
34 account1.role == account2.role &&
35 account1.display_name == account2.display_name &&
36 account1.email == account2.email &&
37 account1.profile_url == account2.profile_url &&
38 account1.profile_image_url == account2.profile_image_url;
41 namespace {
43 std::string BuildGetFamilyProfileResponse(
44 const FamilyInfoFetcher::FamilyProfile& family) {
45 base::DictionaryValue dict;
46 base::DictionaryValue* family_dict = new base::DictionaryValue;
47 family_dict->SetStringWithoutPathExpansion("familyId", family.id);
48 base::DictionaryValue* profile_dict = new base::DictionaryValue;
49 profile_dict->SetStringWithoutPathExpansion("name", family.name);
50 family_dict->SetWithoutPathExpansion("profile", profile_dict);
51 dict.SetWithoutPathExpansion("family", family_dict);
52 std::string result;
53 base::JSONWriter::Write(dict, &result);
54 return result;
57 std::string BuildEmptyGetFamilyProfileResponse() {
58 base::DictionaryValue dict;
59 base::DictionaryValue* family_dict = new base::DictionaryValue;
60 dict.SetWithoutPathExpansion("family", family_dict);
61 std::string result;
62 base::JSONWriter::Write(dict, &result);
63 return result;
66 std::string BuildGetFamilyMembersResponse(
67 const std::vector<FamilyInfoFetcher::FamilyMember>& members) {
68 base::DictionaryValue dict;
69 base::ListValue* list = new base::ListValue;
70 for (size_t i = 0; i < members.size(); i++) {
71 const FamilyInfoFetcher::FamilyMember& member = members[i];
72 base::DictionaryValue* member_dict = new base::DictionaryValue;
73 member_dict->SetStringWithoutPathExpansion("userId",
74 member.obfuscated_gaia_id);
75 member_dict->SetStringWithoutPathExpansion(
76 "role", FamilyInfoFetcher::RoleToString(member.role));
77 if (!member.display_name.empty() ||
78 !member.email.empty() ||
79 !member.profile_url.empty() ||
80 !member.profile_image_url.empty()) {
81 base::DictionaryValue* profile_dict = new base::DictionaryValue;
82 if (!member.display_name.empty())
83 profile_dict->SetStringWithoutPathExpansion("displayName",
84 member.display_name);
85 if (!member.email.empty())
86 profile_dict->SetStringWithoutPathExpansion("email",
87 member.email);
88 if (!member.profile_url.empty())
89 profile_dict->SetStringWithoutPathExpansion("profileUrl",
90 member.profile_url);
91 if (!member.profile_image_url.empty())
92 profile_dict->SetStringWithoutPathExpansion("profileImageUrl",
93 member.profile_image_url);
95 member_dict->SetWithoutPathExpansion("profile", profile_dict);
97 list->Append(member_dict);
99 dict.SetWithoutPathExpansion("members", list);
100 std::string result;
101 base::JSONWriter::Write(dict, &result);
102 return result;
105 } // namespace
107 class FamilyInfoFetcherTest : public testing::Test,
108 public FamilyInfoFetcher::Consumer {
109 public:
110 FamilyInfoFetcherTest()
111 : request_context_(new net::TestURLRequestContextGetter(
112 base::ThreadTaskRunnerHandle::Get())),
113 fetcher_(this, kAccountId, &token_service_, request_context_.get()) {}
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));
122 protected:
123 void IssueRefreshToken() {
124 token_service_.UpdateCredentials(kAccountId, "refresh_token");
127 void IssueRefreshTokenForDifferentAccount() {
128 token_service_.UpdateCredentials(kDifferentAccountId, "refresh_token");
131 void IssueAccessToken() {
132 token_service_.IssueAllTokensForAccount(
133 kAccountId,
134 "access_token",
135 base::Time::Now() + base::TimeDelta::FromHours(1));
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;
146 void SendResponse(net::Error error, const std::string& response) {
147 net::TestURLFetcher* url_fetcher = GetURLFetcher();
148 url_fetcher->set_status(net::URLRequestStatus::FromError(error));
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::OK, BuildGetFamilyProfileResponse(family));
159 void SendValidGetFamilyMembersResponse(
160 const std::vector<FamilyInfoFetcher::FamilyMember>& members) {
161 SendResponse(net::OK, BuildGetFamilyMembersResponse(members));
164 void SendInvalidGetFamilyProfileResponse() {
165 SendResponse(net::OK, BuildEmptyGetFamilyProfileResponse());
168 void SendFailedResponse() {
169 SendResponse(net::ERR_ABORTED, std::string());
172 base::MessageLoop message_loop_;
173 FakeProfileOAuth2TokenService token_service_;
174 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
175 net::TestURLFetcherFactory url_fetcher_factory_;
176 FamilyInfoFetcher fetcher_;
180 TEST_F(FamilyInfoFetcherTest, GetFamilyProfileSuccess) {
181 IssueRefreshToken();
183 fetcher_.StartGetFamilyProfile();
185 // Since a refresh token is already available, we should immediately get a
186 // request for an access token.
187 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
189 IssueAccessToken();
191 FamilyInfoFetcher::FamilyProfile family("test", "My Test Family");
192 EXPECT_CALL(*this, OnGetFamilyProfileSuccess(family));
193 SendValidGetFamilyProfileResponse(family);
196 TEST_F(FamilyInfoFetcherTest, GetFamilyMembersSuccess) {
197 IssueRefreshToken();
199 fetcher_.StartGetFamilyMembers();
201 // Since a refresh token is already available, we should immediately get a
202 // request for an access token.
203 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
205 IssueAccessToken();
207 std::vector<FamilyInfoFetcher::FamilyMember> members;
208 members.push_back(
209 FamilyInfoFetcher::FamilyMember("someObfuscatedGaiaId",
210 FamilyInfoFetcher::HEAD_OF_HOUSEHOLD,
211 "Homer Simpson",
212 "homer@simpson.com",
213 "http://profile.url/homer",
214 "http://profile.url/homer/image"));
215 members.push_back(
216 FamilyInfoFetcher::FamilyMember("anotherObfuscatedGaiaId",
217 FamilyInfoFetcher::PARENT,
218 "Marge Simpson",
219 std::string(),
220 "http://profile.url/marge",
221 std::string()));
222 members.push_back(
223 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId3",
224 FamilyInfoFetcher::CHILD,
225 "Lisa Simpson",
226 "lisa@gmail.com",
227 std::string(),
228 "http://profile.url/lisa/image"));
229 members.push_back(
230 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId4",
231 FamilyInfoFetcher::CHILD,
232 "Bart Simpson",
233 "bart@bart.bart",
234 std::string(),
235 std::string()));
236 members.push_back(
237 FamilyInfoFetcher::FamilyMember("obfuscatedGaiaId5",
238 FamilyInfoFetcher::MEMBER,
239 std::string(),
240 std::string(),
241 std::string(),
242 std::string()));
244 EXPECT_CALL(*this, OnGetFamilyMembersSuccess(members));
245 SendValidGetFamilyMembersResponse(members);
249 TEST_F(FamilyInfoFetcherTest, SuccessAfterWaitingForRefreshToken) {
250 fetcher_.StartGetFamilyProfile();
252 // Since there is no refresh token yet, we should not get a request for an
253 // access token at this point.
254 EXPECT_EQ(0U, token_service_.GetPendingRequests().size());
256 IssueRefreshToken();
258 // Now there is a refresh token and we should have got a request for an
259 // access token.
260 EXPECT_EQ(1U, token_service_.GetPendingRequests().size());
262 IssueAccessToken();
264 FamilyInfoFetcher::FamilyProfile family("test", "My Test Family");
265 EXPECT_CALL(*this, OnGetFamilyProfileSuccess(family));
266 SendValidGetFamilyProfileResponse(family);
269 TEST_F(FamilyInfoFetcherTest, NoRefreshToken) {
270 fetcher_.StartGetFamilyProfile();
272 IssueRefreshTokenForDifferentAccount();
274 // Credentials for a different user should be ignored, i.e. not result in a
275 // request for an access token.
276 EXPECT_EQ(0U, token_service_.GetPendingRequests().size());
278 // After all refresh tokens have been loaded, there is still no token for our
279 // user, so we expect a token error.
280 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::TOKEN_ERROR));
281 token_service_.LoadCredentials("");
284 TEST_F(FamilyInfoFetcherTest, GetTokenFailure) {
285 IssueRefreshToken();
287 fetcher_.StartGetFamilyProfile();
289 // On failure to get an access token we expect a token error.
290 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::TOKEN_ERROR));
291 token_service_.IssueErrorForAllPendingRequestsForAccount(
292 kAccountId,
293 GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
296 TEST_F(FamilyInfoFetcherTest, InvalidResponse) {
297 IssueRefreshToken();
299 fetcher_.StartGetFamilyProfile();
301 IssueAccessToken();
303 // Invalid response data should result in a service error.
304 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::SERVICE_ERROR));
305 SendInvalidGetFamilyProfileResponse();
308 TEST_F(FamilyInfoFetcherTest, FailedResponse) {
309 IssueRefreshToken();
311 fetcher_.StartGetFamilyProfile();
313 IssueAccessToken();
315 // Failed API call should result in a network error.
316 EXPECT_CALL(*this, OnFailure(FamilyInfoFetcher::NETWORK_ERROR));
317 SendFailedResponse();