| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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/FetchBlobDataConsumerHandle.h" | |
| 6 | |
| 7 #include "core/dom/ExecutionContext.h" | |
| 8 #include "core/fetch/ResourceLoaderOptions.h" | |
| 9 #include "core/loader/MockThreadableLoader.h" | |
| 10 #include "core/loader/ThreadableLoaderClient.h" | |
| 11 #include "core/testing/DummyPageHolder.h" | |
| 12 #include "modules/fetch/DataConsumerHandleTestUtil.h" | |
| 13 #include "platform/blob/BlobData.h" | |
| 14 #include "platform/blob/BlobURL.h" | |
| 15 #include "platform/network/ResourceError.h" | |
| 16 #include "platform/network/ResourceRequest.h" | |
| 17 #include "platform/network/ResourceResponse.h" | |
| 18 #include "platform/testing/UnitTestHelpers.h" | |
| 19 #include "testing/gmock/include/gmock/gmock.h" | |
| 20 #include "testing/gtest/include/gtest/gtest.h" | |
| 21 #include "wtf/PassRefPtr.h" | |
| 22 #include "wtf/PtrUtil.h" | |
| 23 #include "wtf/RefPtr.h" | |
| 24 #include <memory> | |
| 25 #include <string.h> | |
| 26 | |
| 27 namespace blink { | |
| 28 namespace { | |
| 29 | |
| 30 using Result = WebDataConsumerHandle::Result; | |
| 31 const Result kShouldWait = WebDataConsumerHandle::ShouldWait; | |
| 32 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError; | |
| 33 const Result kDone = WebDataConsumerHandle::Done; | |
| 34 using Flags = WebDataConsumerHandle::Flags; | |
| 35 const Flags kNone = WebDataConsumerHandle::FlagNone; | |
| 36 using Thread = DataConsumerHandleTestUtil::Thread; | |
| 37 using HandleReader = DataConsumerHandleTestUtil::HandleReader; | |
| 38 using HandleTwoPhaseReader = DataConsumerHandleTestUtil::HandleTwoPhaseReader; | |
| 39 using HandleReadResult = DataConsumerHandleTestUtil::HandleReadResult; | |
| 40 using ReplayingHandle = DataConsumerHandleTestUtil::ReplayingHandle; | |
| 41 using Command = DataConsumerHandleTestUtil::Command; | |
| 42 template <typename T> | |
| 43 using HandleReaderRunner = DataConsumerHandleTestUtil::HandleReaderRunner<T>; | |
| 44 | |
| 45 using ::testing::_; | |
| 46 using ::testing::DoAll; | |
| 47 using ::testing::InSequence; | |
| 48 using ::testing::Ref; | |
| 49 using ::testing::Return; | |
| 50 using ::testing::SaveArg; | |
| 51 using ::testing::StrictMock; | |
| 52 using Checkpoint = StrictMock<::testing::MockFunction<void(int)>>; | |
| 53 | |
| 54 class MockLoaderFactory : public FetchBlobDataConsumerHandle::LoaderFactory { | |
| 55 public: | |
| 56 MOCK_METHOD4(create, ThreadableLoader*(ExecutionContext&, ThreadableLoaderCl
ient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&)); | |
| 57 }; | |
| 58 | |
| 59 PassRefPtr<BlobDataHandle> createBlobDataHandle(const char* s) | |
| 60 { | |
| 61 std::unique_ptr<BlobData> data = BlobData::create(); | |
| 62 data->appendText(s, false); | |
| 63 auto size = data->length(); | |
| 64 return BlobDataHandle::create(std::move(data), size); | |
| 65 } | |
| 66 | |
| 67 String toString(const Vector<char>& data) | |
| 68 { | |
| 69 return String(data.data(), data.size()); | |
| 70 } | |
| 71 | |
| 72 class FetchBlobDataConsumerHandleTest : public ::testing::Test { | |
| 73 public: | |
| 74 FetchBlobDataConsumerHandleTest() | |
| 75 : m_dummyPageHolder(DummyPageHolder::create(IntSize(1, 1))) {} | |
| 76 ~FetchBlobDataConsumerHandleTest() override | |
| 77 { | |
| 78 m_dummyPageHolder = nullptr; | |
| 79 // We need this to collect garbage-collected mocks. | |
| 80 ThreadState::current()-> collectAllGarbage(); | |
| 81 } | |
| 82 | |
| 83 Document& document() { return m_dummyPageHolder->document(); } | |
| 84 | |
| 85 private: | |
| 86 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; | |
| 87 }; | |
| 88 | |
| 89 TEST_F(FetchBlobDataConsumerHandleTest, CreateLoader) | |
| 90 { | |
| 91 auto factory = new StrictMock<MockLoaderFactory>; | |
| 92 Checkpoint checkpoint; | |
| 93 | |
| 94 ResourceRequest request; | |
| 95 ThreadableLoaderOptions options; | |
| 96 ResourceLoaderOptions resourceLoaderOptions; | |
| 97 | |
| 98 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 99 | |
| 100 InSequence s; | |
| 101 EXPECT_CALL(checkpoint, Call(1)); | |
| 102 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll( | |
| 103 SaveArg<2>(&options), | |
| 104 SaveArg<3>(&resourceLoaderOptions), | |
| 105 Return(loader.get()))); | |
| 106 EXPECT_CALL(*loader, start(_)).WillOnce(SaveArg<0>(&request)); | |
| 107 EXPECT_CALL(checkpoint, Call(2)); | |
| 108 EXPECT_CALL(*loader, cancel()); | |
| 109 | |
| 110 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 111 std::unique_ptr<WebDataConsumerHandle> handle | |
| 112 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 113 testing::runPendingTasks(); | |
| 114 | |
| 115 char buffer[1]; | |
| 116 size_t size = 0; | |
| 117 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(buffer, sizeof(bu
ffer), kNone, &size)); | |
| 118 checkpoint.Call(1); | |
| 119 testing::runPendingTasks(); | |
| 120 checkpoint.Call(2); | |
| 121 | |
| 122 EXPECT_TRUE(request.url().getString().startsWith("blob:")); | |
| 123 EXPECT_TRUE(request.useStreamOnResponse()); | |
| 124 | |
| 125 EXPECT_EQ(ConsiderPreflight, options.preflightPolicy); | |
| 126 EXPECT_EQ(DenyCrossOriginRequests, options.crossOriginRequestPolicy); | |
| 127 EXPECT_EQ(DoNotEnforceContentSecurityPolicy, options.contentSecurityPolicyEn
forcement); | |
| 128 | |
| 129 EXPECT_EQ(DoNotBufferData, resourceLoaderOptions.dataBufferingPolicy); | |
| 130 EXPECT_EQ(DoNotAllowStoredCredentials, resourceLoaderOptions.allowCredential
s); | |
| 131 EXPECT_EQ(ClientDidNotRequestCredentials, resourceLoaderOptions.credentialsR
equested); | |
| 132 EXPECT_EQ(CheckContentSecurityPolicy, resourceLoaderOptions.contentSecurityP
olicyOption); | |
| 133 EXPECT_EQ(DocumentContext, resourceLoaderOptions.requestInitiatorContext); | |
| 134 EXPECT_EQ(RequestAsynchronously, resourceLoaderOptions.synchronousPolicy); | |
| 135 EXPECT_EQ(NotCORSEnabled, resourceLoaderOptions.corsEnabled); | |
| 136 } | |
| 137 | |
| 138 TEST_F(FetchBlobDataConsumerHandleTest, ZeroByteReadDoesNotCreateLoader) | |
| 139 { | |
| 140 auto factory = new StrictMock<MockLoaderFactory>; | |
| 141 Checkpoint checkpoint; | |
| 142 | |
| 143 InSequence s; | |
| 144 EXPECT_CALL(checkpoint, Call(1)); | |
| 145 EXPECT_CALL(checkpoint, Call(2)); | |
| 146 | |
| 147 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 148 std::unique_ptr<WebDataConsumerHandle> handle | |
| 149 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 150 testing::runPendingTasks(); | |
| 151 | |
| 152 size_t size = 0; | |
| 153 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(nullptr, 0, kNone
, &size)); | |
| 154 checkpoint.Call(1); | |
| 155 testing::runPendingTasks(); | |
| 156 checkpoint.Call(2); | |
| 157 } | |
| 158 | |
| 159 TEST_F(FetchBlobDataConsumerHandleTest, CancelLoaderWhenStopped) | |
| 160 { | |
| 161 auto factory = new StrictMock<MockLoaderFactory>; | |
| 162 Checkpoint checkpoint; | |
| 163 | |
| 164 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 165 | |
| 166 InSequence s; | |
| 167 EXPECT_CALL(checkpoint, Call(1)); | |
| 168 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(Return(load
er.get())); | |
| 169 EXPECT_CALL(*loader, start(_)); | |
| 170 EXPECT_CALL(checkpoint, Call(2)); | |
| 171 EXPECT_CALL(*loader, cancel()); | |
| 172 EXPECT_CALL(checkpoint, Call(3)); | |
| 173 | |
| 174 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 175 std::unique_ptr<WebDataConsumerHandle> handle | |
| 176 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 177 testing::runPendingTasks(); | |
| 178 | |
| 179 char buffer[1]; | |
| 180 size_t size = 0; | |
| 181 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(buffer, sizeof(bu
ffer), kNone, &size)); | |
| 182 checkpoint.Call(1); | |
| 183 testing::runPendingTasks(); | |
| 184 checkpoint.Call(2); | |
| 185 document().stopActiveDOMObjects(); | |
| 186 checkpoint.Call(3); | |
| 187 } | |
| 188 | |
| 189 TEST_F(FetchBlobDataConsumerHandleTest, CancelLoaderWhenDestinationDetached) | |
| 190 { | |
| 191 auto factory = new StrictMock<MockLoaderFactory>; | |
| 192 Checkpoint checkpoint; | |
| 193 | |
| 194 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 195 | |
| 196 InSequence s; | |
| 197 EXPECT_CALL(checkpoint, Call(1)); | |
| 198 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(Return(load
er.get())); | |
| 199 EXPECT_CALL(*loader, start(_)); | |
| 200 EXPECT_CALL(checkpoint, Call(2)); | |
| 201 EXPECT_CALL(checkpoint, Call(3)); | |
| 202 EXPECT_CALL(*loader, cancel()); | |
| 203 EXPECT_CALL(checkpoint, Call(4)); | |
| 204 | |
| 205 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 206 std::unique_ptr<WebDataConsumerHandle> handle | |
| 207 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 208 std::unique_ptr<WebDataConsumerHandle::Reader> reader = handle->obtainReader
(nullptr); | |
| 209 testing::runPendingTasks(); | |
| 210 | |
| 211 char buffer[1]; | |
| 212 size_t size = 0; | |
| 213 ASSERT_EQ(kShouldWait, reader->read(buffer, sizeof(buffer), kNone, &size)); | |
| 214 checkpoint.Call(1); | |
| 215 testing::runPendingTasks(); | |
| 216 checkpoint.Call(2); | |
| 217 handle = nullptr; | |
| 218 reader = nullptr; | |
| 219 checkpoint.Call(3); | |
| 220 ThreadState::current()-> collectAllGarbage(); | |
| 221 checkpoint.Call(4); | |
| 222 } | |
| 223 | |
| 224 TEST_F(FetchBlobDataConsumerHandleTest, ReadTest) | |
| 225 { | |
| 226 auto factory = new StrictMock<MockLoaderFactory>; | |
| 227 Checkpoint checkpoint; | |
| 228 | |
| 229 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 230 ThreadableLoaderClient* client = nullptr; | |
| 231 | |
| 232 InSequence s; | |
| 233 EXPECT_CALL(checkpoint, Call(1)); | |
| 234 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveA
rg<1>(&client), Return(loader.get()))); | |
| 235 EXPECT_CALL(*loader, start(_)); | |
| 236 EXPECT_CALL(checkpoint, Call(2)); | |
| 237 EXPECT_CALL(*loader, cancel()); | |
| 238 | |
| 239 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 240 std::unique_ptr<WebDataConsumerHandle> handle | |
| 241 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 242 | |
| 243 std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create(); | |
| 244 src->add(Command(Command::Wait)); | |
| 245 src->add(Command(Command::Data, "hello, ")); | |
| 246 src->add(Command(Command::Data, "world")); | |
| 247 src->add(Command(Command::Wait)); | |
| 248 src->add(Command(Command::Done)); | |
| 249 | |
| 250 char buffer[1]; | |
| 251 size_t size = 0; | |
| 252 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(buffer, sizeof(bu
ffer), kNone, &size)); | |
| 253 checkpoint.Call(1); | |
| 254 testing::runPendingTasks(); | |
| 255 checkpoint.Call(2); | |
| 256 client->didReceiveResponse(0, ResourceResponse(), std::move(src)); | |
| 257 HandleReaderRunner<HandleReader> runner(std::move(handle)); | |
| 258 std::unique_ptr<HandleReadResult> r = runner.wait(); | |
| 259 EXPECT_EQ(kDone, r->result()); | |
| 260 EXPECT_EQ("hello, world", toString(r->data())); | |
| 261 } | |
| 262 | |
| 263 TEST_F(FetchBlobDataConsumerHandleTest, TwoPhaseReadTest) | |
| 264 { | |
| 265 auto factory = new StrictMock<MockLoaderFactory>; | |
| 266 Checkpoint checkpoint; | |
| 267 | |
| 268 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 269 ThreadableLoaderClient* client = nullptr; | |
| 270 | |
| 271 InSequence s; | |
| 272 EXPECT_CALL(checkpoint, Call(1)); | |
| 273 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveA
rg<1>(&client), Return(loader.get()))); | |
| 274 EXPECT_CALL(*loader, start(_)); | |
| 275 EXPECT_CALL(checkpoint, Call(2)); | |
| 276 EXPECT_CALL(*loader, cancel()); | |
| 277 | |
| 278 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 279 std::unique_ptr<WebDataConsumerHandle> handle | |
| 280 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 281 | |
| 282 std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create(); | |
| 283 src->add(Command(Command::Wait)); | |
| 284 src->add(Command(Command::Data, "hello, ")); | |
| 285 src->add(Command(Command::Data, "world")); | |
| 286 src->add(Command(Command::Wait)); | |
| 287 src->add(Command(Command::Done)); | |
| 288 | |
| 289 char buffer[1]; | |
| 290 size_t size = 0; | |
| 291 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(buffer, sizeof(bu
ffer), kNone, &size)); | |
| 292 checkpoint.Call(1); | |
| 293 testing::runPendingTasks(); | |
| 294 checkpoint.Call(2); | |
| 295 client->didReceiveResponse(0, ResourceResponse(), std::move(src)); | |
| 296 HandleReaderRunner<HandleTwoPhaseReader> runner(std::move(handle)); | |
| 297 std::unique_ptr<HandleReadResult> r = runner.wait(); | |
| 298 EXPECT_EQ(kDone, r->result()); | |
| 299 EXPECT_EQ("hello, world", toString(r->data())); | |
| 300 } | |
| 301 | |
| 302 TEST_F(FetchBlobDataConsumerHandleTest, LoadErrorTest) | |
| 303 { | |
| 304 auto factory = new StrictMock<MockLoaderFactory>; | |
| 305 Checkpoint checkpoint; | |
| 306 | |
| 307 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 308 ThreadableLoaderClient* client = nullptr; | |
| 309 | |
| 310 InSequence s; | |
| 311 EXPECT_CALL(checkpoint, Call(1)); | |
| 312 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveA
rg<1>(&client), Return(loader.get()))); | |
| 313 EXPECT_CALL(*loader, start(_)); | |
| 314 EXPECT_CALL(checkpoint, Call(2)); | |
| 315 | |
| 316 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 317 std::unique_ptr<WebDataConsumerHandle> handle | |
| 318 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 319 | |
| 320 char buffer[1]; | |
| 321 size_t size = 0; | |
| 322 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(buffer, sizeof(bu
ffer), kNone, &size)); | |
| 323 checkpoint.Call(1); | |
| 324 testing::runPendingTasks(); | |
| 325 checkpoint.Call(2); | |
| 326 client->didFail(ResourceError()); | |
| 327 HandleReaderRunner<HandleReader> runner(std::move(handle)); | |
| 328 std::unique_ptr<HandleReadResult> r = runner.wait(); | |
| 329 EXPECT_EQ(kUnexpectedError, r->result()); | |
| 330 } | |
| 331 | |
| 332 TEST_F(FetchBlobDataConsumerHandleTest, BodyLoadErrorTest) | |
| 333 { | |
| 334 auto factory = new StrictMock<MockLoaderFactory>; | |
| 335 Checkpoint checkpoint; | |
| 336 | |
| 337 Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); | |
| 338 ThreadableLoaderClient* client = nullptr; | |
| 339 | |
| 340 InSequence s; | |
| 341 EXPECT_CALL(checkpoint, Call(1)); | |
| 342 EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveA
rg<1>(&client), Return(loader.get()))); | |
| 343 EXPECT_CALL(*loader, start(_)); | |
| 344 EXPECT_CALL(checkpoint, Call(2)); | |
| 345 EXPECT_CALL(*loader, cancel()); | |
| 346 | |
| 347 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 348 std::unique_ptr<WebDataConsumerHandle> handle | |
| 349 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 350 | |
| 351 std::unique_ptr<ReplayingHandle> src = ReplayingHandle::create(); | |
| 352 src->add(Command(Command::Wait)); | |
| 353 src->add(Command(Command::Data, "hello, ")); | |
| 354 src->add(Command(Command::Error)); | |
| 355 | |
| 356 char buffer[1]; | |
| 357 size_t size = 0; | |
| 358 ASSERT_EQ(kShouldWait, handle->obtainReader(nullptr)->read(buffer, sizeof(bu
ffer), kNone, &size)); | |
| 359 checkpoint.Call(1); | |
| 360 testing::runPendingTasks(); | |
| 361 checkpoint.Call(2); | |
| 362 client->didReceiveResponse(0, ResourceResponse(), std::move(src)); | |
| 363 HandleReaderRunner<HandleReader> runner(std::move(handle)); | |
| 364 std::unique_ptr<HandleReadResult> r = runner.wait(); | |
| 365 EXPECT_EQ(kUnexpectedError, r->result()); | |
| 366 } | |
| 367 | |
| 368 TEST_F(FetchBlobDataConsumerHandleTest, DrainAsBlobDataHandle) | |
| 369 { | |
| 370 auto factory = new StrictMock<MockLoaderFactory>; | |
| 371 | |
| 372 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 373 std::unique_ptr<FetchDataConsumerHandle> handle | |
| 374 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 375 | |
| 376 size_t size = 0; | |
| 377 EXPECT_EQ(blobDataHandle, handle->obtainFetchDataReader(nullptr)->drainAsBlo
bDataHandle()); | |
| 378 EXPECT_FALSE(handle->obtainFetchDataReader(nullptr)->drainAsFormData()); | |
| 379 | |
| 380 EXPECT_EQ(kDone, handle->obtainReader(nullptr)->read(nullptr, 0, kNone, &siz
e)); | |
| 381 } | |
| 382 | |
| 383 TEST_F(FetchBlobDataConsumerHandleTest, DrainAsFormData) | |
| 384 { | |
| 385 auto factory = new StrictMock<MockLoaderFactory>; | |
| 386 | |
| 387 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 388 std::unique_ptr<FetchDataConsumerHandle> handle | |
| 389 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 390 | |
| 391 RefPtr<EncodedFormData> formData = handle->obtainFetchDataReader(nullptr)->d
rainAsFormData(); | |
| 392 ASSERT_TRUE(formData); | |
| 393 EXPECT_TRUE(formData->isSafeToSendToAnotherThread()); | |
| 394 ASSERT_EQ(1u, formData->elements().size()); | |
| 395 EXPECT_EQ(FormDataElement::encodedBlob, formData->elements()[0].m_type); | |
| 396 EXPECT_EQ(blobDataHandle->uuid(), formData->elements()[0].m_blobUUID); | |
| 397 EXPECT_EQ(blobDataHandle, formData->elements()[0].m_optionalBlobDataHandle); | |
| 398 | |
| 399 EXPECT_FALSE(handle->obtainFetchDataReader(nullptr)->drainAsBlobDataHandle()
); | |
| 400 size_t size; | |
| 401 EXPECT_EQ(kDone, handle->obtainFetchDataReader(nullptr)->read(nullptr, 0, kN
one, &size)); | |
| 402 } | |
| 403 | |
| 404 TEST_F(FetchBlobDataConsumerHandleTest, ZeroByteReadDoesNotAffectDraining) | |
| 405 { | |
| 406 auto factory = new StrictMock<MockLoaderFactory>; | |
| 407 | |
| 408 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 409 std::unique_ptr<FetchDataConsumerHandle> handle | |
| 410 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 411 std::unique_ptr<FetchDataConsumerHandle::Reader> reader = handle->obtainFetc
hDataReader(nullptr); | |
| 412 | |
| 413 size_t readSize; | |
| 414 EXPECT_EQ(kShouldWait, reader->read(nullptr, 0, kNone, &readSize)); | |
| 415 EXPECT_EQ(blobDataHandle, reader->drainAsBlobDataHandle()); | |
| 416 } | |
| 417 | |
| 418 TEST_F(FetchBlobDataConsumerHandleTest, OneByteReadAffectsDraining) | |
| 419 { | |
| 420 auto factory = new StrictMock<MockLoaderFactory>; | |
| 421 | |
| 422 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 423 std::unique_ptr<FetchDataConsumerHandle> handle | |
| 424 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 425 std::unique_ptr<FetchDataConsumerHandle::Reader> reader = handle->obtainFetc
hDataReader(nullptr); | |
| 426 | |
| 427 size_t readSize; | |
| 428 char c; | |
| 429 EXPECT_EQ(kShouldWait, reader->read(&c, 1, kNone, &readSize)); | |
| 430 EXPECT_FALSE(reader->drainAsFormData()); | |
| 431 } | |
| 432 | |
| 433 TEST_F(FetchBlobDataConsumerHandleTest, BeginReadAffectsDraining) | |
| 434 { | |
| 435 auto factory = new StrictMock<MockLoaderFactory>; | |
| 436 | |
| 437 RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a ti
me"); | |
| 438 std::unique_ptr<FetchDataConsumerHandle> handle | |
| 439 = FetchBlobDataConsumerHandle::create(&document(), blobDataHandle, facto
ry); | |
| 440 std::unique_ptr<FetchDataConsumerHandle::Reader> reader = handle->obtainFetc
hDataReader(nullptr); | |
| 441 | |
| 442 const void* buffer; | |
| 443 size_t available; | |
| 444 EXPECT_EQ(kShouldWait, reader->beginRead(&buffer, kNone, &available)); | |
| 445 EXPECT_FALSE(reader->drainAsBlobDataHandle()); | |
| 446 } | |
| 447 | |
| 448 } // namespace | |
| 449 } // namespace blink | |
| OLD | NEW |