// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/notifications/notification_database.h"

#include <stddef.h>
#include <stdint.h>

#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "content/public/browser/notification_database_data.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/notifications/notification_resources.h"
#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "third_party/blink/public/mojom/notifications/notification.mojom.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 {

const int kExampleServiceWorkerRegistrationId = 42;

const struct {
  const char* origin;
  const char* tag;
  int64_t service_worker_registration_id;
} kExampleNotificationData[] = {
    {"https://example.com", "" /* tag */, 0},
    {"https://example.com", "" /* tag */, kExampleServiceWorkerRegistrationId},
    {"https://example.com", "" /* tag */, kExampleServiceWorkerRegistrationId},
    {"https://example.com", "" /* tag */,
     kExampleServiceWorkerRegistrationId + 1},
    {"https://chrome.com", "" /* tag */, 0},
    {"https://chrome.com", "" /* tag */, 0},
    {"https://chrome.com", "" /* tag */, kExampleServiceWorkerRegistrationId},
    {"https://chrome.com", "foo" /* tag */, 0}};

class NotificationDatabaseTest : public ::testing::Test {
 public:
  NotificationDatabaseTest()
      : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {}

 protected:
  // Creates a new NotificationDatabase instance in memory.
  NotificationDatabase* CreateDatabaseInMemory() {
    return new NotificationDatabase(base::FilePath(), callback());
  }

  // Creates a new NotificationDatabase instance in |path|.
  NotificationDatabase* CreateDatabaseOnFileSystem(const base::FilePath& path) {
    return new NotificationDatabase(path, callback());
  }

  // Creates a new notification for |service_worker_registration_id| belonging
  // to |origin| and writes it to the database. The written notification id
  // will be stored in |notification_id|.
  void CreateAndWriteNotification(NotificationDatabase* database,
                                  const GURL& origin,
                                  const std::string& tag,
                                  bool is_shown_by_browser,
                                  int64_t service_worker_registration_id,
                                  std::string* notification_id) {
    DCHECK(notification_id);

    NotificationDatabaseData database_data;
    database_data.notification_id = GenerateNotificationId();
    database_data.origin = origin;
    database_data.service_worker_registration_id =
        service_worker_registration_id;
    database_data.notification_data.tag = tag;
    database_data.is_shown_by_browser = is_shown_by_browser;

    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->WriteNotificationData(origin, database_data));

    *notification_id = database_data.notification_id;
  }

  // Populates |database| with a series of example notifications that differ in
  // their origin and Service Worker registration id.
  void PopulateDatabaseWithExampleData(NotificationDatabase* database) {
    std::string notification_id;
    for (const auto& notification_data : kExampleNotificationData) {
      ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
          database, GURL(notification_data.origin), notification_data.tag,
          false /* is_shown_by_browser */,
          notification_data.service_worker_registration_id, &notification_id));
    }
  }

  // Returns if |database| has been opened.
  bool IsDatabaseOpen(NotificationDatabase* database) {
    return database->IsOpen();
  }

  // Returns if |database| is an in-memory only database.
  bool IsInMemoryDatabase(NotificationDatabase* database) {
    return database->IsInMemoryDatabase();
  }

  // Writes a LevelDB key-value pair directly to the LevelDB backing the
  // notification database in |database|.
  void WriteLevelDBKeyValuePair(NotificationDatabase* database,
                                const std::string& key,
                                const std::string& value) {
    leveldb::Status status =
        database->GetDBForTesting()->Put(leveldb::WriteOptions(), key, value);
    ASSERT_TRUE(status.ok());
  }

  // Generates a random notification ID. The format of the ID is opaque.
  std::string GenerateNotificationId() { return base::GenerateGUID(); }

  NotificationDatabase::UkmCallback callback() { return callback_; }

  BrowserTaskEnvironment task_environment_;  // Must be first member.

  NotificationDatabase::UkmCallback callback_;
};

