Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / notifications / sync_notifier / synced_notification_app_info_service_unittest.cc
1 // Copyright 2014 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 "chrome/browser/notifications/sync_notifier/synced_notification_app_info_service.h"
6
7 #include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/test/base/testing_pref_service_syncable.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "sync/api/fake_sync_change_processor.h"
13 #include "sync/api/sync_change.h"
14 #include "sync/api/sync_change_processor.h"
15 #include "sync/api/sync_error_factory.h"
16 #include "sync/api/sync_error_factory_mock.h"
17 #include "sync/protocol/sync.pb.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using sync_pb::EntitySpecifics;
21 using syncer::SyncData;
22 using syncer::SyncChange;
23 using syncer::SyncChangeList;
24 using syncer::SyncDataList;
25 using syncer::SYNCED_NOTIFICATION_APP_INFO;
26 using notifier::SyncedNotificationAppInfo;
27 using notifier::SyncedNotificationAppInfoService;
28 using sync_pb::SyncedNotificationAppInfoSpecifics;
29
30 namespace notifier {
31
32 // Extract app_info id from syncer::SyncData.
33 std::string GetAppInfoId(const SyncData& sync_data) {
34   SyncedNotificationAppInfoSpecifics specifics =
35       sync_data.GetSpecifics().synced_notification_app_info();
36
37   // TODO(petewil): It would be better if we had a designated unique identifier
38   // instead of relying on the display name to be unique.
39   return specifics.synced_notification_app_info(0).settings_display_name();
40 }
41
42 // Dummy SyncChangeProcessor used to help review what SyncChanges are pushed
43 // back up to Sync.
44 class TestChangeProcessor : public syncer::SyncChangeProcessor {
45  public:
46   TestChangeProcessor() {}
47   virtual ~TestChangeProcessor() {}
48
49   // Store a copy of all the changes passed in so we can examine them later.
50   virtual syncer::SyncError ProcessSyncChanges(
51       const tracked_objects::Location& from_here,
52       const SyncChangeList& change_list) OVERRIDE {
53     change_map_.clear();
54     for (SyncChangeList::const_iterator iter = change_list.begin();
55          iter != change_list.end();
56          ++iter) {
57       // Put the data into the change tracking map.
58       change_map_[GetAppInfoId(iter->sync_data())] = *iter;
59     }
60
61     return syncer::SyncError();
62   }
63
64   virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
65       const OVERRIDE {
66     return syncer::SyncDataList();
67   }
68
69   size_t change_list_size() { return change_map_.size(); }
70
71   bool ContainsId(const std::string& id) {
72     return change_map_.find(id) != change_map_.end();
73   }
74
75   SyncChange GetChangeById(const std::string& id) {
76     EXPECT_TRUE(ContainsId(id));
77     return change_map_[id];
78   }
79
80  private:
81   // Track the changes received in ProcessSyncChanges.
82   std::map<std::string, SyncChange> change_map_;
83
84   DISALLOW_COPY_AND_ASSIGN(TestChangeProcessor);
85 };
86
87 class SyncedNotificationAppInfoServiceTest : public testing::Test {
88
89  public:
90   SyncedNotificationAppInfoServiceTest()
91       : sync_processor_(new TestChangeProcessor),
92         sync_processor_delegate_(
93             new syncer::FakeSyncChangeProcessor()) {}
94
95   virtual ~SyncedNotificationAppInfoServiceTest() {}
96
97   // Overrides from testing::Test.
98   virtual void SetUp() { profile_.reset(new TestingProfile()); }
99
100   // Introduce some sample test data into the system.
101   void AddTestingAppInfosToList(
102       SyncedNotificationAppInfoService* app_info_service) {
103     // Create the app_info struct, setting the settings display name.
104
105     // The sending_service_infos_ list will take ownership of this pointer.
106     SyncedNotificationAppInfo* test_item1 = new SyncedNotificationAppInfo(
107         NULL, kSendingService1Name, app_info_service);
108
109     // Add some App IDs.
110     test_item1->AddAppId(kAppId1);
111     test_item1->AddAppId(kAppId2);
112
113     // Set this icon GURL.
114     test_item1->SetSettingsURLs(GURL(kTestIconUrl), GURL());
115
116     // Add to the list.
117     app_info_service->sending_service_infos_.push_back(test_item1);
118
119     // Add a second test item for another service.
120     SyncedNotificationAppInfo* test_item2 = new SyncedNotificationAppInfo(
121         NULL, kSendingService2Name, app_info_service);
122
123     // Add some App IDs.
124     test_item2->AddAppId(kAppId4);
125     test_item2->AddAppId(kAppId5);
126
127     // Set thi icon GURL.
128     test_item2->SetSettingsURLs(GURL(kTestIconUrl), GURL());
129
130     // Add to the list.
131     app_info_service->sending_service_infos_.push_back(test_item2);
132   }
133
134   // Put some representative test data into the AppInfo protobuf.
135   static void FillProtobufWithTestData1(
136       sync_pb::SyncedNotificationAppInfo& protobuf) {
137     protobuf.add_app_id(std::string(kAppId1));
138     protobuf.add_app_id(std::string(kAppId2));
139     protobuf.set_settings_display_name(kSendingService1Name);
140     protobuf.set_info_url(kTestInfoUrl);
141     protobuf.mutable_icon()->set_url(kTestIconUrl);
142   }
143
144   static void FillProtobufWithTestData2(
145       sync_pb::SyncedNotificationAppInfo& protobuf) {
146     protobuf.add_app_id(std::string(kAppId3));
147     protobuf.set_settings_display_name(kSendingService1Name);
148     protobuf.mutable_icon()->set_url(kTestIconUrl);
149   }
150
151   // Helper to create syncer::SyncChange.
152   static SyncChange CreateSyncChange(SyncChange::SyncChangeType type,
153                                      const std::string& settings_display_name,
154                                      const std::string& info_url,
155                                      const std::string& icon_url,
156                                      const std::string& app_id1,
157                                      const std::string& app_id2) {
158
159     return SyncChange(
160         FROM_HERE,
161         type,
162         CreateSyncData(
163             settings_display_name, info_url, icon_url, app_id1, app_id2));
164   }
165
166   // Build a SyncData object to look like what Sync would deliver.
167   static SyncData CreateSyncData(const std::string& settings_display_name,
168                                  const std::string& info_url,
169                                  const std::string& icon_url,
170                                  const std::string& app_id1,
171                                  const std::string& app_id2) {
172     // CreateLocalData makes a copy of this, so it can safely live on the stack.
173     EntitySpecifics entity_specifics;
174     EXPECT_FALSE(app_id1.empty());
175
176     sync_pb::SyncedNotificationAppInfoSpecifics* specifics =
177         entity_specifics.mutable_synced_notification_app_info();
178
179     // Add a synced_notification_app_info object.
180     specifics->add_synced_notification_app_info();
181     sync_pb::SyncedNotificationAppInfo* app_info =
182         specifics->mutable_synced_notification_app_info(0);
183
184     // Add the key, the settings display name.
185     app_info->set_settings_display_name(settings_display_name);
186
187     // Add the welcome notification info URL.
188     app_info->set_info_url(info_url);
189
190     // Add the icon URL.
191     app_info->mutable_icon()->set_url(icon_url);
192
193     // Add the app IDs.
194     app_info->add_app_id(app_id1);
195
196     // Only add the second if it is non-empty
197     if (!app_id2.empty()) {
198       app_info->add_app_id(app_id2);
199     }
200
201     // Create the sync data.
202     SyncData sync_data =
203         SyncData::CreateLocalData("syncer::SYNCED_NOTIFICATION_APP_INFO",
204                                   "SyncedNotificationAppInfoServiceUnitTest",
205                                   entity_specifics);
206
207     return sync_data;
208   }
209
210   TestChangeProcessor* processor() {
211     return static_cast<TestChangeProcessor*>(sync_processor_.get());
212   }
213
214   scoped_ptr<syncer::SyncChangeProcessor> PassProcessor() {
215     return sync_processor_delegate_.Pass();
216   }
217
218  protected:
219   scoped_ptr<TestingProfile> profile_;
220
221  private:
222   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
223   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_delegate_;
224
225   DISALLOW_COPY_AND_ASSIGN(SyncedNotificationAppInfoServiceTest);
226 };
227
228 // Null data case - we have no data, and sync has no data when we start up.
229 TEST_F(SyncedNotificationAppInfoServiceTest, MergeDataAndStartSyncingTest) {
230     SyncedNotificationAppInfoService app_info_service(profile_.get());
231
232   app_info_service.MergeDataAndStartSyncing(
233       SYNCED_NOTIFICATION_APP_INFO,
234       SyncDataList(),  // Empty.
235       PassProcessor(),
236       scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
237
238   EXPECT_EQ(static_cast<size_t>(0),
239             app_info_service.sending_service_infos_size());
240 }
241
242 // Process sync changes when there is no local data.
243 TEST_F(SyncedNotificationAppInfoServiceTest, ProcessSyncChangesEmptyModel) {
244   // We initially have no data.
245   SyncedNotificationAppInfoService app_info_service(profile_.get());
246   app_info_service.set_avoid_bitmap_fetching_for_test(true);
247
248   // Set up an ADD.
249   SyncChangeList changes;
250   changes.push_back(CreateSyncChange(SyncChange::ACTION_ADD,
251                                      kSendingService1Name,
252                                      kTestInfoUrl,
253                                      kTestIconUrl,
254                                      kAppId1,
255                                      kAppId2));
256
257   // Process the changes we built.
258   app_info_service.ProcessSyncChanges(FROM_HERE, changes);
259
260   // Verify sync change made it to the SyncedNotificationAppInfo list.
261   SyncedNotificationAppInfo* app_info1 =
262       app_info_service.FindSyncedNotificationAppInfoByName(
263           kSendingService1Name);
264   EXPECT_NE(static_cast<SyncedNotificationAppInfo*>(NULL), app_info1);
265   EXPECT_TRUE(app_info1->HasAppId(kAppId1));
266   EXPECT_TRUE(app_info1->HasAppId(kAppId2));
267   EXPECT_FALSE(app_info1->HasAppId(kAppId3));
268   EXPECT_EQ(app_info1->settings_icon_url(), GURL(kTestIconUrl));
269 }
270
271 // Process sync changes when there is local data.
272 TEST_F(SyncedNotificationAppInfoServiceTest, ProcessSyncChangesNonEmptyModel) {
273     SyncedNotificationAppInfoService app_info_service(profile_.get());
274     app_info_service.set_avoid_bitmap_fetching_for_test(true);
275
276   // Create some local fake data. We rely on the specific ids set up here.
277   AddTestingAppInfosToList(&app_info_service);
278
279   // Set up an UPDATE.
280   SyncChangeList changes;
281
282   changes.push_back(CreateSyncChange(SyncChange::ACTION_UPDATE,
283                                      kSendingService1Name,
284                                      kTestInfoUrl,
285                                      kTestIconUrl,
286                                      kAppId1,
287                                      kAppId3));
288
289   // Simulate incoming changed sync data at runtime.
290   app_info_service.ProcessSyncChanges(FROM_HERE, changes);
291
292   // We should find that the first item now has a different set of app ids.
293   SyncedNotificationAppInfo* app_info1 =
294       app_info_service.FindSyncedNotificationAppInfoByName(
295           kSendingService1Name);
296   EXPECT_NE(static_cast<SyncedNotificationAppInfo*>(NULL), app_info1);
297   EXPECT_TRUE(app_info1->HasAppId(kAppId1));
298   EXPECT_FALSE(app_info1->HasAppId(kAppId2));
299   EXPECT_TRUE(app_info1->HasAppId(kAppId3));
300   EXPECT_EQ(app_info1->settings_icon_url(), GURL(kTestIconUrl));
301 }
302
303 // Test ProcessIncomingAppInfoProtobuf with an add.
304 TEST_F(SyncedNotificationAppInfoServiceTest,
305        ProcessIncomingAppInfoProtobufAddTest) {
306   // Get an app info service object.
307   SyncedNotificationAppInfoService app_info_service(profile_.get());
308   app_info_service.set_avoid_bitmap_fetching_for_test(true);
309
310   // Get an app info protobuf.
311   sync_pb::SyncedNotificationAppInfo protobuf;
312   FillProtobufWithTestData1(protobuf);
313
314   // Call the function we are testing.
315   app_info_service.ProcessIncomingAppInfoProtobuf(protobuf);
316
317   // Ensure that we now have an app_info in our list, and it looks like we
318   // expect.
319   notifier::SyncedNotificationAppInfo* found_app_info;
320   found_app_info = app_info_service.FindSyncedNotificationAppInfoByName(
321       kSendingService1Name);
322   EXPECT_NE(static_cast<notifier::SyncedNotificationAppInfo*>(NULL),
323             found_app_info);
324   EXPECT_TRUE(found_app_info->HasAppId(kAppId1));
325   EXPECT_TRUE(found_app_info->HasAppId(kAppId2));
326 }
327
328 // Test ProcessIncomingAppInfoProtobuf with an update
329 TEST_F(SyncedNotificationAppInfoServiceTest,
330        ProcessIncomingAppInfoProtobufUpdateTest) {
331   // Get an app info service object.
332   SyncedNotificationAppInfoService app_info_service(profile_.get());
333   app_info_service.set_avoid_bitmap_fetching_for_test(true);
334
335   // Make an app info with the same display name as the first one in the test
336   // data.
337   sync_pb::SyncedNotificationAppInfo protobuf1;
338   FillProtobufWithTestData1(protobuf1);
339   app_info_service.ProcessIncomingAppInfoProtobuf(protobuf1);
340
341   // Ensure that we now have an app_info in our list, and it looks like we
342   // expect.
343   notifier::SyncedNotificationAppInfo* found_app_info1;
344   found_app_info1 = app_info_service.FindSyncedNotificationAppInfoByName(
345       kSendingService1Name);
346   EXPECT_NE(static_cast<notifier::SyncedNotificationAppInfo*>(NULL),
347             found_app_info1);
348   EXPECT_TRUE(found_app_info1->HasAppId(kAppId1));
349   EXPECT_TRUE(found_app_info1->HasAppId(kAppId2));
350
351   // Make an update to the protobuf that has already been sent.
352   app_info_service.FreeSyncedNotificationAppInfoByName(kSendingService1Name);
353   // Change appid1 to appid3
354   sync_pb::SyncedNotificationAppInfo protobuf2;
355   FillProtobufWithTestData2(protobuf2);
356   app_info_service.ProcessIncomingAppInfoProtobuf(protobuf2);
357
358   // Ensure we have the same named app info as before, but it has the new
359   // contents.
360   notifier::SyncedNotificationAppInfo* found_app_info2;
361   found_app_info2 = app_info_service.FindSyncedNotificationAppInfoByName(
362       kSendingService1Name);
363   EXPECT_NE(static_cast<notifier::SyncedNotificationAppInfo*>(NULL),
364             found_app_info2);
365   EXPECT_FALSE(found_app_info2->HasAppId(kAppId1));
366   EXPECT_TRUE(found_app_info2->HasAppId(kAppId3));
367 }
368
369 // Test our function that creates a synced notification from a protobuf.
370 TEST_F(SyncedNotificationAppInfoServiceTest,
371        CreateSyncedNotificationAppInfoFromProtobufTest) {
372   SyncedNotificationAppInfoService app_info_service(profile_.get());
373   // Build a protobuf and fill it with data.
374   sync_pb::SyncedNotificationAppInfo protobuf;
375   FillProtobufWithTestData1(protobuf);
376
377   scoped_ptr<SyncedNotificationAppInfo> app_info;
378   app_info =
379       app_info_service.CreateSyncedNotificationAppInfoFromProtobuf(protobuf);
380
381   // Ensure the app info class has the fields we expect.
382   EXPECT_EQ(std::string(kSendingService1Name),
383             app_info->settings_display_name());
384   EXPECT_EQ(GURL(kTestInfoUrl), app_info->welcome_link_url());
385   EXPECT_TRUE(app_info->HasAppId(kAppId1));
386   EXPECT_TRUE(app_info->HasAppId(kAppId2));
387   EXPECT_EQ(GURL(std::string(kTestIconUrl)), app_info->settings_icon_url());
388 }
389
390 // Test our find by sending service name function.
391 TEST_F(SyncedNotificationAppInfoServiceTest,
392        FindSyncedNotificationAppInfoByNameTest) {
393   SyncedNotificationAppInfoService app_info_service(profile_.get());
394
395   AddTestingAppInfosToList(&app_info_service);
396
397   SyncedNotificationAppInfo* found;
398
399   found = app_info_service.FindSyncedNotificationAppInfoByName(
400       kSendingService1Name);
401
402   EXPECT_NE(static_cast<SyncedNotificationAppInfo*>(NULL), found);
403   EXPECT_EQ(std::string(kSendingService1Name), found->settings_display_name());
404
405   found = app_info_service.FindSyncedNotificationAppInfoByName(
406       kSendingService3Name);
407   EXPECT_EQ(NULL, found);
408 }
409
410 // Test our find by AppId function.
411 TEST_F(SyncedNotificationAppInfoServiceTest,
412        FindSyncedNotificationAppInfoByAppIdTest) {
413   SyncedNotificationAppInfoService app_info_service(profile_.get());
414
415   AddTestingAppInfosToList(&app_info_service);
416
417   SyncedNotificationAppInfo* found;
418
419   found = app_info_service.FindSyncedNotificationAppInfoByAppId(kAppId1);
420
421   EXPECT_NE(static_cast<SyncedNotificationAppInfo*>(NULL), found);
422   EXPECT_EQ(std::string(kSendingService1Name), found->settings_display_name());
423
424   found = app_info_service.FindSyncedNotificationAppInfoByName(kAppId5);
425   EXPECT_EQ(NULL, found);
426 }
427
428 // Test our find sending service name by app id function.
429 TEST_F(SyncedNotificationAppInfoServiceTest,
430        FindSendingServiceNameFromAppIdTest) {
431   SyncedNotificationAppInfoService app_info_service(profile_.get());
432
433   AddTestingAppInfosToList(&app_info_service);
434
435   std::string found_name;
436
437   found_name = app_info_service.FindSendingServiceNameFromAppId(kAppId1);
438
439   EXPECT_EQ(std::string(kSendingService1Name), found_name);
440
441   found_name = app_info_service.FindSendingServiceNameFromAppId(kAppId6);
442   EXPECT_TRUE(found_name.empty());
443 }
444
445 // Test our delete function.
446 TEST_F(SyncedNotificationAppInfoServiceTest,
447        FreeSyncedNotificationAppInfoByNameTest) {
448   SyncedNotificationAppInfoService app_info_service(profile_.get());
449
450   AddTestingAppInfosToList(&app_info_service);
451
452   SyncedNotificationAppInfo* found;
453
454   app_info_service.FreeSyncedNotificationAppInfoByName(kSendingService1Name);
455   found = app_info_service.FindSyncedNotificationAppInfoByName(
456       kSendingService1Name);
457   EXPECT_EQ(NULL, found);
458 }
459
460 TEST_F(SyncedNotificationAppInfoServiceTest,
461        GetAllSendingServiceSettingsDataTest) {
462   SyncedNotificationAppInfoService app_info_service(profile_.get());
463
464   AddTestingAppInfosToList(&app_info_service);
465
466   std::vector<SyncedNotificationSendingServiceSettingsData> data;
467   data = app_info_service.GetAllSendingServiceSettingsData();
468
469   EXPECT_EQ(static_cast<unsigned int>(2), data.size());
470   EXPECT_EQ(kSendingService1Name, data[0].settings_display_name);
471   EXPECT_EQ(kSendingService2Name, data[1].settings_display_name);
472 }
473
474 }  // namespace notifier