openzeppelin_monitor/utils/tests/builders/
network.rs1use crate::models::{BlockChainType, Network, RpcUrl, SecretString, SecretValue};
6
7pub struct NetworkBuilder {
9 name: String,
10 slug: String,
11 network_type: BlockChainType,
12 chain_id: Option<u64>,
13 network_passphrase: Option<String>,
14 store_blocks: Option<bool>,
15 rpc_urls: Vec<RpcUrl>,
16 block_time_ms: u64,
17 confirmation_blocks: u64,
18 cron_schedule: String,
19 max_past_blocks: Option<u64>,
20}
21
22impl Default for NetworkBuilder {
23 fn default() -> Self {
24 Self {
25 name: "Test Network".to_string(),
26 slug: "test_network".to_string(),
27 network_type: BlockChainType::EVM,
28 chain_id: Some(1),
29 network_passphrase: None,
30 store_blocks: Some(true),
31 rpc_urls: vec![],
32 block_time_ms: 1000,
33 confirmation_blocks: 1,
34 cron_schedule: "0 */5 * * * *".to_string(),
35 max_past_blocks: Some(10),
36 }
37 }
38}
39
40impl NetworkBuilder {
41 pub fn new() -> Self {
42 Self::default()
43 }
44
45 pub fn name(mut self, name: &str) -> Self {
46 self.name = name.to_string();
47 self
48 }
49
50 pub fn slug(mut self, slug: &str) -> Self {
51 self.slug = slug.to_string();
52 self
53 }
54
55 pub fn network_type(mut self, network_type: BlockChainType) -> Self {
56 self.network_type = network_type;
57 self
58 }
59
60 pub fn chain_id(mut self, chain_id: u64) -> Self {
61 self.chain_id = Some(chain_id);
62 self
63 }
64
65 pub fn network_passphrase(mut self, passphrase: &str) -> Self {
66 self.network_passphrase = Some(passphrase.to_string());
67 self
68 }
69
70 pub fn store_blocks(mut self, store: bool) -> Self {
71 self.store_blocks = Some(store);
72 self
73 }
74
75 pub fn rpc_url(mut self, url: &str) -> Self {
76 self.rpc_urls = vec![RpcUrl {
77 type_: "rpc".to_string(),
78 url: SecretValue::Plain(SecretString::new(url.to_string())),
79 weight: 100,
80 }];
81 self
82 }
83
84 pub fn rpc_urls(mut self, urls: Vec<&str>) -> Self {
85 self.rpc_urls = urls
86 .into_iter()
87 .map(|url| RpcUrl {
88 type_: "rpc".to_string(),
89 url: SecretValue::Plain(SecretString::new(url.to_string())),
90 weight: 100,
91 })
92 .collect();
93 self
94 }
95
96 pub fn websocket_rpc_urls(mut self, urls: Vec<&str>) -> Self {
97 self.rpc_urls = urls
98 .into_iter()
99 .map(|url| RpcUrl {
100 type_: "ws_rpc".to_string(),
101 url: SecretValue::Plain(SecretString::new(url.to_string())),
102 weight: 100,
103 })
104 .collect();
105 self
106 }
107
108 pub fn add_rpc_url(mut self, url: &str, type_: &str, weight: u32) -> Self {
109 self.rpc_urls.push(RpcUrl {
110 type_: type_.to_string(),
111 url: SecretValue::Plain(SecretString::new(url.to_string())),
112 weight,
113 });
114 self
115 }
116
117 pub fn add_secret_rpc_url(mut self, url: SecretValue, type_: &str, weight: u32) -> Self {
118 self.rpc_urls.push(RpcUrl {
119 type_: type_.to_string(),
120 url,
121 weight,
122 });
123 self
124 }
125
126 pub fn clear_rpc_urls(mut self) -> Self {
127 self.rpc_urls.clear();
128 self
129 }
130
131 pub fn block_time_ms(mut self, block_time: u64) -> Self {
132 self.block_time_ms = block_time;
133 self
134 }
135
136 pub fn confirmation_blocks(mut self, blocks: u64) -> Self {
137 self.confirmation_blocks = blocks;
138 self
139 }
140
141 pub fn cron_schedule(mut self, schedule: &str) -> Self {
142 self.cron_schedule = schedule.to_string();
143 self
144 }
145
146 pub fn max_past_blocks(mut self, blocks: u64) -> Self {
147 self.max_past_blocks = Some(blocks);
148 self
149 }
150
151 pub fn build(self) -> Network {
152 Network {
153 name: self.name,
154 slug: self.slug,
155 network_type: self.network_type,
156 chain_id: self.chain_id,
157 network_passphrase: self.network_passphrase,
158 store_blocks: self.store_blocks,
159 rpc_urls: self.rpc_urls,
160 block_time_ms: self.block_time_ms,
161 confirmation_blocks: self.confirmation_blocks,
162 cron_schedule: self.cron_schedule,
163 max_past_blocks: self.max_past_blocks,
164 }
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171
172 #[test]
173 fn test_default_network() {
174 let network = NetworkBuilder::new().build();
175
176 assert_eq!(network.name, "Test Network");
177 assert_eq!(network.slug, "test_network");
178 assert_eq!(network.network_type, BlockChainType::EVM);
179 assert_eq!(network.chain_id, Some(1));
180 assert_eq!(network.network_passphrase, None);
181 assert_eq!(network.store_blocks, Some(true));
182 assert_eq!(network.block_time_ms, 1000);
183 assert_eq!(network.confirmation_blocks, 1);
184 assert_eq!(network.cron_schedule, "0 */5 * * * *");
185 assert_eq!(network.max_past_blocks, Some(10));
186 assert_eq!(network.rpc_urls.len(), 0);
187 }
188
189 #[test]
190 fn test_basic_builder_methods() {
191 let network = NetworkBuilder::new()
192 .name("Ethereum")
193 .slug("eth")
194 .network_type(BlockChainType::EVM)
195 .chain_id(1)
196 .store_blocks(true)
197 .block_time_ms(15000)
198 .confirmation_blocks(12)
199 .build();
200
201 assert_eq!(network.name, "Ethereum");
202 assert_eq!(network.slug, "eth");
203 assert_eq!(network.network_type, BlockChainType::EVM);
204 assert_eq!(network.chain_id, Some(1));
205 assert_eq!(network.store_blocks, Some(true));
206 assert_eq!(network.block_time_ms, 15000);
207 assert_eq!(network.confirmation_blocks, 12);
208 }
209
210 #[test]
211 fn test_rpc_url_methods() {
212 let network = NetworkBuilder::new()
213 .clear_rpc_urls()
214 .add_rpc_url("https://rpc1.example.com", "http", 50)
215 .add_rpc_url("https://rpc2.example.com", "ws", 50)
216 .build();
217
218 assert_eq!(network.rpc_urls.len(), 2);
219 assert_eq!(
220 network.rpc_urls[0].url.as_ref().to_string(),
221 "https://rpc1.example.com".to_string()
222 );
223 assert_eq!(network.rpc_urls[0].type_, "http");
224 assert_eq!(network.rpc_urls[0].weight, 50);
225 assert_eq!(
226 network.rpc_urls[1].url.as_ref().to_string(),
227 "https://rpc2.example.com".to_string()
228 );
229 assert_eq!(network.rpc_urls[1].type_, "ws");
230 assert_eq!(network.rpc_urls[1].weight, 50);
231 }
232
233 #[test]
234 fn test_secret_rpc_url() {
235 let network = NetworkBuilder::new()
236 .add_secret_rpc_url(
237 SecretValue::Plain(SecretString::new("https://rpc1.example.com".to_string())),
238 "rpc",
239 50,
240 )
241 .build();
242
243 assert_eq!(network.rpc_urls.len(), 1);
244 assert_eq!(
245 network.rpc_urls[0].url.as_ref().to_string(),
246 "https://rpc1.example.com".to_string()
247 );
248 assert_eq!(network.rpc_urls[0].type_, "rpc");
249 }
250
251 #[test]
252 fn test_rpc_urls_bulk_set() {
253 let network = NetworkBuilder::new()
254 .rpc_urls(vec!["https://rpc1.com", "https://rpc2.com"])
255 .build();
256
257 assert_eq!(network.rpc_urls.len(), 2);
258 assert_eq!(
259 network.rpc_urls[0].url.as_ref().to_string(),
260 "https://rpc1.com".to_string()
261 );
262 assert_eq!(
263 network.rpc_urls[1].url.as_ref().to_string(),
264 "https://rpc2.com".to_string()
265 );
266 assert!(network.rpc_urls.iter().all(|url| url.type_ == "rpc"));
268 assert!(network.rpc_urls.iter().all(|url| url.weight == 100));
269 }
270
271 #[test]
272 fn test_websocket_rpc_urls() {
273 let network = NetworkBuilder::new()
274 .websocket_rpc_urls(vec!["wss://ws1.example.com", "wss://ws2.example.com"])
275 .build();
276
277 assert_eq!(network.rpc_urls.len(), 2);
278 assert_eq!(
279 network.rpc_urls[0].url.as_ref().to_string(),
280 "wss://ws1.example.com".to_string()
281 );
282 assert_eq!(network.rpc_urls[0].type_, "ws_rpc");
283 assert_eq!(network.rpc_urls[1].type_, "ws_rpc");
284 }
285
286 #[test]
287 fn test_stellar_network() {
288 let network = NetworkBuilder::new()
289 .name("Stellar")
290 .slug("xlm")
291 .network_type(BlockChainType::Stellar)
292 .network_passphrase("Test SDF Network")
293 .build();
294
295 assert_eq!(network.network_type, BlockChainType::Stellar);
296 assert_eq!(
297 network.network_passphrase,
298 Some("Test SDF Network".to_string())
299 );
300 assert_eq!(network.chain_id, Some(1)); }
302}