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

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: Address more feedback 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/prefetch_utils.h"
11 #include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
12 #include "components/offline_pages/core/prefetch/proto/operation.pb.h"
13 #include "net/http/http_status_code.h"
14 #include "net/url_request/url_request_status.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "url/gurl.h"
17
18 using testing::_;
19 using testing::DoAll;
20 using testing::Eq;
21 using testing::SaveArg;
22
23 namespace offline_pages {
24
25 namespace {
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 protected:
55 // Helper function to build the operation based on |is_done| that controls
56 // where Any value goes.
57 std::string BuildOperation(bool is_done,
58 const std::string& any_type_url,
59 const std::string& any_value) {
60 proto::Operation operation;
61 operation.set_done(is_done);
62 proto::Any* any =
63 is_done ? operation.mutable_response() : operation.mutable_metadata();
64 any->set_type_url(any_type_url);
65 any->set_value(any_value);
66 std::string data;
67 EXPECT_TRUE(operation.SerializeToString(&data));
68 return data;
69 }
70 };
71
72 class DoneOperationBuilder : public OperationBuilder {
73 public:
74 ~DoneOperationBuilder() override {}
75
76 std::string BuildFromAny(const std::string& any_type_url,
77 const std::string& any_value) override {
78 return BuildOperation(true, any_type_url, any_value);
79 }
80 };
81
82 class PendingOperationBuilder : public OperationBuilder {
83 public:
84 ~PendingOperationBuilder() override {}
85
86 std::string BuildFromAny(const std::string& any_type_url,
87 const std::string& any_value) override {
88 return BuildOperation(false, any_type_url, any_value);
89 }
90 };
91
92 class GeneratePageBundleRequestTest : public PrefetchRequestTestBase {
93 public:
94 // Sends GeneratePageBundleRequest for single page with |page_url| and
95 // gets back the data in |http_response|.
96 PrefetchRequestStatus GeneratePage(const std::string& page_url,
97 const std::string& http_response);
98
99 // Sends GeneratePageBundleRequest for multiple pages and gets back the data
100 // in |http_response|.
101 PrefetchRequestStatus GenerateMultiplePages(
102 const std::vector<std::string>& page_urls,
103 const std::string& http_response);
104
105 const std::vector<RenderPageInfo>& pages() const { return pages_; }
106
107 private:
108 std::vector<RenderPageInfo> pages_;
109 };
110
111 PrefetchRequestStatus GeneratePageBundleRequestTest::GeneratePage(
112 const std::string& page_url,
113 const std::string& http_response) {
114 std::vector<std::string> page_urls;
115 page_urls.push_back(page_url);
116 return GenerateMultiplePages(page_urls, http_response);
117 }
118
119 PrefetchRequestStatus GeneratePageBundleRequestTest::GenerateMultiplePages(
120 const std::vector<std::string>& page_urls,
121 const std::string& http_response) {
122 base::MockCallback<GeneratePageBundleRequest::FinishedCallback> callback;
123 std::unique_ptr<GeneratePageBundleRequest> fetcher(
124 new GeneratePageBundleRequest(kTestUserAgent, kTestGCMID,
125 kTestMaxBundleSize, page_urls,
126 request_context(), callback.Get()));
127
128 PrefetchRequestStatus status;
129 pages_.clear();
130 EXPECT_CALL(callback, Run(_, _))
131 .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages_)));
132 RespondWithData(http_response);
133
134 return status;
135 }
136
137 TEST_F(GeneratePageBundleRequestTest, FailedToParse) {
138 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
139 GeneratePage(kTestURL, "Some data"));
140 EXPECT_TRUE(pages().empty());
141 }
142
143 TEST_F(GeneratePageBundleRequestTest, NoResultInDoneOperation) {
144 proto::Operation operation;
145 operation.set_done(true);
146 std::string data;
147 EXPECT_TRUE(operation.SerializeToString(&data));
148 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
149 GeneratePage(kTestURL, data));
150 EXPECT_TRUE(pages().empty());
151 }
152
153 TEST_F(GeneratePageBundleRequestTest, ErrorCodeInDoneOperation) {
154 proto::Operation operation;
155 operation.set_done(true);
156 operation.mutable_error()->set_code(1);
157 std::string data;
158 EXPECT_TRUE(operation.SerializeToString(&data));
159 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
160 GeneratePage(kTestURL, data));
161 EXPECT_TRUE(pages().empty());
162 }
163
164 template <typename T>
165 class GeneratePageBundleRequestOperationTest
166 : public GeneratePageBundleRequestTest {
167 public:
168 std::string BuildFromAny(const std::string& any_type_url,
169 const std::string& any_value) {
170 return builder_.BuildFromAny(any_type_url, any_value);
171 }
172
173 std::string BuildFromPageBundle(const proto::PageBundle& bundle) {
174 return builder_.BuildFromPageBundle(bundle);
175 }
176
177 private:
178 T builder_;
179 };
180
181 typedef testing::Types<DoneOperationBuilder, PendingOperationBuilder> MyTypes;
182 TYPED_TEST_CASE(GeneratePageBundleRequestOperationTest, MyTypes);
183
184 TYPED_TEST(GeneratePageBundleRequestOperationTest, InvalidTypeUrl) {
185 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
186 this->GeneratePage(kTestURL, this->BuildFromAny("foo", "")));
187 EXPECT_TRUE(this->pages().empty());
188 }
189
190 TYPED_TEST(GeneratePageBundleRequestOperationTest, InvalidValue) {
191 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
192 this->GeneratePage(kTestURL,
193 this->BuildFromAny(kPageBundleTypeURL, "foo")));
194 EXPECT_TRUE(this->pages().empty());
195 }
196
197 TYPED_TEST(GeneratePageBundleRequestOperationTest, EmptyPageBundle) {
198 proto::PageBundle bundle;
199 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
200 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
201 EXPECT_TRUE(this->pages().empty());
202 }
203
204 TYPED_TEST(GeneratePageBundleRequestOperationTest, EmptyArchive) {
205 proto::PageBundle bundle;
206 bundle.add_archives();
207 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
208 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
209 EXPECT_TRUE(this->pages().empty());
210 }
211
212 TYPED_TEST(GeneratePageBundleRequestOperationTest, NoPageInfo) {
213 proto::PageBundle bundle;
214 proto::Archive* archive = bundle.add_archives();
215 archive->set_body_name(kTestBodyName);
216 archive->set_body_length(kTestBodyLength);
217 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
218 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
219 EXPECT_TRUE(this->pages().empty());
220 }
221
222 TYPED_TEST(GeneratePageBundleRequestOperationTest, MissingPageInfoUrl) {
223 proto::PageBundle bundle;
224 proto::Archive* archive = bundle.add_archives();
225 proto::PageInfo* page_info = archive->add_page_infos();
226 page_info->set_redirect_url(kTestURL);
227 EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
228 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
229 EXPECT_TRUE(this->pages().empty());
230 }
231
232 TYPED_TEST(GeneratePageBundleRequestOperationTest, SinglePage) {
233 proto::PageBundle bundle;
234 proto::Archive* archive = bundle.add_archives();
235 archive->set_body_name(kTestBodyName);
236 archive->set_body_length(kTestBodyLength);
237 proto::PageInfo* page_info = archive->add_page_infos();
238 page_info->set_url(kTestURL);
239 page_info->set_redirect_url(kTestURL2);
240 page_info->mutable_status()->set_code(proto::OK);
241 page_info->set_transformation(proto::NO_TRANSFORMATION);
242 int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
243 page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
244 page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
245 1000000);
246 EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
247 this->GeneratePage(kTestURL, this->BuildFromPageBundle(bundle)));
248 ASSERT_EQ(1u, this->pages().size());
249 EXPECT_EQ(kTestURL, this->pages().back().url);
250 EXPECT_EQ(kTestURL2, this->pages().back().redirect_url);
251 EXPECT_EQ(RenderStatus::RENDERED, this->pages().back().status);
252 EXPECT_EQ(kTestBodyName, this->pages().back().body_name);
253 EXPECT_EQ(kTestBodyLength, this->pages().back().body_length);
254 EXPECT_EQ(ms_since_epoch, this->pages().back().render_time.ToJavaTime());
255 }
256
257 TYPED_TEST(GeneratePageBundleRequestOperationTest, MultiplePages) {
258 proto::PageBundle bundle;
259
260 // Adds a page that is still being rendered.
261 proto::Archive* archive = bundle.add_archives();
262 proto::PageInfo* page_info = archive->add_page_infos();
263 page_info->set_url(kTestURL);
264 page_info->mutable_status()->set_code(proto::NOT_FOUND);
265
266 // Adds a page that failed to render due to bundle size limits.
267 archive = bundle.add_archives();
268 page_info = archive->add_page_infos();
269 page_info->set_url(kTestURL2);
270 page_info->mutable_status()->set_code(proto::FAILED_PRECONDITION);
271
272 // Adds a page that failed to render for any other reason.
273 archive = bundle.add_archives();
274 page_info = archive->add_page_infos();
275 page_info->set_url(kTestURL3);
276 page_info->mutable_status()->set_code(proto::UNKNOWN);
277
278 // Adds a page that was rendered successfully.
279 archive = bundle.add_archives();
280 archive->set_body_name(kTestBodyName);
281 archive->set_body_length(kTestBodyLength);
282 page_info = archive->add_page_infos();
283 page_info->set_url(kTestURL4);
284 page_info->mutable_status()->set_code(proto::OK);
285 page_info->set_transformation(proto::NO_TRANSFORMATION);
286 int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
287 page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
288 page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
289 1000000);
290
291 std::vector<std::string> page_urls = {kTestURL, kTestURL2, kTestURL3};
292 EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
293 this->GenerateMultiplePages(page_urls,
294 this->BuildFromPageBundle(bundle)));
295 ASSERT_EQ(4u, this->pages().size());
296 EXPECT_EQ(kTestURL, this->pages().at(0).url);
297 EXPECT_EQ(RenderStatus::PENDING, this->pages().at(0).status);
298 EXPECT_EQ(kTestURL2, this->pages().at(1).url);
299 EXPECT_EQ(RenderStatus::EXCEEDED_LIMIT, this->pages().at(1).status);
300 EXPECT_EQ(kTestURL3, this->pages().at(2).url);
301 EXPECT_EQ(RenderStatus::FAILED, this->pages().at(2).status);
302 EXPECT_EQ(kTestURL4, this->pages().at(3).url);
303 EXPECT_EQ(RenderStatus::RENDERED, this->pages().at(3).status);
304 EXPECT_EQ(kTestBodyName, this->pages().at(3).body_name);
305 EXPECT_EQ(kTestBodyLength, this->pages().at(3).body_length);
306 EXPECT_EQ(ms_since_epoch, this->pages().at(3).render_time.ToJavaTime());
307 }
308
309 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698