Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1839)

Side by Side Diff: components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc

Issue 2873383004: [Offline Prefetch] Send GeneratePageBundleRequest to the server (Closed)
Patch Set: Update Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/generate_page_bundle_request.h"
6
7 #include "base/test/mock_callback.h"
8 #include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
9 #include "components/offline_pages/core/prefetch/prefetch_types.h"
10 #include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
11 #include "components/offline_pages/core/prefetch/proto/operation.pb.h"
12 #include "net/http/http_status_code.h"
13 #include "net/url_request/url_request_status.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "url/gurl.h"
16
17 using testing::_;
18 using testing::DoAll;
19 using testing::Eq;
20 using testing::SaveArg;
21
22 namespace offline_pages {
23
24 namespace {
25 const char kPageBundleTypeURL[] = "type.googleapis.com/test.PageBundle";
26 const char kTestURL[] = "http://example.com";
27 const char kTestURL2[] = "http://example.com/2";
28 const char kTestURL3[] = "http://example.com/3";
29 const char kTestURL4[] = "http://example.com/4";
30 const char kTestUserAgent[] = "Test User Agent";
31 const char kTestGCMID[] = "Test GCM ID";
32 const int kTestMaxBundleSize = 100000;
33 const char kTestBodyName[] = "body_name";
34 const int64_t kTestBodyLength = 12345678LL;
35 } // namespace
36
37 class OperationBuilder {
38 public:
39 virtual ~OperationBuilder() {}
40
41 // Builds the opereation with an Any value and returns it in binary serialized
42 // format.
43 virtual std::string BuildFromAny(const std::string& any_type_url,
44 const std::string& any_value) = 0;
45
46 // Builds the opereation with with an Any value filled with page bundle data
47 // and returns it in binary serialized format.
48 std::string BuildFromPageBundle(const proto::PageBundle& bundle) {
49 std::string bundle_data;
50 EXPECT_TRUE(bundle.SerializeToString(&bundle_data));
51 return BuildFromAny(kPageBundleTypeURL, bundle_data);
52 }
53 };
54
55 class DoneOperationBuilder : public OperationBuilder {
56 public:
57 ~DoneOperationBuilder() override {}
58
59 std::string BuildFromAny(const std::string& any_type_url,
60 const std::string& any_value) override {
61 proto::Operation operation;
62 operation.set_done(true);
63 proto::Any* response = operation.mutable_response();
64 response->set_type_url(any_type_url);
65 response->set_value(any_value);
66 std::string data;
67 EXPECT_TRUE(operation.SerializeToString(&data));
68 return data;
69 }
70 };
71
72 class PendingOperationBuilder : public OperationBuilder {
73 public:
74 ~PendingOperationBuilder() override {}
75
76 std::string BuildFromAny(const std::string& any_type_url,
77 const std::string& any_value) override {
78 proto::Operation operation;
79 operation.set_done(false);
80 proto::Any* response = operation.mutable_metadata();
81 response->set_type_url(any_type_url);
82 response->set_value(any_value);
83 std::string data;
84 EXPECT_TRUE(operation.SerializeToString(&data));
85 return data;
86 }
87 };
88
89 class GeneratePageBundleRequestTest : public PrefetchRequestTestBase {
90 public:
91 // Sends GeneratePageBundleRequest for single page with |page_url| and
92 // gets back the data in |http_response|.
93 RequestStatus GeneratePage(const std::string& page_url,
94 const std::string& http_response);
95
96 // Sends GeneratePageBundleRequest for multiple pages and gets back the data
97 // in |http_response|.
98 RequestStatus GenerateMultiplePages(const std::vector<std::string>& page_urls,
99 const std::string& http_response);
100
101 const std::vector<PageInfo>& pages() const { return pages_; }
102
103 private:
104 std::vector<PageInfo> pages_;
105 };
106
107 RequestStatus GeneratePageBundleRequestTest::GeneratePage(
108 const std::string& page_url,
109 const std::string& http_response) {
110 std::vector<std::string> page_urls;
111 page_urls.push_back(page_url);
112 return GenerateMultiplePages(page_urls, http_response);
113 }
114
115 RequestStatus GeneratePageBundleRequestTest::GenerateMultiplePages(
116 const std::vector<std::string>& page_urls,
117 const std::string& http_response) {
118 base::MockCallback<GeneratePageBundleRequest::FinishedCallback> callback;
119 std::unique_ptr<GeneratePageBundleRequest> fetcher(
120 new GeneratePageBundleRequest(kTestUserAgent, kTestGCMID,
121 kTestMaxBundleSize, page_urls,
122 request_context(), callback.Get()));
123
124 RequestStatus status;
125 pages_.clear();
126 EXPECT_CALL(callback, Run(_, _))
127 .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages_)));
128 RespondWithData(http_response);
129
130 return status;
131 }
132
133 TEST_F(GeneratePageBundleRequestTest, FailedToParse) {
134 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
135 GeneratePage(kTestURL, "Some data"));
136 EXPECT_TRUE(pages().empty());
137 }
138
139 TEST_F(GeneratePageBundleRequestTest, NoResultInDoneOperation) {
140 proto::Operation operation;
141 operation.set_done(true);
142 std::string data;
143 EXPECT_TRUE(operation.SerializeToString(&data));
144 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
145 GeneratePage(kTestURL, data));
146 EXPECT_TRUE(pages().empty());
147 }
148
149 TEST_F(GeneratePageBundleRequestTest, ErrorCodeInDoneOperation) {
150 proto::Operation operation;
151 operation.set_done(true);
152 operation.mutable_error()->set_code(1);
153 std::string data;
154 EXPECT_TRUE(operation.SerializeToString(&data));
155 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
156 GeneratePage(kTestURL, data));
157 EXPECT_TRUE(pages().empty());
158 }
159
160 template <typename T>
161 class GeneratePageBundleRequestOperationTest
162 : public GeneratePageBundleRequestTest {
163 public:
164 std::string BuildFromAny(const std::string& any_type_url,
165 const std::string& any_value) {
166 return builder_.BuildFromAny(any_type_url, any_value);
167 }
168
169 std::string BuildFromPageBundle(const proto::PageBundle& bundle) {
170 return builder_.BuildFromPageBundle(bundle);
171 }
172
173 private:
174 T builder_;
175 };
176
177 typedef testing::Types<DoneOperationBuilder, PendingOperationBuilder> MyTypes;
178 TYPED_TEST_CASE(GeneratePageBundleRequestOperationTest, MyTypes);
179
180 TYPED_TEST(GeneratePageBundleRequestOperationTest, InvalidTypeUrl) {
181 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
182 this->GeneratePage(kTestURL, this->BuildFromAny("foo", "")));
183 EXPECT_TRUE(this->pages().empty());
184 }
185
186 TYPED_TEST(GeneratePageBundleRequestOperationTest, InvalidValue) {
187 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
188 this->GeneratePage(kTestURL,
189 this->BuildFromAny(kPageBundleTypeURL, "foo")));
190 EXPECT_TRUE(this->pages().empty());
191 }
192
193 TYPED_TEST(GeneratePageBundleRequestOperationTest, EmptyPageBundle) {
194 proto::PageBundle bundle;
195 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
196 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
197 EXPECT_TRUE(this->pages().empty());
198 }
199
200 TYPED_TEST(GeneratePageBundleRequestOperationTest, EmptyArchive) {
201 proto::PageBundle bundle;
202 bundle.add_archives();
203 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
204 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
205 EXPECT_TRUE(this->pages().empty());
206 }
207
208 TYPED_TEST(GeneratePageBundleRequestOperationTest, NoPageInfo) {
209 proto::PageBundle bundle;
210 proto::Archive* archive = bundle.add_archives();
211 archive->set_body_name(kTestBodyName);
212 archive->set_body_length(kTestBodyLength);
213 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
214 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
215 EXPECT_TRUE(this->pages().empty());
216 }
217
218 TYPED_TEST(GeneratePageBundleRequestOperationTest, MissingPageInfoUrl) {
219 proto::PageBundle bundle;
220 proto::Archive* archive = bundle.add_archives();
221 proto::PageInfo* page_info = archive->add_page_infos();
222 page_info->set_redirect_url(kTestURL);
223 EXPECT_EQ(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
224 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
225 EXPECT_TRUE(this->pages().empty());
226 }
227
228 TYPED_TEST(GeneratePageBundleRequestOperationTest, SinglePage) {
229 proto::PageBundle bundle;
230 proto::Archive* archive = bundle.add_archives();
231 archive->set_body_name(kTestBodyName);
232 archive->set_body_length(kTestBodyLength);
233 proto::PageInfo* page_info = archive->add_page_infos();
234 page_info->set_url(kTestURL);
235 page_info->set_redirect_url(kTestURL2);
236 page_info->mutable_status()->set_code(proto::OK);
237 page_info->set_transformation(proto::NO_TRANSFORMATION);
238 int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
239 page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
240 page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
241 1000000);
242 EXPECT_EQ(RequestStatus::SUCCESS,
243 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
244 ASSERT_EQ(1u, this->pages().size());
245 EXPECT_EQ(kTestURL, this->pages().back().url);
246 EXPECT_EQ(kTestURL2, this->pages().back().redirect_url);
247 EXPECT_EQ(RenderStatus::RENDERED, this->pages().back().status);
248 EXPECT_EQ(kTestBodyName, this->pages().back().body_name);
249 EXPECT_EQ(kTestBodyLength, this->pages().back().body_length);
250 EXPECT_EQ(ms_since_epoch, this->pages().back().render_time.ToJavaTime());
251 }
252
253 TYPED_TEST(GeneratePageBundleRequestOperationTest, MultiplePages) {
254 proto::PageBundle bundle;
255
256 // Adds a page that is still being rendered.
257 proto::Archive* archive = bundle.add_archives();
258 proto::PageInfo* page_info = archive->add_page_infos();
259 page_info->set_url(kTestURL);
260 page_info->mutable_status()->set_code(proto::NOT_FOUND);
261
262 // Adds a page that failed to render due to bundle size limits.
263 archive = bundle.add_archives();
264 page_info = archive->add_page_infos();
265 page_info->set_url(kTestURL2);
266 page_info->mutable_status()->set_code(proto::FAILED_PRECONDITION);
267
268 // Adds a page that failed to render for any other reason.
269 archive = bundle.add_archives();
270 page_info = archive->add_page_infos();
271 page_info->set_url(kTestURL3);
272 page_info->mutable_status()->set_code(proto::UNKNOWN);
273
274 // Adds a page that was rendered successfully.
275 archive = bundle.add_archives();
276 archive->set_body_name(kTestBodyName);
277 archive->set_body_length(kTestBodyLength);
278 page_info = archive->add_page_infos();
279 page_info->set_url(kTestURL4);
280 page_info->mutable_status()->set_code(proto::OK);
281 page_info->set_transformation(proto::NO_TRANSFORMATION);
282 int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
283 page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
284 page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
285 1000000);
286
287 std::vector<std::string> page_urls = {kTestURL, kTestURL2, kTestURL3};
288 EXPECT_EQ(RequestStatus::SUCCESS,
289 this->GenerateMultiplePages(page_urls,
290 this->BuildFromPageBundle(bundle)));
291 ASSERT_EQ(4u, this->pages().size());
292 EXPECT_EQ(kTestURL, this->pages().at(0).url);
293 EXPECT_EQ(RenderStatus::PENDING_TO_RENDER, this->pages().at(0).status);
294 EXPECT_EQ(kTestURL2, this->pages().at(1).url);
295 EXPECT_EQ(RenderStatus::EXCEEDED_LIMIT, this->pages().at(1).status);
296 EXPECT_EQ(kTestURL3, this->pages().at(2).url);
297 EXPECT_EQ(RenderStatus::FAILED_TO_RENDER, this->pages().at(2).status);
298 EXPECT_EQ(kTestURL4, this->pages().at(3).url);
299 EXPECT_EQ(RenderStatus::RENDERED, this->pages().at(3).status);
300 EXPECT_EQ(kTestBodyName, this->pages().at(3).body_name);
301 EXPECT_EQ(kTestBodyLength, this->pages().at(3).body_length);
302 EXPECT_EQ(ms_since_epoch, this->pages().at(3).render_time.ToJavaTime());
303 }
304
305 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698