// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "peridot/bin/sessionmgr/storage/story_storage.h"

#include <memory>

#include <lib/async/cpp/future.h>
#include <lib/fsl/vmo/strings.h>

#include "gtest/gtest.h"
#include "peridot/lib/entity/entity_watcher_impl.h"
#include "peridot/lib/ledger_client/page_id.h"
#include "peridot/lib/testing/test_with_ledger.h"

using fuchsia::modular::ModuleData;
using fuchsia::modular::ModuleDataPtr;

namespace modular {
namespace {

class StoryStorageTest : public testing::TestWithLedger {
 protected:
  std::unique_ptr<StoryStorage> CreateStorage(std::string page_id) {
    return std::make_unique<StoryStorage>(ledger_client(), MakePageId(page_id));
  }
};

ModuleData Clone(const ModuleData& data) {
  ModuleData dup;
  data.Clone(&dup);
  return dup;
}

TEST_F(StoryStorageTest, ReadModuleData_NonexistentModule) {
  auto storage = CreateStorage("page");

  bool read_done{};
  std::vector<std::string> path;
  path.push_back("a");
  storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
    read_done = true;
    ASSERT_FALSE(data);
  });

  RunLoopUntil([&] { return read_done; });
}

TEST_F(StoryStorageTest, ReadAllModuleData_Empty) {
  auto storage = CreateStorage("page");

  bool read_done{};
  fidl::VectorPtr<ModuleData> all_module_data;
  storage->ReadAllModuleData()->Then([&](std::vector<ModuleData> data) {
    read_done = true;
    all_module_data.reset(std::move(data));
  });

  RunLoopUntil([&] { return read_done; });
  ASSERT_TRUE(all_module_data);
  EXPECT_EQ(0u, all_module_data->size());
}

TEST_F(StoryStorageTest, WriteReadModuleData) {
  // Write and then read some ModuleData entries. We expect to get the same data
  // back.
  auto storage = CreateStorage("page");

  int notification_count{0};
  storage->set_on_module_data_updated(
      [&](ModuleData) { notification_count++; });

  ModuleData module_data1;
  module_data1.module_url = "url1";
  module_data1.module_path.push_back("path1");
  storage->WriteModuleData(Clone(module_data1));

  ModuleData module_data2;
  module_data2.module_url = "url2";
  module_data2.module_path.push_back("path2");
  storage->WriteModuleData(Clone(module_data2));

  // We don't need to explicitly wait on WriteModuleData() because the
  // implementation: 1) serializes all storage operations and 2) guarantees the
  // WriteModuleData() action is finished only once the data has been written.
  ModuleData read_data1;
  bool read1_done{};
  storage->ReadModuleData(module_data1.module_path)
      ->Then([&](ModuleDataPtr data) {
        read1_done = true;
        ASSERT_TRUE(data);
        read_data1 = std::move(*data);
      });

  ModuleData read_data2;
  bool read2_done{};
  storage->ReadModuleData(module_data2.module_path)
      ->Then([&](ModuleDataPtr data) {
        read2_done = true;
        ASSERT_TRUE(data);
        read_data2 = std::move(*data);
      });

  RunLoopUntil([&] { return read1_done && read2_done; });
  EXPECT_EQ(module_data1, read_data1);
  EXPECT_EQ(module_data2, read_data2);

  // Read the same data back with ReadAllModuleData().
  fidl::VectorPtr<ModuleData> all_module_data;
  storage->ReadAllModuleData()->Then([&](std::vector<ModuleData> data) {
    all_module_data.reset(std::move(data));
  });
  RunLoopUntil([&] { return !!all_module_data; });
  EXPECT_EQ(2u, all_module_data->size());
  EXPECT_EQ(module_data1, all_module_data->at(0));
  EXPECT_EQ(module_data2, all_module_data->at(1));

  // We should get a notification every time module data is updated.
  EXPECT_EQ(2, notification_count);
}

