1 // Copyright 2017 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 "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
6
7 #include "base/bind.h"
8 #include "base/test/mock_callback.h"
9 #include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
10 #include "components/offline_pages/core/prefetch/prefetch_types.h"
11 #include "net/http/http_status_code.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "url/gurl.h"
14
15 using testing::_;
16 using testing::DoAll;
17 using testing::Eq;
18 using testing::SaveArg;
19
20 namespace offline_pages {
21
22 namespace {
23 const char kTestMessage[] = "Testing";
24
25 // TODO(https://crbug.com/1042727): Fix test GURL scoping and remove this getter
26 // function.
TestURL()27 GURL TestURL() {
28 return GURL("http://example.org");
29 }
30 } // namespace
31
32 class PrefetchRequestFetcherTest : public PrefetchRequestTestBase {
33 public:
34 PrefetchRequestStatus RunFetcherWithNetError(net::Error net_error);
35 PrefetchRequestStatus RunFetcherWithHttpError(net::HttpStatusCode http_error);
36 PrefetchRequestStatus RunFetcherWithData(const std::string& response_data,
37 std::string* data_received);
38 PrefetchRequestStatus RunFetcherWithHttpErrorAndData(
39 net::HttpStatusCode http_error,
40 const std::string& response_data);
SetEmptyRequest(bool empty_request)41 void SetEmptyRequest(bool empty_request) { empty_request_ = empty_request; }
42
43 private:
44 PrefetchRequestStatus RunFetcher(
45 base::OnceCallback<void(void)> respond_callback,
46 std::string* data_received);
47 bool empty_request_;
48 };
49
RunFetcherWithNetError(net::Error net_error)50 PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcherWithNetError(
51 net::Error net_error) {
52 std::string data_received;
53 PrefetchRequestStatus status =
54 RunFetcher(base::BindOnce(&PrefetchRequestTestBase::RespondWithNetError,
55 base::Unretained(this), net_error),
56 &data_received);
57 EXPECT_TRUE(data_received.empty());
58 return status;
59 }
60
RunFetcherWithHttpError(net::HttpStatusCode http_error)61 PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcherWithHttpError(
62 net::HttpStatusCode http_error) {
63 std::string data_received;
64 PrefetchRequestStatus status =
65 RunFetcher(base::BindOnce(&PrefetchRequestTestBase::RespondWithHttpError,
66 base::Unretained(this), http_error),
67 &data_received);
68 EXPECT_TRUE(data_received.empty());
69 return status;
70 }
71
RunFetcherWithData(const std::string & response_data,std::string * data_received)72 PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcherWithData(
73 const std::string& response_data,
74 std::string* data_received) {
75 return RunFetcher(base::BindOnce(&PrefetchRequestTestBase::RespondWithData,
76 base::Unretained(this), response_data),
77 data_received);
78 }
79
80 PrefetchRequestStatus
RunFetcherWithHttpErrorAndData(net::HttpStatusCode http_error,const std::string & response_data)81 PrefetchRequestFetcherTest::RunFetcherWithHttpErrorAndData(
82 net::HttpStatusCode http_error,
83 const std::string& response_data) {
84 std::string data_received;
85 return RunFetcher(
86 base::BindOnce(&PrefetchRequestTestBase::RespondWithHttpErrorAndData,
87 base::Unretained(this), http_error, response_data),
88 &data_received);
89 }
90
RunFetcher(base::OnceCallback<void (void)> respond_callback,std::string * data_received)91 PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcher(
92 base::OnceCallback<void(void)> respond_callback,
93 std::string* data_received) {
94 base::MockCallback<PrefetchRequestFetcher::FinishedCallback> callback;
95 std::unique_ptr<PrefetchRequestFetcher> fetcher =
96 PrefetchRequestFetcher::CreateForPost(
97 TestURL(), kTestMessage, /*testing_header_value=*/"", empty_request_,
98 shared_url_loader_factory(), callback.Get());
99
100 PrefetchRequestStatus status;
101 std::string data;
102 EXPECT_CALL(callback, Run(_, _))
103 .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&data)));
104 std::move(respond_callback).Run();
105 RunUntilIdle();
106
107 *data_received = data;
108 return status;
109 }
110
TEST_F(PrefetchRequestFetcherTest,NetErrors)111 TEST_F(PrefetchRequestFetcherTest, NetErrors) {
112 EXPECT_EQ(PrefetchRequestStatus::kShouldSuspendBlockedByAdministrator,
113 RunFetcherWithNetError(net::ERR_BLOCKED_BY_ADMINISTRATOR));
114
115 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithoutBackoff,
116 RunFetcherWithNetError(net::ERR_INTERNET_DISCONNECTED));
117 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithoutBackoff,
118 RunFetcherWithNetError(net::ERR_NETWORK_CHANGED));
119 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithoutBackoff,
120 RunFetcherWithNetError(net::ERR_CONNECTION_RESET));
121 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithoutBackoff,
122 RunFetcherWithNetError(net::ERR_CONNECTION_CLOSED));
123 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithoutBackoff,
124 RunFetcherWithNetError(net::ERR_CONNECTION_REFUSED));
125 }
126
TEST_F(PrefetchRequestFetcherTest,HttpErrors)127 TEST_F(PrefetchRequestFetcherTest, HttpErrors) {
128 EXPECT_EQ(PrefetchRequestStatus::kShouldSuspendNotImplemented,
129 RunFetcherWithHttpError(net::HTTP_NOT_IMPLEMENTED));
130 EXPECT_EQ(PrefetchRequestStatus::kShouldSuspendForbidden,
131 RunFetcherWithHttpError(net::HTTP_FORBIDDEN));
132
133 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
134 RunFetcherWithHttpError(net::HTTP_BAD_REQUEST));
135 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
136 RunFetcherWithHttpError(net::HTTP_UNAUTHORIZED));
137 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
138 RunFetcherWithHttpError(net::HTTP_NOT_FOUND));
139 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
140 RunFetcherWithHttpError(net::HTTP_CONFLICT));
141 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
142 RunFetcherWithHttpError(net::HTTP_INTERNAL_SERVER_ERROR));
143 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
144 RunFetcherWithHttpError(net::HTTP_BAD_GATEWAY));
145 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
146 RunFetcherWithHttpError(net::HTTP_SERVICE_UNAVAILABLE));
147 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
148 RunFetcherWithHttpError(net::HTTP_GATEWAY_TIMEOUT));
149
150 SetEmptyRequest(false);
151 EXPECT_EQ(PrefetchRequestStatus::kShouldSuspendNewlyForbiddenByOPS,
152 RunFetcherWithHttpErrorAndData(net::HTTP_FORBIDDEN,
153 "request forbidden by OPS"));
154 SetEmptyRequest(true);
155 EXPECT_EQ(PrefetchRequestStatus::kShouldSuspendForbiddenByOPS,
156 RunFetcherWithHttpErrorAndData(net::HTTP_FORBIDDEN,
157 "request forbidden by OPS"));
158 }
159
TEST_F(PrefetchRequestFetcherTest,EmptyResponse)160 TEST_F(PrefetchRequestFetcherTest, EmptyResponse) {
161 std::string data;
162 EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
163 RunFetcherWithData("", &data));
164 EXPECT_TRUE(data.empty());
165 }
166
TEST_F(PrefetchRequestFetcherTest,EmptyRequestSuccess)167 TEST_F(PrefetchRequestFetcherTest, EmptyRequestSuccess) {
168 std::string data;
169 SetEmptyRequest(true);
170 EXPECT_EQ(PrefetchRequestStatus::kEmptyRequestSuccess,
171 RunFetcherWithData("Any data.", &data));
172 EXPECT_FALSE(data.empty());
173 }
174
TEST_F(PrefetchRequestFetcherTest,NonEmptyRequestSuccess)175 TEST_F(PrefetchRequestFetcherTest, NonEmptyRequestSuccess) {
176 std::string data;
177 SetEmptyRequest(false);
178 EXPECT_EQ(PrefetchRequestStatus::kSuccess,
179 RunFetcherWithData("Any data.", &data));
180 EXPECT_FALSE(data.empty());
181 }
182
183 } // namespace offline_pages
184