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