1use std::{sync::Arc, time::Duration};
2
3use candid::Principal;
4use pocket_ic::{nonblocking::PocketIc, PocketIcBuilder, Time};
5use test_principals::TEST_PRINCIPALS;
6use user::IcpUser;
7
8pub mod caller;
9pub mod deployer;
10pub mod provider;
11pub mod user;
12
13#[cfg(feature = "evm")]
14pub(crate) mod http_outcalls;
15
16pub(crate) mod test_principals;
17
18pub struct Icp {
20 pub pic: Arc<PocketIc>,
22}
23
24impl Icp {
25 pub async fn new() -> Self {
27 let pic = PocketIcBuilder::new()
28 .with_nns_subnet()
29 .with_ii_subnet()
30 .with_log_level(slog::Level::Error)
31 .build_async()
32 .await;
33
34 let time = Time::from_nanos_since_unix_epoch(1_740_000_000_000_000_000);
36
37 pic.set_time(time).await;
38
39 Self { pic: Arc::new(pic) }
40 }
41
42 pub fn test_user_count(&self) -> usize {
44 TEST_PRINCIPALS.len()
45 }
46
47 pub fn test_user(&self, index: usize) -> IcpUser {
49 if index >= self.test_user_count() {
50 panic!(
51 "Reached maximum number of test users: {}",
52 self.test_user_count()
53 );
54 }
55 self.user_from(Principal::from_text(TEST_PRINCIPALS[index]).unwrap())
56 }
57
58 pub fn default_user(&self) -> IcpUser {
60 self.test_user(0)
61 }
62
63 pub fn user_from(&self, principal: Principal) -> IcpUser {
65 IcpUser {
66 principal,
67 pic: Arc::clone(&self.pic),
68 }
69 }
70
71 pub async fn tick(&self) {
73 self.pic.advance_time(Duration::from_secs(1)).await;
74 self.pic.tick().await;
75 }
76
77 pub fn pocket_ic(&self) -> &PocketIc {
79 &self.pic
80 }
81}