Index: third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp |
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8301be54c3522fa9a92e7949eb2ea32373d4de34 |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp |
@@ -0,0 +1,836 @@ |
+// 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 "core/loader/ThreadableLoader.h" |
+ |
+#include "core/dom/CrossThreadTask.h" |
+#include "core/fetch/ResourceLoaderOptions.h" |
+#include "core/loader/DocumentThreadableLoader.h" |
+#include "core/loader/ThreadableLoaderClient.h" |
+#include "core/loader/WorkerThreadableLoader.h" |
+#include "core/testing/DummyPageHolder.h" |
+#include "core/workers/WorkerLoaderProxy.h" |
+#include "core/workers/WorkerThreadTestHelper.h" |
+#include "platform/WaitableEvent.h" |
+#include "platform/geometry/IntSize.h" |
+#include "platform/network/ResourceError.h" |
+#include "platform/network/ResourceRequest.h" |
+#include "platform/network/ResourceResponse.h" |
+#include "platform/network/ResourceTimingInfo.h" |
+#include "platform/testing/URLTestHelpers.h" |
+#include "platform/testing/UnitTestHelpers.h" |
+#include "platform/weborigin/KURL.h" |
+#include "platform/weborigin/SecurityOrigin.h" |
+#include "public/platform/Platform.h" |
+#include "public/platform/WebURLLoadTiming.h" |
+#include "public/platform/WebURLResponse.h" |
+#include "public/platform/WebUnitTestSupport.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "wtf/Assertions.h" |
+#include "wtf/OwnPtr.h" |
+#include "wtf/PassOwnPtr.h" |
+#include "wtf/RefPtr.h" |
+ |
+namespace blink { |
+ |
+namespace { |
+ |
+using ::testing::_; |
+using ::testing::InSequence; |
+using ::testing::InvokeWithoutArgs; |
+using ::testing::StrEq; |
+using ::testing::Truly; |
+using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>; |
+ |
+class MockThreadableLoaderClient : public ThreadableLoaderClient { |
+public: |
+ static PassOwnPtr<MockThreadableLoaderClient> create() |
+ { |
+ return adoptPtr(new ::testing::StrictMock<MockThreadableLoaderClient>); |
+ } |
+ MOCK_METHOD2(didSendData, void(unsigned long long, unsigned long long)); |
+ MOCK_METHOD3(didReceiveResponse, void(unsigned long, const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>)); |
+ MOCK_METHOD2(didReceiveData, void(const char*, unsigned)); |
+ MOCK_METHOD2(didReceiveCachedMetadata, void(const char*, int)); |
+ MOCK_METHOD2(didFinishLoading, void(unsigned long, double)); |
+ MOCK_METHOD1(didFail, void(const ResourceError&)); |
+ MOCK_METHOD1(didFailAccessControlCheck, void(const ResourceError&)); |
+ MOCK_METHOD0(didFailRedirectCheck, void()); |
+ MOCK_METHOD1(didReceiveResourceTiming, void(const ResourceTimingInfo&)); |
+ MOCK_METHOD1(didDownloadData, void(int)); |
+ |
+protected: |
+ MockThreadableLoaderClient() = default; |
+}; |
+ |
+bool isCancellation(const ResourceError& error) |
+{ |
+ return error.isCancellation(); |
+} |
+ |
+bool isNotCancellation(const ResourceError& error) |
+{ |
+ return !error.isCancellation(); |
+} |
+ |
+KURL successURL() { return KURL(KURL(), "http://example.com/success"); } |
+KURL errorURL() { return KURL(KURL(), "http://example.com/error"); } |
+KURL redirectURL() { return KURL(KURL(), "http://example.com/redirect"); } |
+KURL redirectLoopURL() { return KURL(KURL(), "http://example.com/loop"); } |
+ |
+enum ThreadableLoaderToTest { |
+ DocumentThreadableLoaderTest, |
+ WorkerThreadableLoaderTest |
+}; |
+ |
+class ThreadableLoaderTestHelper { |
+public: |
+ virtual ~ThreadableLoaderTestHelper() { } |
+ |
+ virtual void createLoader(ThreadableLoaderClient*, CrossOriginRequestPolicy) = 0; |
+ virtual void startLoader(const ResourceRequest&) = 0; |
+ virtual void cancelLoader() = 0; |
+ virtual void clearLoader() = 0; |
+ virtual Checkpoint& checkpoint() = 0; |
+ virtual void callCheckpoint(int) = 0; |
+ virtual void onSetUp() = 0; |
+ virtual void onServeRequests() = 0; |
+ virtual void onTearDown() = 0; |
+}; |
+ |
+class DocumentThreadableLoaderTestHelper : public ThreadableLoaderTestHelper { |
+public: |
+ DocumentThreadableLoaderTestHelper() |
+ : m_dummyPageHolder(DummyPageHolder::create(IntSize(1, 1))) |
+ { |
+ } |
+ |
+ void createLoader(ThreadableLoaderClient* client, CrossOriginRequestPolicy crossOriginRequestPolicy) override |
+ { |
+ ThreadableLoaderOptions options; |
+ options.crossOriginRequestPolicy = crossOriginRequestPolicy; |
+ ResourceLoaderOptions resourceLoaderOptions; |
+ m_loader = DocumentThreadableLoader::create(document(), client, options, resourceLoaderOptions); |
+ } |
+ |
+ void startLoader(const ResourceRequest& request) override |
+ { |
+ m_loader->start(request); |
+ } |
+ |
+ void cancelLoader() override { m_loader->cancel(); } |
+ void clearLoader() override { m_loader.clear(); } |
+ Checkpoint& checkpoint() override { return m_checkpoint; } |
+ void callCheckpoint(int n) override { m_checkpoint.Call(n); } |
+ |
+ void onSetUp() override |
+ { |
+ } |
+ |
+ void onServeRequests() override |
+ { |
+ } |
+ |
+ void onTearDown() override |
+ { |
+ m_loader.clear(); |
+ } |
+ |
+private: |
+ Document& document() { return m_dummyPageHolder->document(); } |
+ |
+ OwnPtr<DummyPageHolder> m_dummyPageHolder; |
+ Checkpoint m_checkpoint; |
+ OwnPtr<DocumentThreadableLoader> m_loader; |
+}; |
+ |
+class WorkerThreadableLoaderTestHelper : public ThreadableLoaderTestHelper, public WorkerLoaderProxyProvider { |
+public: |
+ WorkerThreadableLoaderTestHelper() |
+ : m_dummyPageHolder(DummyPageHolder::create(IntSize(1, 1))) |
+ { |
+ } |
+ |
+ void createLoader(ThreadableLoaderClient* client, CrossOriginRequestPolicy crossOriginRequestPolicy) override |
+ { |
+ OwnPtr<WaitableEvent> completionEvent = adoptPtr(new WaitableEvent()); |
+ postTaskToWorkerGlobalScope(createCrossThreadTask( |
+ &WorkerThreadableLoaderTestHelper::workerCreateLoader, |
+ AllowCrossThreadAccess(this), |
+ AllowCrossThreadAccess(client), |
+ AllowCrossThreadAccess(completionEvent.get()), |
+ crossOriginRequestPolicy)); |
+ completionEvent->wait(); |
+ } |
+ |
+ void startLoader(const ResourceRequest& request) override |
+ { |
+ OwnPtr<WaitableEvent> completionEvent = adoptPtr(new WaitableEvent()); |
+ postTaskToWorkerGlobalScope(createCrossThreadTask( |
+ &WorkerThreadableLoaderTestHelper::workerStartLoader, |
+ AllowCrossThreadAccess(this), |
+ AllowCrossThreadAccess(completionEvent.get()), |
+ request)); |
+ completionEvent->wait(); |
+ } |
+ |
+ // Must be called on the worker thread. |
+ void cancelLoader() override |
+ { |
+ ASSERT(m_workerThread); |
+ ASSERT(m_workerThread->isCurrentThread()); |
+ m_loader->cancel(); |
+ } |
+ |
+ // Must be called on the worker thread. |
+ void clearLoader() override |
+ { |
+ ASSERT(m_workerThread); |
+ ASSERT(m_workerThread->isCurrentThread()); |
+ m_loader.clear(); |
+ } |
+ |
+ Checkpoint& checkpoint() override |
+ { |
+ return m_checkpoint; |
+ } |
+ |
+ void callCheckpoint(int n) override |
+ { |
+ testing::runPendingTasks(); |
+ |
+ OwnPtr<WaitableEvent> completionEvent = adoptPtr(new WaitableEvent()); |
+ postTaskToWorkerGlobalScope(createCrossThreadTask( |
+ &WorkerThreadableLoaderTestHelper::workerCallCheckpoint, |
+ AllowCrossThreadAccess(this), |
+ AllowCrossThreadAccess(completionEvent.get()), |
+ n)); |
+ completionEvent->wait(); |
+ } |
+ |
+ void onSetUp() override |
+ { |
+ m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy()); |
+ m_securityOrigin = document().getSecurityOrigin(); |
+ m_workerThread = adoptPtr(new WorkerThreadForTest( |
+ this, |
+ *m_mockWorkerReportingProxy)); |
+ |
+ expectWorkerLifetimeReportingCalls(); |
+ m_workerThread->startWithSourceCode(m_securityOrigin.get(), "//fake source code"); |
+ m_workerThread->waitForInit(); |
+ } |
+ |
+ void onServeRequests() override |
+ { |
+ testing::runPendingTasks(); |
+ } |
+ |
+ void onTearDown() override |
+ { |
+ postTaskToWorkerGlobalScope(createCrossThreadTask(&WorkerThreadableLoaderTestHelper::clearLoader, AllowCrossThreadAccess(this))); |
+ m_workerThread->terminateAndWait(); |
+ |
+ // Needed to clean up the things on the main thread side and |
+ // avoid Resource leaks. |
+ testing::runPendingTasks(); |
+ |
+ m_workerThread->workerLoaderProxy()->detachProvider(this); |
+ } |
+ |
+private: |
+ Document& document() { return m_dummyPageHolder->document(); } |
+ |
+ void expectWorkerLifetimeReportingCalls() |
+ { |
+ EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times(1); |
+ EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)).Times(1); |
+ EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1); |
+ EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Times(1); |
+ } |
+ |
+ void workerCreateLoader(ThreadableLoaderClient* client, WaitableEvent* event, CrossOriginRequestPolicy crossOriginRequestPolicy) |
+ { |
+ ASSERT(m_workerThread); |
+ ASSERT(m_workerThread->isCurrentThread()); |
+ |
+ ThreadableLoaderOptions options; |
+ options.crossOriginRequestPolicy = crossOriginRequestPolicy; |
+ ResourceLoaderOptions resourceLoaderOptions; |
+ |
+ // Ensure that WorkerThreadableLoader is created. |
+ // ThreadableLoader::create() determines whether it should create |
+ // a DocumentThreadableLoader or WorkerThreadableLoader based on |
+ // isWorkerGlobalScope(). |
+ ASSERT(m_workerThread->workerGlobalScope()->isWorkerGlobalScope()); |
+ |
+ m_loader = ThreadableLoader::create(*m_workerThread->workerGlobalScope(), client, options, resourceLoaderOptions); |
+ ASSERT(m_loader); |
+ event->signal(); |
+ } |
+ |
+ void workerStartLoader(WaitableEvent* event, PassOwnPtr<CrossThreadResourceRequestData> requestData) |
+ { |
+ ASSERT(m_workerThread); |
+ ASSERT(m_workerThread->isCurrentThread()); |
+ |
+ ResourceRequest request(requestData.get()); |
+ m_loader->start(request); |
+ event->signal(); |
+ } |
+ |
+ void workerCallCheckpoint(WaitableEvent* event, int n) |
+ { |
+ ASSERT(m_workerThread); |
+ ASSERT(m_workerThread->isCurrentThread()); |
+ m_checkpoint.Call(n); |
+ event->signal(); |
+ } |
+ |
+ // WorkerLoaderProxyProvider methods. |
+ void postTaskToLoader(PassOwnPtr<ExecutionContextTask> task) override |
+ { |
+ ASSERT(m_workerThread); |
+ ASSERT(m_workerThread->isCurrentThread()); |
+ document().postTask(BLINK_FROM_HERE, task); |
+ } |
+ |
+ bool postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask> task) override |
+ { |
+ ASSERT(m_workerThread); |
+ m_workerThread->postTask(BLINK_FROM_HERE, task); |
+ return true; |
+ } |
+ |
+ RefPtr<SecurityOrigin> m_securityOrigin; |
+ OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; |
+ OwnPtr<WorkerThreadForTest> m_workerThread; |
+ |
+ OwnPtr<DummyPageHolder> m_dummyPageHolder; |
+ Checkpoint m_checkpoint; |
+ // |m_loader| must be touched only from the worker thread only. |
+ OwnPtr<ThreadableLoader> m_loader; |
+}; |
+ |
+class ThreadableLoaderTest : public ::testing::TestWithParam<ThreadableLoaderToTest> { |
+public: |
+ ThreadableLoaderTest() |
+ { |
+ switch (GetParam()) { |
+ case DocumentThreadableLoaderTest: |
+ m_helper = adoptPtr(new DocumentThreadableLoaderTestHelper); |
+ break; |
+ case WorkerThreadableLoaderTest: |
+ m_helper = adoptPtr(new WorkerThreadableLoaderTestHelper); |
+ break; |
+ } |
+ } |
+ |
+ void startLoader(const KURL& url) |
+ { |
+ ResourceRequest request(url); |
+ request.setRequestContext(WebURLRequest::RequestContextInternal); |
+ m_helper->startLoader(request); |
+ } |
+ |
+ void cancelLoader() { m_helper->cancelLoader(); } |
+ void clearLoader() { m_helper->clearLoader(); } |
+ Checkpoint& checkpoint() { return m_helper->checkpoint(); } |
+ void callCheckpoint(int n) { m_helper->callCheckpoint(n); } |
+ |
+ void serveRequests() |
+ { |
+ m_helper->onServeRequests(); |
+ Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(); |
+ } |
+ |
+ void createLoader(CrossOriginRequestPolicy crossOriginRequestPolicy = AllowCrossOriginRequests) |
+ { |
+ m_helper->createLoader(client(), crossOriginRequestPolicy); |
+ } |
+ |
+ MockThreadableLoaderClient* client() const { return m_client.get(); } |
+ |
+private: |
+ void SetUp() override |
+ { |
+ setUpSuccessURL(); |
+ setUpErrorURL(); |
+ setUpRedirectURL(); |
+ setUpRedirectLoopURL(); |
+ |
+ m_client = MockThreadableLoaderClient::create(); |
+ m_helper->onSetUp(); |
+ } |
+ |
+ void TearDown() override |
+ { |
+ m_helper->onTearDown(); |
+ Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); |
+ m_client.clear(); |
+ } |
+ |
+ void setUpSuccessURL() |
+ { |
+ URLTestHelpers::registerMockedURLLoad(successURL(), "fox-null-terminated.html", "text/html"); |
+ } |
+ |
+ void setUpErrorURL() |
+ { |
+ URLTestHelpers::registerMockedErrorURLLoad(errorURL()); |
+ } |
+ |
+ void setUpRedirectURL() |
+ { |
+ KURL url = redirectURL(); |
+ |
+ WebURLLoadTiming timing; |
+ timing.initialize(); |
+ |
+ WebURLResponse response; |
+ response.initialize(); |
+ response.setURL(url); |
+ response.setHTTPStatusCode(301); |
+ response.setLoadTiming(timing); |
+ response.addHTTPHeaderField("Location", successURL().getString()); |
+ response.addHTTPHeaderField("Access-Control-Allow-Origin", "null"); |
+ |
+ URLTestHelpers::registerMockedURLLoadWithCustomResponse(url, "fox-null-terminated.html", "", response); |
+ } |
+ |
+ void setUpRedirectLoopURL() |
+ { |
+ KURL url = redirectLoopURL(); |
+ |
+ WebURLLoadTiming timing; |
+ timing.initialize(); |
+ |
+ WebURLResponse response; |
+ response.initialize(); |
+ response.setURL(url); |
+ response.setHTTPStatusCode(301); |
+ response.setLoadTiming(timing); |
+ response.addHTTPHeaderField("Location", redirectLoopURL().getString()); |
+ response.addHTTPHeaderField("Access-Control-Allow-Origin", "null"); |
+ |
+ URLTestHelpers::registerMockedURLLoadWithCustomResponse(url, "fox-null-terminated.html", "", response); |
+ } |
+ |
+ OwnPtr<MockThreadableLoaderClient> m_client; |
+ OwnPtr<ThreadableLoaderTestHelper> m_helper; |
+}; |
+ |
+INSTANTIATE_TEST_CASE_P(Document, |
+ ThreadableLoaderTest, |
+ ::testing::Values(DocumentThreadableLoaderTest)); |
+ |
+INSTANTIATE_TEST_CASE_P(Worker, |
+ ThreadableLoaderTest, |
+ ::testing::Values(WorkerThreadableLoaderTest)); |
+ |
+TEST_P(ThreadableLoaderTest, StartAndStop) |
+{ |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelAfterStart) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ EXPECT_CALL(*client(), didFail(Truly(isCancellation))); |
+ EXPECT_CALL(checkpoint(), Call(3)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ callCheckpoint(3); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearAfterStart) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ EXPECT_CALL(checkpoint(), Call(3)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ callCheckpoint(3); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidReceiveResponse) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ EXPECT_CALL(*client(), didFail(Truly(isCancellation))); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidReceiveResponse) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidReceiveData) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(_, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ EXPECT_CALL(*client(), didFail(Truly(isCancellation))); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidReceiveData) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(_, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, DidFinishLoading) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(StrEq("fox"), 4)); |
+ // We expect didReceiveResourceTiming() calls in DocumentThreadableLoader; |
+ // it's used to connect DocumentThreadableLoader to WorkerThreadableLoader, |
+ // not to ThreadableLoaderClient. |
+ if (GetParam() == DocumentThreadableLoaderTest) |
+ EXPECT_CALL(*client(), didReceiveResourceTiming(_)); |
+ EXPECT_CALL(*client(), didFinishLoading(_, _)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidFinishLoading) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(_, _)); |
+ if (GetParam() == DocumentThreadableLoaderTest) |
+ EXPECT_CALL(*client(), didReceiveResourceTiming(_)); |
+ EXPECT_CALL(*client(), didFinishLoading(_, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidFinishLoading) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(_, _)); |
+ if (GetParam() == DocumentThreadableLoaderTest) |
+ EXPECT_CALL(*client(), didReceiveResourceTiming(_)); |
+ EXPECT_CALL(*client(), didFinishLoading(_, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, DidFail) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didFail(Truly(isNotCancellation))); |
+ |
+ startLoader(errorURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidFail) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didFail(_)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ |
+ startLoader(errorURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidFail) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didFail(_)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(errorURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, DidFailInStart) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(DenyCrossOriginRequests); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(*client(), didFail(ResourceError(errorDomainBlinkInternal, 0, errorURL().getString(), "Cross origin requests are not supported."))); |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ |
+ startLoader(errorURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidFailInStart) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(DenyCrossOriginRequests); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(*client(), didFail(_)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ |
+ startLoader(errorURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidFailInStart) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(DenyCrossOriginRequests); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(*client(), didFail(_)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ |
+ startLoader(errorURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, DidFailAccessControlCheck) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(UseAccessControl); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, successURL().getString(), "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access."))); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidFailAccessControlCheck) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(UseAccessControl); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didFailAccessControlCheck(_)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidFailAccessControlCheck) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(UseAccessControl); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didFailAccessControlCheck(_)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(successURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, RedirectDidFinishLoading) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(StrEq("fox"), 4)); |
+ if (GetParam() == DocumentThreadableLoaderTest) |
+ EXPECT_CALL(*client(), didReceiveResourceTiming(_)); |
+ EXPECT_CALL(*client(), didFinishLoading(_, _)); |
+ |
+ startLoader(redirectURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInRedirectDidFinishLoading) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(StrEq("fox"), 4)); |
+ if (GetParam() == DocumentThreadableLoaderTest) |
+ EXPECT_CALL(*client(), didReceiveResourceTiming(_)); |
+ EXPECT_CALL(*client(), didFinishLoading(_, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ |
+ startLoader(redirectURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInRedirectDidFinishLoading) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didReceiveResponse(_, _, _)); |
+ EXPECT_CALL(*client(), didReceiveData(StrEq("fox"), 4)); |
+ if (GetParam() == DocumentThreadableLoaderTest) |
+ EXPECT_CALL(*client(), didReceiveResourceTiming(_)); |
+ EXPECT_CALL(*client(), didFinishLoading(_, _)).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(redirectURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, DidFailRedirectCheck) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(UseAccessControl); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didFailRedirectCheck()); |
+ |
+ startLoader(redirectLoopURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, CancelInDidFailRedirectCheck) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(UseAccessControl); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didFailRedirectCheck()).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::cancelLoader)); |
+ |
+ startLoader(redirectLoopURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+TEST_P(ThreadableLoaderTest, ClearInDidFailRedirectCheck) |
+{ |
+ InSequence s; |
+ EXPECT_CALL(checkpoint(), Call(1)); |
+ createLoader(UseAccessControl); |
+ callCheckpoint(1); |
+ |
+ EXPECT_CALL(checkpoint(), Call(2)); |
+ EXPECT_CALL(*client(), didFailRedirectCheck()).WillOnce(InvokeWithoutArgs(this, &ThreadableLoaderTest::clearLoader)); |
+ |
+ startLoader(redirectLoopURL()); |
+ callCheckpoint(2); |
+ serveRequests(); |
+} |
+ |
+} // namespace |
+ |
+} // namespace blink |