TEST_F(StoryStorageTest, UpdateModuleData) {
  // Call UpdateModuleData() on a record that doesn't exist yet.
  auto storage = CreateStorage("page");

  // We're going to observe changes on another storage instance, which
  // simulates another device.
  auto other_storage = CreateStorage("page");
  bool got_notification{};
  ModuleData notified_module_data;
  other_storage->set_on_module_data_updated([&](ModuleData data) {
    got_notification = true;
    notified_module_data = std::move(data);
  });

  std::vector<std::string> path;
  path.push_back("a");

  // Case 1: Don't mutate anything.
  bool update_done{};
  storage
      ->UpdateModuleData(path, [](ModuleDataPtr* ptr) { EXPECT_FALSE(*ptr); })
      ->Then([&] { update_done = true; });
  RunLoopUntil([&] { return update_done; });

  bool read_done{};
  ModuleData read_data;
  storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
    read_done = true;
    EXPECT_FALSE(data);
  });
  RunLoopUntil([&] { return read_done; });
  // Since nothing changed, we should not have seen a notification.
  EXPECT_FALSE(got_notification);

  // Case 2: Initialize an otherwise empty record.
  update_done = false;
  storage
      ->UpdateModuleData(path,
                         [&](ModuleDataPtr* ptr) {
                           EXPECT_FALSE(*ptr);

                           *ptr = ModuleData::New();
                           (*ptr)->module_path = path;
                           (*ptr)->module_url = "foobar";
                         })
      ->Then([&] { update_done = true; });
  RunLoopUntil([&] { return update_done; });

  read_done = false;
  storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
    read_done = true;
    ASSERT_TRUE(data);
    EXPECT_EQ(path, data->module_path);
    EXPECT_EQ("foobar", data->module_url);
  });
  RunLoopUntil([&] { return read_done; });
  // Now something changed, so we should see a notification.
  EXPECT_TRUE(got_notification);
  EXPECT_EQ("foobar", notified_module_data.module_url);

  // Case 3: Leave alone an existing record.
  got_notification = false;
  storage->UpdateModuleData(path,
                            [&](ModuleDataPtr* ptr) { EXPECT_TRUE(*ptr); });

  read_done = false;
  storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
    read_done = true;
    ASSERT_TRUE(data);
    EXPECT_EQ("foobar", data->module_url);
  });
  RunLoopUntil([&] { return read_done; });
  // Now something changed, so we should see a notification.
  EXPECT_FALSE(got_notification);

  // Case 4: Mutate an existing record.
  storage->UpdateModuleData(path, [&](ModuleDataPtr* ptr) {
    EXPECT_TRUE(*ptr);
    (*ptr)->module_url = "baz";
  });

  read_done = false;
  storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
    read_done = true;
    ASSERT_TRUE(data);
    EXPECT_EQ("baz", data->module_url);
  });
  RunLoopUntil([&] { return read_done; });
  // Now something changed, so we should see a notification.
  EXPECT_TRUE(got_notification);
  EXPECT_EQ("baz", notified_module_data.module_url);
}

namespace {
LinkPath MakeLinkPath(const std::string& name) {
  LinkPath path;
  path.link_name = name;
  return path;
}
}  // namespace

TEST_F(StoryStorageTest, GetLink_Null) {
  auto storage = CreateStorage("page");

  // Default for an un-set Link is to get a "null" back.
  bool get_done{};
  fidl::StringPtr value;
  storage->GetLinkValue(MakeLinkPath("link"))
      ->Then([&](StoryStorage::Status status, fidl::StringPtr v) {
        EXPECT_EQ(StoryStorage::Status::OK, status);
        value = v;
        get_done = true;
      });
  RunLoopUntil([&] { return get_done; });
  EXPECT_EQ("null", value);
}

TEST_F(StoryStorageTest, UpdateLinkValue) {
  auto storage = CreateStorage("page");

  // Let's set a value.
  int mutate_count{0};
  int context;
  storage
      ->UpdateLinkValue(MakeLinkPath("link"),
                        [](fidl::StringPtr* current_value) {
                          EXPECT_TRUE(current_value->is_null());
                          *current_value = "10";
                        },
                        &context)
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(StoryStorage::Status::OK, status);
        ++mutate_count;
      });

  // If we mutate again, we should see the old value.
  storage
      ->UpdateLinkValue(MakeLinkPath("link"),
                        [](fidl::StringPtr* current_value) {
                          EXPECT_EQ("10", *current_value);
                          *current_value = "20";
                        },
                        &context)
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(StoryStorage::Status::OK, status);
        ++mutate_count;
      });

  // Now let's fetch it and see the newest value.
  bool get_done{};
  fidl::StringPtr value;
  storage->GetLinkValue(MakeLinkPath("link"))
      ->Then([&](StoryStorage::Status status, fidl::StringPtr v) {
        EXPECT_EQ(StoryStorage::Status::OK, status);
        value = v;
        get_done = true;
      });
  RunLoopUntil([&] { return get_done; });

  EXPECT_EQ(2, mutate_count);
  EXPECT_EQ("20", value);
}

