strip all comments, extract tests to tests/ dirs, remove #[allow(clippy::...)], extract magic numbers to constants, refactor schedule engine private methods to use param structs, add Default impls, clippy.toml for persistence constructors
112 lines
3.3 KiB
Rust
112 lines
3.3 KiB
Rust
use super::*;
|
|
|
|
fn t(h: u32, m: u32) -> NaiveTime {
|
|
NaiveTime::from_hms_opt(h, m, 0).unwrap()
|
|
}
|
|
|
|
fn make_block(start: NaiveTime, duration_mins: u32) -> ProgrammingBlock {
|
|
ProgrammingBlock::new_algorithmic(
|
|
"test",
|
|
start,
|
|
duration_mins,
|
|
Default::default(),
|
|
FillStrategy::Random,
|
|
)
|
|
}
|
|
|
|
fn cfg_with_monday_block(start: NaiveTime, dur: u32) -> ScheduleConfig {
|
|
let mut cfg = ScheduleConfig::default();
|
|
cfg.insert_day(Weekday::Monday, vec![make_block(start, dur)]);
|
|
cfg
|
|
}
|
|
|
|
#[test]
|
|
fn find_block_at_finds_active_block() {
|
|
let cfg = cfg_with_monday_block(t(8, 0), 60);
|
|
assert!(cfg.find_block_at(Weekday::Monday, t(8, 30)).is_some());
|
|
assert!(cfg.find_block_at(Weekday::Monday, t(9, 0)).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn find_block_at_wrong_day_returns_none() {
|
|
let cfg = cfg_with_monday_block(t(8, 0), 60);
|
|
assert!(cfg.find_block_at(Weekday::Tuesday, t(8, 30)).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn v1_compat_copies_blocks_to_all_days() {
|
|
let json = r#"{"blocks": []}"#;
|
|
let compat: ScheduleConfigCompat = serde_json::from_str(json).unwrap();
|
|
let cfg: ScheduleConfig = compat.into();
|
|
assert_eq!(cfg.day_blocks().len(), 7);
|
|
}
|
|
|
|
#[test]
|
|
fn v2_payload_with_unknown_blocks_key_fails() {
|
|
let json = r#"{"blocks": [], "day_blocks": {}}"#;
|
|
let result: Result<ScheduleConfigCompat, _> = serde_json::from_str(json);
|
|
match result {
|
|
Ok(ScheduleConfigCompat::V2(cfg)) => {
|
|
let _ = cfg;
|
|
}
|
|
Ok(ScheduleConfigCompat::V1(_)) => {}
|
|
Err(_) => {}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn earliest_block_start_across_days() {
|
|
let mut cfg = ScheduleConfig::default();
|
|
cfg.insert_day(Weekday::Monday, vec![make_block(t(10, 0), 60)]);
|
|
cfg.insert_day(Weekday::Friday, vec![make_block(t(7, 0), 60)]);
|
|
assert_eq!(cfg.earliest_block_start(), Some(t(7, 0)));
|
|
}
|
|
|
|
#[test]
|
|
fn empty_config_earliest_block_start_is_none() {
|
|
let cfg = ScheduleConfig::default();
|
|
assert!(cfg.earliest_block_start().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn channel_new_defaults() {
|
|
let owner = UserId::generate();
|
|
let ch = Channel::new(owner, "Test Channel", "America/New_York");
|
|
assert_eq!(ch.name(), "Test Channel");
|
|
assert_eq!(ch.timezone(), "America/New_York");
|
|
assert_eq!(ch.owner_id(), owner);
|
|
assert!(!ch.auto_schedule());
|
|
assert!(ch.description().is_none());
|
|
assert_eq!(ch.logo_opacity(), DEFAULT_LOGO_OPACITY);
|
|
assert_eq!(ch.webhook_poll_interval_secs(), DEFAULT_WEBHOOK_POLL_INTERVAL_SECS);
|
|
}
|
|
|
|
#[test]
|
|
fn programming_block_getters() {
|
|
let block = ProgrammingBlock::new_algorithmic(
|
|
"Morning",
|
|
t(8, 0),
|
|
120,
|
|
Default::default(),
|
|
FillStrategy::BestFit,
|
|
);
|
|
assert_eq!(block.name(), "Morning");
|
|
assert_eq!(block.start_time(), t(8, 0));
|
|
assert_eq!(block.duration_mins(), 120);
|
|
assert!(block.loop_on_finish());
|
|
assert!(!block.ignore_recycle_policy());
|
|
}
|
|
|
|
#[test]
|
|
fn manual_block_creation() {
|
|
let items = vec![MediaItemId::new("item1"), MediaItemId::new("item2")];
|
|
let block = ProgrammingBlock::new_manual("Manual Block", t(20, 0), 60, items);
|
|
match block.content() {
|
|
BlockContent::Manual { items, provider_id } => {
|
|
assert_eq!(items.len(), 2);
|
|
assert!(provider_id.is_empty());
|
|
}
|
|
_ => panic!("Expected Manual content"),
|
|
}
|
|
}
|