blob: f3b0cf9bdcaae9ea3dbc4b7112b5917400ded3f9 [file] [log] [blame]
// Copyright (c) 2012 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 "chrome/browser/ui/webui/sync_internals_ui.h"
#include <cstddef>
#include <string>
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/profile_mock.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/test/test_browser_thread.h"
#include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h"
#include "sync/js/js_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
// Rewrite to use WebUI testing infrastructure. Current code below is mostly
// testing how WebUI concrete class serializes function parameters, and that
// SyncInternalsUI::HandleJSEvent/HandleJsReply prefix the given function with
// "chrome.sync." and postfix it with ".fire" or ".handleReply".
// http://crbug.com/110517
/*
namespace {
using browser_sync::HasArgsAsList;
using syncer::JsArgList;
using syncer::JsEventDetails;
using content::BrowserThread;
using content::WebContents;
using testing::_;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
// Subclass of WebUI to mock out ExecuteJavascript.
class TestSyncWebUI: public WebUI {
public:
explicit TestSyncWebUI(WebContents* web_contents)
: WebUI(web_contents) {}
virtual ~TestSyncWebUI() {}
MOCK_METHOD1(ExecuteJavascript, void(const base::string16&));
};
// Tests with non-NULL ProfileSyncService.
class SyncInternalsUITestWithService : public ChromeRenderViewHostTestHarness {
protected:
SyncInternalsUITestWithService() : sync_internals_ui_(NULL) {}
virtual ~SyncInternalsUITestWithService() {}
virtual void SetUp() {
NiceMock<ProfileMock>* profile_mock = new NiceMock<ProfileMock>();
StrictMock<ProfileSyncServiceMock> profile_sync_service_mock;
EXPECT_CALL(*profile_mock, GetProfileSyncService())
.WillOnce(Return(&profile_sync_service_mock));
browser_context_.reset(profile_mock);
ChromeRenderViewHostTestHarness::SetUp();
EXPECT_CALL(profile_sync_service_mock, GetJsController())
.WillOnce(Return(mock_js_controller_.AsWeakPtr()));
EXPECT_CALL(mock_js_controller_, AddJsEventHandler(_));
{
// Needed by |sync_internals_ui_|'s constructor. The
// message loop is provided by ChromeRenderViewHostTestHarness.
content::TestBrowserThread ui_thread_(BrowserThread::UI,
base::MessageLoopForUI::current());
// |sync_internals_ui_|'s constructor triggers all the
// expectations above.
web_ui_.reset(new TestSyncWebUI(web_contents()));
sync_internals_ui_ = new SyncInternalsUI(web_ui_.get());
web_ui_->SetController(sync_internals_ui_);
}
Mock::VerifyAndClearExpectations(profile_mock);
Mock::VerifyAndClearExpectations(&mock_js_controller_);
}
virtual void TearDown() {
Mock::VerifyAndClearExpectations(&mock_js_controller_);
// Called by |sync_internals_ui_|'s destructor.
EXPECT_CALL(mock_js_controller_,
RemoveJsEventHandler(sync_internals_ui_));
sync_internals_ui_ = NULL;
web_ui_.reset();
ChromeRenderViewHostTestHarness::TearDown();
}
StrictMock<browser_sync::MockJsController> mock_js_controller_;
scoped_ptr<TestSyncWebUI> web_ui_;
SyncInternalsUI* sync_internals_ui_;
};
TEST_F(SyncInternalsUITestWithService, HandleJsEvent) {
EXPECT_CALL(*web_ui_,
ExecuteJavascript(
ASCIIToUTF16("chrome.sync.testMessage.fire({});")));
sync_internals_ui_->HandleJsEvent("testMessage", JsEventDetails());
}
TEST_F(SyncInternalsUITestWithService, HandleJsReply) {
EXPECT_CALL(
*web_ui_,
ExecuteJavascript(
ASCIIToUTF16("chrome.sync.testMessage.handleReply(5,true);")));
base::ListValue args;
args.Append(new base::FundamentalValue(5));
args.Append(new base::FundamentalValue(true));
sync_internals_ui_->HandleJsReply("testMessage", JsArgList(&args));
}
TEST_F(SyncInternalsUITestWithService, OnWebUISendBasic) {
const std::string& name = "testName";
base::ListValue args;
args.Append(new base::FundamentalValue(10));
EXPECT_CALL(mock_js_controller_,
ProcessJsMessage(name, HasArgsAsList(args), _));
sync_internals_ui_->OverrideHandleWebUIMessage(GURL(), name, args);
}
// Tests with NULL ProfileSyncService.
class SyncInternalsUITestWithoutService
: public ChromeRenderViewHostTestHarness {
protected:
SyncInternalsUITestWithoutService() : sync_internals_ui_(NULL) {}
virtual ~SyncInternalsUITestWithoutService() {}
virtual void SetUp() {
NiceMock<ProfileMock>* profile_mock = new NiceMock<ProfileMock>();
EXPECT_CALL(*profile_mock, GetProfileSyncService())
.WillOnce(Return(static_cast<ProfileSyncService*>(NULL)));
browser_context_.reset(profile_mock);
ChromeRenderViewHostTestHarness::SetUp();
{
// Needed by |sync_internals_ui_|'s constructor. The
// message loop is provided by ChromeRenderViewHostTestHarness.
content::TestBrowserThread ui_thread_(BrowserThread::UI,
base::MessageLoopForUI::current());
// |sync_internals_ui_|'s constructor triggers all the
// expectations above.
web_ui_.reset(new TestSyncWebUI(web_contents()));
sync_internals_ui_ = new SyncInternalsUI(web_ui_.get());
web_ui_->SetController(sync_internals_ui_);
}
Mock::VerifyAndClearExpectations(profile_mock);
}
scoped_ptr<TestSyncWebUI> web_ui_;
SyncInternalsUI* sync_internals_ui_;
};
TEST_F(SyncInternalsUITestWithoutService, HandleJsEvent) {
EXPECT_CALL(*web_ui_,
ExecuteJavascript(
ASCIIToUTF16("chrome.sync.testMessage.fire({});")));
sync_internals_ui_->HandleJsEvent("testMessage", JsEventDetails());
}
TEST_F(SyncInternalsUITestWithoutService, HandleJsReply) {
EXPECT_CALL(
*web_ui_,
ExecuteJavascript(
ASCIIToUTF16("chrome.sync.testMessage.handleReply(5,true);")));
base::ListValue args;
args.Append(new base::FundamentalValue(5));
args.Append(new base::FundamentalValue(true));
sync_internals_ui_->HandleJsReply(
"testMessage", JsArgList(&args));
}
TEST_F(SyncInternalsUITestWithoutService, OnWebUISendBasic) {
const std::string& name = "testName";
base::ListValue args;
args.Append(new base::FundamentalValue(5));
// Should drop the message.
sync_internals_ui_->OverrideHandleWebUIMessage(GURL(), name, args);
}
// TODO(lipalani) - add a test case to test about:sync with a non null
// service.
TEST_F(SyncInternalsUITestWithoutService, OnWebUISendGetAboutInfo) {
const char kAboutInfoCall[] =
"chrome.sync.getAboutInfo.handleReply({\"summary\":\"SYNC DISABLED\"});";
EXPECT_CALL(*web_ui_,
ExecuteJavascript(ASCIIToUTF16(kAboutInfoCall)));
base::ListValue args;
sync_internals_ui_->OverrideHandleWebUIMessage(
GURL(), "getAboutInfo", args);
}
} // namespace
*/