1use std::{
2 sync::Arc,
3 time::{Duration, SystemTime},
4};
5
6use candid::Principal;
7use pocket_ic::{nonblocking::PocketIc, PocketIcBuilder};
8use test_principals::TEST_PRINCIPALS;
9use user::IcpUser;
10
11pub mod caller;
12pub mod deployer;
13pub mod provider;
14pub mod user;
15
16#[cfg(feature = "evm")]
17pub(crate) mod http_outcalls;
18
19pub(crate) mod test_principals;
20
21pub struct Icp {
22 pub pic: Arc<PocketIc>,
23}
24
25impl Icp {
26 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 pic.set_time(
35 SystemTime::UNIX_EPOCH
36 .checked_add(Duration::from_secs(1740000000))
37 .unwrap(),
38 )
39 .await;
40
41 Self { pic: Arc::new(pic) }
42 }
43
44 pub fn test_user_count(&self) -> usize {
45 TEST_PRINCIPALS.len()
46 }
47
48 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 {
59 self.test_user(0)
60 }
61
62 pub fn user_from(&self, principal: Principal) -> IcpUser {
63 IcpUser {
64 principal,
65 pic: Arc::clone(&self.pic),
66 }
67 }
68
69 pub async fn tick(&self) {
70 self.pic.advance_time(Duration::from_secs(1)).await;
71 self.pic.tick().await;
72 }
73
74 pub fn pocket_ic(&self) -> &PocketIc {
75 &self.pic
76 }
77}