TEST_F(NotificationDatabaseTest, OpenCloseMemory) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());

  // Should return false because the database does not exist in memory.
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->Open(false /* create_if_missing */));

  // Should return true, indicating that the database could be created.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  EXPECT_TRUE(IsDatabaseOpen(database.get()));
  EXPECT_TRUE(IsInMemoryDatabase(database.get()));

  // Verify that in-memory databases do not persist when being re-created.
  database.reset(CreateDatabaseInMemory());

  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->Open(false /* create_if_missing */));
}

TEST_F(NotificationDatabaseTest, OpenCloseFileSystem) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());

  std::unique_ptr<NotificationDatabase> database(
      CreateDatabaseOnFileSystem(database_dir.GetPath()));

  // Should return false because the database does not exist on the file system.
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->Open(false /* create_if_missing */));

  // Should return true, indicating that the database could be created.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  EXPECT_TRUE(IsDatabaseOpen(database.get()));
  EXPECT_FALSE(IsInMemoryDatabase(database.get()));

  // Close the database, and re-open it without attempting to create it because
  // the files on the file system should still exist as expected.
  database.reset(CreateDatabaseOnFileSystem(database_dir.GetPath()));
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(false /* create_if_missing */));
}

TEST_F(NotificationDatabaseTest, DestroyDatabase) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());

  std::unique_ptr<NotificationDatabase> database(
      CreateDatabaseOnFileSystem(database_dir.GetPath()));

  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));
  EXPECT_TRUE(IsDatabaseOpen(database.get()));

  // Destroy the database. This will immediately close it as well.
  ASSERT_EQ(NotificationDatabase::STATUS_OK, database->Destroy());
  EXPECT_FALSE(IsDatabaseOpen(database.get()));

  // Try to re-open the database (but not re-create it). This should fail as
  // the files associated with the database should have been blown away.
  database.reset(CreateDatabaseOnFileSystem(database_dir.GetPath()));
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->Open(false /* create_if_missing */));
}

TEST_F(NotificationDatabaseTest, NotificationIdIncrements) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());

  std::unique_ptr<NotificationDatabase> database(
      CreateDatabaseOnFileSystem(database_dir.GetPath()));

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  std::string notification_id;
  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, "" /* tag */, false /* is_shown_by_browser */,
      0 /* sw_registration_id */, &notification_id));

  database.reset(CreateDatabaseOnFileSystem(database_dir.GetPath()));
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(false /* create_if_missing */));
}

TEST_F(NotificationDatabaseTest, NotificationIdIncrementsStorage) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  NotificationDatabaseData database_data, read_database_data;
  database_data.notification_id = GenerateNotificationId();

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationData(database_data.notification_id,
                                           origin, &read_database_data));

  EXPECT_EQ(database_data.notification_id, read_database_data.notification_id);
}

TEST_F(NotificationDatabaseTest, ReadInvalidNotificationData) {
  std::unique_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("bad-id", GURL("https://chrome.com"),
                                           &database_data));
}

TEST_F(NotificationDatabaseTest, ReadNotificationDataDifferentOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  NotificationDatabaseData database_data, read_database_data;
  database_data.notification_id = GenerateNotificationId();
  database_data.notification_data.title = u"My Notification";

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // 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(database_data.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(database_data.notification_id,
                                           origin, &read_database_data));

  EXPECT_EQ(database_data.notification_data.title,
            read_database_data.notification_data.title);
}

TEST_F(NotificationDatabaseTest, ReadNotificationDataReflection) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  blink::PlatformNotificationData notification_data;
  notification_data.title = u"My Notification";
  notification_data.direction =
      blink::mojom::NotificationDirection::RIGHT_TO_LEFT;
  notification_data.lang = "nl-NL";
  notification_data.body = u"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 = GenerateNotificationId();
  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));

  NotificationDatabaseData read_database_data;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationData(database_data.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 blink::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, ReadInvalidNotificationResources) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  blink::NotificationResources database_resources;

  // Reading the notification resources for a notification that does not exist
  // should return the ERROR_NOT_FOUND status code.
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadNotificationResources(
                "bad-id", GURL("https://chrome.com"), &database_resources));
}

