Files
Genarrative/server-rs/crates/module-runtime/tests/analytics_granularity.rs
2026-05-08 11:44:42 +08:00

127 lines
3.9 KiB
Rust

use module_runtime::{
AnalyticsGranularity, RuntimeAnalyticsDailyStatSnapshot, RuntimeTrackingScopeKind,
aggregate_runtime_tracking_daily_stats,
};
fn stat(
event_key: &str,
scope_id: &str,
day_key: i64,
count: u32,
) -> RuntimeAnalyticsDailyStatSnapshot {
RuntimeAnalyticsDailyStatSnapshot {
event_key: event_key.to_string(),
scope_kind: RuntimeTrackingScopeKind::User,
scope_id: scope_id.to_string(),
day_key,
count,
}
}
#[test]
fn aggregates_daily_stats_by_iso_week_bucket() {
let buckets = aggregate_runtime_tracking_daily_stats(
vec![
stat("daily_login", "user-1", 20_517, 1), // 2026-03-05
stat("daily_login", "user-1", 20_518, 2), // 2026-03-06
stat("daily_login", "user-1", 20_524, 3), // 2026-03-12
stat("daily_login", "user-2", 20_517, 9),
],
"daily_login",
RuntimeTrackingScopeKind::User,
"user-1",
AnalyticsGranularity::Week,
);
assert_eq!(buckets.len(), 2);
assert_eq!(buckets[0].bucket_key, "202610");
assert_eq!(buckets[0].bucket_start_date_key, 20_514); // 2026-03-02
assert_eq!(buckets[0].bucket_end_date_key, 20_520); // 2026-03-08
assert_eq!(buckets[0].value, 3);
assert_eq!(buckets[1].bucket_key, "202611");
assert_eq!(buckets[1].bucket_start_date_key, 20_521); // 2026-03-09
assert_eq!(buckets[1].bucket_end_date_key, 20_527); // 2026-03-15
assert_eq!(buckets[1].value, 3);
}
#[test]
fn aggregates_daily_stats_by_month_quarter_and_year_bucket() {
let stats = vec![
stat("play", "user-1", 20_545, 2), // 2026-04-02
stat("play", "user-1", 20_573, 3), // 2026-04-30
stat("play", "user-1", 20_574, 5), // 2026-05-01
stat("play", "user-1", 20_818, 7), // 2026-12-31
];
let month = aggregate_runtime_tracking_daily_stats(
stats.clone(),
"play",
RuntimeTrackingScopeKind::User,
"user-1",
AnalyticsGranularity::Month,
);
assert_eq!(
month
.iter()
.map(|bucket| (&bucket.bucket_key, bucket.value))
.collect::<Vec<_>>(),
vec![
(&"202604".to_string(), 5),
(&"202605".to_string(), 5),
(&"202612".to_string(), 7)
]
);
assert_eq!(month[0].bucket_start_date_key, 20_544);
assert_eq!(month[0].bucket_end_date_key, 20_573);
let quarter = aggregate_runtime_tracking_daily_stats(
stats.clone(),
"play",
RuntimeTrackingScopeKind::User,
"user-1",
AnalyticsGranularity::Quarter,
);
assert_eq!(
quarter
.iter()
.map(|bucket| (&bucket.bucket_key, bucket.value))
.collect::<Vec<_>>(),
vec![(&"20262".to_string(), 10), (&"20264".to_string(), 7)]
);
let year = aggregate_runtime_tracking_daily_stats(
stats,
"play",
RuntimeTrackingScopeKind::User,
"user-1",
AnalyticsGranularity::Year,
);
assert_eq!(year.len(), 1);
assert_eq!(year[0].bucket_key, "2026");
assert_eq!(year[0].value, 17);
}
#[test]
fn day_granularity_keeps_each_day_bucket_and_filters_scope() {
let buckets = aggregate_runtime_tracking_daily_stats(
vec![
stat("daily_login", "user-1", 20_517, 1),
stat("daily_login", "user-1", 20_518, 2),
stat("daily_login", "user-2", 20_517, 9),
stat("other", "user-1", 20_517, 9),
],
"daily_login",
RuntimeTrackingScopeKind::User,
"user-1",
AnalyticsGranularity::Day,
);
assert_eq!(buckets.len(), 2);
assert_eq!(buckets[0].bucket_key, "2026-03-05");
assert_eq!(buckets[0].bucket_start_date_key, 20_517);
assert_eq!(buckets[0].bucket_end_date_key, 20_517);
assert_eq!(buckets[0].value, 1);
assert_eq!(buckets[1].bucket_key, "2026-03-06");
assert_eq!(buckets[1].value, 2);
}