Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(785)

Side by Side Diff: chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc

Issue 2898723003: [Sync] Migrate SyncInternalsMessageHandler off CallJavascriptFunctionUnsafe. (Closed)
Patch Set: Updates for dbeam and fixing windows browser test. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/sync_internals_message_handler.h" 5 #include "chrome/browser/ui/webui/sync_internals_message_handler.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "chrome/test/base/testing_profile.h" 12 #include "chrome/test/base/testing_profile.h"
13 #include "components/browser_sync/browser_sync_switches.h" 13 #include "components/browser_sync/browser_sync_switches.h"
14 #include "components/sync/driver/about_sync_util.h" 14 #include "components/sync/driver/about_sync_util.h"
15 #include "components/sync/driver/fake_sync_service.h"
15 #include "components/sync/driver/sync_service.h" 16 #include "components/sync/driver/sync_service.h"
17 #include "components/sync/js/js_test_util.h"
16 #include "content/public/browser/site_instance.h" 18 #include "content/public/browser/site_instance.h"
17 #include "content/public/browser/web_contents.h" 19 #include "content/public/browser/web_contents.h"
18 #include "content/public/test/test_browser_thread_bundle.h" 20 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "content/public/test/test_web_ui.h" 21 #include "content/public/test/test_web_ui.h"
20 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
21 23
24 using base::DictionaryValue;
25 using base::ListValue;
26 using base::Value;
27 using syncer::SyncService;
28 using syncer::SyncServiceObserver;
29 using syncer::TypeDebugInfoObserver;
30
22 namespace { 31 namespace {
23 32
24 class TestableSyncInternalsMessageHandler : public SyncInternalsMessageHandler { 33 class TestableSyncInternalsMessageHandler : public SyncInternalsMessageHandler {
25 public: 34 public:
26 explicit TestableSyncInternalsMessageHandler( 35 TestableSyncInternalsMessageHandler(
27 content::WebUI* web_ui, 36 content::WebUI* web_ui,
28 std::unique_ptr<AboutSyncDataExtractor> about_sync_data_extractor) 37 SyncServiceProvider sync_service_provider,
29 : SyncInternalsMessageHandler(std::move(about_sync_data_extractor)) { 38 AboutSyncDataDelegate about_sync_data_delegate)
39 : SyncInternalsMessageHandler(std::move(sync_service_provider),
40 std::move(about_sync_data_delegate)) {
30 set_web_ui(web_ui); 41 set_web_ui(web_ui);
31 } 42 }
32 }; 43 };
33 44
34 class FakeExtractor : public AboutSyncDataExtractor { 45 class TestSyncService : public syncer::FakeSyncService {
35 public: 46 public:
36 std::unique_ptr<base::DictionaryValue> ConstructAboutInformation( 47 void AddObserver(SyncServiceObserver* observer) override {
37 syncer::SyncService* service, 48 ++add_observer_count_;
38 SigninManagerBase* signin) override {
39 call_count_++;
40 last_service_ = service;
41 last_signin_ = signin;
42 std::unique_ptr<base::DictionaryValue> dictionary(
43 new base::DictionaryValue());
44 dictionary->SetString("fake_key", "fake_value");
45 return dictionary;
46 } 49 }
47 50
48 int call_count() const { return call_count_; } 51 void RemoveObserver(SyncServiceObserver* observer) override {
49 syncer::SyncService* last_service() const { return last_service_; } 52 ++remove_observer_count_;
50 SigninManagerBase* last_signin() const { return last_signin_; } 53 }
54
55 void AddTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override {
56 ++add_type_debug_info_observer_count_;
57 }
58
59 void RemoveTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override {
60 ++remove_type_debug_info_observer_count_;
61 }
62
63 base::WeakPtr<syncer::JsController> GetJsController() override {
64 return js_controller_.AsWeakPtr();
65 }
66
67 void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>&
68 callback) override {
69 get_all_nodes_callback_ = std::move(callback);
70 }
71
72 int add_observer_count() const { return add_observer_count_; }
73 int remove_observer_count() const { return remove_observer_count_; }
74 int add_type_debug_info_observer_count() const {
75 return add_type_debug_info_observer_count_;
76 }
77 int remove_type_debug_info_observer_count() const {
78 return remove_type_debug_info_observer_count_;
79 }
80 base::Callback<void(std::unique_ptr<base::ListValue>)>
81 get_all_nodes_callback() {
82 return std::move(get_all_nodes_callback_);
83 }
51 84
52 private: 85 private:
53 int call_count_ = 0; 86 int add_observer_count_ = 0;
54 syncer::SyncService* last_service_ = nullptr; 87 int remove_observer_count_ = 0;
55 SigninManagerBase* last_signin_ = nullptr; 88 int add_type_debug_info_observer_count_ = 0;
89 int remove_type_debug_info_observer_count_ = 0;
90 syncer::MockJsController js_controller_;
91 base::Callback<void(std::unique_ptr<base::ListValue>)>
92 get_all_nodes_callback_;
56 }; 93 };
57 94
58 class SyncInternalsMessageHandlerTest : public ::testing::Test { 95 class SyncInternalsMessageHandlerTest : public ::testing::Test {
59 protected: 96 protected:
60 SyncInternalsMessageHandlerTest() { 97 SyncInternalsMessageHandlerTest() {
61 site_instance_ = content::SiteInstance::Create(&profile_); 98 site_instance_ = content::SiteInstance::Create(&profile_);
62 web_contents_.reset(content::WebContents::Create( 99 web_contents_.reset(content::WebContents::Create(
63 content::WebContents::CreateParams(&profile_, site_instance_.get()))); 100 content::WebContents::CreateParams(&profile_, site_instance_.get())));
64 web_ui_.set_web_contents(web_contents_.get()); 101 web_ui_.set_web_contents(web_contents_.get());
65 fake_extractor_ = new FakeExtractor(); 102 test_sync_service_ = base::MakeUnique<TestSyncService>();
66 handler_.reset(new TestableSyncInternalsMessageHandler( 103 handler_.reset(new TestableSyncInternalsMessageHandler(
67 &web_ui_, std::unique_ptr<FakeExtractor>(fake_extractor_))); 104 &web_ui_,
105 base::BindRepeating(&SyncInternalsMessageHandlerTest::sync_service,
106 base::Unretained(this)),
107 base::BindRepeating(
108 &SyncInternalsMessageHandlerTest::ConstructAboutInformation,
109 base::Unretained(this))));
110 }
111
112 std::unique_ptr<DictionaryValue> ConstructAboutInformation(
113 SyncService* service,
114 version_info::Channel channel) {
115 ++about_sync_data_delegate_call_count_;
116 last_delegate_sync_service_ = service;
117 auto dictionary = base::MakeUnique<DictionaryValue>();
118 dictionary->SetString("fake_key", "fake_value");
119 return dictionary;
68 } 120 }
69 121
70 void ValidateAboutInfoCall() { 122 void ValidateAboutInfoCall() {
71 const auto& data_vector = web_ui_.call_data(); 123 const auto& data_vector = web_ui_.call_data();
72 ASSERT_FALSE(data_vector.empty()); 124 ASSERT_FALSE(data_vector.empty());
73 EXPECT_EQ(1u, data_vector.size()); 125 EXPECT_EQ(1u, data_vector.size());
74 126
75 const content::TestWebUI::CallData& call_data = *data_vector[0]; 127 const content::TestWebUI::CallData& call_data = *data_vector[0];
76 128
77 EXPECT_EQ(syncer::sync_ui_util::kDispatchEvent, call_data.function_name()); 129 EXPECT_EQ(syncer::sync_ui_util::kDispatchEvent, call_data.function_name());
78 130
79 const base::Value* arg1 = call_data.arg1(); 131 const Value* arg1 = call_data.arg1();
80 ASSERT_TRUE(arg1); 132 ASSERT_TRUE(arg1);
81 std::string event_type; 133 std::string event_type;
82 EXPECT_TRUE(arg1->GetAsString(&event_type)); 134 EXPECT_TRUE(arg1->GetAsString(&event_type));
83 EXPECT_EQ(syncer::sync_ui_util::kOnAboutInfoUpdated, event_type); 135 EXPECT_EQ(syncer::sync_ui_util::kOnAboutInfoUpdated, event_type);
84 136
85 const base::Value* arg2 = call_data.arg2(); 137 const Value* arg2 = call_data.arg2();
86 ASSERT_TRUE(arg2); 138 ASSERT_TRUE(arg2);
87 139
88 const base::DictionaryValue* root_dictionary = nullptr; 140 const DictionaryValue* root_dictionary = nullptr;
89 ASSERT_TRUE(arg2->GetAsDictionary(&root_dictionary)); 141 ASSERT_TRUE(arg2->GetAsDictionary(&root_dictionary));
90 142
91 std::string fake_value; 143 std::string fake_value;
92 EXPECT_TRUE(root_dictionary->GetString("fake_key", &fake_value)); 144 EXPECT_TRUE(root_dictionary->GetString("fake_key", &fake_value));
93 EXPECT_EQ("fake_value", fake_value); 145 EXPECT_EQ("fake_value", fake_value);
94 } 146 }
95 147
96 SyncInternalsMessageHandler* handler() { return handler_.get(); } 148 void ValidateEmptyAboutInfoCall() {
97 FakeExtractor* fake_extractor() { return fake_extractor_; } 149 EXPECT_TRUE(web_ui_.call_data().empty());
150 }
151
152 TestSyncService* test_sync_service() { return test_sync_service_.get(); }
153
154 TestableSyncInternalsMessageHandler* handler() { return handler_.get(); }
155
156 int CallCountWithName(const std::string& function_name) {
157 int count = 0;
158 for (const auto& call_data : web_ui_.call_data()) {
159 if (call_data->function_name() == function_name) {
160 count++;
161 }
162 }
163 return count;
164 }
165
166 int about_sync_data_delegate_call_count() {
Dan Beam 2017/05/25 00:28:20 nit: const {
skym 2017/05/25 17:38:12 Done.
167 return about_sync_data_delegate_call_count_;
168 }
169
170 SyncService* last_delegate_sync_service() {
Dan Beam 2017/05/25 00:28:20 const SyncService* last_delegate_sync_service() co
skym 2017/05/25 17:38:12 Done.
171 return last_delegate_sync_service_;
172 }
173
174 void ResetSyncService() { test_sync_service_.reset(); }
175
176 void ResetHandler() { handler_.reset(); }
98 177
99 private: 178 private:
179 SyncService* sync_service() { return test_sync_service_.get(); }
180
100 content::TestBrowserThreadBundle thread_bundle_; 181 content::TestBrowserThreadBundle thread_bundle_;
101 TestingProfile profile_; 182 TestingProfile profile_;
102 content::TestWebUI web_ui_; 183 content::TestWebUI web_ui_;
103 scoped_refptr<content::SiteInstance> site_instance_; 184 scoped_refptr<content::SiteInstance> site_instance_;
104 std::unique_ptr<content::WebContents> web_contents_; 185 std::unique_ptr<content::WebContents> web_contents_;
105 std::unique_ptr<SyncInternalsMessageHandler> handler_; 186 std::unique_ptr<TestSyncService> test_sync_service_;
187 std::unique_ptr<TestableSyncInternalsMessageHandler> handler_;
106 188
107 // Non-owning pointer to the about information the handler uses. This 189 int about_sync_data_delegate_call_count_ = 0;
108 // extractor is owned by the handler. 190 SyncService* last_delegate_sync_service_ = nullptr;
109 FakeExtractor* fake_extractor_;
110 }; 191 };
111 192
112 } // namespace 193 TEST_F(SyncInternalsMessageHandlerTest, AddRemoveObservers) {
194 ListValue empty_list;
113 195
114 TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfoWithService) { 196 EXPECT_EQ(0, test_sync_service()->add_observer_count());
197 handler()->HandleRegisterForEvents(&empty_list);
198 EXPECT_EQ(1, test_sync_service()->add_observer_count());
199
200 EXPECT_EQ(0, test_sync_service()->add_type_debug_info_observer_count());
201 handler()->HandleRegisterForPerTypeCounters(&empty_list);
202 EXPECT_EQ(1, test_sync_service()->add_type_debug_info_observer_count());
203
204 EXPECT_EQ(0, test_sync_service()->remove_observer_count());
205 EXPECT_EQ(0, test_sync_service()->remove_type_debug_info_observer_count());
206 ResetHandler();
207 EXPECT_EQ(1, test_sync_service()->remove_observer_count());
208 EXPECT_EQ(1, test_sync_service()->remove_type_debug_info_observer_count());
209
210 // Add calls should never have increased since the initial subscription.
211 EXPECT_EQ(1, test_sync_service()->add_observer_count());
212 EXPECT_EQ(1, test_sync_service()->add_type_debug_info_observer_count());
213 }
214
215 TEST_F(SyncInternalsMessageHandlerTest, AddRemoveObserversDisallowJavascript) {
216 ListValue empty_list;
217
218 EXPECT_EQ(0, test_sync_service()->add_observer_count());
219 handler()->HandleRegisterForEvents(&empty_list);
220 EXPECT_EQ(1, test_sync_service()->add_observer_count());
221
222 EXPECT_EQ(0, test_sync_service()->add_type_debug_info_observer_count());
223 handler()->HandleRegisterForPerTypeCounters(&empty_list);
224 EXPECT_EQ(1, test_sync_service()->add_type_debug_info_observer_count());
225
226 EXPECT_EQ(0, test_sync_service()->remove_observer_count());
227 EXPECT_EQ(0, test_sync_service()->remove_type_debug_info_observer_count());
228 handler()->DisallowJavascript();
229 EXPECT_EQ(1, test_sync_service()->remove_observer_count());
230 EXPECT_EQ(1, test_sync_service()->remove_type_debug_info_observer_count());
231
232 // Deregistration should not repeat, no counts should increase.
233 ResetHandler();
234 EXPECT_EQ(1, test_sync_service()->add_observer_count());
235 EXPECT_EQ(1, test_sync_service()->add_type_debug_info_observer_count());
236 EXPECT_EQ(1, test_sync_service()->remove_observer_count());
237 EXPECT_EQ(1, test_sync_service()->remove_type_debug_info_observer_count());
238 }
239
240 TEST_F(SyncInternalsMessageHandlerTest, AddRemoveObserversSyncDisabled) {
241 // Simulate completely disabling sync by flag or other mechanism.
242 ResetSyncService();
243
244 ListValue empty_list;
245 handler()->HandleRegisterForEvents(&empty_list);
246 handler()->HandleRegisterForPerTypeCounters(&empty_list);
247 handler()->DisallowJavascript();
248 // Cannot verify observer methods on sync services were not called, because
249 // there is no sync service. Rather, we're just making sure the handler hasn't
250 // performed any invalid operations when the sync service is missing.
251 }
252
253 TEST_F(SyncInternalsMessageHandlerTest,
254 RepeatedHandleRegisterForPerTypeCounters) {
255 ListValue empty_list;
256 handler()->HandleRegisterForPerTypeCounters(&empty_list);
257 EXPECT_EQ(1, test_sync_service()->add_type_debug_info_observer_count());
258 EXPECT_EQ(0, test_sync_service()->remove_type_debug_info_observer_count());
259
260 handler()->HandleRegisterForPerTypeCounters(&empty_list);
261 EXPECT_EQ(2, test_sync_service()->add_type_debug_info_observer_count());
262 EXPECT_EQ(1, test_sync_service()->remove_type_debug_info_observer_count());
263
264 handler()->HandleRegisterForPerTypeCounters(&empty_list);
265 EXPECT_EQ(3, test_sync_service()->add_type_debug_info_observer_count());
266 EXPECT_EQ(2, test_sync_service()->remove_type_debug_info_observer_count());
267
268 ResetHandler();
269 EXPECT_EQ(3, test_sync_service()->add_type_debug_info_observer_count());
270 EXPECT_EQ(3, test_sync_service()->remove_type_debug_info_observer_count());
271 }
272
273 TEST_F(SyncInternalsMessageHandlerTest, HandleGetAllNodes) {
274 ListValue args;
275 args.AppendInteger(0);
276 handler()->HandleGetAllNodes(&args);
277 test_sync_service()->get_all_nodes_callback().Run(
278 base::MakeUnique<ListValue>());
279 EXPECT_EQ(1, CallCountWithName(syncer::sync_ui_util::kGetAllNodesCallback));
280
281 handler()->HandleGetAllNodes(&args);
282 // This breaks the weak ref the callback is hanging onto. Which results in
283 // the call count not incrementing.
284 handler()->DisallowJavascript();
285 test_sync_service()->get_all_nodes_callback().Run(
286 base::MakeUnique<ListValue>());
287 EXPECT_EQ(1, CallCountWithName(syncer::sync_ui_util::kGetAllNodesCallback));
288
289 handler()->HandleGetAllNodes(&args);
290 test_sync_service()->get_all_nodes_callback().Run(
291 base::MakeUnique<ListValue>());
292 EXPECT_EQ(2, CallCountWithName(syncer::sync_ui_util::kGetAllNodesCallback));
293 }
294
295 TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfo) {
296 handler()->AllowJavascriptForTesting();
115 handler()->OnStateChanged(nullptr); 297 handler()->OnStateChanged(nullptr);
116 EXPECT_EQ(1, fake_extractor()->call_count()); 298 EXPECT_EQ(1, about_sync_data_delegate_call_count());
117 EXPECT_NE(nullptr, fake_extractor()->last_service()); 299 EXPECT_NE(nullptr, last_delegate_sync_service());
118 EXPECT_NE(nullptr, fake_extractor()->last_signin());
119 ValidateAboutInfoCall(); 300 ValidateAboutInfoCall();
120 } 301 }
121 302
122 TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfoWithoutService) { 303 TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfoSyncDisabled) {
123 base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync); 304 // Simulate completely disabling sync by flag or other mechanism.
305 ResetSyncService();
306
307 handler()->AllowJavascriptForTesting();
124 handler()->OnStateChanged(nullptr); 308 handler()->OnStateChanged(nullptr);
125 EXPECT_EQ(1, fake_extractor()->call_count()); 309 EXPECT_EQ(1, about_sync_data_delegate_call_count());
126 EXPECT_EQ(nullptr, fake_extractor()->last_service()); 310 EXPECT_EQ(nullptr, last_delegate_sync_service());
127 EXPECT_EQ(nullptr, fake_extractor()->last_signin());
128 ValidateAboutInfoCall(); 311 ValidateAboutInfoCall();
129 } 312 }
313
314 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698