blob: 1aee3969c691f9f92f0eb2a108e44d4dff608bc8 [file] [log] [blame]
// Copyright 2015 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 "content/browser/background_sync/background_sync_service_impl.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "content/browser/background_sync/background_sync_context_impl.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
const char kServiceWorkerPattern[] = "https://example.com/a";
const char kServiceWorkerScript[] = "https://example.com/a/script.js";
const int kRenderProcessId = 99;
// Callbacks from SetUp methods
void RegisterServiceWorkerCallback(bool* called,
int64* store_registration_id,
ServiceWorkerStatusCode status,
const std::string& status_message,
int64 registration_id) {
EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
}
void FindServiceWorkerRegistrationCallback(
scoped_refptr<ServiceWorkerRegistration>* out_registration,
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration) {
EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
*out_registration = registration;
}
// Callbacks from BackgroundSyncServiceImpl methods
void ErrorAndRegistrationCallback(bool* called,
BackgroundSyncError* out_error,
SyncRegistrationPtr* out_registration,
BackgroundSyncError error,
const SyncRegistrationPtr& registration) {
*called = true;
*out_error = error;
*out_registration = registration.Clone();
}
void ErrorCallback(bool* called,
BackgroundSyncError* out_error,
BackgroundSyncError error) {
*called = true;
*out_error = error;
}
void ErrorAndRegistrationListCallback(
bool* called,
BackgroundSyncError* out_error,
unsigned long* out_array_size,
BackgroundSyncError error,
mojo::Array<content::SyncRegistrationPtr> registrations) {
*called = true;
*out_error = error;
if (error == BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE)
*out_array_size = registrations.size();
}
} // namespace
class BackgroundSyncServiceImplTest : public testing::Test {
public:
BackgroundSyncServiceImplTest()
: thread_bundle_(
new TestBrowserThreadBundle(TestBrowserThreadBundle::IO_MAINLOOP)) {
default_sync_registration_ = SyncRegistration::New();
}
void SetUp() override {
CreateTestHelper();
CreateBackgroundSyncContext();
CreateServiceWorkerRegistration();
CreateBackgroundSyncServiceImpl();
}
void TearDown() override {
// This must be explicitly destroyed here to ensure that destruction
// of both the BackgroundSyncContext and the BackgroundSyncManager occurs on
// the correct thread.
background_sync_context_ = nullptr;
}
// SetUp helper methods
void CreateTestHelper() {
embedded_worker_helper_.reset(
new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
}
void CreateBackgroundSyncContext() {
background_sync_context_ = new BackgroundSyncContextImpl();
background_sync_context_->Init(embedded_worker_helper_->context_wrapper());
base::RunLoop().RunUntilIdle();
}
void CreateServiceWorkerRegistration() {
bool called = false;
embedded_worker_helper_->context()->RegisterServiceWorker(
GURL(kServiceWorkerPattern), GURL(kServiceWorkerScript), NULL,
base::Bind(&RegisterServiceWorkerCallback, &called,
&sw_registration_id_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
embedded_worker_helper_->context_wrapper()->FindRegistrationForId(
sw_registration_id_, GURL(kServiceWorkerPattern).GetOrigin(),
base::Bind(FindServiceWorkerRegistrationCallback, &sw_registration_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(sw_registration_);
}
void CreateBackgroundSyncServiceImpl() {
// Create a dummy mojo channel so that the BackgroundSyncServiceImpl can be
// instantiated
mojo::InterfaceRequest<BackgroundSyncService> service_request =
mojo::GetProxy(&service_ptr_);
// Create a new BackgroundSyncServiceImpl bound to the dummy channel
service_impl_.reset(new BackgroundSyncServiceImpl(background_sync_context_,
service_request.Pass()));
base::RunLoop().RunUntilIdle();
}
// Helpers for testing BackgroundSyncServiceImpl methods
void RegisterOneShot(
SyncRegistrationPtr sync,
const BackgroundSyncService::RegisterCallback& callback) {
service_impl_->Register(sync.Pass(), sw_registration_id_, callback);
base::RunLoop().RunUntilIdle();
}
void UnregisterOneShot(
SyncRegistrationPtr sync,
const BackgroundSyncService::UnregisterCallback& callback) {
service_impl_->Unregister(
BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT,
sync->id, sync->tag, sw_registration_id_, callback);
base::RunLoop().RunUntilIdle();
}
void GetRegistrationOneShot(
const mojo::String& tag,
const BackgroundSyncService::RegisterCallback& callback) {
service_impl_->GetRegistration(
BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT, tag,
sw_registration_id_, callback);
base::RunLoop().RunUntilIdle();
}
void GetRegistrationsOneShot(
const BackgroundSyncService::GetRegistrationsCallback& callback) {
service_impl_->GetRegistrations(
BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT,
sw_registration_id_, callback);
base::RunLoop().RunUntilIdle();
}
scoped_ptr<TestBrowserThreadBundle> thread_bundle_;
scoped_ptr<EmbeddedWorkerTestHelper> embedded_worker_helper_;
scoped_refptr<BackgroundSyncContextImpl> background_sync_context_;
int64 sw_registration_id_;
scoped_refptr<ServiceWorkerRegistration> sw_registration_;
BackgroundSyncServicePtr service_ptr_;
scoped_ptr<BackgroundSyncServiceImpl> service_impl_;
SyncRegistrationPtr default_sync_registration_;
};
// Tests
TEST_F(BackgroundSyncServiceImplTest, Register) {
bool called = false;
BackgroundSyncError error;
SyncRegistrationPtr reg;
RegisterOneShot(
default_sync_registration_.Clone(),
base::Bind(&ErrorAndRegistrationCallback, &called, &error, &reg));
EXPECT_TRUE(called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, error);
EXPECT_EQ("", reg->tag);
}
TEST_F(BackgroundSyncServiceImplTest, Unregister) {
bool unregister_called = false;
BackgroundSyncError unregister_error;
SyncRegistrationPtr reg;
UnregisterOneShot(
default_sync_registration_.Clone(),
base::Bind(&ErrorCallback, &unregister_called, &unregister_error));
EXPECT_TRUE(unregister_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_FOUND,
unregister_error);
}
TEST_F(BackgroundSyncServiceImplTest, UnregisterWithRegisteredSync) {
bool register_called = false;
bool unregister_called = false;
BackgroundSyncError register_error;
BackgroundSyncError unregister_error;
SyncRegistrationPtr reg;
RegisterOneShot(default_sync_registration_.Clone(),
base::Bind(&ErrorAndRegistrationCallback, &register_called,
&register_error, &reg));
EXPECT_TRUE(register_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, register_error);
UnregisterOneShot(reg.Pass(), base::Bind(&ErrorCallback, &unregister_called,
&unregister_error));
EXPECT_TRUE(unregister_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, unregister_error);
}
TEST_F(BackgroundSyncServiceImplTest, GetRegistration) {
bool called = false;
BackgroundSyncError error;
SyncRegistrationPtr reg;
GetRegistrationOneShot(
"", base::Bind(&ErrorAndRegistrationCallback, &called, &error, &reg));
EXPECT_TRUE(called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_FOUND, error);
}
TEST_F(BackgroundSyncServiceImplTest, GetRegistrationWithRegisteredSync) {
bool register_called = false;
bool getregistration_called = false;
BackgroundSyncError register_error;
BackgroundSyncError getregistration_error;
SyncRegistrationPtr register_reg;
SyncRegistrationPtr getregistration_reg;
RegisterOneShot(default_sync_registration_.Clone(),
base::Bind(&ErrorAndRegistrationCallback, &register_called,
&register_error, &register_reg));
EXPECT_TRUE(register_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, register_error);
GetRegistrationOneShot(
register_reg->tag,
base::Bind(&ErrorAndRegistrationCallback, &getregistration_called,
&getregistration_error, &getregistration_reg));
EXPECT_TRUE(getregistration_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE,
getregistration_error);
}
TEST_F(BackgroundSyncServiceImplTest, GetRegistrations) {
bool called = false;
BackgroundSyncError error;
unsigned long array_size = 0UL;
GetRegistrationsOneShot(base::Bind(&ErrorAndRegistrationListCallback, &called,
&error, &array_size));
EXPECT_TRUE(called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, error);
EXPECT_EQ(0UL, array_size);
}
TEST_F(BackgroundSyncServiceImplTest, GetRegistrationsWithRegisteredSync) {
bool register_called = false;
bool getregistrations_called = false;
BackgroundSyncError register_error;
BackgroundSyncError getregistrations_error;
SyncRegistrationPtr register_reg;
unsigned long array_size = 0UL;
RegisterOneShot(default_sync_registration_.Clone(),
base::Bind(&ErrorAndRegistrationCallback, &register_called,
&register_error, &register_reg));
EXPECT_TRUE(register_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE, register_error);
GetRegistrationsOneShot(base::Bind(&ErrorAndRegistrationListCallback,
&getregistrations_called,
&getregistrations_error, &array_size));
EXPECT_TRUE(getregistrations_called);
EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE,
getregistrations_error);
EXPECT_EQ(1UL, array_size);
}
} // namespace content