OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "modules/fetch/FormDataBytesConsumer.h" | |
6 | |
7 #include "core/dom/DOMArrayBuffer.h" | |
8 #include "core/dom/DOMTypedArray.h" | |
9 #include "core/dom/Document.h" | |
10 #include "core/html/FormData.h" | |
11 #include "core/testing/DummyPageHolder.h" | |
12 #include "modules/fetch/BytesConsumerTestUtil.h" | |
13 #include "platform/blob/BlobData.h" | |
14 #include "platform/network/EncodedFormData.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 #include "wtf/RefPtr.h" | |
18 #include "wtf/Vector.h" | |
19 #include "wtf/text/WTFString.h" | |
20 | |
21 namespace blink { | |
22 namespace { | |
23 | |
24 using Result = BytesConsumer::Result; | |
25 using ::testing::_; | |
26 using ::testing::DoAll; | |
27 using ::testing::InSequence; | |
28 using ::testing::Return; | |
29 using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>; | |
30 | |
31 String toString(const Vector<char>& v) | |
32 { | |
33 return String(v.data(), v.size()); | |
34 } | |
35 | |
36 PassRefPtr<EncodedFormData> complexFormData() | |
37 { | |
38 RefPtr<EncodedFormData> data = EncodedFormData::create(); | |
39 | |
40 data->appendData("foo", 3); | |
41 data->appendFileRange("/foo/bar/baz", 3, 4, 5); | |
42 data->appendFileSystemURLRange(KURL(KURL(), "file:///foo/bar/baz"), 6, 7, 8) ; | |
43 std::unique_ptr<BlobData> blobData = BlobData::create(); | |
44 blobData->appendText("hello", false); | |
45 auto size = blobData->length(); | |
46 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(std::move(blo bData), size); | |
47 data->appendBlob(blobDataHandle->uuid(), blobDataHandle); | |
48 Vector<char> boundary; | |
49 boundary.append("\0", 1); | |
50 data->setBoundary(boundary); | |
51 return data.release(); | |
52 } | |
53 | |
54 class NoopClient final : public GarbageCollectedFinalized<NoopClient>, public By tesConsumer::Client { | |
55 USING_GARBAGE_COLLECTED_MIXIN(NoopClient); | |
56 public: | |
57 void onStateChange() override {} | |
58 }; | |
59 | |
60 class MockBytesConsumer : public BytesConsumer { | |
61 public: | |
62 static MockBytesConsumer* create() { return new ::testing::StrictMock<MockBy tesConsumer>(); } | |
63 | |
64 MOCK_METHOD2(beginRead, Result(const char**, size_t*)); | |
65 MOCK_METHOD1(endRead, Result(size_t)); | |
66 MOCK_METHOD1(setClient, void(Client*)); | |
67 MOCK_METHOD0(clearClient, void()); | |
68 MOCK_METHOD0(cancel, void()); | |
69 MOCK_CONST_METHOD0(getPublicState, PublicState()); | |
70 MOCK_CONST_METHOD0(getError, Error()); | |
71 | |
72 String debugName() const override { return "MockBytesConsumer"; } | |
73 | |
74 protected: | |
75 MockBytesConsumer() = default; | |
76 }; | |
77 | |
78 class FormDataBytesConsumerTest : public ::testing::Test { | |
79 public: | |
80 FormDataBytesConsumerTest() : m_page(DummyPageHolder::create()) {} | |
81 | |
82 protected: | |
83 Document* getDocument() { return &m_page->document(); } | |
84 | |
85 std::unique_ptr<DummyPageHolder> m_page; | |
86 }; | |
87 | |
88 TEST_F(FormDataBytesConsumerTest, ReadFromString) | |
89 { | |
90 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(" hello, world")))->run(); | |
91 EXPECT_EQ(Result::Done, result.first); | |
92 EXPECT_EQ("hello, world", toString(result.second)); | |
93 } | |
94 | |
95 TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromString) | |
96 { | |
97 auto result = (new BytesConsumerTestUtil::TwoPhaseReader(new FormDataBytesCo nsumer("hello, world")))->run(); | |
98 EXPECT_EQ(Result::Done, result.first); | |
99 EXPECT_EQ("hello, world", toString(result.second)); | |
100 } | |
101 | |
102 TEST_F(FormDataBytesConsumerTest, ReadFromStringNonLatin) | |
103 { | |
104 constexpr UChar cs[] = {0x3042, 0}; | |
105 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(S tring(cs))))->run(); | |
106 EXPECT_EQ(Result::Done, result.first); | |
107 EXPECT_EQ("\xe3\x81\x82", toString(result.second)); | |
108 } | |
109 | |
110 TEST_F(FormDataBytesConsumerTest, ReadFromArrayBuffer) | |
111 { | |
112 constexpr unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x30, 0x42, 0x99, 0x88 }; | |
113 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGTH(data) ); | |
114 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(b uffer)))->run(); | |
115 Vector<char> expected; | |
116 expected.append(data, WTF_ARRAY_LENGTH(data)); | |
117 | |
118 EXPECT_EQ(Result::Done, result.first); | |
119 EXPECT_EQ(expected, result.second); | |
120 } | |
121 | |
122 TEST_F(FormDataBytesConsumerTest, ReadFromArrayBufferView) | |
123 { | |
124 constexpr unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x30, 0x42, 0x99, 0x88 }; | |
125 constexpr size_t offset = 1, size = 4; | |
126 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGTH(data) ); | |
127 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(D OMUint8Array::create(buffer, offset, size))))->run(); | |
128 Vector<char> expected; | |
129 expected.append(data + offset, size); | |
130 | |
131 EXPECT_EQ(Result::Done, result.first); | |
132 EXPECT_EQ(expected, result.second); | |
133 } | |
134 | |
135 TEST_F(FormDataBytesConsumerTest, ReadFromSimpleFormData) | |
136 { | |
137 RefPtr<EncodedFormData> data = EncodedFormData::create(); | |
138 data->appendData("foo", 3); | |
139 data->appendData("hoge", 4); | |
140 | |
141 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(g etDocument(), data)))->run(); | |
142 EXPECT_EQ(Result::Done, result.first); | |
143 EXPECT_EQ("foohoge", toString(result.second)); | |
144 } | |
145 | |
146 TEST_F(FormDataBytesConsumerTest, ReadFromComplexFormData) | |
147 { | |
148 RefPtr<EncodedFormData> data = complexFormData(); | |
149 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
150 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), data, underlying); | |
151 Checkpoint checkpoint; | |
152 | |
153 char c; | |
154 size_t read = 0; | |
155 | |
156 InSequence s; | |
157 EXPECT_CALL(checkpoint, Call(1)); | |
158 EXPECT_CALL(*underlying, beginRead(_, _)).WillOnce(DoAll(::testing::SetArgPo intee<1>(0), Return(Result::Ok))); | |
159 EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok)); | |
160 EXPECT_CALL(checkpoint, Call(2)); | |
161 | |
162 checkpoint.Call(1); | |
163 EXPECT_EQ(Result::Ok, consumer->read(&c, 1, &read)); | |
164 checkpoint.Call(2); | |
165 } | |
166 | |
167 TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData) | |
168 { | |
169 RefPtr<EncodedFormData> data = complexFormData(); | |
170 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
171 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), data, underlying); | |
172 Checkpoint checkpoint; | |
173 | |
174 const char* buffer = nullptr; | |
175 size_t available = 0; | |
176 | |
177 InSequence s; | |
178 EXPECT_CALL(checkpoint, Call(1)); | |
179 EXPECT_CALL(*underlying, beginRead(&buffer, &available)).WillOnce(Return(Res ult::Ok)); | |
180 EXPECT_CALL(checkpoint, Call(2)); | |
181 EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok)); | |
182 EXPECT_CALL(checkpoint, Call(3)); | |
183 | |
184 checkpoint.Call(1); | |
185 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
186 checkpoint.Call(2); | |
187 EXPECT_EQ(Result::Ok, consumer->endRead(0)); | |
188 checkpoint.Call(3); | |
189 } | |
190 | |
191 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromString) | |
192 { | |
193 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
194 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
195 ASSERT_TRUE(blobDataHandle); | |
196 | |
197 EXPECT_EQ(String(), blobDataHandle->type()); | |
198 EXPECT_EQ(12u, blobDataHandle->size()); | |
199 EXPECT_FALSE(consumer->drainAsFormData()); | |
200 char c; | |
201 size_t readSize; | |
202 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
203 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
204 } | |
205 | |
206 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromArrayBuffer) | |
207 { | |
208 BytesConsumer* consumer = new FormDataBytesConsumer(DOMArrayBuffer::create(" foo", 3)); | |
209 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
210 ASSERT_TRUE(blobDataHandle); | |
211 | |
212 EXPECT_EQ(String(), blobDataHandle->type()); | |
213 EXPECT_EQ(3u, blobDataHandle->size()); | |
214 EXPECT_FALSE(consumer->drainAsFormData()); | |
215 char c; | |
216 size_t readSize; | |
217 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
218 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
219 } | |
220 | |
221 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromSimpleFormData) | |
222 { | |
223 FormData* data = FormData::create(UTF8Encoding()); | |
224 data->append("name1", "value1"); | |
225 data->append("name2", "value2"); | |
226 RefPtr<EncodedFormData> inputFormData = data->encodeMultiPartFormData(); | |
227 | |
228 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
229 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
230 ASSERT_TRUE(blobDataHandle); | |
231 | |
232 EXPECT_EQ(String(), blobDataHandle->type()); | |
233 EXPECT_EQ(inputFormData->flattenToString().utf8().length(), blobDataHandle-> size()); | |
234 EXPECT_FALSE(consumer->drainAsFormData()); | |
235 char c; | |
236 size_t readSize; | |
237 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
238 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
239 } | |
240 | |
241 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromComplexFormData) | |
242 { | |
243 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
244 | |
245 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
246 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
247 ASSERT_TRUE(blobDataHandle); | |
248 | |
249 EXPECT_FALSE(consumer->drainAsFormData()); | |
250 char c; | |
251 size_t readSize; | |
252 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
253 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
254 } | |
255 | |
256 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromString) | |
257 { | |
258 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
259 RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); | |
260 ASSERT_TRUE(formData); | |
261 EXPECT_EQ("hello, world", formData->flattenToString()); | |
262 | |
263 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
264 const char* buffer = nullptr; | |
265 size_t size; | |
266 EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); | |
267 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); | |
268 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
269 } | |
270 | |
271 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromArrayBuffer) | |
272 { | |
273 BytesConsumer* consumer = new FormDataBytesConsumer(DOMArrayBuffer::create(" foo", 3)); | |
274 RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); | |
275 ASSERT_TRUE(formData); | |
276 EXPECT_TRUE(formData->isSafeToSendToAnotherThread()); | |
277 EXPECT_EQ("foo", formData->flattenToString()); | |
278 | |
279 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
280 const char* buffer = nullptr; | |
281 size_t size; | |
282 EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); | |
283 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); | |
284 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
285 } | |
286 | |
287 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromSimpleFormData) | |
288 { | |
289 FormData* data = FormData::create(UTF8Encoding()); | |
290 data->append("name1", "value1"); | |
291 data->append("name2", "value2"); | |
292 RefPtr<EncodedFormData> inputFormData = data->encodeMultiPartFormData(); | |
293 | |
294 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
295 EXPECT_EQ(inputFormData, consumer->drainAsFormData()); | |
296 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
297 const char* buffer = nullptr; | |
298 size_t size; | |
299 EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); | |
300 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); | |
301 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
302 } | |
303 | |
304 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromComplexFormData) | |
305 { | |
306 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
307 | |
308 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
309 EXPECT_EQ(inputFormData, consumer->drainAsFormData()); | |
310 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
311 const char* buffer = nullptr; | |
312 size_t size; | |
313 EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); | |
314 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); | |
315 EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState()); | |
316 } | |
317 | |
318 TEST_F(FormDataBytesConsumerTest, ReadAffectsDraining) | |
319 { | |
320 char c; | |
321 size_t readSize = 0; | |
322 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
323 EXPECT_EQ(Result::Ok, consumer->read(&c, 0, &readSize)); | |
324 EXPECT_EQ(0u, readSize); | |
325 EXPECT_FALSE(consumer->drainAsFormData()); | |
326 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
327 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, consumer->getPublic State()); | |
328 } | |
329 | |
330 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDraining) | |
331 { | |
332 const char* buffer = nullptr; | |
333 size_t available = 0; | |
334 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
335 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
336 EXPECT_EQ("hello, world", String(buffer, available)); | |
337 | |
338 ASSERT_EQ(Result::Ok, consumer->endRead(0)); | |
339 EXPECT_FALSE(consumer->drainAsFormData()); | |
340 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
341 EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, consumer->getPublic State()); | |
342 } | |
343 | |
344 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDrainingWithComplexFormData) | |
345 { | |
346 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
347 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), complexFormData(), underlying); | |
348 | |
349 const char* buffer = nullptr; | |
350 size_t available = 0; | |
351 Checkpoint checkpoint; | |
352 | |
353 InSequence s; | |
354 EXPECT_CALL(checkpoint, Call(1)); | |
355 EXPECT_CALL(*underlying, beginRead(&buffer, &available)).WillOnce(Return(Res ult::Ok)); | |
356 EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok)); | |
357 EXPECT_CALL(checkpoint, Call(2)); | |
358 // drainAsFormData / drainAsBlobDataHandle should not be called here. | |
359 EXPECT_CALL(checkpoint, Call(3)); | |
360 | |
361 checkpoint.Call(1); | |
362 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
363 ASSERT_EQ(Result::Ok, consumer->endRead(0)); | |
364 checkpoint.Call(2); | |
365 EXPECT_FALSE(consumer->drainAsFormData()); | |
366 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
367 checkpoint.Call(3); | |
hiroshige
2016/09/16 07:24:34
Could you test getPublicState() here?
yhirano
2016/09/21 03:16:16
In this case consumer->getPublicState() is simply
hiroshige
2016/09/21 07:42:19
I think at least we should test getPublicState() d
yhirano
2016/09/21 08:02:12
Done.
| |
368 } | |
369 | |
370 TEST_F(FormDataBytesConsumerTest, SetClientWithComplexFormData) | |
371 { | |
372 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
373 | |
374 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
375 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), inputFormData, underlying); | |
376 Checkpoint checkpoint; | |
377 | |
378 InSequence s; | |
379 EXPECT_CALL(checkpoint, Call(1)); | |
380 EXPECT_CALL(*underlying, setClient(_)); | |
381 EXPECT_CALL(checkpoint, Call(2)); | |
382 EXPECT_CALL(*underlying, clearClient()); | |
383 EXPECT_CALL(checkpoint, Call(3)); | |
384 | |
385 checkpoint.Call(1); | |
386 consumer->setClient(new NoopClient()); | |
387 checkpoint.Call(2); | |
388 consumer->clearClient(); | |
389 checkpoint.Call(3); | |
390 } | |
391 | |
392 TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData) | |
393 { | |
394 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
395 | |
396 MockBytesConsumer* underlying = MockBytesConsumer::create(); | |
397 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), inputFormData, underlying); | |
398 Checkpoint checkpoint; | |
399 | |
400 InSequence s; | |
401 EXPECT_CALL(checkpoint, Call(1)); | |
402 EXPECT_CALL(*underlying, cancel()); | |
403 EXPECT_CALL(checkpoint, Call(2)); | |
404 | |
405 checkpoint.Call(1); | |
406 consumer->cancel(); | |
407 checkpoint.Call(2); | |
408 } | |
409 | |
410 } // namespace | |
411 } // namespace blink | |
OLD | NEW |