OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/sync/glue/chrome_sync_notification_bridge.h" | 5 #include "chrome/browser/sync/glue/chrome_sync_notification_bridge.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/memory/ref_counted.h" | |
8 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
9 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/sequenced_task_runner.h" | |
10 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
11 #include "base/test/test_timeouts.h" | 14 #include "base/test/test_timeouts.h" |
12 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
13 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
14 #include "chrome/test/base/profile_mock.h" | 17 #include "chrome/test/base/profile_mock.h" |
15 #include "content/public/browser/notification_details.h" | 18 #include "content/public/browser/notification_details.h" |
16 #include "content/public/browser/notification_service.h" | 19 #include "content/public/browser/notification_service.h" |
17 #include "content/public/test/test_browser_thread.h" | 20 #include "content/public/test/test_browser_thread.h" |
18 #include "sync/internal_api/public/base/model_type.h" | 21 #include "sync/internal_api/public/base/model_type.h" |
19 #include "sync/internal_api/public/base/model_type_payload_map.h" | 22 #include "sync/internal_api/public/base/model_type_payload_map.h" |
20 #include "sync/notifier/mock_sync_notifier_observer.h" | |
21 #include "sync/notifier/sync_notifier_observer.h" | 23 #include "sync/notifier/sync_notifier_observer.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
24 | 26 |
25 namespace browser_sync { | 27 namespace browser_sync { |
26 namespace { | 28 namespace { |
27 | 29 |
28 using ::testing::Mock; | 30 using ::testing::Mock; |
29 using ::testing::NiceMock; | 31 using ::testing::NiceMock; |
30 using ::testing::StrictMock; | 32 using ::testing::StrictMock; |
31 using content::BrowserThread; | 33 using content::BrowserThread; |
32 | 34 |
33 // Receives a ChromeSyncNotificationBridge to register to, and an expected | 35 // Receives a ChromeSyncNotificationBridge to register to, and an expected |
34 // ModelTypePayloadMap. ReceivedProperNotification() will return true only | 36 // ModelTypePayloadMap. ReceivedProperNotification() will return true only |
35 // if the observer has received a notification with the proper source and | 37 // if the observer has received a notification with the proper source and |
36 // payload. | 38 // payload. |
37 // Note: Because this object lives on the IO thread, we use a fake (vs a mock) | 39 // Note: Because this object lives on the sync thread, we use a fake |
38 // so we don't have to worry about possible thread safety issues within | 40 // (vs a mock) so we don't have to worry about possible thread safety |
39 // GTest/GMock. | 41 // issues within GTest/GMock. |
40 class FakeSyncNotifierObserverIO | 42 class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { |
41 : public syncer::SyncNotifierObserver { | |
42 public: | 43 public: |
43 FakeSyncNotifierObserverIO( | 44 FakeSyncNotifierObserver( |
45 const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner, | |
44 ChromeSyncNotificationBridge* bridge, | 46 ChromeSyncNotificationBridge* bridge, |
45 const syncer::ModelTypePayloadMap& expected_payloads) | 47 const syncer::ModelTypePayloadMap& expected_payloads, |
46 : bridge_(bridge), | 48 syncer::IncomingNotificationSource expected_source) |
49 : sync_task_runner_(sync_task_runner), | |
50 bridge_(bridge), | |
47 received_improper_notification_(false), | 51 received_improper_notification_(false), |
48 notification_count_(0), | 52 notification_count_(0), |
49 expected_payloads_(expected_payloads) { | 53 expected_payloads_(expected_payloads), |
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 54 expected_source_(expected_source) { |
55 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); | |
51 bridge_->AddObserver(this); | 56 bridge_->AddObserver(this); |
52 } | 57 } |
53 virtual ~FakeSyncNotifierObserverIO() { | 58 |
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 59 virtual ~FakeSyncNotifierObserver() { |
60 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); | |
55 bridge_->RemoveObserver(this); | 61 bridge_->RemoveObserver(this); |
56 } | 62 } |
57 | 63 |
58 // SyncNotifierObserver implementation. | 64 // SyncNotifierObserver implementation. |
59 virtual void OnIncomingNotification( | 65 virtual void OnIncomingNotification( |
60 const syncer::ModelTypePayloadMap& type_payloads, | 66 const syncer::ModelTypePayloadMap& type_payloads, |
61 syncer::IncomingNotificationSource source) OVERRIDE { | 67 syncer::IncomingNotificationSource source) OVERRIDE { |
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 68 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); |
63 notification_count_++; | 69 notification_count_++; |
64 if (source != syncer::LOCAL_NOTIFICATION) { | 70 if (source != expected_source_) { |
65 LOG(ERROR) << "Received notification with wrong source."; | 71 LOG(ERROR) << "Received notification with wrong source"; |
66 received_improper_notification_ = true; | 72 received_improper_notification_ = true; |
67 } | 73 } |
68 if (expected_payloads_ != type_payloads) { | 74 if (expected_payloads_ != type_payloads) { |
69 LOG(ERROR) << "Received wrong payload."; | 75 LOG(ERROR) << "Received wrong payload"; |
70 received_improper_notification_ = true; | 76 received_improper_notification_ = true; |
71 } | 77 } |
72 } | 78 } |
73 virtual void OnNotificationsEnabled() OVERRIDE { | 79 virtual void OnNotificationsEnabled() OVERRIDE { |
74 NOTREACHED(); | 80 NOTREACHED(); |
75 } | 81 } |
76 virtual void OnNotificationsDisabled( | 82 virtual void OnNotificationsDisabled( |
77 syncer::NotificationsDisabledReason reason) OVERRIDE { | 83 syncer::NotificationsDisabledReason reason) OVERRIDE { |
78 NOTREACHED(); | 84 NOTREACHED(); |
79 } | 85 } |
80 | 86 |
81 bool ReceivedProperNotification() const { | 87 bool ReceivedProperNotification() const { |
88 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); | |
82 return (notification_count_ == 1) && !received_improper_notification_; | 89 return (notification_count_ == 1) && !received_improper_notification_; |
83 } | 90 } |
84 | 91 |
85 private: | 92 private: |
86 ChromeSyncNotificationBridge* bridge_; | 93 const scoped_refptr<base::SequencedTaskRunner> sync_task_runner_; |
94 ChromeSyncNotificationBridge* const bridge_; | |
87 bool received_improper_notification_; | 95 bool received_improper_notification_; |
88 size_t notification_count_; | 96 size_t notification_count_; |
89 syncer::ModelTypePayloadMap expected_payloads_; | 97 const syncer::ModelTypePayloadMap expected_payloads_; |
98 const syncer::IncomingNotificationSource expected_source_; | |
90 }; | 99 }; |
91 | 100 |
92 class ChromeSyncNotificationBridgeTest : public testing::Test { | 101 class ChromeSyncNotificationBridgeTest : public testing::Test { |
93 public: | 102 public: |
94 ChromeSyncNotificationBridgeTest() | 103 ChromeSyncNotificationBridgeTest() |
95 : ui_thread_(BrowserThread::UI, &ui_loop_), | 104 : ui_thread_(BrowserThread::UI, &ui_loop_), |
Nicolas Zea
2012/07/20 20:01:37
are ui thread and ui loop both still needed? I don
akalin
2012/07/20 20:19:54
Removed ui_loop_. Also made all the member variab
| |
96 io_thread_(BrowserThread::IO), | 105 sync_thread_("Sync thread"), |
97 io_observer_(NULL), | 106 sync_observer_(NULL), |
98 io_observer_notification_failure_(false), | 107 sync_observer_notification_failure_(false), |
99 bridge_(&mock_profile_), | 108 done_(true, false) {} |
100 done_(true, false) { | 109 |
101 io_thread_.StartIOThread(); | |
102 } | |
103 virtual ~ChromeSyncNotificationBridgeTest() {} | 110 virtual ~ChromeSyncNotificationBridgeTest() {} |
104 | 111 |
105 protected: | 112 protected: |
106 virtual void TearDown() OVERRIDE { | 113 virtual void SetUp() OVERRIDE { |
107 io_thread_.Stop(); | 114 ASSERT_TRUE(sync_thread_.Start()); |
108 ui_loop_.RunAllPending(); | 115 bridge_.reset( |
109 EXPECT_EQ(NULL, io_observer_); | 116 new ChromeSyncNotificationBridge( |
110 if (io_observer_notification_failure_) | 117 &mock_profile_, sync_thread_.message_loop_proxy())); |
111 ADD_FAILURE() << "IO Observer did not receive proper notification."; | |
112 } | 118 } |
113 | 119 |
114 void VerifyAndDestroyObserverOnIOThread() { | 120 virtual void TearDown() OVERRIDE { |
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 121 sync_thread_.Stop(); |
116 if (!io_observer_) { | 122 // Must be reset only after the sync thread is stopped. |
117 io_observer_notification_failure_ = true; | 123 bridge_.reset(); |
124 ui_loop_.RunAllPending(); | |
125 EXPECT_EQ(NULL, sync_observer_); | |
126 if (sync_observer_notification_failure_) | |
127 ADD_FAILURE() << "Sync Observer did not receive proper notification."; | |
128 } | |
129 | |
130 void VerifyAndDestroyObserverOnSyncThread() { | |
131 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); | |
132 if (!sync_observer_) { | |
133 sync_observer_notification_failure_ = true; | |
118 } else { | 134 } else { |
119 io_observer_notification_failure_ = | 135 sync_observer_notification_failure_ = |
120 !io_observer_->ReceivedProperNotification(); | 136 !sync_observer_->ReceivedProperNotification(); |
121 delete io_observer_; | 137 delete sync_observer_; |
122 io_observer_ = NULL; | 138 sync_observer_ = NULL; |
123 } | 139 } |
124 } | 140 } |
125 | 141 |
126 void VerifyAndDestroyObserver() { | 142 void VerifyAndDestroyObserver() { |
127 ASSERT_TRUE(BrowserThread::PostTask( | 143 ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
128 BrowserThread::IO, | |
129 FROM_HERE, | 144 FROM_HERE, |
130 base::Bind(&ChromeSyncNotificationBridgeTest:: | 145 base::Bind(&ChromeSyncNotificationBridgeTest:: |
131 VerifyAndDestroyObserverOnIOThread, | 146 VerifyAndDestroyObserverOnSyncThread, |
132 base::Unretained(this)))); | 147 base::Unretained(this)))); |
Nicolas Zea
2012/07/20 20:01:37
does this need a BlockForSyncThread after it? I su
akalin
2012/07/20 20:19:54
Done.
| |
133 } | 148 } |
134 | 149 |
135 void CreateObserverOnIOThread( | 150 void CreateObserverOnSyncThread( |
136 syncer::ModelTypePayloadMap expected_payloads) { | 151 syncer::ModelTypePayloadMap expected_payloads, |
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 152 syncer::IncomingNotificationSource expected_source) { |
138 io_observer_ = new FakeSyncNotifierObserverIO(&bridge_, | 153 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
139 expected_payloads); | 154 sync_observer_ = new FakeSyncNotifierObserver( |
155 sync_thread_.message_loop_proxy(), | |
156 bridge_.get(), | |
157 expected_payloads, | |
158 expected_source); | |
140 } | 159 } |
141 | 160 |
142 void CreateObserverWithExpectedPayload( | 161 void CreateObserverWithExpectations( |
143 syncer::ModelTypePayloadMap expected_payloads) { | 162 syncer::ModelTypePayloadMap expected_payloads, |
144 ASSERT_TRUE(BrowserThread::PostTask( | 163 syncer::IncomingNotificationSource expected_source) { |
145 BrowserThread::IO, | 164 ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
146 FROM_HERE, | 165 FROM_HERE, |
147 base::Bind(&ChromeSyncNotificationBridgeTest::CreateObserverOnIOThread, | 166 base::Bind( |
148 base::Unretained(this), | 167 &ChromeSyncNotificationBridgeTest::CreateObserverOnSyncThread, |
149 expected_payloads))); | 168 base::Unretained(this), |
150 BlockForIOThread(); | 169 expected_payloads, |
170 expected_source))); | |
171 BlockForSyncThread(); | |
151 } | 172 } |
152 | 173 |
153 void SignalOnIOThread() { | 174 void SignalOnSyncThread() { |
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 175 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
155 done_.Signal(); | 176 done_.Signal(); |
156 } | 177 } |
157 | 178 |
158 void BlockForIOThread() { | 179 void BlockForSyncThread() { |
159 done_.Reset(); | 180 done_.Reset(); |
160 BrowserThread::PostTask( | 181 ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
161 BrowserThread::IO, | |
162 FROM_HERE, | 182 FROM_HERE, |
163 base::Bind(&ChromeSyncNotificationBridgeTest::SignalOnIOThread, | 183 base::Bind(&ChromeSyncNotificationBridgeTest::SignalOnSyncThread, |
164 base::Unretained(this))); | 184 base::Unretained(this)))); |
165 done_.TimedWait(TestTimeouts::action_timeout()); | 185 done_.TimedWait(TestTimeouts::action_timeout()); |
166 if (!done_.IsSignaled()) | 186 if (!done_.IsSignaled()) |
167 ADD_FAILURE() << "Timed out waiting for IO thread."; | 187 ADD_FAILURE() << "Timed out waiting for IO thread."; |
168 } | 188 } |
169 | 189 |
170 void TriggerRefreshNotification( | 190 void TriggerRefreshNotification( |
171 int type, | 191 int type, |
172 const syncer::ModelTypePayloadMap& payload_map) { | 192 const syncer::ModelTypePayloadMap& payload_map) { |
173 content::NotificationService::current()->Notify( | 193 content::NotificationService::current()->Notify( |
174 type, | 194 type, |
175 content::Source<Profile>(&mock_profile_), | 195 content::Source<Profile>(&mock_profile_), |
176 content::Details<const syncer::ModelTypePayloadMap>(&payload_map)); | 196 content::Details<const syncer::ModelTypePayloadMap>(&payload_map)); |
177 } | 197 } |
178 | 198 |
179 MessageLoop ui_loop_; | 199 MessageLoop ui_loop_; |
180 content::TestBrowserThread ui_thread_; | 200 content::TestBrowserThread ui_thread_; |
181 content::TestBrowserThread io_thread_; | 201 base::Thread sync_thread_; |
182 NiceMock<ProfileMock> mock_profile_; | 202 NiceMock<ProfileMock> mock_profile_; |
183 // Created/used/destroyed on I/O thread. | 203 // Created/used/destroyed on sync thread. |
184 FakeSyncNotifierObserverIO* io_observer_; | 204 FakeSyncNotifierObserver* sync_observer_; |
185 bool io_observer_notification_failure_; | 205 bool sync_observer_notification_failure_; |
186 ChromeSyncNotificationBridge bridge_; | 206 scoped_ptr<ChromeSyncNotificationBridge> bridge_; |
187 base::WaitableEvent done_; | 207 base::WaitableEvent done_; |
188 }; | 208 }; |
189 | 209 |
190 // Adds an observer on the UI thread, triggers a local refresh notification, and | 210 // Adds an observer on the sync thread, triggers a local refresh |
191 // ensures the bridge posts a LOCAL_NOTIFICATION with the proper payload to it. | 211 // notification, and ensures the bridge posts a LOCAL_NOTIFICATION |
212 // with the proper payload to it. | |
192 TEST_F(ChromeSyncNotificationBridgeTest, LocalNotification) { | 213 TEST_F(ChromeSyncNotificationBridgeTest, LocalNotification) { |
193 syncer::ModelTypePayloadMap payload_map; | 214 syncer::ModelTypePayloadMap payload_map; |
194 payload_map[syncer::SESSIONS] = ""; | 215 payload_map[syncer::SESSIONS] = ""; |
195 StrictMock<syncer::MockSyncNotifierObserver> observer; | 216 CreateObserverWithExpectations(payload_map, syncer::LOCAL_NOTIFICATION); |
196 EXPECT_CALL(observer, | |
197 OnIncomingNotification(payload_map, | |
198 syncer::LOCAL_NOTIFICATION)); | |
199 bridge_.AddObserver(&observer); | |
200 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, | 217 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, |
201 payload_map); | 218 payload_map); |
202 ui_loop_.RunAllPending(); | 219 VerifyAndDestroyObserver(); |
203 Mock::VerifyAndClearExpectations(&observer); | |
204 } | 220 } |
205 | 221 |
206 // Adds an observer on the UI thread, triggers a remote refresh notification, | 222 // Adds an observer on the sync thread, triggers a remote refresh |
207 // and ensures the bridge posts a REMOTE_NOTIFICATION with the proper payload | 223 // notification, and ensures the bridge posts a REMOTE_NOTIFICATION |
208 // to it. | 224 // with the proper payload to it. |
209 TEST_F(ChromeSyncNotificationBridgeTest, RemoteNotification) { | 225 TEST_F(ChromeSyncNotificationBridgeTest, RemoteNotification) { |
210 syncer::ModelTypePayloadMap payload_map; | 226 syncer::ModelTypePayloadMap payload_map; |
211 payload_map[syncer::BOOKMARKS] = ""; | 227 payload_map[syncer::SESSIONS] = ""; |
212 StrictMock<syncer::MockSyncNotifierObserver> observer; | 228 CreateObserverWithExpectations(payload_map, syncer::REMOTE_NOTIFICATION); |
213 EXPECT_CALL(observer, | |
214 OnIncomingNotification(payload_map, | |
215 syncer::REMOTE_NOTIFICATION)); | |
216 bridge_.AddObserver(&observer); | |
217 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, | 229 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, |
218 payload_map); | 230 payload_map); |
219 ui_loop_.RunAllPending(); | 231 VerifyAndDestroyObserver(); |
220 Mock::VerifyAndClearExpectations(&observer); | |
221 } | 232 } |
222 | 233 |
223 // Adds an observer on the UI thread, triggers a local refresh notification | 234 // Adds an observer on the sync thread, triggers a local refresh |
224 // with empty payload map and ensures the bridge posts a | 235 // notification with empty payload map and ensures the bridge posts a |
225 // LOCAL_NOTIFICATION with the proper payload to it. | 236 // LOCAL_NOTIFICATION with the proper payload to it. |
226 TEST_F(ChromeSyncNotificationBridgeTest, LocalNotificationEmptyPayloadMap) { | 237 TEST_F(ChromeSyncNotificationBridgeTest, LocalNotificationEmptyPayloadMap) { |
227 const syncer::ModelTypeSet enabled_types( | 238 const syncer::ModelTypeSet enabled_types( |
228 syncer::BOOKMARKS, syncer::PASSWORDS); | 239 syncer::BOOKMARKS, syncer::PASSWORDS); |
229 const syncer::ModelTypePayloadMap enabled_types_payload_map = | 240 const syncer::ModelTypePayloadMap enabled_types_payload_map = |
230 syncer::ModelTypePayloadMapFromEnumSet(enabled_types, std::string()); | 241 syncer::ModelTypePayloadMapFromEnumSet(enabled_types, std::string()); |
231 | 242 CreateObserverWithExpectations( |
232 StrictMock<syncer::MockSyncNotifierObserver> observer; | 243 enabled_types_payload_map, syncer::LOCAL_NOTIFICATION); |
233 EXPECT_CALL(observer, | |
234 OnIncomingNotification(enabled_types_payload_map, | |
235 syncer::LOCAL_NOTIFICATION)); | |
236 bridge_.AddObserver(&observer); | |
237 // Set enabled types on the bridge. | |
238 bridge_.UpdateEnabledTypes(enabled_types); | |
239 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, | 244 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, |
240 syncer::ModelTypePayloadMap()); | 245 enabled_types_payload_map); |
241 ui_loop_.RunAllPending(); | 246 VerifyAndDestroyObserver(); |
242 Mock::VerifyAndClearExpectations(&observer); | |
243 } | 247 } |
244 | 248 |
245 // Adds an observer on the UI thread, triggers a remote refresh notification | 249 // Adds an observer on the sync thread, triggers a remote refresh |
246 // with empty payload map and ensures the bridge posts a | 250 // notification with empty payload map and ensures the bridge posts a |
247 // REMOTE_NOTIFICATION with the proper payload to it. | 251 // REMOTE_NOTIFICATION with the proper payload to it. |
248 TEST_F(ChromeSyncNotificationBridgeTest, RemoteNotificationEmptyPayloadMap) { | 252 TEST_F(ChromeSyncNotificationBridgeTest, RemoteNotificationEmptyPayloadMap) { |
249 const syncer::ModelTypeSet enabled_types( | 253 const syncer::ModelTypeSet enabled_types( |
250 syncer::BOOKMARKS, syncer::TYPED_URLS); | 254 syncer::BOOKMARKS, syncer::TYPED_URLS); |
251 const syncer::ModelTypePayloadMap enabled_types_payload_map = | 255 const syncer::ModelTypePayloadMap enabled_types_payload_map = |
252 syncer::ModelTypePayloadMapFromEnumSet(enabled_types, std::string()); | 256 syncer::ModelTypePayloadMapFromEnumSet(enabled_types, std::string()); |
253 | 257 CreateObserverWithExpectations( |
254 StrictMock<syncer::MockSyncNotifierObserver> observer; | 258 enabled_types_payload_map, syncer::REMOTE_NOTIFICATION); |
255 EXPECT_CALL(observer, | |
256 OnIncomingNotification(enabled_types_payload_map, | |
257 syncer::REMOTE_NOTIFICATION)); | |
258 bridge_.AddObserver(&observer); | |
259 // Set enabled types on the bridge. | |
260 bridge_.UpdateEnabledTypes(enabled_types); | |
261 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, | 259 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, |
262 syncer::ModelTypePayloadMap()); | 260 enabled_types_payload_map); |
263 ui_loop_.RunAllPending(); | |
264 Mock::VerifyAndClearExpectations(&observer); | |
265 } | |
266 | |
267 // Adds an observer on the I/O thread. Then triggers a refresh notification on | |
268 // the UI thread. We finally verify the proper notification was received by the | |
269 // observer and destroy it on the I/O thread. | |
270 TEST_F(ChromeSyncNotificationBridgeTest, BasicThreaded) { | |
271 syncer::ModelTypePayloadMap payload_map; | |
272 payload_map[syncer::SESSIONS] = ""; | |
273 CreateObserverWithExpectedPayload(payload_map); | |
274 TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, | |
275 payload_map); | |
276 VerifyAndDestroyObserver(); | 261 VerifyAndDestroyObserver(); |
277 } | 262 } |
278 | 263 |
279 } // namespace | 264 } // namespace |
280 } // namespace browser_sync | 265 } // namespace browser_sync |
OLD | NEW |