| 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), |
| 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 EXPECT_EQ(NULL, sync_observer_); |
| 125 if (sync_observer_notification_failure_) |
| 126 ADD_FAILURE() << "Sync Observer did not receive proper notification."; |
| 127 } |
| 128 |
| 129 void VerifyAndDestroyObserverOnSyncThread() { |
| 130 DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); |
| 131 if (!sync_observer_) { |
| 132 sync_observer_notification_failure_ = true; |
| 118 } else { | 133 } else { |
| 119 io_observer_notification_failure_ = | 134 sync_observer_notification_failure_ = |
| 120 !io_observer_->ReceivedProperNotification(); | 135 !sync_observer_->ReceivedProperNotification(); |
| 121 delete io_observer_; | 136 delete sync_observer_; |
| 122 io_observer_ = NULL; | 137 sync_observer_ = NULL; |
| 123 } | 138 } |
| 124 } | 139 } |
| 125 | 140 |
| 126 void VerifyAndDestroyObserver() { | 141 void VerifyAndDestroyObserver() { |
| 127 ASSERT_TRUE(BrowserThread::PostTask( | 142 ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( |
| 128 BrowserThread::IO, | |
| 129 FROM_HERE, | 143 FROM_HERE, |
| 130 base::Bind(&ChromeSyncNotificationBridgeTest:: | 144 base::Bind(&ChromeSyncNotificationBridgeTest:: |
| 131 VerifyAndDestroyObserverOnIOThread, | 145 VerifyAndDestroyObserverOnSyncThread, |
| 132 base::Unretained(this)))); | 146 base::Unretained(this)))); |
| 147 BlockForSyncThread(); |
| 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 private: |
| 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 |