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