| 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 |