TEST_F(StoryStorageTest, WatchingLink_IgnoresOthers) {
  // When we watch a link, we should see changes only for that link.
  auto storage = CreateStorage("page");

  // We'll be watching "foo", but updating "bar".
  int notified_count{0};
  auto cancel =
      storage->WatchLink(MakeLinkPath("foo"),
                         [&](const fidl::StringPtr& value,
                             const void* /* context */) { ++notified_count; });

  bool mutate_done{};
  int context;
  storage
      ->UpdateLinkValue(MakeLinkPath("bar"),
                        [](fidl::StringPtr* value) { *value = "10"; }, &context)
      ->Then([&](StoryStorage::Status status) { mutate_done = true; });
  RunLoopUntil([&] { return mutate_done; });
  EXPECT_EQ(0, notified_count);
}

TEST_F(StoryStorageTest, WatchingLink_IgnoresNoopUpdates) {
  // When we watch a link, we should see changes only for that link.
  auto storage = CreateStorage("page");

  int notified_count{0};
  auto cancel =
      storage->WatchLink(MakeLinkPath("foo"),
                         [&](const fidl::StringPtr& value,
                             const void* /* context */) { ++notified_count; });

  bool mutate_done{};
  int context;
  storage
      ->UpdateLinkValue(MakeLinkPath("foo"),
                        [](fidl::StringPtr* value) { /* do nothing */ },
                        &context)
      ->Then([&](StoryStorage::Status status) { mutate_done = true; });
  RunLoopUntil([&] { return mutate_done; });
  EXPECT_EQ(0, notified_count);
}

TEST_F(StoryStorageTest, WatchingLink_SeesUpdates) {
  // When we make changes to Link values, we should see those changes in our
  // observation functions. When we cancel the observer, we shouldn't see any
  // more notifications.
  auto storage = CreateStorage("page");

  // We'll tell StoryStorage to stop notifying us about "bar" later by using
  // |bar_cancel|.
  int notified_count{0};
  fidl::StringPtr notified_value;
  const void* notified_context;
  auto watch_cancel = storage->WatchLink(
      MakeLinkPath("bar"),
      [&](const fidl::StringPtr& value, const void* context) {
        ++notified_count;
        notified_value = value;
        notified_context = context;
      });

  // Change "bar"'s value to "10".
  bool mutate_done{};
  int context;
  storage
      ->UpdateLinkValue(MakeLinkPath("bar"),
                        [](fidl::StringPtr* value) { *value = "10"; }, &context)
      ->Then([&](StoryStorage::Status status) { mutate_done = true; });
  RunLoopUntil([&] { return mutate_done; });
  EXPECT_EQ(1, notified_count);
  EXPECT_EQ("10", notified_value);
  EXPECT_EQ(&context, notified_context);

  // Change it two more times. We expect to be notified of the first one, but
  // not the second because we are going to cancel our watcher.
  storage
      ->UpdateLinkValue(MakeLinkPath("bar"),
                        [](fidl::StringPtr* value) { *value = "20"; }, &context)
      ->Then([&](StoryStorage::Status status) {
        watch_cancel.call();  // Remove the watcher for bar.
      });

  mutate_done = false;
  storage
      ->UpdateLinkValue(MakeLinkPath("bar"),
                        [](fidl::StringPtr* value) { *value = "30"; }, &context)
      ->Then([&](StoryStorage::Status status) { mutate_done = true; });
  RunLoopUntil([&] { return mutate_done; });

  EXPECT_EQ(2, notified_count);
  EXPECT_EQ("20", notified_value);
  EXPECT_EQ(&context, notified_context);
}

TEST_F(StoryStorageTest, WatchingOtherStorageInstance) {
  // Observations made on other StoryStorage instances get a special nullptr
  // context.
  auto storage = CreateStorage("page");

  auto other_storage = CreateStorage("page");

  int notified_count{0};
  fidl::StringPtr notified_value;
  const void* notified_context;
  auto watch_cancel = other_storage->WatchLink(
      MakeLinkPath("foo"),
      [&](const fidl::StringPtr& value, const void* context) {
        ++notified_count;
        notified_value = value;
        notified_context = context;
        return true;
      });

  int context;
  storage->UpdateLinkValue(MakeLinkPath("foo"),
                           [](fidl::StringPtr* value) { *value = "10"; },
                           &context);

  RunLoopUntil([&] { return notified_count > 0; });
  EXPECT_EQ(1, notified_count);
  EXPECT_EQ("10", notified_value);
  EXPECT_EQ(nullptr, notified_context);
}