TEST_F(NotificationDatabaseTest, ReadNotificationResourcesDifferentOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  NotificationDatabaseData database_data;
  blink::NotificationResources database_resources;
  database_data.notification_id = GenerateNotificationId();
  database_data.notification_data.title = u"My Notification";
  database_data.notification_resources = blink::NotificationResources();

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // Reading the notification resources from the database when given a different
  // origin should return the ERROR_NOT_FOUND status code.
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadNotificationResources(database_data.notification_id,
                                                GURL("https://chrome.com"),
                                                &database_resources));

  // However, reading the notification from the database with the same origin
  // should return STATUS_OK and the associated notification data.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationResources(database_data.notification_id,
                                                origin, &database_resources));
}

TEST_F(NotificationDatabaseTest, ReadNotificationResourcesReflection) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  blink::NotificationResources notification_resources;
  NotificationDatabaseData database_data;
  database_data.notification_id = GenerateNotificationId();
  database_data.origin = origin;
  database_data.service_worker_registration_id = 42;
  database_data.notification_resources = notification_resources;

  // 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));

  NotificationDatabaseData read_database_data;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationData(database_data.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);

  // We do not populate the resources when reading from the database.
  EXPECT_FALSE(read_database_data.notification_resources.has_value());

  blink::NotificationResources read_notification_resources;
  EXPECT_EQ(
      NotificationDatabase::STATUS_OK,
      database->ReadNotificationResources(database_data.notification_id, origin,
                                          &read_notification_resources));
}

TEST_F(NotificationDatabaseTest, ReadWriteMultipleNotificationData) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  std::vector<std::string> notification_ids;

  // 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) {
    std::string notification_id;
    ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
        database.get(), origin, "" /* tag */, false /* is_shown_by_browser */,
        i /* sw_registration_id */, &notification_id));

    EXPECT_FALSE(notification_id.empty());

    notification_ids.push_back(notification_id);
  }

  NotificationDatabaseData database_data;

  int64_t service_worker_registration_id = 1;

  // Read the ten notifications from the database, and verify that the titles
  // of each of them matches with how they were created.
  for (const std::string& notification_id : notification_ids) {
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->ReadNotificationData(notification_id, origin,
                                             &database_data));

    EXPECT_EQ(service_worker_registration_id++,
              database_data.service_worker_registration_id);
  }
}

TEST_F(NotificationDatabaseTest, ReadNotificationUpdateInteraction) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  NotificationDatabaseData database_data, read_database_data;
  database_data.notification_id = GenerateNotificationId();
  database_data.notification_data.title = u"My Notification";

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // Check that the time deltas have not yet been set.
  EXPECT_EQ(false,
            read_database_data.time_until_first_click_millis.has_value());
  EXPECT_EQ(false, read_database_data.time_until_last_click_millis.has_value());
  EXPECT_EQ(false, read_database_data.time_until_close_millis.has_value());

  // Check that when a notification has an interaction, the appropriate field is
  // updated on the read.
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationDataAndRecordInteraction(
                database_data.notification_id, origin,
                PlatformNotificationContext::Interaction::CLICKED,
                &read_database_data));
  EXPECT_EQ(1, read_database_data.num_clicks);

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationDataAndRecordInteraction(
                database_data.notification_id, origin,
                PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED,
                &read_database_data));
  EXPECT_EQ(1, read_database_data.num_action_button_clicks);

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationDataAndRecordInteraction(
                database_data.notification_id, origin,
                PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED,
                &read_database_data));
  EXPECT_EQ(2, read_database_data.num_action_button_clicks);

  // Check that the click timestamps are correctly updated.
  EXPECT_EQ(true, read_database_data.time_until_first_click_millis.has_value());
  EXPECT_EQ(true, read_database_data.time_until_last_click_millis.has_value());

  // Check that when a read with a CLOSED interaction occurs, the correct
  // field is updated.
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationDataAndRecordInteraction(
                database_data.notification_id, origin,
                PlatformNotificationContext::Interaction::CLOSED,
                &read_database_data));
  EXPECT_EQ(true, read_database_data.time_until_close_millis.has_value());
}

TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationData) {
  std::unique_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("bad-id", GURL("https://chrome.com")));
}

TEST_F(NotificationDatabaseTest, DeleteNotificationDataSameOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  const std::string notification_id = GenerateNotificationId();

  NotificationDatabaseData database_data;
  database_data.notification_id = notification_id;

  GURL origin("https://example.com");

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // 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, DeleteNotificationResourcesSameOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  const std::string notification_id = GenerateNotificationId();

  blink::NotificationResources notification_resources;
  NotificationDatabaseData database_data;
  database_data.notification_id = notification_id;
  database_data.notification_resources = notification_resources;

  GURL origin("https://example.com");

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // Reading notification resources after writing should succeed.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationResources(notification_id, origin,
                                                &notification_resources));

  // Delete the notification which was just written to the database, and verify
  // that reading the resources again will fail.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->DeleteNotificationData(notification_id, origin));
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadNotificationResources(notification_id, origin,
                                                &notification_resources));
}

TEST_F(NotificationDatabaseTest, DeleteNotificationDataDifferentOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  const std::string notification_id = GenerateNotificationId();

  NotificationDatabaseData database_data;
  database_data.notification_id = notification_id;

  GURL origin("https://example.com");

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // 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));
}

TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationResources) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  // Deleting non-existing resources is not considered to be a failure.
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->DeleteNotificationResources("bad-id",
                                                  GURL("https://chrome.com")));
}

TEST_F(NotificationDatabaseTest, DeleteNotificationResources) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  const std::string notification_id = GenerateNotificationId();

  blink::NotificationResources notification_resources;
  NotificationDatabaseData database_data;
  database_data.notification_id = notification_id;
  database_data.notification_resources = notification_resources;

  GURL origin("https://example.com");

  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->WriteNotificationData(origin, database_data));

  // Reading notification resources after writing should succeed.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadNotificationResources(notification_id, origin,
                                                &notification_resources));

  // Delete the notification resources for the notification which was just
  // written to the database, and verify that reading them again will fail.
  EXPECT_EQ(NotificationDatabase::STATUS_OK,
            database->DeleteNotificationResources(notification_id, origin));
  EXPECT_EQ(NotificationDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadNotificationResources(notification_id, origin,
                                                &notification_resources));
}

TEST_F(NotificationDatabaseTest,
       ForEachNotificationDataForServiceWorkerRegistration) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get()));

  GURL origin("https://example.com:443");

  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ForEachNotificationDataForServiceWorkerRegistration(
                origin, kExampleServiceWorkerRegistrationId,
                base::BindLambdaForTesting(
                    [&notifications](const NotificationDatabaseData& data) {
                      notifications.push_back(data);
                    })));

  EXPECT_EQ(2u, notifications.size());
}

TEST_F(NotificationDatabaseTest, ReadAllNotificationDataForOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get()));

  GURL origin("https://example.com");

  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForOrigin(origin, &notifications));

  EXPECT_EQ(4u, notifications.size());
}

TEST_F(NotificationDatabaseTest,
       ReadAllNotificationDataForServiceWorkerRegistration) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get()));

  GURL origin("https://example.com:443");

  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForServiceWorkerRegistration(
                origin, kExampleServiceWorkerRegistrationId,
                absl::nullopt /* is_shown_by_browser */, &notifications));

  EXPECT_EQ(2u, notifications.size());
}

