Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / upload_job_unittest.cc
blob76eca09364ffb261a6af27e75629194e3a56cccd
1 // Copyright (c) 2015 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 "chrome/browser/chromeos/policy/upload_job.h"
7 #include <queue>
8 #include <set>
9 #include <utility>
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/location.h"
14 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "base/time/time.h"
18 #include "chrome/browser/chromeos/policy/upload_job_impl.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "google_apis/gaia/fake_oauth2_token_service.h"
21 #include "google_apis/gaia/google_service_auth_error.h"
22 #include "net/http/http_status_code.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "net/test/embedded_test_server/http_request.h"
25 #include "net/test/embedded_test_server/http_response.h"
26 #include "net/url_request/url_request_test_util.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 namespace policy {
31 namespace {
33 const char kUploadPath[] = "/upload";
34 const char kRobotAccountId[] = "robot@gmail.com";
35 const char kCustomField1[] = "customfield1";
36 const char kCustomField2[] = "customfield2";
37 const char kTestPayload1[] = "**||--||PAYLOAD1||--||**";
38 const char kTestPayload2[] = "**||--||PAYLOAD2||--||**";
39 const char kTokenExpired[] = "EXPIRED_TOKEN";
40 const char kTokenInvalid[] = "INVALID_TOKEN";
41 const char kTokenValid[] = "VALID_TOKEN";
43 class RepeatingMimeBoundaryGenerator
44 : public UploadJobImpl::MimeBoundaryGenerator {
45 public:
46 explicit RepeatingMimeBoundaryGenerator(char character)
47 : character_(character) {}
48 ~RepeatingMimeBoundaryGenerator() override {}
50 // MimeBoundaryGenerator:
51 std::string GenerateBoundary(size_t length) const override {
52 return std::string(length, character_);
55 private:
56 const char character_;
58 DISALLOW_COPY_AND_ASSIGN(RepeatingMimeBoundaryGenerator);
61 class MockOAuth2TokenService : public FakeOAuth2TokenService {
62 public:
63 MockOAuth2TokenService();
64 ~MockOAuth2TokenService() override;
66 // OAuth2TokenService:
67 void FetchOAuth2Token(RequestImpl* request,
68 const std::string& account_id,
69 net::URLRequestContextGetter* getter,
70 const std::string& client_id,
71 const std::string& client_secret,
72 const ScopeSet& scopes) override;
74 // OAuth2TokenService:
75 void InvalidateAccessTokenImpl(const std::string& account_id,
76 const std::string& client_id,
77 const ScopeSet& scopes,
78 const std::string& access_token) override;
80 void AddTokenToQueue(const std::string& token);
81 bool IsTokenValid(const std::string& token) const;
82 void SetTokenValid(const std::string& token);
83 void SetTokenInvalid(const std::string& token);
85 private:
86 std::queue<std::string> token_replies_;
87 std::set<std::string> valid_tokens_;
89 DISALLOW_COPY_AND_ASSIGN(MockOAuth2TokenService);
92 MockOAuth2TokenService::MockOAuth2TokenService() {
95 MockOAuth2TokenService::~MockOAuth2TokenService() {
98 void MockOAuth2TokenService::FetchOAuth2Token(
99 OAuth2TokenService::RequestImpl* request,
100 const std::string& account_id,
101 net::URLRequestContextGetter* getter,
102 const std::string& client_id,
103 const std::string& client_secret,
104 const FakeOAuth2TokenService::ScopeSet& scopes) {
105 GoogleServiceAuthError response_error =
106 GoogleServiceAuthError::AuthErrorNone();
107 const base::Time response_expiration = base::Time::Now();
108 std::string access_token;
109 if (token_replies_.empty()) {
110 response_error =
111 GoogleServiceAuthError::FromServiceError("Service unavailable.");
112 } else {
113 access_token = token_replies_.front();
114 token_replies_.pop();
116 base::ThreadTaskRunnerHandle::Get()->PostTask(
117 FROM_HERE, base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer,
118 request->AsWeakPtr(), response_error, access_token,
119 response_expiration));
122 void MockOAuth2TokenService::AddTokenToQueue(const std::string& token) {
123 token_replies_.push(token);
126 bool MockOAuth2TokenService::IsTokenValid(const std::string& token) const {
127 return valid_tokens_.find(token) != valid_tokens_.end();
130 void MockOAuth2TokenService::SetTokenValid(const std::string& token) {
131 valid_tokens_.insert(token);
134 void MockOAuth2TokenService::SetTokenInvalid(const std::string& token) {
135 valid_tokens_.erase(token);
138 void MockOAuth2TokenService::InvalidateAccessTokenImpl(
139 const std::string& account_id,
140 const std::string& client_id,
141 const ScopeSet& scopes,
142 const std::string& access_token) {
143 SetTokenInvalid(access_token);
146 } // namespace
148 class UploadJobTestBase : public testing::Test, public UploadJob::Delegate {
149 public:
150 UploadJobTestBase()
151 : test_browser_thread_bundle_(
152 content::TestBrowserThreadBundle::IO_MAINLOOP) {}
154 // policy::UploadJob::Delegate:
155 void OnSuccess() override {
156 if (!expected_error_)
157 run_loop_.Quit();
158 else
159 FAIL();
162 // policy::UploadJob::Delegate:
163 void OnFailure(UploadJob::ErrorCode error_code) override {
164 if (expected_error_ && *expected_error_.get() == error_code)
165 run_loop_.Quit();
166 else
167 FAIL();
170 const GURL GetServerURL() const { return test_server_.GetURL(kUploadPath); }
172 void SetExpectedError(scoped_ptr<UploadJob::ErrorCode> expected_error) {
173 expected_error_ = expected_error.Pass();
176 // testing::Test:
177 void SetUp() override {
178 request_context_getter_ = new net::TestURLRequestContextGetter(
179 base::ThreadTaskRunnerHandle::Get());
180 oauth2_service_.AddAccount("robot@gmail.com");
181 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
184 // testing::Test:
185 void TearDown() override {
186 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
189 protected:
190 scoped_ptr<UploadJob> PrepareUploadJob(scoped_ptr<
191 UploadJobImpl::MimeBoundaryGenerator> mime_boundary_generator) {
192 scoped_ptr<UploadJob> upload_job(new UploadJobImpl(
193 GetServerURL(), kRobotAccountId, &oauth2_service_,
194 request_context_getter_.get(), this, mime_boundary_generator.Pass()));
196 std::map<std::string, std::string> header_entries;
197 header_entries.insert(std::make_pair(kCustomField1, "CUSTOM1"));
198 scoped_ptr<std::string> data(new std::string(kTestPayload1));
199 upload_job->AddDataSegment("Name1", "file1.ext", header_entries,
200 data.Pass());
202 header_entries.insert(std::make_pair(kCustomField2, "CUSTOM2"));
203 scoped_ptr<std::string> data2(new std::string(kTestPayload2));
204 upload_job->AddDataSegment("Name2", "", header_entries, data2.Pass());
205 return upload_job.Pass();
208 content::TestBrowserThreadBundle test_browser_thread_bundle_;
209 base::RunLoop run_loop_;
210 net::test_server::EmbeddedTestServer test_server_;
211 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
212 MockOAuth2TokenService oauth2_service_;
214 scoped_ptr<UploadJob::ErrorCode> expected_error_;
217 class UploadFlowTest : public UploadJobTestBase {
218 public:
219 UploadFlowTest() {}
221 // UploadJobTestBase:
222 void SetUp() override {
223 UploadJobTestBase::SetUp();
224 test_server_.RegisterRequestHandler(
225 base::Bind(&UploadFlowTest::HandlePostRequest, base::Unretained(this)));
228 scoped_ptr<net::test_server::HttpResponse> HandlePostRequest(
229 const net::test_server::HttpRequest& request) {
230 EXPECT_TRUE(request.headers.find("Authorization") != request.headers.end());
231 const std::string authorization_header =
232 request.headers.at("Authorization");
233 scoped_ptr<net::test_server::BasicHttpResponse> response(
234 new net::test_server::BasicHttpResponse);
235 const size_t pos = authorization_header.find(" ");
236 if (pos == std::string::npos) {
237 response->set_code(net::HTTP_UNAUTHORIZED);
238 return response.Pass();
241 const std::string token = authorization_header.substr(pos + 1);
242 response->set_code(oauth2_service_.IsTokenValid(token)
243 ? net::HTTP_OK
244 : net::HTTP_UNAUTHORIZED);
245 return response.Pass();
249 TEST_F(UploadFlowTest, SuccessfulUpload) {
250 oauth2_service_.SetTokenValid(kTokenValid);
251 oauth2_service_.AddTokenToQueue(kTokenValid);
252 scoped_ptr<UploadJob> upload_job = PrepareUploadJob(
253 make_scoped_ptr(new UploadJobImpl::RandomMimeBoundaryGenerator));
254 upload_job->Start();
255 run_loop_.Run();
258 TEST_F(UploadFlowTest, TokenExpired) {
259 oauth2_service_.SetTokenValid(kTokenValid);
260 oauth2_service_.AddTokenToQueue(kTokenExpired);
261 oauth2_service_.AddTokenToQueue(kTokenValid);
262 scoped_ptr<UploadJob> upload_job = PrepareUploadJob(
263 make_scoped_ptr(new UploadJobImpl::RandomMimeBoundaryGenerator));
264 upload_job->Start();
265 run_loop_.Run();
268 TEST_F(UploadFlowTest, TokenInvalid) {
269 oauth2_service_.AddTokenToQueue(kTokenInvalid);
270 oauth2_service_.AddTokenToQueue(kTokenInvalid);
271 SetExpectedError(scoped_ptr<UploadJob::ErrorCode>(
272 new UploadJob::ErrorCode(UploadJob::AUTHENTICATION_ERROR)));
274 scoped_ptr<UploadJob> upload_job = PrepareUploadJob(
275 make_scoped_ptr(new UploadJobImpl::RandomMimeBoundaryGenerator));
276 upload_job->Start();
277 run_loop_.Run();
280 TEST_F(UploadFlowTest, TokenFetchFailure) {
281 SetExpectedError(scoped_ptr<UploadJob::ErrorCode>(
282 new UploadJob::ErrorCode(UploadJob::AUTHENTICATION_ERROR)));
284 scoped_ptr<UploadJob> upload_job = PrepareUploadJob(
285 make_scoped_ptr(new UploadJobImpl::RandomMimeBoundaryGenerator));
286 upload_job->Start();
287 run_loop_.Run();
290 class UploadRequestTest : public UploadJobTestBase {
291 public:
292 UploadRequestTest() {}
294 // UploadJobTestBase:
295 void SetUp() override {
296 UploadJobTestBase::SetUp();
297 test_server_.RegisterRequestHandler(base::Bind(
298 &UploadRequestTest::HandlePostRequest, base::Unretained(this)));
301 scoped_ptr<net::test_server::HttpResponse> HandlePostRequest(
302 const net::test_server::HttpRequest& request) {
303 scoped_ptr<net::test_server::BasicHttpResponse> response(
304 new net::test_server::BasicHttpResponse);
305 response->set_code(net::HTTP_OK);
306 EXPECT_EQ(expected_content_, request.content);
307 return response.Pass();
310 void SetExpectedRequestContent(const std::string& expected_content) {
311 expected_content_ = expected_content;
314 protected:
315 std::string expected_content_;
318 TEST_F(UploadRequestTest, TestRequestStructure) {
319 oauth2_service_.SetTokenValid(kTokenValid);
320 oauth2_service_.AddTokenToQueue(kTokenValid);
321 scoped_ptr<UploadJob> upload_job = PrepareUploadJob(
322 make_scoped_ptr(new RepeatingMimeBoundaryGenerator('A')));
323 SetExpectedRequestContent(
324 "--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n"
325 "Content-Disposition: form-data; "
326 "name=\"Name1\"; filename=\"file1.ext\"\r\n"
327 "customfield1: CUSTOM1\r\n"
328 "\r\n"
329 "**||--||PAYLOAD1||--||**\r\n"
330 "--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n"
331 "Content-Disposition: form-data; name=\"Name2\"\r\n"
332 "customfield1: CUSTOM1\r\n"
333 "customfield2: CUSTOM2\r\n"
334 "\r\n"
335 "**||--||PAYLOAD2||--||**\r\n--"
336 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA--\r\n");
338 upload_job->Start();
339 run_loop_.Run();
342 } // namespace policy