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 using base::ASCIIToUTF16
;
26 // Rewrite to use WebUI testing infrastructure. Current code below is mostly
27 // testing how WebUI concrete class serializes function parameters, and that
28 // SyncInternalsUI::HandleJSEvent/HandleJsReply prefix the given function with
29 // "chrome.sync." and postfix it with ".fire" or ".handleReply".
30 // http://crbug.com/110517
35 using browser_sync::HasArgsAsList;
36 using syncer::JsArgList;
37 using syncer::JsEventDetails;
38 using content::BrowserThread;
39 using content::WebContents;
42 using testing::NiceMock;
43 using testing::Return;
44 using testing::StrictMock;
46 // Subclass of WebUI to mock out ExecuteJavascript.
47 class TestSyncWebUI: public WebUI {
49 explicit TestSyncWebUI(WebContents* web_contents)
50 : WebUI(web_contents) {}
51 virtual ~TestSyncWebUI() {}
53 MOCK_METHOD1(ExecuteJavascript, void(const base::string16&));
56 // Tests with non-NULL ProfileSyncService.
57 class SyncInternalsUITestWithService : public ChromeRenderViewHostTestHarness {
59 SyncInternalsUITestWithService() : sync_internals_ui_(NULL) {}
61 virtual ~SyncInternalsUITestWithService() {}
63 virtual void SetUp() {
64 NiceMock<ProfileMock>* profile_mock = new NiceMock<ProfileMock>();
65 StrictMock<ProfileSyncServiceMock> profile_sync_service_mock;
66 EXPECT_CALL(*profile_mock, GetProfileSyncService())
67 .WillOnce(Return(&profile_sync_service_mock));
68 browser_context_.reset(profile_mock);
70 ChromeRenderViewHostTestHarness::SetUp();
72 EXPECT_CALL(profile_sync_service_mock, GetJsController())
73 .WillOnce(Return(mock_js_controller_.AsWeakPtr()));
75 EXPECT_CALL(mock_js_controller_, AddJsEventHandler(_));
78 // Needed by |sync_internals_ui_|'s constructor. The
79 // message loop is provided by ChromeRenderViewHostTestHarness.
80 content::TestBrowserThread ui_thread_(BrowserThread::UI,
81 base::MessageLoopForUI::current());
82 // |sync_internals_ui_|'s constructor triggers all the
83 // expectations above.
84 web_ui_.reset(new TestSyncWebUI(web_contents()));
85 sync_internals_ui_ = new SyncInternalsUI(web_ui_.get());
86 web_ui_->SetController(sync_internals_ui_);
89 Mock::VerifyAndClearExpectations(profile_mock);
90 Mock::VerifyAndClearExpectations(&mock_js_controller_);
93 virtual void TearDown() {
94 Mock::VerifyAndClearExpectations(&mock_js_controller_);
96 // Called by |sync_internals_ui_|'s destructor.
97 EXPECT_CALL(mock_js_controller_,
98 RemoveJsEventHandler(sync_internals_ui_));
99 sync_internals_ui_ = NULL;
102 ChromeRenderViewHostTestHarness::TearDown();
105 StrictMock<browser_sync::MockJsController> mock_js_controller_;
106 scoped_ptr<TestSyncWebUI> web_ui_;
107 SyncInternalsUI* sync_internals_ui_;
110 TEST_F(SyncInternalsUITestWithService, HandleJsEvent) {
111 EXPECT_CALL(*web_ui_,
113 ASCIIToUTF16("chrome.sync.testMessage.fire({});")));
115 sync_internals_ui_->HandleJsEvent("testMessage", JsEventDetails());
118 TEST_F(SyncInternalsUITestWithService, HandleJsReply) {
122 ASCIIToUTF16("chrome.sync.testMessage.handleReply(5,true);")));
124 base::ListValue args;
125 args.Append(new base::FundamentalValue(5));
126 args.Append(new base::FundamentalValue(true));
127 sync_internals_ui_->HandleJsReply("testMessage", JsArgList(&args));
130 TEST_F(SyncInternalsUITestWithService, OnWebUISendBasic) {
131 const std::string& name = "testName";
132 base::ListValue args;
133 args.Append(new base::FundamentalValue(10));
135 EXPECT_CALL(mock_js_controller_,
136 ProcessJsMessage(name, HasArgsAsList(args), _));
138 sync_internals_ui_->OverrideHandleWebUIMessage(GURL(), name, args);
141 // Tests with NULL ProfileSyncService.
142 class SyncInternalsUITestWithoutService
143 : public ChromeRenderViewHostTestHarness {
145 SyncInternalsUITestWithoutService() : sync_internals_ui_(NULL) {}
147 virtual ~SyncInternalsUITestWithoutService() {}
149 virtual void SetUp() {
150 NiceMock<ProfileMock>* profile_mock = new NiceMock<ProfileMock>();
151 EXPECT_CALL(*profile_mock, GetProfileSyncService())
152 .WillOnce(Return(static_cast<ProfileSyncService*>(NULL)));
153 browser_context_.reset(profile_mock);
155 ChromeRenderViewHostTestHarness::SetUp();
158 // Needed by |sync_internals_ui_|'s constructor. The
159 // message loop is provided by ChromeRenderViewHostTestHarness.
160 content::TestBrowserThread ui_thread_(BrowserThread::UI,
161 base::MessageLoopForUI::current());
162 // |sync_internals_ui_|'s constructor triggers all the
163 // expectations above.
164 web_ui_.reset(new TestSyncWebUI(web_contents()));
165 sync_internals_ui_ = new SyncInternalsUI(web_ui_.get());
166 web_ui_->SetController(sync_internals_ui_);
169 Mock::VerifyAndClearExpectations(profile_mock);
172 scoped_ptr<TestSyncWebUI> web_ui_;
173 SyncInternalsUI* sync_internals_ui_;
176 TEST_F(SyncInternalsUITestWithoutService, HandleJsEvent) {
177 EXPECT_CALL(*web_ui_,
179 ASCIIToUTF16("chrome.sync.testMessage.fire({});")));
181 sync_internals_ui_->HandleJsEvent("testMessage", JsEventDetails());
184 TEST_F(SyncInternalsUITestWithoutService, HandleJsReply) {
188 ASCIIToUTF16("chrome.sync.testMessage.handleReply(5,true);")));
190 base::ListValue args;
191 args.Append(new base::FundamentalValue(5));
192 args.Append(new base::FundamentalValue(true));
193 sync_internals_ui_->HandleJsReply(
194 "testMessage", JsArgList(&args));
197 TEST_F(SyncInternalsUITestWithoutService, OnWebUISendBasic) {
198 const std::string& name = "testName";
199 base::ListValue args;
200 args.Append(new base::FundamentalValue(5));
202 // Should drop the message.
203 sync_internals_ui_->OverrideHandleWebUIMessage(GURL(), name, args);
206 // TODO(lipalani) - add a test case to test about:sync with a non null
208 TEST_F(SyncInternalsUITestWithoutService, OnWebUISendGetAboutInfo) {
209 const char kAboutInfoCall[] =
210 "chrome.sync.getAboutInfo.handleReply({\"summary\":\"SYNC DISABLED\"});";
211 EXPECT_CALL(*web_ui_,
212 ExecuteJavascript(ASCIIToUTF16(kAboutInfoCall)));
214 base::ListValue args;
215 sync_internals_ui_->OverrideHandleWebUIMessage(
216 GURL(), "getAboutInfo", args);