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