| OLD | NEW | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "content/browser/notifications/notification_database.h" |    5 #include "content/browser/notifications/notification_database.h" | 
|    6  |    6  | 
|    7 #include "base/files/scoped_temp_dir.h" |    7 #include "base/files/scoped_temp_dir.h" | 
|    8 #include "base/strings/string_number_conversions.h" |    8 #include "base/strings/string_number_conversions.h" | 
|    9 #include "base/strings/utf_string_conversions.h" |    9 #include "base/strings/utf_string_conversions.h" | 
|   10 #include "content/public/browser/notification_database_data.h" |   10 #include "content/public/browser/notification_database_data.h" | 
|   11 #include "content/public/common/platform_notification_data.h" |   11 #include "content/public/common/platform_notification_data.h" | 
|   12 #include "testing/gtest/include/gtest/gtest.h" |   12 #include "testing/gtest/include/gtest/gtest.h" | 
|   13 #include "third_party/leveldatabase/src/include/leveldb/db.h" |   13 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 
|   14 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |   14 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 
|   15 #include "url/gurl.h" |   15 #include "url/gurl.h" | 
|   16  |   16  | 
|   17 namespace content { |   17 namespace content { | 
|   18  |   18  | 
 |   19 const int kExampleServiceWorkerRegistrationId = 42; | 
 |   20  | 
 |   21 const struct { | 
 |   22   const char* origin; | 
 |   23   int64_t service_worker_registration_id; | 
 |   24 } kExampleNotificationData[] = { | 
 |   25   { "https://example.com",   0 }, | 
 |   26   { "https://example.com",   kExampleServiceWorkerRegistrationId }, | 
 |   27   { "https://example.com",   kExampleServiceWorkerRegistrationId }, | 
 |   28   { "https://example.com",   kExampleServiceWorkerRegistrationId + 1 }, | 
 |   29   { "https://chrome.com",    0 }, | 
 |   30   { "https://chrome.com",    0 }, | 
 |   31   { "https://chrome.com",    kExampleServiceWorkerRegistrationId } | 
 |   32 }; | 
 |   33  | 
|   19 class NotificationDatabaseTest : public ::testing::Test { |   34 class NotificationDatabaseTest : public ::testing::Test { | 
|   20  protected: |   35  protected: | 
|   21   // Creates a new NotificationDatabase instance in memory. |   36   // Creates a new NotificationDatabase instance in memory. | 
|   22   NotificationDatabase* CreateDatabaseInMemory() { |   37   NotificationDatabase* CreateDatabaseInMemory() { | 
|   23     return new NotificationDatabase(base::FilePath()); |   38     return new NotificationDatabase(base::FilePath()); | 
|   24   } |   39   } | 
|   25  |   40  | 
|   26   // Creates a new NotificationDatabase instance in |path|. |   41   // Creates a new NotificationDatabase instance in |path|. | 
|   27   NotificationDatabase* CreateDatabaseOnFileSystem( |   42   NotificationDatabase* CreateDatabaseOnFileSystem( | 
|   28       const base::FilePath& path) { |   43       const base::FilePath& path) { | 
|   29     return new NotificationDatabase(path); |   44     return new NotificationDatabase(path); | 
|   30   } |   45   } | 
|   31  |   46  | 
 |   47   // Creates a new notification for |service_worker_registration_id| belonging | 
 |   48   // to |origin| and writes it to the database. The written notification id | 
 |   49   // will be stored in |notification_id|. | 
 |   50   void CreateAndWriteNotification(NotificationDatabase* database, | 
 |   51                                   const GURL& origin, | 
 |   52                                   int64_t service_worker_registration_id, | 
 |   53                                   int64_t* notification_id) { | 
 |   54     NotificationDatabaseData database_data; | 
 |   55     database_data.origin = origin; | 
 |   56     database_data.service_worker_registration_id = | 
 |   57         service_worker_registration_id; | 
 |   58  | 
 |   59     ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |   60               database->WriteNotificationData(origin, | 
 |   61                                               database_data, | 
 |   62                                               notification_id)); | 
 |   63   } | 
 |   64  | 
 |   65   // Populates |database| with a series of example notifications that differ in | 
 |   66   // their origin and Service Worker registration id. | 
 |   67   void PopulateDatabaseWithExampleData(NotificationDatabase* database) { | 
 |   68     int64_t notification_id; | 
 |   69     for (size_t i = 0; i < arraysize(kExampleNotificationData); ++i) { | 
 |   70       ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 
 |   71           database, | 
 |   72           GURL(kExampleNotificationData[i].origin), | 
 |   73           kExampleNotificationData[i].service_worker_registration_id, | 
 |   74           ¬ification_id)); | 
 |   75     } | 
 |   76   } | 
 |   77  | 
|   32   // Returns if |database| has been opened. |   78   // Returns if |database| has been opened. | 
|   33   bool IsDatabaseOpen(NotificationDatabase* database) { |   79   bool IsDatabaseOpen(NotificationDatabase* database) { | 
|   34     return database->IsOpen(); |   80     return database->IsOpen(); | 
|   35   } |   81   } | 
|   36  |   82  | 
|   37   // Returns if |database| is an in-memory only database. |   83   // Returns if |database| is an in-memory only database. | 
|   38   bool IsInMemoryDatabase(NotificationDatabase* database) { |   84   bool IsInMemoryDatabase(NotificationDatabase* database) { | 
|   39     return database->IsInMemoryDatabase(); |   85     return database->IsInMemoryDatabase(); | 
|   40   } |   86   } | 
|   41  |   87  | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  123   ASSERT_TRUE(database_dir.CreateUniqueTempDir()); |  169   ASSERT_TRUE(database_dir.CreateUniqueTempDir()); | 
|  124  |  170  | 
|  125   scoped_ptr<NotificationDatabase> database( |  171   scoped_ptr<NotificationDatabase> database( | 
|  126       CreateDatabaseOnFileSystem(database_dir.path())); |  172       CreateDatabaseOnFileSystem(database_dir.path())); | 
|  127  |  173  | 
|  128   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  174   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
|  129             database->Open(true /* create_if_missing */)); |  175             database->Open(true /* create_if_missing */)); | 
|  130  |  176  | 
|  131   GURL origin("https://example.com"); |  177   GURL origin("https://example.com"); | 
|  132  |  178  | 
|  133   NotificationDatabaseData database_data; |  | 
|  134   int64_t notification_id = 0; |  179   int64_t notification_id = 0; | 
|  135  |  180  | 
|  136   // Verify that getting two ids on the same database instance results in |  181   // Verify that getting two ids on the same database instance results in | 
|  137   // incrementing values. Notification ids will start at 1. |  182   // incrementing values. Notification ids will start at 1. | 
|  138   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  183   ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 
|  139             database->WriteNotificationData(origin, |  184       database.get(), origin, 0 /* sw_registration_id */, ¬ification_id)); | 
|  140                                             database_data, |  | 
|  141                                             ¬ification_id)); |  | 
|  142   EXPECT_EQ(notification_id, 1); |  185   EXPECT_EQ(notification_id, 1); | 
|  143  |  186  | 
|  144   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  187   ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 
|  145             database->WriteNotificationData(origin, |  188       database.get(), origin, 0 /* sw_registration_id */, ¬ification_id)); | 
|  146                                             database_data, |  | 
|  147                                             ¬ification_id)); |  | 
|  148   EXPECT_EQ(notification_id, 2); |  189   EXPECT_EQ(notification_id, 2); | 
|  149  |  190  | 
|  150   database.reset(CreateDatabaseOnFileSystem(database_dir.path())); |  191   database.reset(CreateDatabaseOnFileSystem(database_dir.path())); | 
|  151   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  192   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
|  152             database->Open(false /* create_if_missing */)); |  193             database->Open(false /* create_if_missing */)); | 
|  153  |  194  | 
|  154   // Verify that the next notification id was stored in the database, and |  195   // Verify that the next notification id was stored in the database, and | 
|  155   // continues where we expect it to be, even after closing and opening it. |  196   // continues where we expect it to be, even after closing and opening it. | 
|  156   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  197   ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 
|  157             database->WriteNotificationData(origin, |  198       database.get(), origin, 0 /* sw_registration_id */, ¬ification_id)); | 
|  158                                             database_data, |  | 
|  159                                             ¬ification_id)); |  | 
|  160   EXPECT_EQ(notification_id, 3); |  199   EXPECT_EQ(notification_id, 3); | 
|  161 } |  200 } | 
|  162  |  201  | 
|  163 TEST_F(NotificationDatabaseTest, NotificationIdCorruption) { |  202 TEST_F(NotificationDatabaseTest, NotificationIdCorruption) { | 
|  164   base::ScopedTempDir database_dir; |  203   base::ScopedTempDir database_dir; | 
|  165   ASSERT_TRUE(database_dir.CreateUniqueTempDir()); |  204   ASSERT_TRUE(database_dir.CreateUniqueTempDir()); | 
|  166  |  205  | 
|  167   scoped_ptr<NotificationDatabase> database( |  206   scoped_ptr<NotificationDatabase> database( | 
|  168       CreateDatabaseOnFileSystem(database_dir.path())); |  207       CreateDatabaseOnFileSystem(database_dir.path())); | 
|  169  |  208  | 
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  298   EXPECT_EQ(notification_data.tag, read_notification_data.tag); |  337   EXPECT_EQ(notification_data.tag, read_notification_data.tag); | 
|  299   EXPECT_EQ(notification_data.icon, read_notification_data.icon); |  338   EXPECT_EQ(notification_data.icon, read_notification_data.icon); | 
|  300   EXPECT_EQ(notification_data.silent, read_notification_data.silent); |  339   EXPECT_EQ(notification_data.silent, read_notification_data.silent); | 
|  301 } |  340 } | 
|  302  |  341  | 
|  303 TEST_F(NotificationDatabaseTest, ReadWriteMultipleNotificationData) { |  342 TEST_F(NotificationDatabaseTest, ReadWriteMultipleNotificationData) { | 
|  304   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |  343   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
|  305   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  344   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
|  306             database->Open(true /* create_if_missing */)); |  345             database->Open(true /* create_if_missing */)); | 
|  307  |  346  | 
|  308   NotificationDatabaseData database_data; |  | 
|  309   GURL origin("https://example.com"); |  347   GURL origin("https://example.com"); | 
 |  348   int64_t notification_id = 0; | 
