#include "data_fake.h"
#include <cstdint>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <gtest/gtest.h>
namespace
{
Card makeCard(
std::int64_t id,
std::optional<std::string> game_short_name,
std::uint64_t card_number,
std::string name)
{
return {
id,
{std::move(game_short_name), card_number},
std::move(name),
std::nullopt,
std::nullopt,
0,
"avif",
std::nullopt,
"avif",
1,
};
}
} // namespace
/// Verify configured card records can be read by identity.
TEST(DataSourceFakeTest, ReturnsCards)
{
DataSourceFake data_source({
makeCard(1, std::nullopt, 10, "Loose card"),
makeCard(2, "test", 3, "Game card"),
});
const auto cards = data_source.getCards(
GameContentScope::INCLUDE_INTERNAL);
ASSERT_TRUE(cards);
ASSERT_EQ(cards->size(), 2U);
const auto card = data_source.getCard(
{"test", 3}, GameContentScope::INCLUDE_INTERNAL);
ASSERT_TRUE(card);
ASSERT_TRUE(*card);
EXPECT_EQ((*card)->name, "Game card");
const auto missing = data_source.getCard(
{"test", 4}, GameContentScope::INCLUDE_INTERNAL);
ASSERT_TRUE(missing);
EXPECT_FALSE(*missing);
}
/// Verify series data, memberships, and game definitions are deterministic.
TEST(DataSourceFakeTest, ReturnsRelatedData)
{
DataSourceFake data_source(
{makeCard(2, "test", 3, "Game card")},
{{7, "test", "First series", "Description"}},
{{2, {7}}},
{{{"test", "Test Game", "", GameVisibility::PUBLIC, 1}, {}}});
const auto memberships = data_source.getCardSeries(2);
ASSERT_TRUE(memberships);
EXPECT_EQ(*memberships, std::vector<std::int64_t>({7}));
const auto games = data_source.getGames(
GameContentScope::INCLUDE_INTERNAL);
ASSERT_TRUE(games);
ASSERT_EQ(games->size(), 1);
EXPECT_EQ(games->front().short_name, "test");
}
/// Verify equal display names use the permanent short name as a tie-breaker.
TEST(DataSourceFakeTest, SortsGamesDeterministically)
{
DataSourceFake data_source(
{},
{},
{},
{
{{"z", "Same", "", GameVisibility::PUBLIC, 1}, {}},
{{"a", "Same", "", GameVisibility::PUBLIC, 1}, {}},
});
const auto games = data_source.getGames(
GameContentScope::INCLUDE_INTERNAL);
ASSERT_TRUE(games);
ASSERT_EQ(games->size(), 2);
EXPECT_EQ((*games)[0].short_name, "a");
EXPECT_EQ((*games)[1].short_name, "z");
}
TEST(DataSourceFakeTest, FiltersInternalGameContent)
{
DataSourceFake data_source(
{
makeCard(1, std::nullopt, 1, "Loose"),
makeCard(2, "public", 1, "Public"),
makeCard(3, "internal", 1, "Internal"),
},
{
{1, "public", "Public series", ""},
{2, "internal", "Internal series", ""},
},
{},
{
{{"public", "Public", "", GameVisibility::PUBLIC, 1}, {}},
{{"internal", "Internal", "", GameVisibility::INTERNAL, 1},
{}},
});
auto cards = data_source.getCards(GameContentScope::PUBLIC_ONLY);
ASSERT_TRUE(cards);
ASSERT_EQ(cards->size(), 2);
EXPECT_EQ((*cards)[0].name, "Loose");
EXPECT_EQ((*cards)[1].name, "Public");
auto hidden = data_source.getCard(
{"internal", 1}, GameContentScope::PUBLIC_ONLY);
ASSERT_TRUE(hidden);
EXPECT_FALSE(*hidden);
auto games = data_source.getGames(GameContentScope::PUBLIC_ONLY);
ASSERT_TRUE(games);
ASSERT_EQ(games->size(), 1);
EXPECT_EQ(games->front().short_name, "public");
auto series = data_source.getSeries(GameContentScope::PUBLIC_ONLY);
ASSERT_TRUE(series);
ASSERT_EQ(series->size(), 1);
EXPECT_EQ(series->front().game_short_name, "public");
}
/// Verify development data cannot accidentally be mutated.
TEST(DataSourceFakeTest, RejectsMutations)
{
DataSourceFake data_source;
const auto transaction = data_source.beginTransaction();
ASSERT_FALSE(transaction);
EXPECT_EQ(
transaction.error().msg(),
"DataSourceFake is read-only and cannot begin a transaction.");
}