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

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
« no previous file with comments | « third_party/WebKit/Source/modules/fetch/FormDataBytesConsumer.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..94ac06429a0525753bc56e077e34be7d4b305546
--- /dev/null
+++ b/third_party/WebKit/Source/modules/fetch/FormDataBytesConsumerTest.cpp
@@ -0,0 +1,385 @@
+// 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/gmock/include/gmock/gmock.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;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Return;
+using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>;
+
+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 MockBytesConsumer : public BytesConsumer {
+public:
+ static MockBytesConsumer* create() { return new ::testing::StrictMock<MockBytesConsumer>(); }
+
+ MOCK_METHOD2(beginRead, Result(const char**, size_t*));
+ MOCK_METHOD1(endRead, Result(size_t));
+ MOCK_METHOD1(setClient, void(Client*));
+ MOCK_METHOD0(clearClient, void());
+ MOCK_METHOD0(cancel, void());
+ MOCK_CONST_METHOD0(getPublicState, PublicState());
+ MOCK_CONST_METHOD0(getError, Error());
+
+ String debugName() const override { return "MockBytesConsumer"; }
+
+protected:
+ MockBytesConsumer() = default;
+};
+
+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, 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, TwoPhaseReadFromStringNonLatin)
+{
+ constexpr UChar cs[] = {0x3042, 0};
+ auto result = (new BytesConsumerTestUtil::TwoPhaseReader(new FormDataBytesConsumer(String(cs))))->run();
+ EXPECT_EQ(Result::Done, result.first);
+ EXPECT_EQ("\xe3\x81\x82", toString(result.second));
+}
+
+TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromArrayBuffer)
+{
+ 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::TwoPhaseReader(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, TwoPhaseReadFromArrayBufferView)
+{
+ 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::TwoPhaseReader(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, TwoPhaseReadFromSimpleFormData)
+{
+ RefPtr<EncodedFormData> data = EncodedFormData::create();
+ data->appendData("foo", 3);
+ data->appendData("hoge", 4);
+
+ auto result = (new BytesConsumerTestUtil::TwoPhaseReader(new FormDataBytesConsumer(getDocument(), data)))->run();
+ EXPECT_EQ(Result::Done, result.first);
+ EXPECT_EQ("foohoge", toString(result.second));
+}
+
+TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData)
+{
+ RefPtr<EncodedFormData> data = complexFormData();
+ MockBytesConsumer* underlying = MockBytesConsumer::create();
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), data, underlying);
+ Checkpoint checkpoint;
+
+ const char* buffer = nullptr;
+ size_t available = 0;
+
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*underlying, beginRead(&buffer, &available)).WillOnce(Return(Result::Ok));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok));
+ EXPECT_CALL(checkpoint, Call(3));
+
+ checkpoint.Call(1);
+ ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
+ checkpoint.Call(2);
+ EXPECT_EQ(Result::Ok, consumer->endRead(0));
+ checkpoint.Call(3);
+}
+
+TEST_F(FormDataBytesConsumerTest, EndReadCanReturnDone)
+{
+ BytesConsumer* consumer = new FormDataBytesConsumer("hello, world");
+ const char* buffer = nullptr;
+ size_t available = 0;
+ ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
+ ASSERT_EQ(12u, available);
+ EXPECT_EQ("hello, world", String(buffer, available));
+ EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, consumer->getPublicState());
+ EXPECT_EQ(Result::Done, consumer->endRead(available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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());
+ const char* buffer = nullptr;
+ size_t available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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());
+ const char* buffer = nullptr;
+ size_t available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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());
+ const char* buffer = nullptr;
+ size_t available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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());
+ const char* buffer = nullptr;
+ size_t available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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 available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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 available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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 available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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 available = 0;
+ EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
+ EXPECT_EQ(BytesConsumer::PublicState::Closed, consumer->getPublicState());
+}
+
+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());
+ EXPECT_FALSE(consumer->drainAsBlobDataHandle());
+ EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, consumer->getPublicState());
+}
+
+TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDrainingWithComplexFormData)
+{
+ MockBytesConsumer* underlying = MockBytesConsumer::create();
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), complexFormData(), underlying);
+
+ const char* buffer = nullptr;
+ size_t available = 0;
+ Checkpoint checkpoint;
+
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*underlying, beginRead(&buffer, &available)).WillOnce(Return(Result::Ok));
+ EXPECT_CALL(*underlying, endRead(0)).WillOnce(Return(Result::Ok));
+ EXPECT_CALL(checkpoint, Call(2));
+ // drainAsFormData / drainAsBlobDataHandle should not be called here.
+ EXPECT_CALL(checkpoint, Call(3));
+ // |consumer| delegates the getPublicState call to |underlying|.
+ EXPECT_CALL(*underlying, getPublicState()).WillOnce(Return(BytesConsumer::PublicState::ReadableOrWaiting));
+ EXPECT_CALL(checkpoint, Call(4));
+
+ checkpoint.Call(1);
+ ASSERT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
+ ASSERT_EQ(Result::Ok, consumer->endRead(0));
+ checkpoint.Call(2);
+ EXPECT_FALSE(consumer->drainAsFormData());
+ EXPECT_FALSE(consumer->drainAsBlobDataHandle());
+ checkpoint.Call(3);
+ EXPECT_EQ(BytesConsumer::PublicState::ReadableOrWaiting, consumer->getPublicState());
+ checkpoint.Call(4);
+}
+
+TEST_F(FormDataBytesConsumerTest, SetClientWithComplexFormData)
+{
+ RefPtr<EncodedFormData> inputFormData = complexFormData();
+
+ MockBytesConsumer* underlying = MockBytesConsumer::create();
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), inputFormData, underlying);
+ Checkpoint checkpoint;
+
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*underlying, setClient(_));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(*underlying, clearClient());
+ EXPECT_CALL(checkpoint, Call(3));
+
+ checkpoint.Call(1);
+ consumer->setClient(new NoopClient());
+ checkpoint.Call(2);
+ consumer->clearClient();
+ checkpoint.Call(3);
+}
+
+TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData)
+{
+ RefPtr<EncodedFormData> inputFormData = complexFormData();
+
+ MockBytesConsumer* underlying = MockBytesConsumer::create();
+ BytesConsumer* consumer = FormDataBytesConsumer::createForTesting(getDocument(), inputFormData, underlying);
+ Checkpoint checkpoint;
+
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*underlying, cancel());
+ EXPECT_CALL(checkpoint, Call(2));
+
+ checkpoint.Call(1);
+ consumer->cancel();
+ checkpoint.Call(2);
+}
+
+} // namespace
+} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/modules/fetch/FormDataBytesConsumer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698