// Creates an entity with a valid type and data and verifies they are returned
// as expected.
TEST_F(StoryStorageTest, CreateAndReadEntity) {
  auto storage = CreateStorage("page");
  std::string cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });

  bool read_entity_type{};
  storage->GetEntityType(cookie)->Then(
      [&](StoryStorage::Status status, std::string type) {
        EXPECT_EQ(type, expected_type);
        read_entity_type = true;
      });
  RunLoopUntil([&] { return read_entity_type; });

  bool read_entity_data{};
  storage->GetEntityData(cookie, expected_type)
      ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
        EXPECT_TRUE(buffer);
        std::string read_data;
        EXPECT_TRUE(fsl::StringFromVmo(*buffer, &read_data));
        EXPECT_EQ(read_data, data_string);
        read_entity_data = true;
      });
  RunLoopUntil([&] { return read_entity_data; });
}

// Creates an entity with a valid type and data and attempts to get the data of
// a different type.
TEST_F(StoryStorageTest, CreateAndReadEntityIncorrectType) {
  auto storage = CreateStorage("page");
  std::string cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });

  bool read_entity_data{};
  storage->GetEntityData(cookie, expected_type + expected_type)
      ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
        EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_TYPE);
        read_entity_data = true;
      });
  RunLoopUntil([&] { return read_entity_data; });
}

// Creates an entity with a valid type and data and attempts to get the data of
// a different cookie.
TEST_F(StoryStorageTest, CreateAndReadEntityIncorrectCookie) {
  auto storage = CreateStorage("page");
  std::string cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });

  bool read_entity_data{};
  storage->GetEntityData(cookie + cookie, expected_type)
      ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
        EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_COOKIE);
        read_entity_data = true;
      });
  RunLoopUntil([&] { return read_entity_data; });
}

// Attempts to create an entity with an empty type and verifies it fails.
TEST_F(StoryStorageTest, CreateEntityWithEmptyType) {
  auto storage = CreateStorage("page");
  std::string cookie = "cookie";
  std::string expected_type = "";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_TYPE);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });
}

// Attempts to create an entity with an empty cookie and verifies it fails.
TEST_F(StoryStorageTest, CreateEntityWithEmptyCookie) {
  auto storage = CreateStorage("page");
  std::string cookie = "";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_COOKIE);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });
}

// Creates an entity and performs a second write with a different type, and
// verifies the second write fails and that the second attempted write doesn't
// corrupt the data.
TEST_F(StoryStorageTest, WriteEntityDataWithIncorrectType) {
  auto storage = CreateStorage("page");
  std::string cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";
  std::string incorrect_type = "com.fuchsia.test.incorrect.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });

  bool wrote_entity{};
  storage->SetEntityData(cookie, incorrect_type, fuchsia::mem::Buffer())
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_TYPE);
        wrote_entity = true;
      });
  RunLoopUntil([&] { return wrote_entity; });

  // Verify that the second write didn't mess up the data or type.
  bool read_entity_type{};
  storage->GetEntityType(cookie)->Then(
      [&](StoryStorage::Status status, std::string type) {
        EXPECT_EQ(type, expected_type);
        read_entity_type = true;
      });
  RunLoopUntil([&] { return read_entity_type; });

  bool read_entity_data{};
  storage->GetEntityData(cookie, expected_type)
      ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
        EXPECT_TRUE(buffer);
        std::string read_data;
        EXPECT_TRUE(fsl::StringFromVmo(*buffer, &read_data));
        EXPECT_EQ(read_data, data_string);
        read_entity_data = true;
      });
  RunLoopUntil([&] { return read_entity_data; });
}

// Creates an entity and performs a second write with the same type, and
// verifies the data is written correctly.
TEST_F(StoryStorageTest, WriteToEntityTwice) {
  auto storage = CreateStorage("page");
  std::string cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  std::string second_data_string = "more_test_data";
  fuchsia::mem::Buffer second_buffer;
  FXL_CHECK(fsl::VmoFromString(second_data_string, &second_buffer));

  bool created_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });

  bool wrote_entity{};
  storage->SetEntityData(cookie, expected_type, std::move(second_buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        wrote_entity = true;
      });
  RunLoopUntil([&] { return wrote_entity; });

  // Verify that the second write successfully updated the data.
  bool read_entity_type{};
  storage->GetEntityType(cookie)->Then(
      [&](StoryStorage::Status status, std::string type) {
        EXPECT_EQ(type, expected_type);
        read_entity_type = true;
      });
  RunLoopUntil([&] { return read_entity_type; });

  bool read_entity_data{};
  storage->GetEntityData(cookie, expected_type)
      ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
        EXPECT_TRUE(buffer);
        std::string read_data;
        EXPECT_TRUE(fsl::StringFromVmo(*buffer, &read_data));
        EXPECT_EQ(read_data, second_data_string);
        read_entity_data = true;
      });
  RunLoopUntil([&] { return read_entity_data; });
}

