initial commit
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
#include "db/database_manager.h"
|
||||
#include "network/api_client.h"
|
||||
#include "network/proclamation_sync.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace radiantwave::api;
|
||||
|
||||
namespace {
|
||||
|
||||
// Reads an env var, returning "" when unset.
|
||||
std::string env(const char* name) {
|
||||
const char* value = std::getenv(name);
|
||||
return value ? std::string(value) : std::string();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ─── Offline: GET /color-palettes parse ────────────────────────────────
|
||||
|
||||
TEST(ColorPalettesTest, ParseColorPalettesJson) {
|
||||
const std::string body =
|
||||
R"([
|
||||
{"solfeggioFrequencyId":1,
|
||||
"colors":["#8B6914","#B8860B","#DAA520","#E8B64C","#FFD700","#FFE9A8","#FFF4CC"]},
|
||||
{"solfeggioFrequencyId":5,
|
||||
"colors":["#32CD32","#3CB371","#90EE90","#98FB98","#ADFFA9","#C8FFD2","#F0FFF0"]}
|
||||
])";
|
||||
|
||||
std::vector<ColorPalette> out;
|
||||
EXPECT_TRUE(parseColorPalettesJson(body, out));
|
||||
ASSERT_EQ(out.size(), 2u);
|
||||
|
||||
EXPECT_EQ(out[0].solfeggio_frequency_id, 1);
|
||||
ASSERT_EQ(out[0].colors.size(), 7u);
|
||||
EXPECT_EQ(out[0].colors[0].r, 0x8B);
|
||||
EXPECT_EQ(out[0].colors[0].g, 0x69);
|
||||
EXPECT_EQ(out[0].colors[0].b, 0x14);
|
||||
EXPECT_EQ(out[0].colors[6].b, 0xCC);
|
||||
|
||||
EXPECT_EQ(out[1].solfeggio_frequency_id, 5);
|
||||
ASSERT_EQ(out[1].colors.size(), 7u);
|
||||
EXPECT_EQ(out[1].colors[0].r, 0x32);
|
||||
EXPECT_EQ(out[1].colors[0].g, 0xCD);
|
||||
EXPECT_EQ(out[1].colors[0].b, 0x32);
|
||||
}
|
||||
|
||||
TEST(ColorPalettesTest, ParseColorPalettesJsonAcceptsHexWithoutHash) {
|
||||
const std::string body = R"([{"solfeggioFrequencyId":1,"colors":["32CD32"]}])";
|
||||
|
||||
std::vector<ColorPalette> out;
|
||||
EXPECT_TRUE(parseColorPalettesJson(body, out));
|
||||
ASSERT_EQ(out.size(), 1u);
|
||||
ASSERT_EQ(out[0].colors.size(), 1u);
|
||||
EXPECT_EQ(out[0].colors[0].r, 0x32);
|
||||
EXPECT_EQ(out[0].colors[0].g, 0xCD);
|
||||
EXPECT_EQ(out[0].colors[0].b, 0x32);
|
||||
}
|
||||
|
||||
TEST(ColorPalettesTest, ParseColorPalettesJsonSkipsMissingFrequencyId) {
|
||||
const std::string body =
|
||||
R"([{"colors":["#32CD32"]},{"solfeggioFrequencyId":5,"colors":["#00FF7F"]}])";
|
||||
|
||||
std::vector<ColorPalette> out;
|
||||
EXPECT_TRUE(parseColorPalettesJson(body, out));
|
||||
ASSERT_EQ(out.size(), 1u);
|
||||
EXPECT_EQ(out[0].solfeggio_frequency_id, 5);
|
||||
}
|
||||
|
||||
TEST(ColorPalettesTest, ParseColorPalettesJsonEmptyAndMalformed) {
|
||||
std::vector<ColorPalette> out;
|
||||
EXPECT_TRUE(parseColorPalettesJson("[]", out));
|
||||
EXPECT_TRUE(out.empty());
|
||||
|
||||
out.clear();
|
||||
EXPECT_FALSE(parseColorPalettesJson("not json", out));
|
||||
EXPECT_FALSE(parseColorPalettesJson(R"({"solfeggioFrequencyId":1})", out));
|
||||
}
|
||||
|
||||
// ─── Offline: palettes embedded in /proclamations payload ──────────────
|
||||
|
||||
TEST(ColorPalettesTest, ParseProclamationPalettesJson) {
|
||||
const std::string body =
|
||||
R"PALETTE([
|
||||
{"id":"p1","name":"One","solfeggioFrequencyId":1,
|
||||
"colorPalette":["#8B6914","#B8860B"]},
|
||||
{"id":"p2","name":"Two","solfeggioFrequencyId":5,
|
||||
"colorPalette":["#32CD32","#3CB371","#90EE90"]},
|
||||
{"id":"p3","name":"Also freq 5 (ignored, first wins)",
|
||||
"solfeggioFrequencyId":5,
|
||||
"colorPalette":["#FF0000"]}
|
||||
])PALETTE";
|
||||
|
||||
std::vector<radiantwave::db::PaletteRecord> out;
|
||||
EXPECT_TRUE(radiantwave::sync::parseProclamationPalettesJson(body, out));
|
||||
ASSERT_EQ(out.size(), 2u);
|
||||
|
||||
EXPECT_EQ(out[0].solfeggio_frequency_id, 1);
|
||||
ASSERT_EQ(out[0].colors.size(), 2u);
|
||||
EXPECT_EQ(out[0].colors[0].r, 0x8B);
|
||||
|
||||
EXPECT_EQ(out[1].solfeggio_frequency_id, 5);
|
||||
ASSERT_EQ(out[1].colors.size(), 3u);
|
||||
EXPECT_EQ(out[1].colors[0].r, 0x32); // not #FF0000: first proclamation wins
|
||||
}
|
||||
|
||||
TEST(ColorPalettesTest, ParseProclamationPalettesJsonSkipsMissingPalette) {
|
||||
const std::string body =
|
||||
R"([{"id":"p1","name":"No palette","solfeggioFrequencyId":1}])";
|
||||
|
||||
std::vector<radiantwave::db::PaletteRecord> out;
|
||||
EXPECT_TRUE(radiantwave::sync::parseProclamationPalettesJson(body, out));
|
||||
EXPECT_TRUE(out.empty());
|
||||
}
|
||||
|
||||
// ─── Offline: DB round-trip via replaceColorPalettes ───────────────────
|
||||
|
||||
TEST(ColorPalettesTest, ReplaceColorPalettesRoundTrip) {
|
||||
const std::string temp_path =
|
||||
(std::filesystem::temp_directory_path() / "test_rw_db_palettesync.db").string();
|
||||
if (std::filesystem::exists(temp_path)) {
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
radiantwave::db::DatabaseManager db;
|
||||
ASSERT_TRUE(db.initialize(temp_path));
|
||||
|
||||
radiantwave::db::PaletteRecord rec;
|
||||
rec.solfeggio_frequency_id = 1;
|
||||
rec.colors = {{0x8B, 0x69, 0x14, 255}, {0xFF, 0xD7, 0x00, 255}};
|
||||
ASSERT_TRUE(db.replaceColorPalettes({rec}));
|
||||
|
||||
auto palette = db.getPaletteForFrequencyId(1);
|
||||
ASSERT_EQ(palette.size(), 2u);
|
||||
EXPECT_EQ(palette[0].r, 0x8B);
|
||||
EXPECT_EQ(palette[0].g, 0x69);
|
||||
EXPECT_EQ(palette[0].b, 0x14);
|
||||
EXPECT_EQ(palette[1].r, 0xFF);
|
||||
EXPECT_EQ(palette[1].g, 0xD7);
|
||||
EXPECT_EQ(palette[1].b, 0x00);
|
||||
|
||||
db.close();
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
TEST(ColorPalettesTest, ReplaceColorPalettesEmptyClearsAndFallsBackTo528) {
|
||||
const std::string temp_path =
|
||||
(std::filesystem::temp_directory_path() / "test_rw_db_paletteclear.db").string();
|
||||
if (std::filesystem::exists(temp_path)) {
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
radiantwave::db::DatabaseManager db;
|
||||
ASSERT_TRUE(db.initialize(temp_path));
|
||||
|
||||
ASSERT_TRUE(db.replaceColorPalettes({}));
|
||||
|
||||
// id 5 was cleared, so both the direct lookup and the 528 Hz fallback are empty.
|
||||
EXPECT_TRUE(db.getPaletteForFrequencyId(5).empty());
|
||||
|
||||
db.close();
|
||||
std::filesystem::remove(temp_path);
|
||||
}
|
||||
|
||||
// ─── Live: GET /color-palettes (route not live yet; opt-in) ────────────
|
||||
|
||||
TEST(ColorPalettesLiveTest, FetchColorPalettesLive) {
|
||||
if (env("RW_LIVE_COLOR_PALETTES").empty()) {
|
||||
GTEST_SKIP() << "RW_LIVE_COLOR_PALETTES not set (route not live yet)";
|
||||
}
|
||||
|
||||
std::vector<ColorPalette> palettes;
|
||||
ASSERT_TRUE(fetchColorPalettes(palettes, env("RW_LIVE_API_KEY")));
|
||||
EXPECT_FALSE(palettes.empty());
|
||||
for (const auto& p : palettes) {
|
||||
EXPECT_GE(p.colors.size(), 1u);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user