From 9f452dda296f907fc1a0180f894e835d986882aa Mon Sep 17 00:00:00 2001 From: sendi0011 Date: Mon, 27 Jul 2026 19:32:48 +0100 Subject: [PATCH] fix(analytics-aggregator): increment GlobalStats.total_campaigns on first impression for each campaign MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Record a campaign in GlobalStats when its first impression is recorded, so total_campaigns reflects the number of distinct campaigns with analytics data instead of always returning 0. Tracks newness by checking if total_impressions == 0 before the increment — no extra storage key needed since CampaignAnalytics is only created via record_impression. Closes #720 --- contracts/analytics-aggregator/src/lib.rs | 4 ++ contracts/analytics-aggregator/src/test.rs | 59 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/contracts/analytics-aggregator/src/lib.rs b/contracts/analytics-aggregator/src/lib.rs index 245ef4b..8886e43 100644 --- a/contracts/analytics-aggregator/src/lib.rs +++ b/contracts/analytics-aggregator/src/lib.rs @@ -130,6 +130,7 @@ impl AnalyticsAggregatorContract { last_updated: 0, }); + let is_new_campaign = analytics.total_impressions == 0; analytics.total_impressions += 1; analytics.total_spend += spend; analytics.last_updated = env.ledger().timestamp(); @@ -188,6 +189,9 @@ impl AnalyticsAggregatorContract { // Update global stats let mut global: GlobalStats = env.storage().instance().get(&DataKey::GlobalStats).unwrap(); + if is_new_campaign { + global.total_campaigns += 1; + } global.total_impressions += 1; global.total_spend += spend; global.last_updated = env.ledger().timestamp(); diff --git a/contracts/analytics-aggregator/src/test.rs b/contracts/analytics-aggregator/src/test.rs index 1b20085..4e8be4e 100644 --- a/contracts/analytics-aggregator/src/test.rs +++ b/contracts/analytics-aggregator/src/test.rs @@ -50,6 +50,9 @@ fn test_record_impression() { let a = c.get_campaign_analytics(&1u64).unwrap(); assert_eq!(a.total_impressions, 1); assert_eq!(a.unique_viewers, 1); + let stats = c.get_global_stats(); + assert_eq!(stats.total_campaigns, 1); + assert_eq!(stats.total_impressions, 1); } #[test] @@ -102,6 +105,41 @@ fn test_record_impression_tracks_unique_viewers() { let a = c.get_campaign_analytics(&1u64).unwrap(); assert_eq!(a.total_impressions, 3); assert_eq!(a.unique_viewers, 2); + let stats = c.get_global_stats(); + assert_eq!(stats.total_campaigns, 1); +} + +#[test] +fn test_total_campaigns_not_double_counted() { + let env = Env::default(); + env.mock_all_auths(); + let (c, _, oracle) = setup(&env); + let viewer = Address::generate(&env); + + c.record_impression(&oracle, &1u64, &viewer, &100i128); + c.record_impression(&oracle, &1u64, &viewer, &100i128); + c.record_impression(&oracle, &1u64, &viewer, &100i128); + + let stats = c.get_global_stats(); + assert_eq!(stats.total_campaigns, 1); + assert_eq!(stats.total_impressions, 3); +} + +#[test] +fn test_total_campaigns_counts_distinct_campaigns() { + let env = Env::default(); + env.mock_all_auths(); + let (c, _, oracle) = setup(&env); + let viewer = Address::generate(&env); + + c.record_impression(&oracle, &1u64, &viewer, &100i128); + c.record_impression(&oracle, &2u64, &viewer, &200i128); + c.record_impression(&oracle, &3u64, &viewer, &300i128); + + let stats = c.get_global_stats(); + assert_eq!(stats.total_campaigns, 3); + assert_eq!(stats.total_impressions, 3); + assert_eq!(stats.total_spend, 600); } #[test] @@ -137,6 +175,27 @@ fn test_get_global_stats() { let (c, _, _) = setup(&env); let stats = c.get_global_stats(); assert_eq!(stats.total_campaigns, 0); + assert_eq!(stats.total_impressions, 0); + assert_eq!(stats.total_clicks, 0); + assert_eq!(stats.total_spend, 0); +} + +#[test] +fn test_get_global_stats_after_multiple_campaigns() { + let env = Env::default(); + env.mock_all_auths(); + let (c, _, oracle) = setup(&env); + let viewer = Address::generate(&env); + + c.record_impression(&oracle, &1u64, &viewer, &100i128); + c.record_impression(&oracle, &2u64, &viewer, &200i128); + c.record_click(&oracle, &1u64); + + let stats = c.get_global_stats(); + assert_eq!(stats.total_campaigns, 2); + assert_eq!(stats.total_impressions, 2); + assert_eq!(stats.total_clicks, 1); + assert_eq!(stats.total_spend, 300); } #[test]