Add schedule sync and schedule-aware playback
This commit is contained in:
@@ -113,6 +113,58 @@ TEST(ApiClientTest, ParseCreateAccountJsonRejectsMalformed) {
|
||||
EXPECT_FALSE(parseCreateAccountJson("[]", account));
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, ParseScheduleJson) {
|
||||
const std::string body =
|
||||
R"({"email":"jane@example.com","blocks":[
|
||||
{"id":"b1","startTime":"06:00","startMinutes":360,"endTime":"08:00",
|
||||
"endMinutes":480,"overnight":false,"durationMinutes":120,
|
||||
"dynamicAudio":false,"proclamationIds":["p1","p2"]},
|
||||
{"id":"b2","startTime":"21:00","startMinutes":1260,"endTime":"09:00",
|
||||
"endMinutes":540,"overnight":true,"durationMinutes":720,
|
||||
"dynamicAudio":true,"proclamationIds":[]}]})";
|
||||
|
||||
ScheduleResponse out;
|
||||
EXPECT_TRUE(parseScheduleJson(body, out));
|
||||
EXPECT_EQ(out.email, "jane@example.com");
|
||||
ASSERT_EQ(out.blocks.size(), 2u);
|
||||
|
||||
EXPECT_EQ(out.blocks[0].id, "b1");
|
||||
EXPECT_EQ(out.blocks[0].start_minutes, 360);
|
||||
EXPECT_EQ(out.blocks[0].end_minutes, 480);
|
||||
EXPECT_FALSE(out.blocks[0].overnight);
|
||||
EXPECT_EQ(out.blocks[0].duration_minutes, 120);
|
||||
EXPECT_FALSE(out.blocks[0].dynamic_audio);
|
||||
ASSERT_EQ(out.blocks[0].proclamation_ids.size(), 2u);
|
||||
EXPECT_EQ(out.blocks[0].proclamation_ids[0], "p1");
|
||||
EXPECT_EQ(out.blocks[0].proclamation_ids[1], "p2");
|
||||
|
||||
EXPECT_EQ(out.blocks[1].id, "b2");
|
||||
EXPECT_TRUE(out.blocks[1].overnight);
|
||||
EXPECT_TRUE(out.blocks[1].dynamic_audio);
|
||||
EXPECT_TRUE(out.blocks[1].proclamation_ids.empty());
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, ParseScheduleDefaultsDynamicAudioTrue) {
|
||||
const std::string body =
|
||||
R"({"email":"a@b.com","blocks":[
|
||||
{"id":"b1","startMinutes":0,"endMinutes":60,"overnight":false,
|
||||
"durationMinutes":60,"proclamationIds":["p1"]}]})";
|
||||
|
||||
ScheduleResponse out;
|
||||
EXPECT_TRUE(parseScheduleJson(body, out));
|
||||
ASSERT_EQ(out.blocks.size(), 1u);
|
||||
EXPECT_TRUE(out.blocks[0].dynamic_audio);
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, ParseScheduleRejectsMalformed) {
|
||||
ScheduleResponse out;
|
||||
EXPECT_FALSE(parseScheduleJson("not json", out));
|
||||
EXPECT_FALSE(parseScheduleJson("[1,2,3]", out)); // array, not object
|
||||
// Missing id blocks are skipped, not fatal.
|
||||
EXPECT_TRUE(parseScheduleJson(R"({"blocks":[{"startMinutes":0}]})", out));
|
||||
EXPECT_TRUE(out.blocks.empty());
|
||||
}
|
||||
|
||||
// ─── Offline: error message extraction ────────────────────────────────
|
||||
|
||||
TEST(ApiClientTest, ExtractErrorMessage) {
|
||||
|
||||
Reference in New Issue
Block a user