Index: content/browser/notifications/notification_database_unittest.cc |
diff --git a/content/browser/notifications/notification_database_unittest.cc b/content/browser/notifications/notification_database_unittest.cc |
index 35ea1a38ee19ae6251687d89fa8849b14696d33b..7bd835b20a5c04c4299c3766d2881990c402d739 100644 |
--- a/content/browser/notifications/notification_database_unittest.cc |
+++ b/content/browser/notifications/notification_database_unittest.cc |
@@ -5,9 +5,14 @@ |
#include "content/browser/notifications/notification_database.h" |
#include "base/files/scoped_temp_dir.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "content/browser/notifications/notification_database_data.h" |
+#include "content/public/common/platform_notification_data.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "third_party/leveldatabase/src/include/leveldb/db.h" |
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
+#include "url/gurl.h" |
namespace content { |
@@ -43,25 +48,6 @@ class NotificationDatabaseTest : public ::testing::Test { |
database->GetDBForTesting()->Put(leveldb::WriteOptions(), key, value); |
ASSERT_TRUE(status.ok()); |
} |
- |
- // Increments the next notification id value in the database. Normally this |
- // is managed by the NotificationDatabase when writing notification data. |
- // |
- // TODO(peter): Stop doing this manually when writing notification data will |
- // do this for us, except for tests verifying corruption behavior. |
- void IncrementNextNotificationId(NotificationDatabase* database) { |
- int64_t next_notification_id; |
- ASSERT_EQ(NotificationDatabase::STATUS_OK, |
- database->GetNextNotificationId(&next_notification_id)); |
- |
- leveldb::WriteBatch batch; |
- database->WriteNextNotificationId(&batch, next_notification_id + 1); |
- |
- leveldb::Status status = |
- database->GetDBForTesting()->Write(leveldb::WriteOptions(), &batch); |
- |
- ASSERT_TRUE(status.ok()); |
- } |
}; |
TEST_F(NotificationDatabaseTest, OpenCloseMemory) { |
@@ -132,7 +118,7 @@ TEST_F(NotificationDatabaseTest, DestroyDatabase) { |
database->Open(false /* create_if_missing */)); |
} |
-TEST_F(NotificationDatabaseTest, GetNextNotificationIdIncrements) { |
+TEST_F(NotificationDatabaseTest, NotificationIdIncrements) { |
base::ScopedTempDir database_dir; |
ASSERT_TRUE(database_dir.CreateUniqueTempDir()); |
@@ -142,21 +128,24 @@ TEST_F(NotificationDatabaseTest, GetNextNotificationIdIncrements) { |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
database->Open(true /* create_if_missing */)); |
+ GURL origin("https://example.com"); |
+ |
+ NotificationDatabaseData database_data; |
int64_t notification_id = 0; |
// Verify that getting two ids on the same database instance results in |
// incrementing values. Notification ids will start at 1. |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
- database->GetNextNotificationId(¬ification_id)); |
- EXPECT_EQ(1, notification_id); |
- |
- ASSERT_NO_FATAL_FAILURE(IncrementNextNotificationId(database.get())); |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ EXPECT_EQ(notification_id, 1); |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
- database->GetNextNotificationId(¬ification_id)); |
- EXPECT_EQ(2, notification_id); |
- |
- ASSERT_NO_FATAL_FAILURE(IncrementNextNotificationId(database.get())); |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ EXPECT_EQ(notification_id, 2); |
database.reset(CreateDatabaseOnFileSystem(database_dir.path())); |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
@@ -165,30 +154,255 @@ TEST_F(NotificationDatabaseTest, GetNextNotificationIdIncrements) { |
// Verify that the next notification id was stored in the database, and |
// continues where we expect it to be, even after closing and opening it. |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
- database->GetNextNotificationId(¬ification_id)); |
- EXPECT_EQ(3, notification_id); |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ EXPECT_EQ(notification_id, 3); |
} |
-TEST_F(NotificationDatabaseTest, GetNextNotificationIdCorruption) { |
- scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+TEST_F(NotificationDatabaseTest, NotificationIdCorruption) { |
+ base::ScopedTempDir database_dir; |
+ ASSERT_TRUE(database_dir.CreateUniqueTempDir()); |
+ |
+ scoped_ptr<NotificationDatabase> database( |
+ CreateDatabaseOnFileSystem(database_dir.path())); |
+ |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
database->Open(true /* create_if_missing */)); |
+ GURL origin("https://example.com"); |
+ |
+ NotificationDatabaseData database_data; |
int64_t notification_id = 0; |
ASSERT_EQ(NotificationDatabase::STATUS_OK, |
- database->GetNextNotificationId(¬ification_id)); |
- EXPECT_EQ(1, notification_id); |
- |
- // Deliberately write an invalid value as the next notification id to the |
- // database, which should cause GetNextNotificationId to realize that |
- // something is wrong with the data it's reading. |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ EXPECT_EQ(notification_id, 1); |
+ |
+ // Deliberately write an invalid value as the next notification id. When |
+ // re-opening the database, the Open() method should realize that an invalid |
+ // value is being read, and mark the database as corrupted. |
ASSERT_NO_FATAL_FAILURE(WriteLevelDBKeyValuePair(database.get(), |
"NEXT_NOTIFICATION_ID", |
"-42")); |
+ database.reset(CreateDatabaseOnFileSystem(database_dir.path())); |
EXPECT_EQ(NotificationDatabase::STATUS_ERROR_CORRUPTED, |
- database->GetNextNotificationId(¬ification_id)); |
+ database->Open(false /* create_if_missing */)); |
+} |
+ |
+TEST_F(NotificationDatabaseTest, ReadInvalidNotificationData) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ NotificationDatabaseData database_data; |
+ |
+ // Reading the notification data for a notification that does not exist should |
+ // return the ERROR_NOT_FOUND status code. |
+ EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, |
+ database->ReadNotificationData(9001, |
+ GURL("https://chrome.com"), |
+ &database_data)); |
+} |
+ |
+TEST_F(NotificationDatabaseTest, ReadNotificationDataDifferentOrigin) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ int64_t notification_id = 0; |
+ GURL origin("https://example.com"); |
+ |
+ NotificationDatabaseData database_data, read_database_data; |
+ database_data.notification_data.title = base::UTF8ToUTF16("My Notification"); |
+ |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ |
+ // Reading the notification from the database when given a different origin |
+ // should return the ERROR_NOT_FOUND status code. |
+ EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, |
+ database->ReadNotificationData(notification_id, |
+ GURL("https://chrome.com"), |
+ &read_database_data)); |
+ |
+ // However, reading the notification from the database with the same origin |
+ // should return STATUS_OK and the associated notification data. |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->ReadNotificationData(notification_id, |
+ origin, |
+ &read_database_data)); |
+ |
+ EXPECT_EQ(database_data.notification_data.title, |
+ read_database_data.notification_data.title); |
+} |
+ |
+TEST_F(NotificationDatabaseTest, ReadNotificationDataReflection) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ int64_t notification_id = 0; |
+ |
+ GURL origin("https://example.com"); |
+ |
+ PlatformNotificationData notification_data; |
+ notification_data.title = base::UTF8ToUTF16("My Notification"); |
+ notification_data.direction = |
+ PlatformNotificationData::NotificationDirectionRightToLeft; |
+ notification_data.lang = "nl-NL"; |
+ notification_data.body = base::UTF8ToUTF16("Hello, world!"); |
+ notification_data.tag = "replace id"; |
+ notification_data.icon = GURL("https://example.com/icon.png"); |
+ notification_data.silent = true; |
+ |
+ NotificationDatabaseData database_data; |
+ database_data.notification_id = notification_id; |
+ database_data.origin = origin; |
+ database_data.service_worker_registration_id = 42; |
+ database_data.notification_data = notification_data; |
+ |
+ // Write the constructed notification to the database, and then immediately |
+ // read it back from the database again as well. |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ |
+ NotificationDatabaseData read_database_data; |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->ReadNotificationData(notification_id, |
+ origin, |
+ &read_database_data)); |
+ |
+ // Verify that all members retrieved from the database are exactly the same |
+ // as the ones that were written to it. This tests the serialization behavior. |
+ |
+ EXPECT_EQ(database_data.notification_id, read_database_data.notification_id); |
+ EXPECT_EQ(database_data.origin, read_database_data.origin); |
+ EXPECT_EQ(database_data.service_worker_registration_id, |
+ read_database_data.service_worker_registration_id); |
+ |
+ const PlatformNotificationData& read_notification_data = |
+ read_database_data.notification_data; |
+ |
+ EXPECT_EQ(notification_data.title, read_notification_data.title); |
+ EXPECT_EQ(notification_data.direction, read_notification_data.direction); |
+ EXPECT_EQ(notification_data.lang, read_notification_data.lang); |
+ EXPECT_EQ(notification_data.body, read_notification_data.body); |
+ EXPECT_EQ(notification_data.tag, read_notification_data.tag); |
+ EXPECT_EQ(notification_data.icon, read_notification_data.icon); |
+ EXPECT_EQ(notification_data.silent, read_notification_data.silent); |
+} |
+ |
+TEST_F(NotificationDatabaseTest, ReadWriteMultipleNotificationData) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ NotificationDatabaseData database_data; |
+ GURL origin("https://example.com"); |
+ |
+ // Write ten notifications to the database, each with a unique title and |
+ // notification id (it is the responsibility of the user to increment this). |
+ for (int i = 1; i <= 10; ++i) { |
+ database_data.notification_id = i; |
+ database_data.notification_data.title = base::IntToString16(i); |
+ |
+ int64_t notification_id = 0; |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ EXPECT_EQ(notification_id, i); |
+ } |
+ |
+ // Read the ten notifications from the database, and verify that the titles |
+ // of each of them matches with how they were created. |
+ for (int i = 1; i <= 10; ++i) { |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->ReadNotificationData(i /* notification_id */, |
+ origin, |
+ &database_data)); |
+ |
+ EXPECT_EQ(base::IntToString16(i), database_data.notification_data.title); |
+ } |
+} |
+ |
+TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationData) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ // Deleting non-existing notifications is not considered to be a failure. |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->DeleteNotificationData(9001, |
+ GURL("https://chrome.com"))); |
+} |
+ |
+TEST_F(NotificationDatabaseTest, DeleteNotificationDataSameOrigin) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ int64_t notification_id = 0; |
+ |
+ NotificationDatabaseData database_data; |
+ GURL origin("https://example.com"); |
+ |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ |
+ // Reading a notification after writing one should succeed. |
+ EXPECT_EQ(NotificationDatabase::STATUS_OK, |
+ database->ReadNotificationData(notification_id, |
+ origin, |
+ &database_data)); |
+ |
+ // Delete the notification which was just written to the database, and verify |
+ // that reading it again will fail. |
+ EXPECT_EQ(NotificationDatabase::STATUS_OK, |
+ database->DeleteNotificationData(notification_id, origin)); |
+ EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND, |
+ database->ReadNotificationData(notification_id, |
+ origin, |
+ &database_data)); |
+} |
+ |
+TEST_F(NotificationDatabaseTest, DeleteNotificationDataDifferentOrigin) { |
+ scoped_ptr<NotificationDatabase> database(CreateDatabaseInMemory()); |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->Open(true /* create_if_missing */)); |
+ |
+ int64_t notification_id = 0; |
+ |
+ NotificationDatabaseData database_data; |
+ GURL origin("https://example.com"); |
+ |
+ ASSERT_EQ(NotificationDatabase::STATUS_OK, |
+ database->WriteNotificationData(origin, |
+ database_data, |
+ ¬ification_id)); |
+ |
+ // Attempting to delete the notification with a different origin, but with the |
+ // same |notification_id|, should not return an error (the notification could |
+ // not be found, but that's not considered a failure). However, it should not |
+ // remove the notification either. |
+ EXPECT_EQ(NotificationDatabase::STATUS_OK, |
+ database->DeleteNotificationData(notification_id, |
+ GURL("https://chrome.com"))); |
+ |
+ EXPECT_EQ(NotificationDatabase::STATUS_OK, |
+ database->ReadNotificationData(notification_id, |
+ origin, |
+ &database_data)); |
} |
} // namespace content |