// Creates an entity with a watcher and verifies that updates to the entity are
// delivered to the watcher.
TEST_F(StoryStorageTest, WatchEntityData) {
  auto storage = CreateStorage("page");
  std::string expected_cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool saw_entity_update{};
  bool saw_entity_update_with_no_data{};
  auto watcher_impl =
      EntityWatcherImpl([&](std::unique_ptr<fuchsia::mem::Buffer> value) {
        // Verify that the first callback is called with no data, since the
        // entity data has yet to be set.
        if (!value && !saw_entity_update_with_no_data) {
          saw_entity_update_with_no_data = true;
          return;
        }

        ASSERT_TRUE(value) << "Saw multiple empty entity updates.";

        std::string read_data;
        EXPECT_TRUE(fsl::StringFromVmo(*value, &read_data));
        EXPECT_EQ(read_data, data_string);

        saw_entity_update = true;
      });

  fuchsia::modular::EntityWatcherPtr watcher_ptr;
  watcher_impl.Connect(watcher_ptr.NewRequest());

  storage->WatchEntity(expected_cookie, expected_type, std::move(watcher_ptr));

  bool created_entity{};
  storage->SetEntityData(expected_cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });
  RunLoopUntil([&] { return saw_entity_update; });
  EXPECT_TRUE(saw_entity_update_with_no_data);
}

// Creates an entity with multiple watchers and verifies that updates to the
// entity are delivered to all watchers.
TEST_F(StoryStorageTest, WatchEntityDataMultipleWatchers) {
  auto storage = CreateStorage("page");
  std::string expected_cookie = "cookie";
  std::string expected_type = "com.fuchsia.test.type";

  std::string data_string = "test_data";
  fuchsia::mem::Buffer buffer;
  FXL_CHECK(fsl::VmoFromString(data_string, &buffer));

  bool saw_entity_update{};
  auto watcher_impl =
      EntityWatcherImpl([&](std::unique_ptr<fuchsia::mem::Buffer> value) {
        if (!value) {
          // The first update may not contain any data, so skip it.
          return;
        }

        std::string read_data;
        EXPECT_TRUE(fsl::StringFromVmo(*value, &read_data));
        EXPECT_EQ(read_data, data_string);

        saw_entity_update = true;
      });

  fuchsia::modular::EntityWatcherPtr watcher_ptr;
  watcher_impl.Connect(watcher_ptr.NewRequest());
  storage->WatchEntity(expected_cookie, expected_type, std::move(watcher_ptr));

  bool saw_entity_update_too{};
  auto second_watcher_impl =
      EntityWatcherImpl([&](std::unique_ptr<fuchsia::mem::Buffer> value) {
        if (!value) {
          // The first update may not contain any data, so skip it.
          return;
        }

        std::string read_data;
        EXPECT_TRUE(fsl::StringFromVmo(*value, &read_data));
        EXPECT_EQ(read_data, data_string);

        saw_entity_update_too = true;
      });

  fuchsia::modular::EntityWatcherPtr second_watcher_ptr;
  second_watcher_impl.Connect(second_watcher_ptr.NewRequest());
  storage->WatchEntity(expected_cookie, expected_type,
                       std::move(second_watcher_ptr));

  bool created_entity{};
  storage->SetEntityData(expected_cookie, expected_type, std::move(buffer))
      ->Then([&](StoryStorage::Status status) {
        EXPECT_EQ(status, StoryStorage::Status::OK);
        created_entity = true;
      });
  RunLoopUntil([&] { return created_entity; });
  RunLoopUntil([&] { return saw_entity_update && saw_entity_update_too; });
}

// Creates a name for a given Entity cookie and verifies it is retrieved
// successfully.
TEST_F(StoryStorageTest, NameEntity) {
  auto storage = CreateStorage("page");
  std::string expected_cookie = "cookie";
  std::string expected_name = "the best entity";

  storage->SetEntityName(expected_cookie, expected_name);

  bool did_get_cookie{};
  storage->GetEntityCookieForName(expected_name)
      ->Then([&](StoryStorage::Status status, const std::string& cookie) {
        EXPECT_EQ(cookie, expected_cookie);
        did_get_cookie = true;
      });
  RunLoopUntil([&] { return did_get_cookie; });
}

}  // namespace
}  // namespace modular
