| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "content/public/browser/notification_database_data.h" | 14 #include "content/public/browser/notification_database_data.h" |
| 15 #include "content/public/common/platform_notification_data.h" | 15 #include "content/public/common/platform_notification_data.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 17 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
| 18 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 18 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
| 19 #include "url/gurl.h" | 19 #include "url/gurl.h" |
| 20 | 20 |
| 21 namespace content { | 21 namespace content { |
| 22 | 22 |
| 23 const int kExampleServiceWorkerRegistrationId = 42; | 23 const int kExampleServiceWorkerRegistrationId = 42; |
| 24 | 24 |
| 25 const struct { | 25 const struct { |
| 26 const char* origin; | 26 const char* origin; |
| 27 const char* tag; |
| 27 int64_t service_worker_registration_id; | 28 int64_t service_worker_registration_id; |
| 28 } kExampleNotificationData[] = { | 29 } kExampleNotificationData[] = { |
| 29 {"https://example.com", 0}, | 30 {"https://example.com", "" /* tag */, 0}, |
| 30 {"https://example.com", kExampleServiceWorkerRegistrationId}, | 31 {"https://example.com", "" /* tag */, kExampleServiceWorkerRegistrationId}, |
| 31 {"https://example.com", kExampleServiceWorkerRegistrationId}, | 32 {"https://example.com", "" /* tag */, kExampleServiceWorkerRegistrationId}, |
| 32 {"https://example.com", kExampleServiceWorkerRegistrationId + 1}, | 33 {"https://example.com", "" /* tag */, |
| 33 {"https://chrome.com", 0}, | 34 kExampleServiceWorkerRegistrationId + 1}, |
| 34 {"https://chrome.com", 0}, | 35 {"https://chrome.com", "" /* tag */, 0}, |
| 35 {"https://chrome.com", kExampleServiceWorkerRegistrationId}}; | 36 {"https://chrome.com", "" /* tag */, 0}, |
| 37 {"https://chrome.com", "" /* tag */, kExampleServiceWorkerRegistrationId}, |
| 38 {"https://chrome.com", "foo" /* tag */, 0}}; |
| 36 | 39 |
| 37 class NotificationDatabaseTest : public ::testing::Test { | 40 class NotificationDatabaseTest : public ::testing::Test { |
| 38 protected: | 41 protected: |
| 39 // Creates a new NotificationDatabase instance in memory. | 42 // Creates a new NotificationDatabase instance in memory. |
| 40 NotificationDatabase* CreateDatabaseInMemory() { | 43 NotificationDatabase* CreateDatabaseInMemory() { |
| 41 return new NotificationDatabase(base::FilePath()); | 44 return new NotificationDatabase(base::FilePath()); |
| 42 } | 45 } |
| 43 | 46 |
| 44 // Creates a new NotificationDatabase instance in |path|. | 47 // Creates a new NotificationDatabase instance in |path|. |
| 45 NotificationDatabase* CreateDatabaseOnFileSystem(const base::FilePath& path) { | 48 NotificationDatabase* CreateDatabaseOnFileSystem(const base::FilePath& path) { |
| 46 return new NotificationDatabase(path); | 49 return new NotificationDatabase(path); |
| 47 } | 50 } |
| 48 | 51 |
| 49 // Creates a new notification for |service_worker_registration_id| belonging | 52 // Creates a new notification for |service_worker_registration_id| belonging |
| 50 // to |origin| and writes it to the database. The written notification id | 53 // to |origin| and writes it to the database. The written notification id |
| 51 // will be stored in |notification_id|. | 54 // will be stored in |notification_id|. |
| 52 void CreateAndWriteNotification(NotificationDatabase* database, | 55 void CreateAndWriteNotification(NotificationDatabase* database, |
| 53 const GURL& origin, | 56 const GURL& origin, |
| 57 const std::string& tag, |
| 54 int64_t service_worker_registration_id, | 58 int64_t service_worker_registration_id, |
| 55 int64_t* notification_id) { | 59 int64_t* notification_id) { |
| 56 NotificationDatabaseData database_data; | 60 NotificationDatabaseData database_data; |
| 57 database_data.origin = origin; | 61 database_data.origin = origin; |
| 58 database_data.service_worker_registration_id = | 62 database_data.service_worker_registration_id = |
| 59 service_worker_registration_id; | 63 service_worker_registration_id; |
| 64 database_data.notification_data.tag = tag; |
| 60 | 65 |
| 61 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 66 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 62 database->WriteNotificationData(origin, database_data, | 67 database->WriteNotificationData(origin, database_data, |
| 63 notification_id)); | 68 notification_id)); |
| 64 } | 69 } |
| 65 | 70 |
| 66 // Populates |database| with a series of example notifications that differ in | 71 // Populates |database| with a series of example notifications that differ in |
| 67 // their origin and Service Worker registration id. | 72 // their origin and Service Worker registration id. |
| 68 void PopulateDatabaseWithExampleData(NotificationDatabase* database) { | 73 void PopulateDatabaseWithExampleData(NotificationDatabase* database) { |
| 69 int64_t notification_id; | 74 int64_t notification_id; |
| 70 for (size_t i = 0; i < arraysize(kExampleNotificationData); ++i) { | 75 for (size_t i = 0; i < arraysize(kExampleNotificationData); ++i) { |
| 71 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 76 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( |
| 72 database, GURL(kExampleNotificationData[i].origin), | 77 database, GURL(kExampleNotificationData[i].origin), |
| 78 kExampleNotificationData[i].tag, |
| 73 kExampleNotificationData[i].service_worker_registration_id, | 79 kExampleNotificationData[i].service_worker_registration_id, |
| 74 ¬ification_id)); | 80 ¬ification_id)); |
| 75 } | 81 } |
| 76 } | 82 } |
| 77 | 83 |
| 78 // Returns if |database| has been opened. | 84 // Returns if |database| has been opened. |
| 79 bool IsDatabaseOpen(NotificationDatabase* database) { | 85 bool IsDatabaseOpen(NotificationDatabase* database) { |
| 80 return database->IsOpen(); | 86 return database->IsOpen(); |
| 81 } | 87 } |
| 82 | 88 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 179 |
| 174 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 180 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 175 database->Open(true /* create_if_missing */)); | 181 database->Open(true /* create_if_missing */)); |
| 176 | 182 |
| 177 GURL origin("https://example.com"); | 183 GURL origin("https://example.com"); |
| 178 | 184 |
| 179 int64_t notification_id = 0; | 185 int64_t notification_id = 0; |
| 180 | 186 |
| 181 // Verify that getting two ids on the same database instance results in | 187 // Verify that getting two ids on the same database instance results in |
| 182 // incrementing values. Notification ids will start at 1. | 188 // incrementing values. Notification ids will start at 1. |
| 183 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 189 ASSERT_NO_FATAL_FAILURE( |
| 184 database.get(), origin, 0 /* sw_registration_id */, ¬ification_id)); | 190 CreateAndWriteNotification(database.get(), origin, "" /* tag */, |
| 191 0 /* sw_registration_id */, ¬ification_id)); |
| 185 EXPECT_EQ(notification_id, 1); | 192 EXPECT_EQ(notification_id, 1); |
| 186 | 193 |
| 187 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 194 ASSERT_NO_FATAL_FAILURE( |
| 188 database.get(), origin, 0 /* sw_registration_id */, ¬ification_id)); | 195 CreateAndWriteNotification(database.get(), origin, "" /* tag */, |
| 196 0 /* sw_registration_id */, ¬ification_id)); |
| 189 EXPECT_EQ(notification_id, 2); | 197 EXPECT_EQ(notification_id, 2); |
| 190 | 198 |
| 191 database.reset(CreateDatabaseOnFileSystem(database_dir.path())); | 199 database.reset(CreateDatabaseOnFileSystem(database_dir.path())); |
| 192 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 200 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 193 database->Open(false /* create_if_missing */)); | 201 database->Open(false /* create_if_missing */)); |
| 194 | 202 |
| 195 // Verify that the next notification id was stored in the database, and | 203 // Verify that the next notification id was stored in the database, and |
| 196 // continues where we expect it to be, even after closing and opening it. | 204 // continues where we expect it to be, even after closing and opening it. |
| 197 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 205 ASSERT_NO_FATAL_FAILURE( |
| 198 database.get(), origin, 0 /* sw_registration_id */, ¬ification_id)); | 206 CreateAndWriteNotification(database.get(), origin, "" /* tag */, |
| 207 0 /* sw_registration_id */, ¬ification_id)); |
| 199 EXPECT_EQ(notification_id, 3); | 208 EXPECT_EQ(notification_id, 3); |
| 200 } | 209 } |
| 201 | 210 |
| 202 TEST_F(NotificationDatabaseTest, NotificationIdIncrementsStorage) { | 211 TEST_F(NotificationDatabaseTest, NotificationIdIncrementsStorage) { |
| 203 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 212 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
| 204 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 213 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 205 database->Open(true /* create_if_missing */)); | 214 database->Open(true /* create_if_missing */)); |
| 206 | 215 |
| 207 GURL origin("https://example.com"); | 216 GURL origin("https://example.com"); |
| 208 | 217 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 369 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 361 database->Open(true /* create_if_missing */)); | 370 database->Open(true /* create_if_missing */)); |
| 362 | 371 |
| 363 GURL origin("https://example.com"); | 372 GURL origin("https://example.com"); |
| 364 int64_t notification_id = 0; | 373 int64_t notification_id = 0; |
| 365 | 374 |
| 366 // Write ten notifications to the database, each with a unique title and | 375 // Write ten notifications to the database, each with a unique title and |
| 367 // notification id (it is the responsibility of the user to increment this). | 376 // notification id (it is the responsibility of the user to increment this). |
| 368 for (int i = 1; i <= 10; ++i) { | 377 for (int i = 1; i <= 10; ++i) { |
| 369 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( | 378 ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification( |
| 370 database.get(), origin, i /* sw_registration_id */, ¬ification_id)); | 379 database.get(), origin, "" /* tag */, i /* sw_registration_id */, |
| 380 ¬ification_id)); |
| 371 EXPECT_EQ(notification_id, i); | 381 EXPECT_EQ(notification_id, i); |
| 372 } | 382 } |
| 373 | 383 |
| 374 NotificationDatabaseData database_data; | 384 NotificationDatabaseData database_data; |
| 375 | 385 |
| 376 // Read the ten notifications from the database, and verify that the titles | 386 // Read the ten notifications from the database, and verify that the titles |
| 377 // of each of them matches with how they were created. | 387 // of each of them matches with how they were created. |
| 378 for (int i = 1; i <= 10; ++i) { | 388 for (int i = 1; i <= 10; ++i) { |
| 379 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 389 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 380 database->ReadNotificationData(i /* notification_id */, origin, | 390 database->ReadNotificationData(i /* notification_id */, origin, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 524 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 515 database->Open(true /* create_if_missing */)); | 525 database->Open(true /* create_if_missing */)); |
| 516 | 526 |
| 517 ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); | 527 ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); |
| 518 | 528 |
| 519 GURL origin("https://example.com:443"); | 529 GURL origin("https://example.com:443"); |
| 520 | 530 |
| 521 std::set<int64_t> deleted_notification_set; | 531 std::set<int64_t> deleted_notification_set; |
| 522 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 532 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 523 database->DeleteAllNotificationDataForOrigin( | 533 database->DeleteAllNotificationDataForOrigin( |
| 524 origin, &deleted_notification_set)); | 534 origin, "" /* tag */, &deleted_notification_set)); |
| 525 | 535 |
| 526 EXPECT_EQ(4u, deleted_notification_set.size()); | 536 EXPECT_EQ(4u, deleted_notification_set.size()); |
| 527 | 537 |
| 528 std::vector<NotificationDatabaseData> notifications; | 538 std::vector<NotificationDatabaseData> notifications; |
| 529 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 539 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 530 database->ReadAllNotificationDataForOrigin(origin, ¬ifications)); | 540 database->ReadAllNotificationDataForOrigin(origin, ¬ifications)); |
| 531 | 541 |
| 532 EXPECT_EQ(0u, notifications.size()); | 542 EXPECT_EQ(0u, notifications.size()); |
| 533 } | 543 } |
| 534 | 544 |
| 545 TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOriginWithTag) { |
| 546 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
| 547 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 548 database->Open(true /* create_if_missing */)); |
| 549 |
| 550 ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get())); |
| 551 |
| 552 GURL origin("https://chrome.com"); |
| 553 |
| 554 std::vector<NotificationDatabaseData> notifications; |
| 555 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 556 database->ReadAllNotificationDataForOrigin(origin, ¬ifications)); |
| 557 |
| 558 const std::string& tag = "foo"; |
| 559 |
| 560 size_t notifications_with_tag = 0; |
| 561 size_t notifications_without_tag = 0; |
| 562 |
| 563 for (const auto& database_data : notifications) { |
| 564 if (database_data.notification_data.tag == tag) |
| 565 ++notifications_with_tag; |
| 566 else |
| 567 ++notifications_without_tag; |
| 568 } |
| 569 |
| 570 ASSERT_GT(notifications_with_tag, 0u); |
| 571 ASSERT_GT(notifications_without_tag, 0u); |
| 572 |
| 573 std::set<int64_t> deleted_notification_set; |
| 574 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 575 database->DeleteAllNotificationDataForOrigin( |
| 576 origin, "foo" /* tag */, &deleted_notification_set)); |
| 577 |
| 578 EXPECT_EQ(notifications_with_tag, deleted_notification_set.size()); |
| 579 |
| 580 std::vector<NotificationDatabaseData> updated_notifications; |
| 581 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 582 database->ReadAllNotificationDataForOrigin(origin, |
| 583 &updated_notifications)); |
| 584 |
| 585 EXPECT_EQ(notifications_without_tag, updated_notifications.size()); |
| 586 |
| 587 size_t updated_notifications_with_tag = 0; |
| 588 size_t updated_notifications_without_tag = 0; |
| 589 |
| 590 for (const auto& database_data : updated_notifications) { |
| 591 if (database_data.notification_data.tag == tag) |
| 592 ++updated_notifications_with_tag; |
| 593 else |
| 594 ++updated_notifications_without_tag; |
| 595 } |
| 596 |
| 597 EXPECT_EQ(0u, updated_notifications_with_tag); |
| 598 EXPECT_EQ(notifications_without_tag, updated_notifications_without_tag); |
| 599 } |
| 600 |
| 535 TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOriginEmpty) { | 601 TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOriginEmpty) { |
| 536 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 602 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
| 537 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 603 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 538 database->Open(true /* create_if_missing */)); | 604 database->Open(true /* create_if_missing */)); |
| 539 | 605 |
| 540 GURL origin("https://example.com"); | 606 GURL origin("https://example.com"); |
| 541 | 607 |
| 542 std::set<int64_t> deleted_notification_set; | 608 std::set<int64_t> deleted_notification_set; |
| 543 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 609 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 544 database->DeleteAllNotificationDataForOrigin( | 610 database->DeleteAllNotificationDataForOrigin( |
| 545 origin, &deleted_notification_set)); | 611 origin, "" /* tag */, &deleted_notification_set)); |
| 546 | 612 |
| 547 EXPECT_EQ(0u, deleted_notification_set.size()); | 613 EXPECT_EQ(0u, deleted_notification_set.size()); |
| 548 } | 614 } |
| 549 | 615 |
| 550 TEST_F(NotificationDatabaseTest, | 616 TEST_F(NotificationDatabaseTest, |
| 551 DeleteAllNotificationDataForServiceWorkerRegistration) { | 617 DeleteAllNotificationDataForServiceWorkerRegistration) { |
| 552 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); | 618 std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
| 553 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 619 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 554 database->Open(true /* create_if_missing */)); | 620 database->Open(true /* create_if_missing */)); |
| 555 | 621 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 566 | 632 |
| 567 std::vector<NotificationDatabaseData> notifications; | 633 std::vector<NotificationDatabaseData> notifications; |
| 568 ASSERT_EQ(NotificationDatabase::STATUS_OK, | 634 ASSERT_EQ(NotificationDatabase::STATUS_OK, |
| 569 database->ReadAllNotificationDataForServiceWorkerRegistration( | 635 database->ReadAllNotificationDataForServiceWorkerRegistration( |
| 570 origin, kExampleServiceWorkerRegistrationId, ¬ifications)); | 636 origin, kExampleServiceWorkerRegistrationId, ¬ifications)); |
| 571 | 637 |
| 572 EXPECT_EQ(0u, notifications.size()); | 638 EXPECT_EQ(0u, notifications.size()); |
| 573 } | 639 } |
| 574 | 640 |
| 575 } // namespace content | 641 } // namespace content |
| OLD | NEW |