Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(640)

Unified Diff: third_party/WebKit/Source/modules/fetch/FormDataBytesConsumerTest.cpp

Issue 2342023002: Introduce FormDataBytesConsumer (Closed)
Patch Set: fix Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698