diff --git a/backend/integration_tests/src/chit_tests.rs b/backend/integration_tests/src/chit_tests.rs index 3f8bdede44..29cb0f40fa 100644 --- a/backend/integration_tests/src/chit_tests.rs +++ b/backend/integration_tests/src/chit_tests.rs @@ -1,11 +1,11 @@ -use pocket_ic::PocketIc; -use types::{ChitEarnedReason, Milliseconds, TimestampMillis}; - use crate::env::ENV; use crate::utils::now_millis; use crate::{client, TestEnv}; -use std::ops::Deref; +use pocket_ic::PocketIc; +use std::ops::{Add, Deref}; use std::time::{Duration, SystemTime}; +use types::{ChitEarnedReason, Milliseconds, TimestampMillis}; +use utils::time::MonthKey; const DAY_ZERO: TimestampMillis = 1704067200000; // Mon Jan 01 2024 00:00:00 GMT+0000 const MS_IN_DAY: Milliseconds = 1000 * 60 * 60 * 24; @@ -80,6 +80,51 @@ fn chit_streak_gained_and_lost_as_expected() { assert_eq!(result.users[0].volatile.as_ref().unwrap().streak, 0); } +#[test] +fn chit_stored_per_month() { + let mut wrapper = ENV.deref().get(); + let TestEnv { env, canister_ids, .. } = wrapper.env(); + + let user = client::register_user(env, canister_ids); + ensure_time_at_least_day0(env); + advance_to_next_month(env); + let start_month = MonthKey::from_timestamp(now_millis(env)); + + for i in 1..5 { + for j in 0..i { + client::user::happy_path::claim_daily_chit(env, &user); + env.advance_time(Duration::from_millis(2 * MS_IN_DAY)); + } + advance_to_next_month(env); + } + + env.tick(); + + let mut month = start_month; + for i in 1..5 { + let chit_balance = client::user_index::happy_path::chit_balances( + env, + canister_ids.user_index, + vec![user.user_id], + month.year() as u16, + month.month(), + ) + .values() + .next() + .unwrap(); + + assert_eq!(chit_balance, i * 200); + + month = month.next(); + } +} + +fn advance_to_next_month(env: &mut PocketIc) { + let now = now_millis(env); + let next_month = MonthKey::from_timestamp(now).next(); + env.set_time(SystemTime::UNIX_EPOCH.add(Duration::from_millis(next_month.start_timestamp()))); +} + fn ensure_time_at_least_day0(env: &mut PocketIc) { if now_millis(env) < DAY_ZERO { env.set_time(SystemTime::now()); diff --git a/backend/integration_tests/src/client/user_index.rs b/backend/integration_tests/src/client/user_index.rs index 7b5fa4d792..c93c6ba199 100644 --- a/backend/integration_tests/src/client/user_index.rs +++ b/backend/integration_tests/src/client/user_index.rs @@ -3,6 +3,7 @@ use user_index_canister::*; // Queries generate_query_call!(check_username); +generate_query_call!(chit_balances); generate_query_call!(current_user); generate_query_call!(search); generate_query_call!(platform_moderators); @@ -31,6 +32,7 @@ generate_update_call!(upgrade_user_canister_wasm); pub mod happy_path { use candid::Principal; use pocket_ic::PocketIc; + use std::collections::HashMap; use types::{ CanisterId, CanisterWasm, Cryptocurrency, DiamondMembershipFees, DiamondMembershipPlanDuration, Empty, UserId, }; @@ -212,4 +214,23 @@ pub mod happy_path { user_index_canister::add_platform_operator::Response::Success => {} } } + + pub fn chit_balances( + env: &PocketIc, + user_index_canister_id: CanisterId, + user_ids: Vec, + year: u16, + month: u8, + ) -> HashMap { + let response = super::chit_balances( + env, + Principal::anonymous(), + user_index_canister_id, + &user_index_canister::chit_balances::Args { users, year, month }, + ); + + match response { + user_index_canister::chit_balances::Response::Success(result) => result.balances, + } + } } diff --git a/backend/libraries/utils/src/time.rs b/backend/libraries/utils/src/time.rs index 8c1dd24435..443f181509 100644 --- a/backend/libraries/utils/src/time.rs +++ b/backend/libraries/utils/src/time.rs @@ -85,7 +85,7 @@ impl MonthKey { start..end } - fn start_timestamp(&self) -> TimestampMillis { + pub fn start_timestamp(&self) -> TimestampMillis { let date = time::Date::from_calendar_date(self.year as i32, self.month.try_into().unwrap(), 1).unwrap(); (OffsetDateTime::new_utc(date, Time::MIDNIGHT).unix_timestamp() * 1000) as TimestampMillis }