TEST_F(NotificationDatabaseTest,
       ReadAllNotificationDataForServiceWorkerRegistrationShownByBrowser) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));
  GURL origin("https://example.com:443");
  std::string kTag = "tag";

  std::string non_browser_notification_id;
  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, kTag, false /* is_shown_by_browser */,
      kExampleServiceWorkerRegistrationId, &non_browser_notification_id));

  std::string browser_notification_id;
  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, kTag, true /* is_shown_by_browser */,
      kExampleServiceWorkerRegistrationId, &browser_notification_id));

  {
    // Expect to be able to read notification shown by the browser.
    std::vector<NotificationDatabaseData> notifications;
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->ReadAllNotificationDataForServiceWorkerRegistration(
                  origin, kExampleServiceWorkerRegistrationId,
                  true /* is_shown_by_browser */, &notifications));
    ASSERT_EQ(1u, notifications.size());
    EXPECT_EQ(browser_notification_id, notifications[0].notification_id);
  }

  {
    // Expect to be able to read notification not shown by the browser.
    std::vector<NotificationDatabaseData> notifications;
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->ReadAllNotificationDataForServiceWorkerRegistration(
                  origin, kExampleServiceWorkerRegistrationId,
                  false /* is_shown_by_browser */, &notifications));
    ASSERT_EQ(1u, notifications.size());
    EXPECT_EQ(non_browser_notification_id, notifications[0].notification_id);
  }

  {
    // Expect to be able to read notification not shown by anyone.
    std::vector<NotificationDatabaseData> notifications;
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->ReadAllNotificationDataForServiceWorkerRegistration(
                  origin, kExampleServiceWorkerRegistrationId,
                  absl::nullopt /* is_shown_by_browser */, &notifications));
    ASSERT_EQ(2u, notifications.size());
  }
}

TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOrigin) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get()));

  GURL origin("https://example.com:443");

  std::set<std::string> deleted_notification_ids;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->DeleteAllNotificationDataForOrigin(
                origin, "" /* tag */, absl::nullopt /* is_shown_by_browser */,
                &deleted_notification_ids));

  EXPECT_EQ(4u, deleted_notification_ids.size());

  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForOrigin(origin, &notifications));

  EXPECT_EQ(0u, notifications.size());
}

TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOriginWithTag) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get()));

  GURL origin("https://chrome.com");

  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForOrigin(origin, &notifications));

  const std::string& tag = "foo";

  size_t notifications_with_tag = 0;
  size_t notifications_without_tag = 0;

  for (const auto& database_data : notifications) {
    if (database_data.notification_data.tag == tag)
      ++notifications_with_tag;
    else
      ++notifications_without_tag;
  }

  ASSERT_GT(notifications_with_tag, 0u);
  ASSERT_GT(notifications_without_tag, 0u);

  std::set<std::string> deleted_notification_ids;
  ASSERT_EQ(
      NotificationDatabase::STATUS_OK,
      database->DeleteAllNotificationDataForOrigin(
          origin, "foo" /* tag */, absl::nullopt /* is_shown_by_browser */,
          &deleted_notification_ids));

  EXPECT_EQ(notifications_with_tag, deleted_notification_ids.size());

  std::vector<NotificationDatabaseData> updated_notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForOrigin(origin,
                                                       &updated_notifications));

  EXPECT_EQ(notifications_without_tag, updated_notifications.size());

  size_t updated_notifications_with_tag = 0;
  size_t updated_notifications_without_tag = 0;

  for (const auto& database_data : updated_notifications) {
    if (database_data.notification_data.tag == tag)
      ++updated_notifications_with_tag;
    else
      ++updated_notifications_without_tag;
  }

  EXPECT_EQ(0u, updated_notifications_with_tag);
  EXPECT_EQ(notifications_without_tag, updated_notifications_without_tag);
}

TEST_F(NotificationDatabaseTest, DeleteAllNotificationDataForOriginEmpty) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  GURL origin("https://example.com");

  std::set<std::string> deleted_notification_ids;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->DeleteAllNotificationDataForOrigin(
                origin, "" /* tag */, absl::nullopt /* is_shown_by_browser */,
                &deleted_notification_ids));

  EXPECT_EQ(0u, deleted_notification_ids.size());
}

