Index: third_party/WebKit/Source/modules/fetch/FormDataBytesConsumerTest.cpp |
diff --git a/third_party/WebKit/Source/modules/fetch/FormDataBytesConsumerTest.cpp b/third_party/WebKit/Source/modules/fetch/FormDataBytesConsumerTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b44df806cabc41eaec51592a24c04bc8f6231873 |
--- /dev/null |
+++ b/third_party/WebKit/Source/modules/fetch/FormDataBytesConsumerTest.cpp |
@@ -0,0 +1,374 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "modules/fetch/FormDataBytesConsumer.h" |
+ |
+#include "core/dom/DOMArrayBuffer.h" |
+#include "core/dom/DOMTypedArray.h" |
+#include "core/dom/Document.h" |
+#include "core/html/FormData.h" |
+#include "core/testing/DummyPageHolder.h" |
+#include "modules/fetch/BytesConsumerTestUtil.h" |
+#include "platform/blob/BlobData.h" |
+#include "platform/network/EncodedFormData.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "wtf/RefPtr.h" |
+#include "wtf/Vector.h" |
+#include "wtf/text/WTFString.h" |
+ |
+namespace blink { |
+namespace { |
+ |
+using Result = BytesConsumer::Result; |
+ |
+String toString(const Vector<char>& v) |
+{ |
+ return String(v.data(), v.size()); |
+} |
+ |
+PassRefPtr<EncodedFormData> complexFormData() |
+{ |
+ RefPtr<EncodedFormData> data = EncodedFormData::create(); |
+ |
+ data->appendData("foo", 3); |
+ data->appendFileRange("/foo/bar/baz", 3, 4, 5); |
+ data->appendFileSystemURLRange(KURL(KURL(), "file:///foo/bar/baz"), 6, 7, 8); |
+ std::unique_ptr<BlobData> blobData = BlobData::create(); |
+ blobData->appendText("hello", false); |
+ auto size = blobData->length(); |
+ RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(std::move(blobData), size); |
+ data->appendBlob(blobDataHandle->uuid(), blobDataHandle); |
+ Vector<char> boundary; |
+ boundary.append("\0", 1); |
+ data->setBoundary(boundary); |
+ return data.release(); |
+} |
+ |
+class NoopClient final : public GarbageCollectedFinalized<NoopClient>, public BytesConsumer::Client { |
+ USING_GARBAGE_COLLECTED_MIXIN(NoopClient); |
+public: |
+ void onStateChange() override {} |
+}; |
+ |
+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.
|
+public: |
+ // BytesConsumer implementation |
+ Result beginRead(const char** buffer, size_t* available) override |
+ { |
+ ++m_numBeginReadCalled; |
+ *buffer = nullptr; |
+ *available = 0; |
+ return Result::Ok; |
+ } |
+ Result endRead(size_t readSize) override |
+ { |
+ ++m_numEndReadCalled; |
+ return Result::Ok; |
+ } |
+ void setClient(BytesConsumer::Client* client) override |
+ { |
+ ++m_numSetClientCalled; |
+ } |
+ void clearClient() override |
+ { |
+ ++m_numClearClientCalled; |
+ } |
+ void cancel() override |
+ { |
+ m_isCancelled = true; |
+ } |
+ PublicState getPublicState() const override |
+ { |
+ return PublicState::ReadableOrWaiting; |
+ } |
+ Error getError() const override |
+ { |
+ NOTREACHED(); |
+ return Error(); |
+ } |
+ String debugName() const override |
+ { |
+ return "StubBytesConsumer"; |
+ } |
+ |
+ int numBeginReadCalled() const { return m_numBeginReadCalled; } |
+ int numEndReadCalled() const { return m_numEndReadCalled; } |
+ int numSetClientCalled() const { return m_numSetClientCalled; } |
+ int numClearClientCalled() const { return m_numClearClientCalled; } |
+ bool isCancelled() const { return m_isCancelled; } |
+ |
+private: |
+ int m_numBeginReadCalled = 0; |
+ int m_numEndReadCalled = 0; |
+ int m_numSetClientCalled = 0; |
+ int m_numClearClientCalled = 0; |
+ bool m_isCancelled = false; |
+}; |
+ |
+class FormDataBytesConsumerTest : public ::testing::Test { |
+public: |
+ FormDataBytesConsumerTest() : m_page(DummyPageHolder::create()) {} |
+ |
+protected: |
+ Document* getDocument() { return &m_page->document(); } |
+ |
+ std::unique_ptr<DummyPageHolder> m_page; |
+}; |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadFromString) |
+{ |
+ auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer("hello, world")))->run(); |
+ EXPECT_EQ(Result::Done, result.first); |
+ EXPECT_EQ("hello, world", toString(result.second)); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromString) |
+{ |
+ auto result = (new BytesConsumerTestUtil::TwoPhaseReader(new FormDataBytesConsumer("hello, world")))->run(); |
+ EXPECT_EQ(Result::Done, result.first); |
+ EXPECT_EQ("hello, world", toString(result.second)); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadFromStringNonLatin) |
+{ |
+ constexpr UChar cs[] = {0x3042, 0}; |
+ auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(String(cs))))->run(); |
+ EXPECT_EQ(Result::Done, result.first); |
+ EXPECT_EQ("\xe3\x81\x82", toString(result.second)); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadFromArrayBuffer) |
+{ |
+ constexpr unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x30, 0x42, 0x99, 0x88 }; |
+ DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGTH(data)); |
+ auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(buffer)))->run(); |
+ Vector<char> expected; |
+ expected.append(data, WTF_ARRAY_LENGTH(data)); |
+ |
+ EXPECT_EQ(Result::Done, result.first); |
+ EXPECT_EQ(expected, result.second); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadFromArrayBufferView) |
+{ |
+ constexpr unsigned char data[] = { 0x21, 0xfe, 0x00, 0x00, 0xff, 0xa3, 0x42, 0x30, 0x42, 0x99, 0x88 }; |
+ constexpr size_t offset = 1, size = 4; |
+ DOMArrayBuffer* buffer = DOMArrayBuffer::create(data, WTF_ARRAY_LENGTH(data)); |
+ auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(DOMUint8Array::create(buffer, offset, size))))->run(); |
+ Vector<char> expected; |
+ expected.append(data + offset, size); |
+ |
+ EXPECT_EQ(Result::Done, result.first); |
+ EXPECT_EQ(expected, result.second); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadFromSimplFormData) |
hiroshige
2016/09/15 09:47:33
nit: s/Simpl/Simple/
yhirano
2016/09/16 03:10:32
Done.
|
+{ |
+ RefPtr<EncodedFormData> data = EncodedFormData::create(); |
+ data->appendData("foo", 3); |
+ data->appendData("hoge", 4); |
+ |
+ auto result = (new BytesConsumerTestUtil::Reader(new FormDataBytesConsumer(getDocument(), data)))->run(); |
+ EXPECT_EQ(Result::Done, result.first); |
+ EXPECT_EQ("foohoge", toString(result.second)); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadFromComplexFormData) |
+{ |
+ RefPtr<EncodedFormData> data = complexFormData(); |
+ StubBytesConsumer* underlying = new StubBytesConsumer(); |
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), data, underlying); |
+ |
+ char c; |
+ size_t read = 0; |
+ EXPECT_EQ(Result::Ok, consumer->read(&c, 1, &read)); |
+ EXPECT_EQ(1, underlying->numBeginReadCalled()); |
+ EXPECT_EQ(1, underlying->numEndReadCalled()); |
+ EXPECT_FALSE(underlying->isCancelled()); |
+ EXPECT_EQ(0, underlying->numSetClientCalled()); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData) |
+{ |
+ RefPtr<EncodedFormData> data = complexFormData(); |
+ StubBytesConsumer* underlying = new StubBytesConsumer(); |
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), data, underlying); |
+ |
+ const char* buffer = nullptr; |
+ size_t available = 0; |
+ ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); |
+ EXPECT_EQ(1, underlying->numBeginReadCalled()); |
+ EXPECT_EQ(0, underlying->numEndReadCalled()); |
+ |
+ EXPECT_EQ(Result::Ok, consumer->endRead(0)); |
+ EXPECT_EQ(1, underlying->numBeginReadCalled()); |
+ EXPECT_EQ(1, underlying->numEndReadCalled()); |
+ EXPECT_FALSE(underlying->isCancelled()); |
+ EXPECT_EQ(0, underlying->numSetClientCalled()); |
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromString) |
+{ |
+ BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
+ RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); |
+ ASSERT_TRUE(blobDataHandle); |
+ |
+ EXPECT_EQ(String(), blobDataHandle->type()); |
+ EXPECT_EQ(12u, blobDataHandle->size()); |
+ EXPECT_FALSE(consumer->drainAsFormData()); |
+ char c; |
+ size_t readSize; |
+ 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.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromArrayBuffer) |
+{ |
+ BytesConsumer* consumer = new FormDataBytesConsumer(DOMArrayBuffer::create("foo", 3)); |
+ RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); |
+ ASSERT_TRUE(blobDataHandle); |
+ |
+ EXPECT_EQ(String(), blobDataHandle->type()); |
+ EXPECT_EQ(3u, blobDataHandle->size()); |
+ EXPECT_FALSE(consumer->drainAsFormData()); |
+ char c; |
+ size_t readSize; |
+ 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.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromSimpleFormData) |
+{ |
+ FormData* data = FormData::create(UTF8Encoding()); |
+ data->append("name1", "value1"); |
+ data->append("name2", "value2"); |
+ RefPtr<EncodedFormData> inputFormData = data->encodeMultiPartFormData(); |
+ |
+ BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputFormData); |
+ RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); |
+ ASSERT_TRUE(blobDataHandle); |
+ |
+ EXPECT_EQ(String(), blobDataHandle->type()); |
+ EXPECT_EQ(inputFormData->flattenToString().utf8().length(), blobDataHandle->size()); |
+ EXPECT_FALSE(consumer->drainAsFormData()); |
+ char c; |
+ size_t readSize; |
+ 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.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromComplexFormData) |
+{ |
+ RefPtr<EncodedFormData> inputFormData = complexFormData(); |
+ |
+ BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputFormData); |
+ RefPtr<BlobDataHandle> blobDataHandle = consumer->drainAsBlobDataHandle(); |
+ ASSERT_TRUE(blobDataHandle); |
+ |
+ EXPECT_FALSE(consumer->drainAsFormData()); |
+ char c; |
+ size_t readSize; |
+ 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.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromString) |
+{ |
+ BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
+ RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); |
+ ASSERT_TRUE(formData); |
+ EXPECT_EQ("hello, world", formData->flattenToString()); |
+ |
+ EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
+ const char* buffer = nullptr; |
+ size_t size; |
+ EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); |
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); |
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromArrayBuffer) |
+{ |
+ BytesConsumer* consumer = new FormDataBytesConsumer(DOMArrayBuffer::create("foo", 3)); |
+ RefPtr<EncodedFormData> formData = consumer->drainAsFormData(); |
+ ASSERT_TRUE(formData); |
+ EXPECT_TRUE(formData->isSafeToSendToAnotherThread()); |
+ EXPECT_EQ("foo", formData->flattenToString()); |
+ |
+ EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
+ const char* buffer = nullptr; |
+ size_t size; |
+ EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); |
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); |
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromSimpleFormData) |
+{ |
+ FormData* data = FormData::create(UTF8Encoding()); |
+ data->append("name1", "value1"); |
+ data->append("name2", "value2"); |
+ RefPtr<EncodedFormData> inputFormData = data->encodeMultiPartFormData(); |
+ |
+ BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputFormData); |
+ EXPECT_EQ(inputFormData, consumer->drainAsFormData()); |
+ EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
+ const char* buffer = nullptr; |
+ size_t size; |
+ EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); |
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); |
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromComplexFormData) |
+{ |
+ RefPtr<EncodedFormData> inputFormData = complexFormData(); |
+ |
+ BytesConsumer* consumer = new FormDataBytesConsumer(getDocument(), inputFormData); |
+ EXPECT_EQ(inputFormData, consumer->drainAsFormData()); |
+ EXPECT_FALSE(consumer->drainAsBlobDataHandle()); |
+ const char* buffer = nullptr; |
+ size_t size; |
+ EXPECT_EQ(Result::Done, consumer->read(nullptr, 0, &size)); |
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &size)); |
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, ReadAffectsDraining) |
+{ |
+ char c; |
+ size_t readSize = 0; |
+ BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
+ EXPECT_EQ(Result::Ok, consumer->read(&c, 0, &readSize)); |
+ EXPECT_EQ(0u, readSize); |
+ EXPECT_FALSE(consumer->drainAsFormData()); |
hiroshige
2016/09/15 09:47:33
Could you also test drainAsBlobDataHandle()?
yhirano
2016/09/16 03:10:32
Done.
|
+} |
+ |
+TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDraining) |
+{ |
+ const char* buffer = nullptr; |
+ size_t available = 0; |
+ BytesConsumer* consumer = new FormDataBytesConsumer("hello, world"); |
+ ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available)); |
+ EXPECT_EQ("hello, world", String(buffer, available)); |
+ |
+ ASSERT_EQ(Result::Ok, consumer->endRead(0)); |
+ EXPECT_FALSE(consumer->drainAsFormData()); |
hiroshige
2016/09/15 09:47:33
ditto.
yhirano
2016/09/16 03:10:32
Done.
|
+} |
+ |
hiroshige
2016/09/15 09:47:33
Could you also test ReadAffectsDraining/BeginReadA
yhirano
2016/09/16 03:10:32
Done.
|
+TEST_F(FormDataBytesConsumerTest, SetClientWithComplexFormData) |
+{ |
+ RefPtr<EncodedFormData> inputFormData = complexFormData(); |
+ |
+ StubBytesConsumer* underlying = new StubBytesConsumer(); |
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), inputFormData, underlying); |
+ |
+ EXPECT_EQ(0, underlying->numSetClientCalled()); |
+ EXPECT_EQ(0, underlying->numClearClientCalled()); |
+ |
+ consumer->setClient(new NoopClient()); |
+ |
+ EXPECT_EQ(1, underlying->numSetClientCalled()); |
+ EXPECT_EQ(0, underlying->numClearClientCalled()); |
+ |
+ consumer->clearClient(); |
+ |
+ EXPECT_EQ(1, underlying->numSetClientCalled()); |
+ EXPECT_EQ(1, underlying->numClearClientCalled()); |
+} |
+ |
+} // namespace |
+} // namespace blink |