|  310  |  349  | 
|  311   // Write ten notifications to the database, each with a unique title and |  350   // Write ten notifications to the database, each with a unique title and | 
|  312   // notification id (it is the responsibility of the user to increment this). |  351   // notification id (it is the responsibility of the user to increment this). | 
|  313   for (int i = 1; i <= 10; ++i) { |  352   for (int i = 1; i <= 10; ++i) { | 
|  314     database_data.notification_id = i; |  353     ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 
|  315     database_data.notification_data.title = base::IntToString16(i); |  354         database.get(), origin, i /* sw_registration_id */, ¬ification_id)); | 
|  316  |  | 
|  317     int64_t notification_id = 0; |  | 
|  318     ASSERT_EQ(NotificationDatabase::STATUS_OK, |  | 
|  319               database->WriteNotificationData(origin, |  | 
|  320                                               database_data, |  | 
|  321                                               ¬ification_id)); |  | 
|  322     EXPECT_EQ(notification_id, i); |  355     EXPECT_EQ(notification_id, i); | 
|  323   } |  356   } | 
|  324  |  357  | 
 |  358   NotificationDatabaseData database_data; | 
 |  359  | 
|  325   // Read the ten notifications from the database, and verify that the titles |  360   // Read the ten notifications from the database, and verify that the titles | 
|  326   // of each of them matches with how they were created. |  361   // of each of them matches with how they were created. | 
|  327   for (int i = 1; i <= 10; ++i) { |  362   for (int i = 1; i <= 10; ++i) { | 
|  328     ASSERT_EQ(NotificationDatabase::STATUS_OK, |  363     ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
|  329               database->ReadNotificationData(i /* notification_id */, |  364               database->ReadNotificationData(i /* notification_id */, | 
|  330                                              origin, |  365                                              origin, | 
|  331                                              &database_data)); |  366                                              &database_data)); | 
|  332  |  367  | 
|  333     EXPECT_EQ(base::IntToString16(i), database_data.notification_data.title); |  368     EXPECT_EQ(i, database_data.service_worker_registration_id); | 
|  334   } |  369   } | 
|  335 } |  370 } | 
|  336  |  371  | 
|  337 TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationData) { |  372 TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationData) { | 
|  338   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |  373   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
|  339   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  374   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
|  340             database->Open(true /* create_if_missing */)); |  375             database->Open(true /* create_if_missing */)); | 
|  341  |  376  | 
|  342   // Deleting non-existing notifications is not considered to be a failure. |  377   // Deleting non-existing notifications is not considered to be a failure. | 
|  343   ASSERT_EQ(NotificationDatabase::STATUS_OK, |  378   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  398   EXPECT_EQ(NotificationDatabase::STATUS_OK, |  433   EXPECT_EQ(NotificationDatabase::STATUS_OK, | 
|  399             database->DeleteNotificationData(notification_id, |  434             database->DeleteNotificationData(notification_id, | 
|  400                                              GURL("https://chrome.com"))); |  435                                              GURL("https://chrome.com"))); | 
|  401  |  436  | 
|  402   EXPECT_EQ(NotificationDatabase::STATUS_OK, |  437   EXPECT_EQ(NotificationDatabase::STATUS_OK, | 
|  403             database->ReadNotificationData(notification_id, |  438             database->ReadNotificationData(notification_id, | 
|  404                                            origin, |  439                                            origin, | 
|  405                                            &database_data)); |  440                                            &database_data)); | 
|  406 } |  441 } | 
|  407  |  442  | 
 |  443 TEST_F(NotificationDatabaseTest, ReadAllNotificationData) { | 
 |  444   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  445   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  446             database->Open(true /* create_if_missing */)); | 
 |  447  | 
 |  448   ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); | 
 |  449  | 
 |  450   std::vector<NotificationDatabaseData> notifications; | 
 |  451   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  452             database->ReadAllNotificationData(¬ifications)); | 
 |  453  | 
 |  454   EXPECT_EQ(arraysize(kExampleNotificationData), notifications.size()); | 
 |  455 } | 
 |  456  | 
 |  457 TEST_F(NotificationDatabaseTest, ReadAllNotificationDataEmpty) { | 
 |  458   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  459   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  460             database->Open(true /* create_if_missing */)); | 
 |  461  | 
 |  462   std::vector<NotificationDatabaseData> notifications; | 
 |  463   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  464             database->ReadAllNotificationData(¬ifications)); | 
 |  465  | 
 |  466   EXPECT_EQ(0u, notifications.size()); | 
 |  467 } | 
 |  468  | 
 |  469 TEST_F(NotificationDatabaseTest, ReadAllNotificationDataForOrigin) { | 
 |  470   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  471   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  472             database->Open(true /* create_if_missing */)); | 
 |  473  | 
 |  474   ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); | 
 |  475  | 
 |  476   GURL origin("https://example.com"); | 
 |  477  | 
 |  478   std::vector<NotificationDatabaseData> notifications; | 
 |  479   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  480             database->ReadAllNotificationDataForOrigin(origin, ¬ifications)); | 
 |  481  | 
 |  482   EXPECT_EQ(4u, notifications.size()); | 
 |  483 } | 
 |  484  | 
 |  485 TEST_F(NotificationDatabaseTest, | 
 |  486        ReadAllNotificationDataForServiceWorkerRegistration) { | 
 |  487   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  488   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  489             database->Open(true /* create_if_missing */)); | 
 |  490  | 
 |  491   ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); | 
 |  492  | 
 |  493   GURL origin("https://example.com:443"); | 
 |  494  | 
 |  495   std::vector<NotificationDatabaseData> notifications; | 
 |  496   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  497             database->ReadAllNotificationDataForServiceWorkerRegistration( | 
 |  498                 origin, kExampleServiceWorkerRegistrationId, ¬ifications)); | 
 |  499  | 
 |  500   EXPECT_EQ(2u, notifications.size()); | 
 |  501 } | 
 |  502  | 
 |  503 TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOrigin) { | 
 |  504   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  505   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  506             database->Open(true /* create_if_missing */)); | 
 |  507  | 
 |  508   ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); | 
 |  509  | 
 |  510   GURL origin("https://example.com:443"); | 
 |  511  | 
 |  512   std::set<int64_t> deleted_notification_set; | 
 |  513   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  514             database->DeleteAllNotificationDataForOrigin( | 
 |  515                 origin, &deleted_notification_set)); | 
 |  516  | 
 |  517   EXPECT_EQ(4u, deleted_notification_set.size()); | 
 |  518  | 
 |  519   std::vector<NotificationDatabaseData> notifications; | 
 |  520   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  521             database->ReadAllNotificationDataForOrigin(origin, ¬ifications)); | 
 |  522  | 
 |  523   EXPECT_EQ(0u, notifications.size()); | 
 |  524 } | 
 |  525  | 
 |  526 TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOriginEmpty) { | 
 |  527   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  528   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  529             database->Open(true /* create_if_missing */)); | 
 |  530  | 
 |  531   GURL origin("https://example.com"); | 
 |  532  | 
 |  533   std::set<int64_t> deleted_notification_set; | 
 |  534   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  535             database->DeleteAllNotificationDataForOrigin( | 
 |  536                 origin, &deleted_notification_set)); | 
 |  537  | 
 |  538   EXPECT_EQ(0u, deleted_notification_set.size()); | 
 |  539 } | 
 |  540  | 
 |  541 TEST_F(NotificationDatabaseTest, | 
 |  542        DeleteAllNotificationDataForServiceWorkerRegistration) { | 
 |  543   scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 
 |  544   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  545             database->Open(true /* create_if_missing */)); | 
 |  546  | 
 |  547   ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); | 
 |  548  | 
 |  549   GURL origin("https://example.com:443"); | 
 |  550   std::set<int64_t> deleted_notification_set; | 
 |  551   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  552             database->DeleteAllNotificationDataForServiceWorkerRegistration( | 
 |  553                 origin, | 
 |  554                 kExampleServiceWorkerRegistrationId, | 
 |  555                 &deleted_notification_set)); | 
 |  556  | 
 |  557   EXPECT_EQ(2u, deleted_notification_set.size()); | 
 |  558  | 
 |  559   std::vector<NotificationDatabaseData> notifications; | 
 |  560   ASSERT_EQ(NotificationDatabase::STATUS_OK, | 
 |  561             database->ReadAllNotificationDataForServiceWorkerRegistration( | 
 |  562                 origin, kExampleServiceWorkerRegistrationId, ¬ifications)); | 
 |  563  | 
 |  564   EXPECT_EQ(0u, notifications.size()); | 
 |  565 } | 
 |  566  | 
|  408 }  // namespace content |  567 }  // namespace content | 
| OLD | NEW |