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

Side by Side Diff: chrome/browser/extensions/app_notification_manager_sync_unittest.cc

Issue 12680004: Remove chrome/ code to handle App Notifications (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix merge conflicts. Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "base/bind.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "chrome/browser/extensions/app_notification.h"
10 #include "chrome/browser/extensions/app_notification_manager.h"
11 #include "chrome/test/base/testing_profile.h"
12 #include "content/public/test/test_browser_thread.h"
13 #include "sync/api/sync_error_factory.h"
14 #include "sync/api/sync_error_factory_mock.h"
15 #include "sync/protocol/app_notification_specifics.pb.h"
16 #include "sync/protocol/sync.pb.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using content::BrowserThread;
20 using ::testing::_;
21 using ::testing::Return;
22
23 namespace {
24
25 // Extract notification guid from syncer::SyncData.
26 std::string GetGuid(const syncer::SyncData& sync_data) {
27 return sync_data.GetSpecifics().app_notification().guid();
28 }
29
30 // Dummy SyncChangeProcessor used to help review what SyncChanges are pushed
31 // back up to Sync.
32 class TestChangeProcessor : public syncer::SyncChangeProcessor {
33 public:
34 TestChangeProcessor() { }
35 virtual ~TestChangeProcessor() { }
36
37 // Store a copy of all the changes passed in so we can examine them later.
38 virtual syncer::SyncError ProcessSyncChanges(
39 const tracked_objects::Location& from_here,
40 const syncer::SyncChangeList& change_list) OVERRIDE {
41 // change_map_.erase(change_map_.begin(), change_map_.end());
42 for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
43 iter != change_list.end(); ++iter) {
44 change_map_[GetGuid(iter->sync_data())] = *iter;
45 }
46
47 return syncer::SyncError();
48 }
49
50 bool ContainsGuid(const std::string& guid) {
51 return change_map_.find(guid) != change_map_.end();
52 }
53
54 syncer::SyncChange GetChangeByGuid(const std::string& guid) {
55 DCHECK(ContainsGuid(guid));
56 return change_map_[guid];
57 }
58
59 size_t change_list_size() { return change_map_.size(); }
60
61 private:
62 // Track the changes received in ProcessSyncChanges.
63 std::map<std::string, syncer::SyncChange> change_map_;
64
65 DISALLOW_COPY_AND_ASSIGN(TestChangeProcessor);
66 };
67
68 class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
69 public:
70 explicit SyncChangeProcessorDelegate(syncer::SyncChangeProcessor* recipient)
71 : recipient_(recipient) {
72 DCHECK(recipient_);
73 }
74 virtual ~SyncChangeProcessorDelegate() {}
75
76 // syncer::SyncChangeProcessor implementation.
77 virtual syncer::SyncError ProcessSyncChanges(
78 const tracked_objects::Location& from_here,
79 const syncer::SyncChangeList& change_list) OVERRIDE {
80 return recipient_->ProcessSyncChanges(from_here, change_list);
81 }
82
83 private:
84 // The recipient of all sync changes.
85 syncer::SyncChangeProcessor* recipient_;
86
87 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
88 };
89
90 } // namespace
91
92 namespace extensions {
93
94 class AppNotificationManagerSyncTest : public testing::Test {
95 public:
96 AppNotificationManagerSyncTest()
97 : ui_thread_(BrowserThread::UI, &ui_loop_),
98 file_thread_(BrowserThread::FILE),
99 sync_processor_(new TestChangeProcessor),
100 sync_processor_delegate_(new SyncChangeProcessorDelegate(
101 sync_processor_.get())) {}
102
103 virtual ~AppNotificationManagerSyncTest() {
104 model_ = NULL;
105 }
106
107 virtual void SetUp() {
108 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 file_thread_.Start();
110
111 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
112 profile_.reset(new TestingProfile(temp_dir_.path()));
113 model_ = new AppNotificationManager(profile_.get());
114 model_->Init();
115
116 WaitForFileThread();
117 ASSERT_TRUE(model_->loaded());
118 }
119
120 virtual void TearDown() {
121 WaitForFileThread();
122 }
123
124 static void PostQuitToUIThread() {
125 BrowserThread::PostTask(BrowserThread::UI,
126 FROM_HERE,
127 MessageLoop::QuitClosure());
128 }
129
130 static void WaitForFileThread() {
131 BrowserThread::PostTask(BrowserThread::FILE,
132 FROM_HERE,
133 base::Bind(&PostQuitToUIThread));
134 MessageLoop::current()->Run();
135 }
136
137 AppNotificationManager* model() { return model_.get(); }
138 TestChangeProcessor* processor() { return sync_processor_.get(); }
139
140 scoped_ptr<syncer::SyncChangeProcessor> PassProcessor() {
141 return sync_processor_delegate_.PassAs<syncer::SyncChangeProcessor>();
142 }
143
144 // Creates a notification whose properties are set from the given integer.
145 static AppNotification* CreateNotification(int suffix) {
146 return CreateNotification(false, suffix);
147 }
148 static AppNotification* CreateNotification(bool is_local, int suffix) {
149 std::string s = base::IntToString(suffix);
150 return CreateNotification(
151 is_local, suffix, "guid" + s, "ext" + s, "text" + s, "body" + s,
152 "http://www.url" + s + ".com", "link text " + s);
153 }
154 static AppNotification* CreateNotification(
155 bool is_local, int suffix, const std::string& extension_id) {
156 std::string s = base::IntToString(suffix);
157 return CreateNotification(
158 is_local, suffix, "guid" + s, extension_id, "text" + s, "body" + s,
159 "http://www.url" + s + ".com", "link text " + s);
160 }
161
162 // Creates a notification whose properties are set from the given integer
163 // but does not set link url and link text.
164 static AppNotification* CreateNotificationNoLink(int suffix) {
165 return CreateNotificationNoLink(false, suffix);
166 }
167 static AppNotification* CreateNotificationNoLink(bool is_local, int suffix) {
168 std::string s = base::IntToString(suffix);
169 return CreateNotification(
170 is_local, suffix,
171 "guid" + s, "ext" + s, "text" + s, "body" + s, "", "");
172 }
173
174 // link_url and link_text are only set if the passed in values are not empty.
175 static AppNotification* CreateNotification(bool is_local,
176 int64 time,
177 const std::string& guid,
178 const std::string& extension_id,
179 const std::string& title,
180 const std::string& body,
181 const std::string& link_url,
182 const std::string& link_text) {
183 AppNotification* notif = new AppNotification(
184 is_local, base::Time::FromInternalValue(time),
185 guid, extension_id, title, body);
186 if (!link_url.empty())
187 notif->set_link_url(GURL(link_url));
188 if (!link_text.empty())
189 notif->set_link_text(link_text);
190 return notif;
191 }
192
193 static syncer::SyncData CreateSyncData(int suffix) {
194 scoped_ptr<AppNotification> notif(CreateNotification(suffix));
195 return AppNotificationManager::CreateSyncDataFromNotification(*notif);
196 }
197 static syncer::SyncData CreateSyncData(
198 int suffix, const std::string& extension_id) {
199 scoped_ptr<AppNotification> notif(
200 CreateNotification(false, suffix, extension_id));
201 return AppNotificationManager::CreateSyncDataFromNotification(*notif);
202 }
203
204 // Helper to create syncer::SyncChange. Takes ownership of |notif|.
205 static syncer::SyncChange CreateSyncChange(
206 syncer::SyncChange::SyncChangeType type,
207 AppNotification* notif) {
208 // Take control of notif to clean it up after we create data out of it.
209 scoped_ptr<AppNotification> scoped_notif(notif);
210 return syncer::SyncChange(
211 FROM_HERE,
212 type,
213 AppNotificationManager::CreateSyncDataFromNotification(*notif));
214 }
215
216 void AssertSyncChange(const syncer::SyncChange& change,
217 syncer::SyncChange::SyncChangeType type,
218 const AppNotification& notif) {
219 ASSERT_EQ(type, change.change_type());
220 scoped_ptr<AppNotification> notif2(
221 AppNotificationManager::CreateNotificationFromSyncData(
222 change.sync_data()));
223 ASSERT_TRUE(notif.Equals(*notif2));
224 }
225
226 protected:
227 MessageLoop ui_loop_;
228 content::TestBrowserThread ui_thread_;
229 content::TestBrowserThread file_thread_;
230
231 // We keep two TemplateURLServices to test syncing between them.
232 base::ScopedTempDir temp_dir_;
233 scoped_ptr<TestingProfile> profile_;
234 scoped_refptr<AppNotificationManager> model_;
235
236 scoped_ptr<TestChangeProcessor> sync_processor_;
237 scoped_ptr<SyncChangeProcessorDelegate> sync_processor_delegate_;
238
239 DISALLOW_COPY_AND_ASSIGN(AppNotificationManagerSyncTest);
240 };
241
242 // Create an AppNotification, convert it to SyncData and convert it back.
243 TEST_F(AppNotificationManagerSyncTest, NotificationToSyncDataToNotification) {
244 { // Partial properties set.
245 scoped_ptr<AppNotification> notif1(CreateNotificationNoLink(1));
246 syncer::SyncData sync_data =
247 AppNotificationManager::CreateSyncDataFromNotification(*notif1);
248 scoped_ptr<AppNotification> notif2(
249 AppNotificationManager::CreateNotificationFromSyncData(sync_data));
250 EXPECT_TRUE(notif2.get());
251 EXPECT_TRUE(notif1->Equals(*notif2));
252 }
253 { // All properties set.
254 scoped_ptr<AppNotification> notif1(CreateNotification(1));
255 syncer::SyncData sync_data =
256 AppNotificationManager::CreateSyncDataFromNotification(*notif1);
257 scoped_ptr<AppNotification> notif2(
258 AppNotificationManager::CreateNotificationFromSyncData(sync_data));
259 EXPECT_TRUE(notif2.get());
260 EXPECT_TRUE(notif1->Equals(*notif2));
261 }
262 }
263
264 // GetAllSyncData returns all notifications since none are marked local only.
265 TEST_F(AppNotificationManagerSyncTest, GetAllSyncDataNoLocal) {
266 model()->Add(CreateNotificationNoLink(1));
267 model()->Add(CreateNotification(2));
268 model()->Add(CreateNotification(3));
269 syncer::SyncDataList all_sync_data =
270 model()->GetAllSyncData(syncer::APP_NOTIFICATIONS);
271
272 EXPECT_EQ(3U, all_sync_data.size());
273
274 for (syncer::SyncDataList::const_iterator iter = all_sync_data.begin();
275 iter != all_sync_data.end(); ++iter) {
276 scoped_ptr<AppNotification> notif1(
277 AppNotificationManager::CreateNotificationFromSyncData(*iter));
278
279 const std::string& guid = notif1->guid();
280 const std::string& ext_id = notif1->extension_id();
281
282 const AppNotification* notif2 = model()->GetNotification(ext_id, guid);
283 ASSERT_TRUE(notif1->Equals(*notif2));
284 }
285 }
286
287 // GetAllSyncData should not return notifications marked as local only.
288 TEST_F(AppNotificationManagerSyncTest, GetAllSyncDataSomeLocal) {
289 model()->Add(CreateNotificationNoLink(1));
290 model()->Add(CreateNotification(true, 2));
291 model()->Add(CreateNotification(3));
292 model()->Add(CreateNotification(true, 4));
293 model()->Add(CreateNotification(5));
294 syncer::SyncDataList all_sync_data =
295 model()->GetAllSyncData(syncer::APP_NOTIFICATIONS);
296
297 EXPECT_EQ(3U, all_sync_data.size());
298
299 for (syncer::SyncDataList::const_iterator iter = all_sync_data.begin();
300 iter != all_sync_data.end(); ++iter) {
301 scoped_ptr<AppNotification> notif1(
302 AppNotificationManager::CreateNotificationFromSyncData(*iter));
303 const std::string& guid = notif1->guid();
304 const std::string& ext_id = notif1->extension_id();
305
306 const AppNotification* notif2 = model()->GetNotification(ext_id, guid);
307 ASSERT_TRUE(notif1->Equals(*notif2));
308 }
309 }
310
311 // Model assocation: both models are empty.
312 TEST_F(AppNotificationManagerSyncTest, ModelAssocBothEmpty) {
313 model()->MergeDataAndStartSyncing(
314 syncer::APP_NOTIFICATIONS,
315 syncer::SyncDataList(), // Empty.
316 PassProcessor(),
317 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
318
319 EXPECT_EQ(0U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
320 EXPECT_EQ(0U, processor()->change_list_size());
321 }
322
323 // Model assocation: empty sync model and non-empty local model.
324 TEST_F(AppNotificationManagerSyncTest, ModelAssocModelEmpty) {
325 syncer::SyncDataList initial_data;
326 initial_data.push_back(CreateSyncData(1));
327 initial_data.push_back(CreateSyncData(2));
328 initial_data.push_back(CreateSyncData(3));
329 initial_data.push_back(CreateSyncData(4));
330
331 model()->MergeDataAndStartSyncing(
332 syncer::APP_NOTIFICATIONS,
333 initial_data,
334 PassProcessor(),
335 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
336
337 EXPECT_EQ(4U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
338 // Model should all of the initial sync data.
339 for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
340 iter != initial_data.end(); ++iter) {
341 scoped_ptr<AppNotification> notif1(
342 AppNotificationManager::CreateNotificationFromSyncData(*iter));
343 const std::string& ext_id = notif1->extension_id();
344 const std::string& guid = notif1->guid();
345 const AppNotification* notif2 = model()->GetNotification(ext_id, guid);
346 EXPECT_TRUE(notif2);
347 EXPECT_TRUE(notif1->Equals(*notif2));
348 }
349
350 EXPECT_EQ(0U, processor()->change_list_size());
351 }
352
353 // Model has some notifications, some of them are local only. Sync has some
354 // notifications. No items match up.
355 TEST_F(AppNotificationManagerSyncTest, ModelAssocBothNonEmptyNoOverlap) {
356 AppNotification* n1 = CreateNotification(1);
357 model()->Add(n1);
358 AppNotification* n2 = CreateNotification(true, 2);
359 model()->Add(n2);
360 AppNotification* n3 = CreateNotification(3);
361 model()->Add(n3);
362
363 syncer::SyncDataList initial_data;
364 initial_data.push_back(CreateSyncData(4));
365 initial_data.push_back(CreateSyncData(5));
366 initial_data.push_back(CreateSyncData(6));
367 initial_data.push_back(CreateSyncData(7));
368
369 model()->MergeDataAndStartSyncing(
370 syncer::APP_NOTIFICATIONS,
371 initial_data,
372 PassProcessor(),
373 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
374
375 EXPECT_EQ(6U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
376 for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
377 iter != initial_data.end(); ++iter) {
378 scoped_ptr<AppNotification> notif1(
379 AppNotificationManager::CreateNotificationFromSyncData(*iter));
380 const std::string& ext_id = notif1->extension_id();
381 const std::string& guid = notif1->guid();
382 const AppNotification* notif2 = model()->GetNotification(ext_id, guid);
383 EXPECT_TRUE(notif2);
384 EXPECT_TRUE(notif1->Equals(*notif2));
385 }
386 EXPECT_TRUE(model()->GetNotification(n1->extension_id(), n1->guid()));
387 EXPECT_TRUE(model()->GetNotification(n2->extension_id(), n2->guid()));
388 EXPECT_TRUE(model()->GetNotification(n3->extension_id(), n3->guid()));
389
390 EXPECT_EQ(2U, processor()->change_list_size());
391 EXPECT_TRUE(processor()->ContainsGuid(n1->guid()));
392 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
393 processor()->GetChangeByGuid(n1->guid()).change_type());
394 EXPECT_FALSE(processor()->ContainsGuid(n2->guid()));
395 EXPECT_TRUE(processor()->ContainsGuid(n3->guid()));
396 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
397 processor()->GetChangeByGuid(n3->guid()).change_type());
398 }
399
400 // Model has some notifications, some of them are local only. Sync has some
401 // notifications. Some items match up.
402 TEST_F(AppNotificationManagerSyncTest, ModelAssocBothNonEmptySomeOverlap) {
403 AppNotification* n1 = CreateNotification(1);
404 model()->Add(n1);
405 AppNotification* n2 = CreateNotification(true, 2);
406 model()->Add(n2);
407 AppNotification* n3 = CreateNotification(3);
408 model()->Add(n3);
409 AppNotification* n4 = CreateNotification(4);
410 model()->Add(n4);
411
412 syncer::SyncDataList initial_data;
413 initial_data.push_back(CreateSyncData(5));
414 initial_data.push_back(
415 AppNotificationManager::CreateSyncDataFromNotification(*n1));
416 initial_data.push_back(CreateSyncData(6));
417 initial_data.push_back(
418 AppNotificationManager::CreateSyncDataFromNotification(*n4));
419 initial_data.push_back(CreateSyncData(7));
420
421 model()->MergeDataAndStartSyncing(
422 syncer::APP_NOTIFICATIONS,
423 initial_data,
424 PassProcessor(),
425 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
426
427 EXPECT_EQ(6U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
428 for (syncer::SyncDataList::const_iterator iter = initial_data.begin();
429 iter != initial_data.end(); ++iter) {
430 scoped_ptr<AppNotification> notif1(
431 AppNotificationManager::CreateNotificationFromSyncData(*iter));
432 const std::string& ext_id = notif1->extension_id();
433 const std::string& guid = notif1->guid();
434 const AppNotification* notif2 = model()->GetNotification(ext_id, guid);
435 EXPECT_TRUE(notif2);
436 EXPECT_TRUE(notif1->Equals(*notif2));
437 }
438 EXPECT_TRUE(model()->GetNotification(n1->extension_id(), n1->guid()));
439 EXPECT_TRUE(model()->GetNotification(n2->extension_id(), n2->guid()));
440 EXPECT_TRUE(model()->GetNotification(n3->extension_id(), n3->guid()));
441 EXPECT_TRUE(model()->GetNotification(n4->extension_id(), n4->guid()));
442
443 EXPECT_EQ(1U, processor()->change_list_size());
444 EXPECT_FALSE(processor()->ContainsGuid(n1->guid()));
445 EXPECT_FALSE(processor()->ContainsGuid(n2->guid()));
446 EXPECT_TRUE(processor()->ContainsGuid(n3->guid()));
447 EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
448 processor()->GetChangeByGuid(n3->guid()).change_type());
449 EXPECT_FALSE(processor()->ContainsGuid(n4->guid()));
450 }
451
452 // When an item that matches up in model and sync is different, an error
453 // should be returned.
454 TEST_F(AppNotificationManagerSyncTest, ModelAssocBothNonEmptyTitleMismatch) {
455 AppNotification* n1 = CreateNotification(1);
456 model()->Add(n1);
457 AppNotification* n2 = CreateNotification(true, 2);
458 model()->Add(n2);
459
460 syncer::SyncDataList initial_data;
461 initial_data.push_back(CreateSyncData(1));
462 scoped_ptr<AppNotification> n1_a(CreateNotification(
463 n1->is_local(), n1->creation_time().ToInternalValue(),
464 n1->guid(), n1->extension_id(),
465 n1->title() + "_changed", // different title
466 n1->body(), n1->link_url().spec(), n1->link_text()));
467 initial_data.push_back(
468 AppNotificationManager::CreateSyncDataFromNotification(*n1_a));
469
470 scoped_ptr<syncer::SyncErrorFactoryMock> error_handler(
471 new syncer::SyncErrorFactoryMock());
472 EXPECT_CALL(*error_handler, CreateAndUploadError(_, _)).
473 WillOnce(
474 Return(
475 syncer::SyncError(
476 FROM_HERE, "error", syncer::APP_NOTIFICATIONS)));
477
478 syncer::SyncError sync_error = model()->MergeDataAndStartSyncing(
479 syncer::APP_NOTIFICATIONS,
480 initial_data,
481 PassProcessor(),
482 error_handler.PassAs<syncer::SyncErrorFactory>()).error();
483
484 EXPECT_TRUE(sync_error.IsSet());
485 EXPECT_EQ(syncer::APP_NOTIFICATIONS, sync_error.type());
486 EXPECT_EQ(0U, processor()->change_list_size());
487 }
488
489 // When an item in sync matches with a local-only item in model, an error
490 // should be returned.
491 TEST_F(AppNotificationManagerSyncTest, ModelAssocBothNonEmptyMatchesLocal) {
492 AppNotification* n1 = CreateNotification(1);
493 model()->Add(n1);
494 AppNotification* n2 = CreateNotification(true, 2);
495 model()->Add(n2);
496
497 syncer::SyncDataList initial_data;
498 initial_data.push_back(CreateSyncData(1));
499 scoped_ptr<AppNotification> n2_a(CreateNotification(2));
500 initial_data.push_back(
501 AppNotificationManager::CreateSyncDataFromNotification(*n2_a));
502
503 scoped_ptr<syncer::SyncErrorFactoryMock> error_handler(
504 new syncer::SyncErrorFactoryMock());
505 EXPECT_CALL(*error_handler, CreateAndUploadError(_, _)).
506 WillOnce(
507 Return(
508 syncer::SyncError(
509 FROM_HERE, "error", syncer::APP_NOTIFICATIONS)));
510
511 syncer::SyncError sync_error = model()->MergeDataAndStartSyncing(
512 syncer::APP_NOTIFICATIONS,
513 initial_data,
514 PassProcessor(),
515 error_handler.PassAs<syncer::SyncErrorFactory>()).error();
516
517 EXPECT_TRUE(sync_error.IsSet());
518 EXPECT_EQ(syncer::APP_NOTIFICATIONS, sync_error.type());
519 EXPECT_EQ(0U, processor()->change_list_size());
520 }
521
522 // Process sync changes when model is empty.
523 TEST_F(AppNotificationManagerSyncTest, ProcessSyncChangesEmptyModel) {
524 // We initially have no data.
525 model()->MergeDataAndStartSyncing(
526 syncer::APP_NOTIFICATIONS,
527 syncer::SyncDataList(),
528 PassProcessor(),
529 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
530
531 // Set up a bunch of ADDs.
532 syncer::SyncChangeList changes;
533 changes.push_back(CreateSyncChange(
534 syncer::SyncChange::ACTION_ADD, CreateNotification(1)));
535 changes.push_back(CreateSyncChange(
536 syncer::SyncChange::ACTION_ADD, CreateNotification(2)));
537 changes.push_back(CreateSyncChange(
538 syncer::SyncChange::ACTION_ADD, CreateNotification(3)));
539
540 model()->ProcessSyncChanges(FROM_HERE, changes);
541
542 EXPECT_EQ(3U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
543 EXPECT_EQ(0U, processor()->change_list_size());
544 }
545
546 // Process sync changes when model is not empty.
547 TEST_F(AppNotificationManagerSyncTest, ProcessSyncChangesNonEmptyModel) {
548 AppNotification* n1 = CreateNotification(1);
549 model()->Add(n1);
550 AppNotification* n2 = CreateNotification(2);
551 model()->Add(n2);
552 model()->MergeDataAndStartSyncing(
553 syncer::APP_NOTIFICATIONS,
554 syncer::SyncDataList(),
555 PassProcessor(),
556 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
557
558 // Some adds and some deletes.
559 syncer::SyncChangeList changes;
560 changes.push_back(CreateSyncChange(
561 syncer::SyncChange::ACTION_ADD, CreateNotification(3)));
562 changes.push_back(CreateSyncChange(
563 syncer::SyncChange::ACTION_DELETE, n1->Copy()));
564 changes.push_back(CreateSyncChange(
565 syncer::SyncChange::ACTION_ADD, CreateNotification(4)));
566
567 model()->ProcessSyncChanges(FROM_HERE, changes);
568
569 EXPECT_EQ(3U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
570 EXPECT_EQ(2U, processor()->change_list_size());
571 }
572
573 // Process sync changes should ignore a bad ADD.
574 // Hangs: http://crbug.com/149712
575 TEST_F(AppNotificationManagerSyncTest,
576 DISABLED_ProcessSyncChangesIgnoreBadAdd) {
577 AppNotification* n1 = CreateNotification(1);
578 model()->Add(n1);
579 AppNotification* n2 = CreateNotification(2);
580 model()->Add(n2);
581 model()->MergeDataAndStartSyncing(
582 syncer::APP_NOTIFICATIONS,
583 syncer::SyncDataList(),
584 PassProcessor(),
585 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
586
587 // Some adds and some deletes.
588 syncer::SyncChangeList changes;
589 changes.push_back(CreateSyncChange(
590 syncer::SyncChange::ACTION_ADD, CreateNotification(1)));
591
592 syncer::SyncError error = model()->ProcessSyncChanges(FROM_HERE, changes);
593 EXPECT_FALSE(error.IsSet());
594
595 EXPECT_EQ(2U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
596 EXPECT_EQ(2U, processor()->change_list_size());
597 }
598
599 // Process sync changes should ignore a bad DELETE.
600 TEST_F(AppNotificationManagerSyncTest, ProcessSyncChangesIgnoreBadDelete) {
601 AppNotification* n1 = CreateNotification(1);
602 model()->Add(n1);
603 AppNotification* n2 = CreateNotification(2);
604 model()->Add(n2);
605 model()->MergeDataAndStartSyncing(
606 syncer::APP_NOTIFICATIONS,
607 syncer::SyncDataList(),
608 PassProcessor(),
609 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
610
611 // Some adds and some deletes.
612 syncer::SyncChangeList changes;
613 changes.push_back(CreateSyncChange(
614 syncer::SyncChange::ACTION_DELETE, CreateNotification(3)));
615
616 syncer::SyncError error = model()->ProcessSyncChanges(FROM_HERE, changes);
617 EXPECT_FALSE(error.IsSet());
618
619 EXPECT_EQ(2U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
620 EXPECT_EQ(2U, processor()->change_list_size());
621 }
622
623 // Process sync changes should ignore bad UPDATEs.
624 // Hangs: http://crbug.com/149712
625 TEST_F(AppNotificationManagerSyncTest,
626 DISABLED_ProcessSyncChangesIgnoreBadUpdates) {
627 AppNotification* n1 = CreateNotification(1);
628 model()->Add(n1);
629 AppNotification* n2 = CreateNotification(2);
630 model()->Add(n2);
631 model()->MergeDataAndStartSyncing(
632 syncer::APP_NOTIFICATIONS,
633 syncer::SyncDataList(),
634 PassProcessor(),
635 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
636
637 // Some adds and some deletes.
638 syncer::SyncChangeList changes;
639 changes.push_back(CreateSyncChange(
640 syncer::SyncChange::ACTION_UPDATE, CreateNotification(3)));
641 AppNotification* n2_changed = n2->Copy();
642 n2_changed->set_link_text(n2_changed->link_text() + "-changed");
643 changes.push_back(CreateSyncChange(
644 syncer::SyncChange::ACTION_UPDATE, n2_changed));
645
646 syncer::SyncError error = model()->ProcessSyncChanges(FROM_HERE, changes);
647 EXPECT_FALSE(error.IsSet());
648
649 EXPECT_EQ(2U, model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
650 EXPECT_EQ(2U, processor()->change_list_size());
651 }
652
653 // Process over 15 changes when model is not empty.
654 TEST_F(AppNotificationManagerSyncTest, ProcessSyncChangesEmptyModelWithMax) {
655 const std::string& ext_id = "e1";
656 model()->MergeDataAndStartSyncing(
657 syncer::APP_NOTIFICATIONS,
658 syncer::SyncDataList(),
659 PassProcessor(),
660 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
661 for (unsigned int i = 0;
662 i < AppNotificationManager::kMaxNotificationPerApp * 2; i++) {
663 syncer::SyncChangeList changes;
664 changes.push_back(CreateSyncChange(
665 syncer::SyncChange::ACTION_ADD, CreateNotification(false, i, ext_id)));
666 model()->ProcessSyncChanges(FROM_HERE, changes);
667 if (i < AppNotificationManager::kMaxNotificationPerApp) {
668 EXPECT_EQ(i + 1,
669 model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
670 } else {
671 EXPECT_EQ(AppNotificationManager::kMaxNotificationPerApp,
672 model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
673 for (unsigned int j = i; j > i - 5; j--) {
674 EXPECT_EQ(
675 AppNotificationManager::kMaxNotificationPerApp,
676 model()->GetAllSyncData(syncer::APP_NOTIFICATIONS).size());
677 }
678 }
679 }
680 }
681
682 // Stop syncing sets state correctly.
683 TEST_F(AppNotificationManagerSyncTest, StopSyncing) {
684 EXPECT_FALSE(model()->sync_processor_.get());
685 EXPECT_FALSE(model()->models_associated_);
686
687 model()->MergeDataAndStartSyncing(
688 syncer::APP_NOTIFICATIONS,
689 syncer::SyncDataList(),
690 PassProcessor(),
691 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
692
693 EXPECT_TRUE(model()->sync_processor_.get());
694 EXPECT_TRUE(model()->models_associated_);
695
696 model()->StopSyncing(syncer::APP_NOTIFICATIONS);
697 EXPECT_FALSE(model()->sync_processor_.get());
698 EXPECT_FALSE(model()->models_associated_);
699 }
700
701 // Adds get pushed to sync but local only are skipped.
702 TEST_F(AppNotificationManagerSyncTest, AddsGetsSynced) {
703 model()->MergeDataAndStartSyncing(
704 syncer::APP_NOTIFICATIONS,
705 syncer::SyncDataList(),
706 PassProcessor(),
707 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
708
709 AppNotification* n1 = CreateNotification(1);
710 model()->Add(n1);
711 AppNotification* n2 = CreateNotification(2);
712 model()->Add(n2);
713 AppNotification* n3 = CreateNotification(true, 2);
714 model()->Add(n3);
715
716 EXPECT_EQ(2U, processor()->change_list_size());
717 EXPECT_TRUE(processor()->ContainsGuid(n1->guid()));
718 syncer::SyncChange c1 = processor()->GetChangeByGuid(n1->guid());
719 AssertSyncChange(c1, syncer::SyncChange::ACTION_ADD, *n1);
720 syncer::SyncChange c2 = processor()->GetChangeByGuid(n2->guid());
721 AssertSyncChange(c2, syncer::SyncChange::ACTION_ADD, *n2);
722 }
723
724 // Clear all gets pushed to sync.
725 TEST_F(AppNotificationManagerSyncTest, ClearAllGetsSynced) {
726 const std::string& ext_id = "e1";
727 scoped_ptr<AppNotification> n1(CreateNotification(false, 1, ext_id));
728 scoped_ptr<AppNotification> n2(CreateNotification(false, 2, ext_id));
729 scoped_ptr<AppNotification> n3(CreateNotification(false, 3, ext_id));
730 scoped_ptr<AppNotification> n4(CreateNotification(4));
731
732 syncer::SyncDataList initial_data;
733 initial_data.push_back(
734 AppNotificationManager::CreateSyncDataFromNotification(*n1));
735 initial_data.push_back(
736 AppNotificationManager::CreateSyncDataFromNotification(*n2));
737 initial_data.push_back(
738 AppNotificationManager::CreateSyncDataFromNotification(*n3));
739 initial_data.push_back(
740 AppNotificationManager::CreateSyncDataFromNotification(*n4));
741 model()->MergeDataAndStartSyncing(
742 syncer::APP_NOTIFICATIONS,
743 initial_data,
744 PassProcessor(),
745 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
746
747 model()->ClearAll(ext_id);
748
749 EXPECT_EQ(3U, processor()->change_list_size());
750 EXPECT_TRUE(processor()->ContainsGuid(n1->guid()));
751 syncer::SyncChange c1 = processor()->GetChangeByGuid(n1->guid());
752 AssertSyncChange(c1, syncer::SyncChange::ACTION_DELETE, *n1);
753 syncer::SyncChange c2 = processor()->GetChangeByGuid(n2->guid());
754 AssertSyncChange(c2, syncer::SyncChange::ACTION_DELETE, *n2);
755 syncer::SyncChange c3 = processor()->GetChangeByGuid(n3->guid());
756 AssertSyncChange(c3, syncer::SyncChange::ACTION_DELETE, *n3);
757 }
758
759 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/app_notification_manager.cc ('k') | chrome/browser/extensions/app_notification_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698