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 "third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
9 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
10 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
11 #include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
12 #include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
13 #include "third_party/blink/renderer/core/fetch/request.h"
14 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
15 #include "third_party/blink/renderer/platform/bindings/script_state.h"
16 #include "third_party/blink/renderer/platform/blob/blob_data.h"
17
18 namespace blink {
19
20 class BackgroundFetchManagerTest : public testing::Test {
21 protected:
22 // Creates a vector of FetchAPIRequestPtr entries for the given |requests|
23 // based on the |scope|. Proxied in the fixture to reduce the number of friend
24 // declarations necessary in the BackgroundFetchManager.
CreateFetchAPIRequestVector(V8TestingScope & scope,const RequestOrUSVStringOrRequestOrUSVStringSequence & requests)25 Vector<mojom::blink::FetchAPIRequestPtr> CreateFetchAPIRequestVector(
26 V8TestingScope& scope,
27 const RequestOrUSVStringOrRequestOrUSVStringSequence& requests) {
28 bool has_requests_with_body;
29 return BackgroundFetchManager::CreateFetchAPIRequestVector(
30 scope.GetScriptState(), requests, scope.GetExceptionState(),
31 &has_requests_with_body);
32 }
33 };
34
TEST_F(BackgroundFetchManagerTest,NullValue)35 TEST_F(BackgroundFetchManagerTest, NullValue) {
36 V8TestingScope scope;
37
38 RequestOrUSVStringOrRequestOrUSVStringSequence requests;
39
40 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
41 CreateFetchAPIRequestVector(scope, requests);
42 ASSERT_TRUE(scope.GetExceptionState().HadException());
43 EXPECT_EQ(scope.GetExceptionState().CodeAs<ESErrorType>(),
44 ESErrorType::kTypeError);
45 }
46
TEST_F(BackgroundFetchManagerTest,SingleUSVString)47 TEST_F(BackgroundFetchManagerTest, SingleUSVString) {
48 V8TestingScope scope;
49
50 KURL image_url("https://www.example.com/my_image.png");
51
52 RequestOrUSVStringOrRequestOrUSVStringSequence requests =
53 RequestOrUSVStringOrRequestOrUSVStringSequence::FromUSVString(
54 image_url.GetString());
55
56 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
57 CreateFetchAPIRequestVector(scope, requests);
58 ASSERT_FALSE(scope.GetExceptionState().HadException());
59
60 ASSERT_EQ(fetch_api_requests.size(), 1u);
61 EXPECT_EQ(fetch_api_requests[0]->url, image_url);
62 EXPECT_EQ(fetch_api_requests[0]->method, "GET");
63 }
64
TEST_F(BackgroundFetchManagerTest,SingleRequest)65 TEST_F(BackgroundFetchManagerTest, SingleRequest) {
66 V8TestingScope scope;
67
68 KURL image_url("https://www.example.com/my_image.png");
69
70 RequestInit* request_init = RequestInit::Create();
71 request_init->setMethod("POST");
72 Request* request =
73 Request::Create(scope.GetScriptState(), image_url.GetString(),
74 request_init, scope.GetExceptionState());
75 ASSERT_FALSE(scope.GetExceptionState().HadException());
76 ASSERT_TRUE(request);
77
78 RequestOrUSVStringOrRequestOrUSVStringSequence requests =
79 RequestOrUSVStringOrRequestOrUSVStringSequence::FromRequest(request);
80
81 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
82 CreateFetchAPIRequestVector(scope, requests);
83 ASSERT_FALSE(scope.GetExceptionState().HadException());
84
85 ASSERT_EQ(fetch_api_requests.size(), 1u);
86 EXPECT_EQ(fetch_api_requests[0]->url, image_url);
87 EXPECT_EQ(fetch_api_requests[0]->method, "POST");
88 }
89
TEST_F(BackgroundFetchManagerTest,Sequence)90 TEST_F(BackgroundFetchManagerTest, Sequence) {
91 V8TestingScope scope;
92
93 KURL image_url("https://www.example.com/my_image.png");
94 KURL icon_url("https://www.example.com/my_icon.jpg");
95 KURL cat_video_url("https://www.example.com/my_cat_video.avi");
96
97 RequestOrUSVString image_request =
98 RequestOrUSVString::FromUSVString(image_url.GetString());
99 RequestOrUSVString icon_request =
100 RequestOrUSVString::FromUSVString(icon_url.GetString());
101
102 RequestInit* request_init = RequestInit::Create();
103 request_init->setMethod("DELETE");
104 Request* request =
105 Request::Create(scope.GetScriptState(), cat_video_url.GetString(),
106 request_init, scope.GetExceptionState());
107 ASSERT_FALSE(scope.GetExceptionState().HadException());
108 ASSERT_TRUE(request);
109
110 RequestOrUSVString cat_video_request =
111 RequestOrUSVString::FromRequest(request);
112
113 HeapVector<RequestOrUSVString> request_sequence;
114 request_sequence.push_back(image_request);
115 request_sequence.push_back(icon_request);
116 request_sequence.push_back(cat_video_request);
117
118 RequestOrUSVStringOrRequestOrUSVStringSequence requests =
119 RequestOrUSVStringOrRequestOrUSVStringSequence::
120 FromRequestOrUSVStringSequence(request_sequence);
121
122 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
123 CreateFetchAPIRequestVector(scope, requests);
124 ASSERT_FALSE(scope.GetExceptionState().HadException());
125
126 ASSERT_EQ(fetch_api_requests.size(), 3u);
127 EXPECT_EQ(fetch_api_requests[0]->url, image_url);
128 EXPECT_EQ(fetch_api_requests[0]->method, "GET");
129
130 EXPECT_EQ(fetch_api_requests[1]->url, icon_url);
131 EXPECT_EQ(fetch_api_requests[1]->method, "GET");
132
133 EXPECT_EQ(fetch_api_requests[2]->url, cat_video_url);
134 EXPECT_EQ(fetch_api_requests[2]->method, "DELETE");
135 }
136
TEST_F(BackgroundFetchManagerTest,SequenceEmpty)137 TEST_F(BackgroundFetchManagerTest, SequenceEmpty) {
138 V8TestingScope scope;
139
140 HeapVector<RequestOrUSVString> request_sequence;
141 RequestOrUSVStringOrRequestOrUSVStringSequence requests =
142 RequestOrUSVStringOrRequestOrUSVStringSequence::
143 FromRequestOrUSVStringSequence(request_sequence);
144
145 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
146 CreateFetchAPIRequestVector(scope, requests);
147 ASSERT_TRUE(scope.GetExceptionState().HadException());
148 EXPECT_EQ(scope.GetExceptionState().CodeAs<ESErrorType>(),
149 ESErrorType::kTypeError);
150 }
151
TEST_F(BackgroundFetchManagerTest,SequenceWithNullValue)152 TEST_F(BackgroundFetchManagerTest, SequenceWithNullValue) {
153 V8TestingScope scope;
154
155 KURL image_url("https://www.example.com/my_image.png");
156
157 RequestOrUSVString null_request;
158 RequestOrUSVString image_request =
159 RequestOrUSVString::FromUSVString(image_url.GetString());
160
161 HeapVector<RequestOrUSVString> request_sequence;
162 request_sequence.push_back(image_request);
163 request_sequence.push_back(null_request);
164
165 RequestOrUSVStringOrRequestOrUSVStringSequence requests =
166 RequestOrUSVStringOrRequestOrUSVStringSequence::
167 FromRequestOrUSVStringSequence(request_sequence);
168
169 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
170 CreateFetchAPIRequestVector(scope, requests);
171 ASSERT_TRUE(scope.GetExceptionState().HadException());
172 EXPECT_EQ(scope.GetExceptionState().CodeAs<ESErrorType>(),
173 ESErrorType::kTypeError);
174 }
175
TEST_F(BackgroundFetchManagerTest,BlobsExtracted)176 TEST_F(BackgroundFetchManagerTest, BlobsExtracted) {
177 V8TestingScope scope;
178
179 KURL image_url("https://www.example.com/my_image.png");
180 KURL icon_url("https://www.example.com/my_icon.jpg");
181
182 // Create first request with a body.
183 String body_text = "cat_pic";
184 RequestInit* request_init = RequestInit::Create();
185 request_init->setMethod("POST");
186 request_init->setBody(blink::ScriptValue(
187 scope.GetIsolate(), ToV8(body_text, scope.GetScriptState())));
188 Request* image_request =
189 Request::Create(scope.GetScriptState(), image_url.GetString(),
190 request_init, scope.GetExceptionState());
191 ASSERT_FALSE(scope.GetExceptionState().HadException());
192 ASSERT_TRUE(image_request);
193 ASSERT_TRUE(image_request->HasBody());
194
195 // Create second request without a body.
196 RequestOrUSVString icon_request =
197 RequestOrUSVString::FromUSVString(icon_url.GetString());
198
199 // Create a request sequence with both requests.
200 HeapVector<RequestOrUSVString> request_sequence;
201 request_sequence.push_back(RequestOrUSVString::FromRequest(image_request));
202 request_sequence.push_back(icon_request);
203
204 RequestOrUSVStringOrRequestOrUSVStringSequence requests =
205 RequestOrUSVStringOrRequestOrUSVStringSequence::
206 FromRequestOrUSVStringSequence(request_sequence);
207
208 // Extract the blobs.
209 Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
210 CreateFetchAPIRequestVector(scope, requests);
211 ASSERT_FALSE(scope.GetExceptionState().HadException());
212
213 ASSERT_EQ(fetch_api_requests.size(), 2u);
214
215 ASSERT_TRUE(fetch_api_requests[0]->blob);
216 EXPECT_EQ(fetch_api_requests[0]->blob->size(), body_text.length());
217
218 EXPECT_FALSE(fetch_api_requests[1]->blob);
219 }
220
221 } // namespace blink
222