TEST_F(NotificationDatabaseTest,
       DeleteAllNotificationDataForOriginShownByBrowser) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));
  GURL origin("https://example.com:443");
  std::string kTag = "tag";

  std::string non_browser_notification_id;
  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, kTag, false /* is_shown_by_browser */,
      kExampleServiceWorkerRegistrationId, &non_browser_notification_id));

  std::string browser_notification_id;
  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, kTag, true /* is_shown_by_browser */,
      kExampleServiceWorkerRegistrationId, &browser_notification_id));

  {
    // Expect two notifications in the database for |origin|.
    std::vector<NotificationDatabaseData> notifications;
    ASSERT_EQ(
        NotificationDatabase::STATUS_OK,
        database->ReadAllNotificationDataForOrigin(origin, &notifications));
    EXPECT_EQ(2u, notifications.size());
  }

  {
    // Expect to be able to delete only notifications from the browser.
    std::set<std::string> deleted_notification_ids;
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->DeleteAllNotificationDataForOrigin(
                  origin, kTag, true /* is_shown_by_browser */,
                  &deleted_notification_ids));
    EXPECT_EQ(1u, deleted_notification_ids.size());
    EXPECT_EQ(1u, deleted_notification_ids.count(browser_notification_id));
  }

  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, kTag, true /* is_shown_by_browser */,
      kExampleServiceWorkerRegistrationId, &browser_notification_id));

  {
    // Expect to be able to delete only notifications not from the browser.
    std::set<std::string> deleted_notification_ids;
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->DeleteAllNotificationDataForOrigin(
                  origin, kTag, false /* is_shown_by_browser */,
                  &deleted_notification_ids));
    EXPECT_EQ(1u, deleted_notification_ids.size());
    EXPECT_EQ(1u, deleted_notification_ids.count(non_browser_notification_id));
  }

  ASSERT_NO_FATAL_FAILURE(CreateAndWriteNotification(
      database.get(), origin, kTag, false /* is_shown_by_browser */,
      kExampleServiceWorkerRegistrationId, &non_browser_notification_id));

  {
    // Expect to be able to delete notifications from the browser or not.
    std::set<std::string> deleted_notification_ids;
    ASSERT_EQ(NotificationDatabase::STATUS_OK,
              database->DeleteAllNotificationDataForOrigin(
                  origin, kTag, absl::nullopt /* is_shown_by_browser */,
                  &deleted_notification_ids));
    EXPECT_EQ(2u, deleted_notification_ids.size());
    EXPECT_EQ(1u, deleted_notification_ids.count(browser_notification_id));
    EXPECT_EQ(1u, deleted_notification_ids.count(non_browser_notification_id));
  }

  // Expect no remaining notifications.
  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForOrigin(origin, &notifications));
  EXPECT_EQ(0u, notifications.size());
}

TEST_F(NotificationDatabaseTest,
       DeleteAllNotificationDataForServiceWorkerRegistration) {
  std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->Open(true /* create_if_missing */));

  ASSERT_NO_FATAL_FAILURE(PopulateDatabaseWithExampleData(database.get()));

  GURL origin("https://example.com:443");
  std::set<std::string> deleted_notification_ids;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->DeleteAllNotificationDataForServiceWorkerRegistration(
                origin, kExampleServiceWorkerRegistrationId,
                &deleted_notification_ids));

  EXPECT_EQ(2u, deleted_notification_ids.size());

  std::vector<NotificationDatabaseData> notifications;
  ASSERT_EQ(NotificationDatabase::STATUS_OK,
            database->ReadAllNotificationDataForServiceWorkerRegistration(
                origin, kExampleServiceWorkerRegistrationId,
                absl::nullopt /* is_shown_by_browser */, &notifications));

  EXPECT_EQ(0u, notifications.size());
}

}  // namespace content
