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
16pub(crate) mod http_outcalls;
17pub(crate) mod test_principals;
18
19pub struct Icp {
20 pub pic: Arc<PocketIc>,
21}
22
23impl Icp {
24 pub async fn new() -> Self {
25 let pic = PocketIcBuilder::new()
26 .with_nns_subnet()
27 .with_ii_subnet()
28 .with_log_level(slog::Level::Error)
29 .build_async()
30 .await;
31
32 pic.set_time(
33 SystemTime::UNIX_EPOCH
34 .checked_add(Duration::from_secs(1740000000))
35 .unwrap(),
36 )
37 .await;
38
39 Self { pic: Arc::new(pic) }
40 }
41
42 pub fn test_user_count(&self) -> usize {
43 TEST_PRINCIPALS.len()
44 }
45
46 pub fn test_user(&self, index: usize) -> IcpUser {
47 if index >= self.test_user_count() {
48 panic!(
49 "Reached maximum number of test users: {}",
50 self.test_user_count()
51 );
52 }
53 self.user_from(Principal::from_text(TEST_PRINCIPALS[index]).unwrap())
54 }
55
56 pub fn default_user(&self) -> IcpUser {
57 self.test_user(0)
58 }
59
60 pub fn user_from(&self, principal: Principal) -> IcpUser {
61 IcpUser {
62 principal,
63 pic: Arc::clone(&self.pic),
64 }
65 }
66
67 pub async fn tick(&self) {
68 self.pic.advance_time(Duration::from_secs(1)).await;
69 self.pic.tick().await;
70 }
71
72 pub fn pocket_ic(&self) -> &PocketIc {
73 &self.pic
74 }
75}