test: verify Kiosk consumes real Portal-generated schedule payloads

Adds two fixtures captured from a running Portal (daily and weekly) and
tests that parse them with the Kiosk API client and evaluate them with the
schedule engine, including adjacency and Sunday->Monday spillover. Proves
the Kiosk consumes actual Portal output with no hand-editing.
This commit is contained in:
NeilClack
2026-09-29 12:46:05 -05:00
parent ff5346fd0c
commit 4535ba223b
3 changed files with 52 additions and 0 deletions
+50
View File
@@ -296,3 +296,53 @@ TEST(ScheduleManagerTest, OfflineFallsBackToCache) {
EXPECT_EQ(etag, "\"cached\"");
radiantwave::sync::schedule_cache::clear();
}
// ─── Phase 5: consume real Portal-generated payloads ───────────────────
//
// These fixtures were captured from a running Portal (GET
// /api/v2/licenses/{key}/schedule). They prove the Kiosk parses and evaluates
// exactly what the Portal emits, with no hand-editing in between.
TEST(SchedulePortalParityTest, ParsesPortalDailyPayload) {
const auto p = loadPayload("schedule-portal-daily.json");
EXPECT_EQ(p.type, "daily");
ASSERT_TRUE(p.hasSchedule());
ASSERT_EQ(p.daily.size(), 2u);
// 06:00-07:00 (dynamicAudio true) and 18:00-20:30 (false).
EXPECT_EQ(p.daily[0].start_minutes, 360);
EXPECT_EQ(p.daily[0].end_minutes, 420);
EXPECT_TRUE(p.daily[0].dynamic_audio);
EXPECT_FALSE(p.daily[1].dynamic_audio);
EXPECT_FALSE(p.daily[0].proclamation_ids.empty());
EXPECT_EQ(p.legacy_blocks.size(), 2u);
// Engine decisions: inside / gap / inside.
EXPECT_TRUE(evaluate(p, 6 * 60 + 30, Weekday::Tue).hasBlock);
EXPECT_FALSE(evaluate(p, 12 * 60, Weekday::Tue).hasBlock);
EXPECT_TRUE(evaluate(p, 19 * 60, Weekday::Tue).hasBlock);
}
TEST(SchedulePortalParityTest, ParsesPortalWeeklyPayloadAndSpillover) {
const auto p = loadPayload("schedule-portal-weekly.json");
EXPECT_EQ(p.type, "weekly");
ASSERT_TRUE(p.hasSchedule());
// Monday has two adjacent blocks; Sunday has one crossing block.
int mon = 0;
int sun = 0;
for (const auto& b : p.weekly) {
if (b.day == "mon") ++mon;
if (b.day == "sun") ++sun;
}
EXPECT_EQ(mon, 2);
EXPECT_EQ(sun, 1);
// Monday 00:30 belongs to Sunday's crossing block.
const auto spill = evaluate(p, 30, Weekday::Mon);
ASSERT_TRUE(spill.hasBlock);
EXPECT_EQ(spill.block.day, "sun");
// Monday 06:30 is a Monday block.
const auto monBlock = evaluate(p, 6 * 60 + 30, Weekday::Mon);
ASSERT_TRUE(monBlock.hasBlock);
EXPECT_EQ(monBlock.block.day, "mon");
}