Index: content/browser/background_fetch/background_fetch_service_unittest.cc |
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..29fbf9d02661b157b3eecee1d7bc23a9d863611a |
--- /dev/null |
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc |
@@ -0,0 +1,444 @@ |
+// Copyright 2017 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 <memory> |
+ |
+#include "base/macros.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/run_loop.h" |
+#include "content/browser/background_fetch/background_fetch_context.h" |
+#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h" |
+#include "content/browser/background_fetch/background_fetch_registration_id.h" |
+#include "content/browser/background_fetch/background_fetch_service_impl.h" |
+#include "content/browser/background_fetch/background_fetch_test_base.h" |
+#include "content/browser/service_worker/service_worker_context_wrapper.h" |
+#include "content/browser/storage_partition_impl.h" |
+ |
+namespace content { |
+namespace { |
+ |
+const char kExampleTag[] = "my-background-fetch"; |
+const char kAlternativeTag[] = "my-alternative-fetch"; |
+ |
+IconDefinition CreateIcon(std::string src, |
+ std::string sizes, |
+ std::string type) { |
+ IconDefinition icon; |
+ icon.src = std::move(src); |
+ icon.sizes = std::move(sizes); |
+ icon.type = std::move(type); |
+ |
+ return icon; |
+} |
+ |
+class BackgroundFetchServiceTest : public BackgroundFetchTestBase { |
+ public: |
+ BackgroundFetchServiceTest() = default; |
+ ~BackgroundFetchServiceTest() override = default; |
+ |
+ // Synchronous wrapper for BackgroundFetchServiceImpl::Fetch(). |
+ // Should be wrapped in ASSERT_NO_FATAL_FAILURE(). |
+ void Fetch(const BackgroundFetchRegistrationId& registration_id, |
+ const std::vector<ServiceWorkerFetchRequest>& requests, |
+ const BackgroundFetchOptions& options, |
+ blink::mojom::BackgroundFetchError* out_error, |
+ BackgroundFetchRegistration* out_registration) { |
+ DCHECK(out_error); |
+ DCHECK(out_registration); |
+ |
+ base::RunLoop run_loop; |
+ service_->Fetch(registration_id.service_worker_registration_id(), |
+ registration_id.origin(), registration_id.tag(), requests, |
+ options, |
+ base::Bind(&BackgroundFetchServiceTest::DidGetRegistration, |
+ base::Unretained(this), run_loop.QuitClosure(), |
+ out_error, out_registration)); |
+ |
+ run_loop.Run(); |
+ } |
+ |
+ // TODO(harkness): Add tests for UpdateUI() when its functionality has been |
+ // implemented. |
+ |
+ // Synchronous wrapper for BackgroundFetchServiceImpl::Abort(). |
+ // Should be wrapped in ASSERT_NO_FATAL_FAILURE(). |
+ void Abort(const BackgroundFetchRegistrationId& registration_id, |
+ blink::mojom::BackgroundFetchError* out_error) { |
+ DCHECK(out_error); |
+ |
+ base::RunLoop run_loop; |
+ service_->Abort( |
+ registration_id.service_worker_registration_id(), |
+ registration_id.origin(), registration_id.tag(), |
+ base::Bind(&BackgroundFetchServiceTest::DidAbort, |
+ base::Unretained(this), run_loop.QuitClosure(), out_error)); |
+ |
+ run_loop.Run(); |
+ } |
+ |
+ // Synchronous wrapper for BackgroundFetchServiceImpl::GetRegistration(). |
+ // Should be wrapped in ASSERT_NO_FATAL_FAILURE(). |
+ void GetRegistration(const BackgroundFetchRegistrationId& registration_id, |
+ blink::mojom::BackgroundFetchError* out_error, |
+ BackgroundFetchRegistration* out_registration) { |
+ DCHECK(out_error); |
+ DCHECK(out_registration); |
+ |
+ base::RunLoop run_loop; |
+ service_->GetRegistration( |
+ registration_id.service_worker_registration_id(), |
+ registration_id.origin(), registration_id.tag(), |
+ base::Bind(&BackgroundFetchServiceTest::DidGetRegistration, |
+ base::Unretained(this), run_loop.QuitClosure(), out_error, |
+ out_registration)); |
+ |
+ run_loop.Run(); |
+ } |
+ |
+ // Synchronous wrapper for BackgroundFetchServiceImpl::GetTags(). |
+ void GetTags(const BackgroundFetchRegistrationId& registration_id, |
+ blink::mojom::BackgroundFetchError* out_error, |
+ std::vector<std::string>* out_tags) { |
+ DCHECK(out_error); |
+ DCHECK(out_tags); |
+ |
+ base::RunLoop run_loop; |
+ service_->GetTags(registration_id.service_worker_registration_id(), |
+ registration_id.origin(), |
+ base::Bind(&BackgroundFetchServiceTest::DidGetTags, |
+ base::Unretained(this), run_loop.QuitClosure(), |
+ out_error, out_tags)); |
+ |
+ run_loop.Run(); |
+ } |
+ |
+ // BackgroundFetchTestBase overrides: |
+ void SetUp() override { |
+ BackgroundFetchTestBase::SetUp(); |
+ StoragePartitionImpl* storage_partition = |
+ static_cast<StoragePartitionImpl*>( |
+ BrowserContext::GetDefaultStoragePartition(browser_context())); |
+ |
+ context_ = new BackgroundFetchContext( |
+ browser_context(), storage_partition, |
+ make_scoped_refptr(embedded_worker_test_helper()->context_wrapper())); |
+ service_ = base::MakeUnique<BackgroundFetchServiceImpl>( |
+ 0 /* render_process_id */, context_); |
+ } |
+ |
+ void TearDown() override { |
+ service_.reset(); |
+ |
+ context_->Shutdown(); |
+ context_ = nullptr; |
+ |
+ // Give pending shutdown operations a chance to finish. |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ BackgroundFetchTestBase::TearDown(); |
+ } |
+ |
+ private: |
+ void DidGetRegistration( |
+ base::Closure quit_closure, |
+ blink::mojom::BackgroundFetchError* out_error, |
+ BackgroundFetchRegistration* out_registration, |
+ blink::mojom::BackgroundFetchError error, |
+ const base::Optional<content::BackgroundFetchRegistration>& |
+ registration) { |
+ *out_error = error; |
+ if (registration) |
+ *out_registration = registration.value(); |
+ |
+ quit_closure.Run(); |
+ } |
+ |
+ void DidAbort(base::Closure quit_closure, |
+ blink::mojom::BackgroundFetchError* out_error, |
+ blink::mojom::BackgroundFetchError error) { |
+ *out_error = error; |
+ |
+ quit_closure.Run(); |
+ } |
+ |
+ void DidGetTags(base::Closure quit_closure, |
+ blink::mojom::BackgroundFetchError* out_error, |
+ std::vector<std::string>* out_tags, |
+ blink::mojom::BackgroundFetchError error, |
+ const std::vector<std::string>& tags) { |
+ *out_error = error; |
+ *out_tags = tags; |
+ |
+ quit_closure.Run(); |
+ } |
+ |
+ scoped_refptr<BackgroundFetchContext> context_; |
+ std::unique_ptr<BackgroundFetchServiceImpl> service_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BackgroundFetchServiceTest); |
+}; |
+ |
+TEST_F(BackgroundFetchServiceTest, FetchInvalidArguments) { |
+ // This test verifies that the Fetch() function will kill the renderer and |
+ // return INVALID_ARGUMENT when invalid data is send over the Mojo channel. |
+ |
+ BackgroundFetchOptions options; |
+ |
+ // The `tag` must be a non-empty string. |
+ { |
+ BackgroundFetchRegistrationId registration_id( |
+ 42 /* service_worker_registration_id */, origin(), "" /* tag */); |
+ |
+ std::vector<ServiceWorkerFetchRequest> requests; |
+ requests.emplace_back(); // empty, but valid |
+ |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ ASSERT_NO_FATAL_FAILURE( |
+ Fetch(registration_id, requests, options, &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT); |
+ } |
+ |
+ // At least a single ServiceWorkerFetchRequest must be given. |
+ { |
+ BackgroundFetchRegistrationId registration_id( |
+ 42 /* service_worker_registration_id */, origin(), kExampleTag); |
+ |
+ std::vector<ServiceWorkerFetchRequest> requests; |
+ // |requests| has deliberately been left empty. |
+ |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ ASSERT_NO_FATAL_FAILURE( |
+ Fetch(registration_id, requests, options, &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT); |
+ } |
+} |
+ |
+TEST_F(BackgroundFetchServiceTest, FetchRegistrationProperties) { |
+ // This test starts a new Background Fetch and verifies that the returned |
+ // BackgroundFetchRegistration object matches the given options. Then gets |
+ // the active Background Fetch with the same tag, and verifies it again. |
+ |
+ BackgroundFetchRegistrationId registration_id; |
+ ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
+ |
+ std::vector<ServiceWorkerFetchRequest> requests; |
+ requests.emplace_back(); // empty, but valid |
+ |
+ BackgroundFetchOptions options; |
+ options.icons.push_back(CreateIcon("funny_cat.png", "256x256", "image/png")); |
+ options.icons.push_back(CreateIcon("silly_cat.gif", "512x512", "image/gif")); |
+ options.title = "My Background Fetch!"; |
+ options.total_download_size = 9001; |
+ |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ ASSERT_NO_FATAL_FAILURE( |
+ Fetch(registration_id, requests, options, &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ // The |registration| should reflect the options given in |options|. |
+ EXPECT_EQ(registration.tag, kExampleTag); |
+ ASSERT_EQ(registration.icons.size(), options.icons.size()); |
+ |
+ for (size_t i = 0; i < registration.icons.size(); ++i) { |
+ EXPECT_EQ(registration.icons[i].src, options.icons[i].src); |
+ EXPECT_EQ(registration.icons[i].sizes, options.icons[i].sizes); |
+ EXPECT_EQ(registration.icons[i].type, options.icons[i].type); |
+ } |
+ |
+ EXPECT_EQ(registration.title, options.title); |
+ EXPECT_EQ(registration.total_download_size, options.total_download_size); |
+ |
+ blink::mojom::BackgroundFetchError second_error; |
+ BackgroundFetchRegistration second_registration; |
+ |
+ ASSERT_NO_FATAL_FAILURE( |
+ GetRegistration(registration_id, &second_error, &second_registration)); |
+ ASSERT_EQ(second_error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ // The |second_registration| should reflect the options given in |options|. |
+ EXPECT_EQ(second_registration.tag, kExampleTag); |
+ ASSERT_EQ(second_registration.icons.size(), options.icons.size()); |
+ |
+ for (size_t i = 0; i < second_registration.icons.size(); ++i) { |
+ EXPECT_EQ(second_registration.icons[i].src, options.icons[i].src); |
+ EXPECT_EQ(second_registration.icons[i].sizes, options.icons[i].sizes); |
+ EXPECT_EQ(second_registration.icons[i].type, options.icons[i].type); |
+ } |
+ |
+ EXPECT_EQ(second_registration.title, options.title); |
+ EXPECT_EQ(second_registration.total_download_size, |
+ options.total_download_size); |
+} |
+ |
+TEST_F(BackgroundFetchServiceTest, FetchDuplicatedRegistrationFailure) { |
+ // This tests starts a new Background Fetch, verifies that a registration was |
+ // successfully created, and then tries to start a second fetch for the same |
+ // registration. This should fail with a DUPLICATED_TAG error. |
+ |
+ BackgroundFetchRegistrationId registration_id; |
+ ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
+ |
+ std::vector<ServiceWorkerFetchRequest> requests; |
+ requests.emplace_back(); // empty, but valid |
+ |
+ BackgroundFetchOptions options; |
+ |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ // Create the first registration. This must succeed. |
+ ASSERT_NO_FATAL_FAILURE( |
+ Fetch(registration_id, requests, options, &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ blink::mojom::BackgroundFetchError second_error; |
+ BackgroundFetchRegistration second_registration; |
+ |
+ // Create the second registration with the same data. This must fail. |
+ ASSERT_NO_FATAL_FAILURE(Fetch(registration_id, requests, options, |
+ &second_error, &second_registration)); |
+ ASSERT_EQ(second_error, blink::mojom::BackgroundFetchError::DUPLICATED_TAG); |
+} |
+ |
+TEST_F(BackgroundFetchServiceTest, Abort) { |
+ // This test starts a new Background Fetch, completes the registration, and |
+ // then aborts the Background Fetch mid-process. Tests all of StartFetch(), |
+ // GetActiveFetches() and GetActiveTagsForServiceWorkerRegistration(). |
+ |
+ BackgroundFetchRegistrationId registration_id; |
+ ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
+ |
+ std::vector<ServiceWorkerFetchRequest> requests; |
+ requests.emplace_back(); // empty, but valid |
+ |
+ BackgroundFetchOptions options; |
+ |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ // Create the registration. This must succeed. |
+ ASSERT_NO_FATAL_FAILURE( |
+ Fetch(registration_id, requests, options, &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ blink::mojom::BackgroundFetchError abort_error; |
+ |
+ // Immediately abort the registration. This also is expected to succeed. |
+ ASSERT_NO_FATAL_FAILURE(Abort(registration_id, &abort_error)); |
+ ASSERT_EQ(abort_error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ blink::mojom::BackgroundFetchError second_error; |
+ BackgroundFetchRegistration second_registration; |
+ |
+ // Now try to get the created registration, which is expected to fail. |
+ ASSERT_NO_FATAL_FAILURE( |
+ GetRegistration(registration_id, &second_error, &second_registration)); |
+ ASSERT_EQ(second_error, blink::mojom::BackgroundFetchError::INVALID_TAG); |
+} |
+ |
+TEST_F(BackgroundFetchServiceTest, AbortInvalidArguments) { |
+ // This test verifies that the Abort() function will kill the renderer and |
+ // return INVALID_ARGUMENT when invalid data is send over the Mojo channel. |
+ |
+ BackgroundFetchOptions options; |
+ |
+ // The `tag` must be a non-empty string. |
+ { |
+ BackgroundFetchRegistrationId registration_id( |
+ 42 /* service_worker_registration_id */, origin(), "" /* tag */); |
+ |
+ blink::mojom::BackgroundFetchError error; |
+ |
+ ASSERT_NO_FATAL_FAILURE(Abort(registration_id, &error)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT); |
+ } |
+} |
+ |
harkness
2017/03/30 14:15:28
nit: For a future patch you should test Abort() fo
Peter Beverloo
2017/03/30 14:50:39
Acknowledged.
|
+TEST_F(BackgroundFetchServiceTest, GetTags) { |
+ // This test verifies that the list of active tags can be retrieved from the |
+ // service for a given Service Worker, as extracted from a registration. |
+ |
+ BackgroundFetchRegistrationId registration_id; |
+ ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
+ |
+ BackgroundFetchRegistrationId second_registration_id; |
+ ASSERT_TRUE(CreateRegistrationId(kAlternativeTag, &second_registration_id)); |
+ |
+ std::vector<ServiceWorkerFetchRequest> requests; |
+ requests.emplace_back(); // empty, but valid |
+ |
+ BackgroundFetchOptions options; |
+ |
+ // Verify that there are no active tags yet. |
+ { |
+ blink::mojom::BackgroundFetchError error; |
+ std::vector<std::string> tags; |
+ |
+ ASSERT_NO_FATAL_FAILURE(GetTags(registration_id, &error, &tags)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ ASSERT_EQ(tags.size(), 0u); |
+ } |
+ |
+ // Start the Background Fetch for the |registration_id|. |
+ { |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ ASSERT_NO_FATAL_FAILURE( |
+ Fetch(registration_id, requests, options, &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ } |
+ |
+ // Verify that there is a single active fetch (the one we just started). |
+ { |
+ blink::mojom::BackgroundFetchError error; |
+ std::vector<std::string> tags; |
+ |
+ ASSERT_NO_FATAL_FAILURE(GetTags(registration_id, &error, &tags)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ ASSERT_EQ(tags.size(), 1u); |
+ EXPECT_EQ(tags[0], kExampleTag); |
+ } |
+ |
+ // Start the Background Fetch for the |second_registration_id|. |
+ { |
+ blink::mojom::BackgroundFetchError error; |
+ BackgroundFetchRegistration registration; |
+ |
+ ASSERT_NO_FATAL_FAILURE(Fetch(second_registration_id, requests, options, |
+ &error, ®istration)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ } |
+ |
+ // Verify that there are two active fetches. |
+ { |
+ blink::mojom::BackgroundFetchError error; |
+ std::vector<std::string> tags; |
+ |
+ ASSERT_NO_FATAL_FAILURE(GetTags(registration_id, &error, &tags)); |
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
+ |
+ ASSERT_EQ(tags.size(), 2u); |
+ |
+ // We make no guarantees about ordering of the tags. |
+ const bool has_example_tag = |
+ tags[0] == kExampleTag || tags[1] == kExampleTag; |
+ const bool has_alternative_tag = |
+ tags[0] == kAlternativeTag || tags[1] == kAlternativeTag; |
+ |
+ EXPECT_TRUE(has_example_tag); |
+ EXPECT_TRUE(has_alternative_tag); |
+ } |
+} |
+ |
+} // namespace |
+} // namespace content |