1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/webui/sync_internals_ui.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/sync/profile_sync_service_mock.h"
14 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
15 #include "chrome/test/base/profile_mock.h"
16 #include "content/public/browser/web_ui_controller.h"
17 #include "content/public/test/test_browser_thread.h"
18 #include "sync/js/js_arg_list.h"
19 #include "sync/js/js_event_details.h"
20 #include "sync/js/js_test_util.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 // Rewrite to use WebUI testing infrastructure. Current code below is mostly
25 // testing how WebUI concrete class serializes function parameters, and that
26 // SyncInternalsUI::HandleJSEvent/HandleJsReply prefix the given function with
27 // "chrome.sync." and postfix it with ".fire" or ".handleReply".
28 // http://crbug.com/110517
33 using browser_sync::HasArgsAsList;
34 using syncer::JsArgList;
35 using syncer::JsEventDetails;
36 using content::BrowserThread;
37 using content::WebContents;
40 using testing::NiceMock;
41 using testing::Return;
42 using testing::StrictMock;
44 // Subclass of WebUI to mock out ExecuteJavascript.
45 class TestSyncWebUI: public WebUI {
47 explicit TestSyncWebUI(WebContents* web_contents)
48 : WebUI(web_contents) {}
49 virtual ~TestSyncWebUI() {}
51 MOCK_METHOD1(ExecuteJavascript, void(const string16&));
54 // Tests with non-NULL ProfileSyncService.
55 class SyncInternalsUITestWithService : public ChromeRenderViewHostTestHarness {
57 SyncInternalsUITestWithService() : sync_internals_ui_(NULL) {}
59 virtual ~SyncInternalsUITestWithService() {}
61 virtual void SetUp() {
62 NiceMock<ProfileMock>* profile_mock = new NiceMock<ProfileMock>();
63 StrictMock<ProfileSyncServiceMock> profile_sync_service_mock;
64 EXPECT_CALL(*profile_mock, GetProfileSyncService())
65 .WillOnce(Return(&profile_sync_service_mock));
66 browser_context_.reset(profile_mock);
68 ChromeRenderViewHostTestHarness::SetUp();
70 EXPECT_CALL(profile_sync_service_mock, GetJsController())
71 .WillOnce(Return(mock_js_controller_.AsWeakPtr()));
73 EXPECT_CALL(mock_js_controller_, AddJsEventHandler(_));
76 // Needed by |sync_internals_ui_|'s constructor. The
77 // message loop is provided by ChromeRenderViewHostTestHarness.
78 content::TestBrowserThread ui_thread_(BrowserThread::UI,
79 base::MessageLoopForUI::current());
80 // |sync_internals_ui_|'s constructor triggers all the
81 // expectations above.
82 web_ui_.reset(new TestSyncWebUI(web_contents()));
83 sync_internals_ui_ = new SyncInternalsUI(web_ui_.get());
84 web_ui_->SetController(sync_internals_ui_);
87 Mock::VerifyAndClearExpectations(profile_mock);
88 Mock::VerifyAndClearExpectations(&mock_js_controller_);
91 virtual void TearDown() {
92 Mock::VerifyAndClearExpectations(&mock_js_controller_);
94 // Called by |sync_internals_ui_|'s destructor.
95 EXPECT_CALL(mock_js_controller_,
96 RemoveJsEventHandler(sync_internals_ui_));
97 sync_internals_ui_ = NULL;
100 ChromeRenderViewHostTestHarness::TearDown();
103 StrictMock<browser_sync::MockJsController> mock_js_controller_;
104 scoped_ptr<TestSyncWebUI> web_ui_;
105 SyncInternalsUI* sync_internals_ui_;
108 TEST_F(SyncInternalsUITestWithService, HandleJsEvent) {
109 EXPECT_CALL(*web_ui_,
111 ASCIIToUTF16("chrome.sync.testMessage.fire({});")));
113 sync_internals_ui_->HandleJsEvent("testMessage", JsEventDetails());
116 TEST_F(SyncInternalsUITestWithService, HandleJsReply) {
120 ASCIIToUTF16("chrome.sync.testMessage.handleReply(5,true);")));
123 args.Append(Value::CreateIntegerValue(5));
124 args.Append(Value::CreateBooleanValue(true));
125 sync_internals_ui_->HandleJsReply("testMessage", JsArgList(&args));
128 TEST_F(SyncInternalsUITestWithService, OnWebUISendBasic) {
129 const std::string& name = "testName";
131 args.Append(Value::CreateIntegerValue(10));
133 EXPECT_CALL(mock_js_controller_,
134 ProcessJsMessage(name, HasArgsAsList(args), _));
136 sync_internals_ui_->OverrideHandleWebUIMessage(GURL(), name, args);
139 // Tests with NULL ProfileSyncService.
140 class SyncInternalsUITestWithoutService
141 : public ChromeRenderViewHostTestHarness {
143 SyncInternalsUITestWithoutService() : sync_internals_ui_(NULL) {}
145 virtual ~SyncInternalsUITestWithoutService() {}
147 virtual void SetUp() {
148 NiceMock<ProfileMock>* profile_mock = new NiceMock<ProfileMock>();
149 EXPECT_CALL(*profile_mock, GetProfileSyncService())
150 .WillOnce(Return(static_cast<ProfileSyncService*>(NULL)));
151 browser_context_.reset(profile_mock);
153 ChromeRenderViewHostTestHarness::SetUp();
156 // Needed by |sync_internals_ui_|'s constructor. The
157 // message loop is provided by ChromeRenderViewHostTestHarness.
158 content::TestBrowserThread ui_thread_(BrowserThread::UI,
159 base::MessageLoopForUI::current());
160 // |sync_internals_ui_|'s constructor triggers all the
161 // expectations above.
162 web_ui_.reset(new TestSyncWebUI(web_contents()));
163 sync_internals_ui_ = new SyncInternalsUI(web_ui_.get());
164 web_ui_->SetController(sync_internals_ui_);
167 Mock::VerifyAndClearExpectations(profile_mock);
170 scoped_ptr<TestSyncWebUI> web_ui_;
171 SyncInternalsUI* sync_internals_ui_;
174 TEST_F(SyncInternalsUITestWithoutService, HandleJsEvent) {
175 EXPECT_CALL(*web_ui_,
177 ASCIIToUTF16("chrome.sync.testMessage.fire({});")));
179 sync_internals_ui_->HandleJsEvent("testMessage", JsEventDetails());
182 TEST_F(SyncInternalsUITestWithoutService, HandleJsReply) {
186 ASCIIToUTF16("chrome.sync.testMessage.handleReply(5,true);")));
189 args.Append(Value::CreateIntegerValue(5));
190 args.Append(Value::CreateBooleanValue(true));
191 sync_internals_ui_->HandleJsReply(
192 "testMessage", JsArgList(&args));
195 TEST_F(SyncInternalsUITestWithoutService, OnWebUISendBasic) {
196 const std::string& name = "testName";
198 args.Append(Value::CreateIntegerValue(5));
200 // Should drop the message.
201 sync_internals_ui_->OverrideHandleWebUIMessage(GURL(), name, args);
204 // TODO(lipalani) - add a test case to test about:sync with a non null
206 TEST_F(SyncInternalsUITestWithoutService, OnWebUISendGetAboutInfo) {
207 const char kAboutInfoCall[] =
208 "chrome.sync.getAboutInfo.handleReply({\"summary\":\"SYNC DISABLED\"});";
209 EXPECT_CALL(*web_ui_,
210 ExecuteJavascript(ASCIIToUTF16(kAboutInfoCall)));
213 sync_internals_ui_->OverrideHandleWebUIMessage(
214 GURL(), "getAboutInfo", args);