Chromium Code Reviews| 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/gtest/include/gtest/gtest.h" | |
| 16 #include "wtf/RefPtr.h" | |
| 17 #include "wtf/Vector.h" | |
| 18 #include "wtf/text/WTFString.h" | |
| 19 | |
| 20 namespace blink { | |
| 21 namespace { | |
| 22 | |
| 23 using Result = BytesConsumer::Result; | |
| 24 | |
| 25 String toString(const Vector<char>& v) | |
| 26 { | |
| 27 return String(v.data(), v.size()); | |
| 28 } | |
| 29 | |
| 30 PassRefPtr<EncodedFormData> complexFormData() | |
| 31 { | |
| 32 RefPtr<EncodedFormData> data = EncodedFormData::create(); | |
| 33 | |
| 34 data->appendData("foo", 3); | |
| 35 data->appendFileRange("/foo/bar/baz", 3, 4, 5); | |
| 36 data->appendFileSystemURLRange(KURL(KURL(), "file:///foo/bar/baz"), 6, 7, 8) ; | |
| 37 std::unique_ptr<BlobData> blobData = BlobData::create(); | |
| 38 blobData->appendText("hello", false); | |
| 39 auto size = blobData->length(); | |
| 40 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(std::move(blo bData), size); | |
| 41 data->appendBlob(blobDataHandle->uuid(), blobDataHandle); | |
| 42 Vector<char> boundary; | |
| 43 boundary.append("\0", 1); | |
| 44 data->setBoundary(boundary); | |
| 45 return data.release(); | |
| 46 } | |
| 47 | |
| 48 class NoopClient final : public GarbageCollectedFinalized<NoopClient>, public By tesConsumer::Client { | |
| 49 USING_GARBAGE_COLLECTED_MIXIN(NoopClient); | |
| 50 public: | |
| 51 void onStateChange() override {} | |
| 52 }; | |
| 53 | |
| 54 class StubBytesConsumer final : public BytesConsumer { | |
|
hiroshige
2016/09/15 09:47:33
optional: How about creating a class with gmock an
yhirano
2016/09/16 03:10:32
Done.
| |
| 55 public: | |
| 56 // BytesConsumer implementation | |
| 57 Result beginRead(const char** buffer, size_t* available) override | |
| 58 { | |
| 59 ++m_numBeginReadCalled; | |
| 60 *buffer = nullptr; | |
| 61 *available = 0; | |
| 62 return Result::Ok; | |
| 63 } | |
| 64 Result endRead(size_t readSize) override | |
| 65 { | |
| 66 ++m_numEndReadCalled; | |
| 67 return Result::Ok; | |
| 68 } | |
| 69 void setClient(BytesConsumer::Client* client) override | |
| 70 { | |
| 71 ++m_numSetClientCalled; | |
| 72 } | |
| 73 void clearClient() override | |
| 74 { | |
| 75 ++m_numClearClientCalled; | |
| 76 } | |
| 77 void cancel() override | |
| 78 { | |
| 79 m_isCancelled = true; | |
| 80 } | |
| 81 PublicState getPublicState() const override | |
| 82 { | |
| 83 return PublicState::ReadableOrWaiting; | |
| 84 } | |
| 85 Error getError() const override | |
| 86 { | |
| 87 NOTREACHED(); | |
| 88 return Error(); | |
| 89 } | |
| 90 String debugName() const override | |
| 91 { | |
| 92 return "StubBytesConsumer"; | |
| 93 } | |
| 94 | |
| 95 int numBeginReadCalled() const { return m_numBeginReadCalled; } | |
| 96 int numEndReadCalled() const { return m_numEndReadCalled; } | |
| 97 int numSetClientCalled() const { return m_numSetClientCalled; } | |
| 98 int numClearClientCalled() const { return m_numClearClientCalled; } | |
| 99 bool isCancelled() const { return m_isCancelled; } | |
| 100 | |
| 101 private: | |
| 102 int m_numBeginReadCalled = 0; | |
| 103 int m_numEndReadCalled = 0; | |
| 104 int m_numSetClientCalled = 0; | |
| 105 int m_numClearClientCalled = 0; | |
| 106 bool m_isCancelled = false; | |
| 107 }; | |
| 108 | |
| 109 class FormDataBytesConsumerTest : public ::testing::Test { | |
| 110 public: | |
| 111 FormDataBytesConsumerTest() : m_page(DummyPageHolder::create()) {} | |
| 112 | |
| 113 protected: | |
| 114 Document* getDocument() { return &m_page->document(); } | |
| 115 | |
| 116 std::unique_ptr<DummyPageHolder> m_page; | |
| 117 }; | |
| 118 | |
| 119 TEST_F(FormDataBytesConsumerTest, ReadFromString) | |
| 120 { | |
| 121 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(" hello, world")))->run(); | |
| 122 EXPECT_EQ(Result::Done, result.first); | |
| 123 EXPECT_EQ("hello, world", toString(result.second)); | |
| 124 } | |
| 125 | |
| 126 TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromString) | |
| 127 { | |
| 128 auto result = (new BytesConsumerTestUtil::TwoPhaseReader(new FormDataBytesCo nsumer("hello, world")))->run(); | |
| 129 EXPECT_EQ(Result::Done, result.first); | |
| 130 EXPECT_EQ("hello, world", toString(result.second)); | |
| 131 } | |
| 132 | |
| 133 TEST_F(FormDataBytesConsumerTest, ReadFromStringNonLatin) | |
| 134 { | |
| 135 constexpr UChar cs[] = {0x3042, 0}; | |
| 136 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(S tring(cs))))->run(); | |
| 137 EXPECT_EQ(Result::Done, result.first); | |
| 138 EXPECT_EQ("\xe3\x81\x82", toString(result.second)); | |
| 139 } | |
| 140 | |
| 141 TEST_F(FormDataBytesConsumerTest, ReadFromArrayBuffer) | |
| 142 { | |
| 143 constexpr unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x30, 0x42, 0x99, 0x88 }; | |
| 144 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGTH(data) ); | |
| 145 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(b uffer)))->run(); | |
| 146 Vector<char> expected; | |
| 147 expected.append(data, WTF_ARRAY_LENGTH(data)); | |
| 148 | |
| 149 EXPECT_EQ(Result::Done, result.first); | |
| 150 EXPECT_EQ(expected, result.second); | |
| 151 } | |
| 152 | |
| 153 TEST_F(FormDataBytesConsumerTest, ReadFromArrayBufferView) | |
| 154 { | |
| 155 constexpr unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x30, 0x42, 0x99, 0x88 }; | |
| 156 constexpr size_t offset = 1, size = 4; | |
| 157 DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGTH(data) ); | |
| 158 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(D OMUint8Array::create(buffer, offset, size))))->run(); | |
| 159 Vector<char> expected; | |
| 160 expected.append(data + offset, size); | |
| 161 | |
| 162 EXPECT_EQ(Result::Done, result.first); | |
| 163 EXPECT_EQ(expected, result.second); | |
| 164 } | |
| 165 | |
| 166 TEST_F(FormDataBytesConsumerTest, ReadFromSimplFormData) | |
|
hiroshige
2016/09/15 09:47:33
nit: s/Simpl/Simple/
yhirano
2016/09/16 03:10:32
Done.
| |
| 167 { | |
| 168 RefPtr<EncodedFormData> data = EncodedFormData::create(); | |
| 169 data->appendData("foo", 3); | |
| 170 data->appendData("hoge", 4); | |
| 171 | |
| 172 auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(g etDocument(), data)))->run(); | |
| 173 EXPECT_EQ(Result::Done, result.first); | |
| 174 EXPECT_EQ("foohoge", toString(result.second)); | |
| 175 } | |
| 176 | |
| 177 TEST_F(FormDataBytesConsumerTest, ReadFromComplexFormData) | |
| 178 { | |
| 179 RefPtr<EncodedFormData> data = complexFormData(); | |
| 180 StubBytesConsumer* underlying = new StubBytesConsumer(); | |
| 181 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), data, underlying); | |
| 182 | |
| 183 char c; | |
| 184 size_t read = 0; | |
| 185 EXPECT_EQ(Result::Ok, consumer->read(&c, 1, &read)); | |
| 186 EXPECT_EQ(1, underlying->numBeginReadCalled()); | |
| 187 EXPECT_EQ(1, underlying->numEndReadCalled()); | |
| 188 EXPECT_FALSE(underlying->isCancelled()); | |
| 189 EXPECT_EQ(0, underlying->numSetClientCalled()); | |
| 190 } | |
| 191 | |
| 192 TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData) | |
| 193 { | |
| 194 RefPtr<EncodedFormData> data = complexFormData(); | |
| 195 StubBytesConsumer* underlying = new StubBytesConsumer(); | |
| 196 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), data, underlying); | |
| 197 | |
| 198 const char* buffer = nullptr; | |
| 199 size_t available = 0; | |
| 200 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
| 201 EXPECT_EQ(1, underlying->numBeginReadCalled()); | |
| 202 EXPECT_EQ(0, underlying->numEndReadCalled()); | |
| 203 | |
| 204 EXPECT_EQ(Result::Ok, consumer->endRead(0)); | |
| 205 EXPECT_EQ(1, underlying->numBeginReadCalled()); | |
| 206 EXPECT_EQ(1, underlying->numEndReadCalled()); | |
| 207 EXPECT_FALSE(underlying->isCancelled()); | |
| 208 EXPECT_EQ(0, underlying->numSetClientCalled()); | |
| 209 } | |
| 210 | |
| 211 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromString) | |
| 212 { | |
| 213 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
| 214 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
| 215 ASSERT_TRUE(blobDataHandle); | |
| 216 | |
| 217 EXPECT_EQ(String(), blobDataHandle->type()); | |
| 218 EXPECT_EQ(12u, blobDataHandle->size()); | |
| 219 EXPECT_FALSE(consumer->drainAsFormData()); | |
| 220 char c; | |
| 221 size_t readSize; | |
| 222 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
|
hiroshige
2016/09/15 09:47:33
Could you also test getPublicState()?
yhirano
2016/09/16 03:10:32
Done.
| |
| 223 } | |
| 224 | |
| 225 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromArrayBuffer) | |
| 226 { | |
| 227 BytesConsumer* consumer = new FormDataBytesConsumer(DOMArrayBuffer::create(" foo", 3)); | |
| 228 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
| 229 ASSERT_TRUE(blobDataHandle); | |
| 230 | |
| 231 EXPECT_EQ(String(), blobDataHandle->type()); | |
| 232 EXPECT_EQ(3u, blobDataHandle->size()); | |
| 233 EXPECT_FALSE(consumer->drainAsFormData()); | |
| 234 char c; | |
| 235 size_t readSize; | |
| 236 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 237 } | |
| 238 | |
| 239 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromSimpleFormData) | |
| 240 { | |
| 241 FormData* data = FormData::create(UTF8Encoding()); | |
| 242 data->append("name1", "value1"); | |
| 243 data->append("name2", "value2"); | |
| 244 RefPtr<EncodedFormData> inputFormData = data->encodeMultiPartFormData(); | |
| 245 | |
| 246 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
| 247 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
| 248 ASSERT_TRUE(blobDataHandle); | |
| 249 | |
| 250 EXPECT_EQ(String(), blobDataHandle->type()); | |
| 251 EXPECT_EQ(inputFormData->flattenToString().utf8().length(), blobDataHandle-> size()); | |
| 252 EXPECT_FALSE(consumer->drainAsFormData()); | |
| 253 char c; | |
| 254 size_t readSize; | |
| 255 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 256 } | |
| 257 | |
| 258 TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromComplexFormData) | |
| 259 { | |
| 260 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
| 261 | |
| 262 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
| 263 RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); | |
| 264 ASSERT_TRUE(blobDataHandle); | |
| 265 | |
| 266 EXPECT_FALSE(consumer->drainAsFormData()); | |
| 267 char c; | |
| 268 size_t readSize; | |
| 269 EXPECT_EQ(Result::Done, consumer->read(&c, 1, &readSize)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 270 } | |
| 271 | |
| 272 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromString) | |
| 273 { | |
| 274 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
| 275 RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); | |
| 276 ASSERT_TRUE(formData); | |
| 277 EXPECT_EQ("hello, world", 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)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 284 } | |
| 285 | |
| 286 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromArrayBuffer) | |
| 287 { | |
| 288 BytesConsumer* consumer = new FormDataBytesConsumer(DOMArrayBuffer::create(" foo", 3)); | |
| 289 RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); | |
| 290 ASSERT_TRUE(formData); | |
| 291 EXPECT_TRUE(formData->isSafeToSendToAnotherThread()); | |
| 292 EXPECT_EQ("foo", formData->flattenToString()); | |
| 293 | |
| 294 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
| 295 const char* buffer = nullptr; | |
| 296 size_t size; | |
| 297 EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); | |
| 298 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 299 } | |
| 300 | |
| 301 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromSimpleFormData) | |
| 302 { | |
| 303 FormData* data = FormData::create(UTF8Encoding()); | |
| 304 data->append("name1", "value1"); | |
| 305 data->append("name2", "value2"); | |
| 306 RefPtr<EncodedFormData> inputFormData = data->encodeMultiPartFormData(); | |
| 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)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 315 } | |
| 316 | |
| 317 TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromComplexFormData) | |
| 318 { | |
| 319 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
| 320 | |
| 321 BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputForm Data); | |
| 322 EXPECT_EQ(inputFormData, consumer->drainAsFormData()); | |
| 323 EXPECT_FALSE(consumer->drainAsBlobDataHandle()); | |
| 324 const char* buffer = nullptr; | |
| 325 size_t size; | |
| 326 EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); | |
| 327 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 328 } | |
| 329 | |
| 330 TEST_F(FormDataBytesConsumerTest, ReadAffectsDraining) | |
| 331 { | |
| 332 char c; | |
| 333 size_t readSize = 0; | |
| 334 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
| 335 EXPECT_EQ(Result::Ok, consumer->read(&c, 0, &readSize)); | |
| 336 EXPECT_EQ(0u, readSize); | |
| 337 EXPECT_FALSE(consumer->drainAsFormData()); | |
|
hiroshige
2016/09/15 09:47:33
Could you also test drainAsBlobDataHandle()?
yhirano
2016/09/16 03:10:32
Done.
| |
| 338 } | |
| 339 | |
| 340 TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDraining) | |
| 341 { | |
| 342 const char* buffer = nullptr; | |
| 343 size_t available = 0; | |
| 344 BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); | |
| 345 ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); | |
| 346 EXPECT_EQ("hello, world", String(buffer, available)); | |
| 347 | |
| 348 ASSERT_EQ(Result::Ok, consumer->endRead(0)); | |
| 349 EXPECT_FALSE(consumer->drainAsFormData()); | |
|
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
| |
| 350 } | |
| 351 | |
|
hiroshige
2016/09/15 09:47:33
Could you also test ReadAffectsDraining/BeginReadA
yhirano
2016/09/16 03:10:32
Done.
| |
| 352 TEST_F(FormDataBytesConsumerTest, SetClientWithComplexFormData) | |
| 353 { | |
| 354 RefPtr<EncodedFormData> inputFormData = complexFormData(); | |
| 355 | |
| 356 StubBytesConsumer* underlying = new StubBytesConsumer(); | |
| 357 BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocumen t(), inputFormData, underlying); | |
| 358 | |
| 359 EXPECT_EQ(0, underlying->numSetClientCalled()); | |
| 360 EXPECT_EQ(0, underlying->numClearClientCalled()); | |
| 361 | |
| 362 consumer->setClient(new NoopClient()); | |
| 363 | |
| 364 EXPECT_EQ(1, underlying->numSetClientCalled()); | |
| 365 EXPECT_EQ(0, underlying->numClearClientCalled()); | |
| 366 | |
| 367 consumer->clearClient(); | |
| 368 | |
| 369 EXPECT_EQ(1, underlying->numSetClientCalled()); | |
| 370 EXPECT_EQ(1, underlying->numClearClientCalled()); | |
| 371 } | |
| 372 | |
| 373 } // namespace | |
| 374 } // namespace blink | |
| OLD | NEW |