upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/test_utils/src/relay.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2023-10-01 00:00:00 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2023-10-01 00:00:00 +0100
commit000901c0cbca8464b5a89bcc93c5474f6564bafd (patch)
tree0ae11836c173ec6246e8b1eab7dc1e265e125426 /test_utils/src/relay.rs
parentb9a88672b8734448615354e3f46748d2fdc2f647 (diff)
feat(prs-create) send to multiple relays
add tests but these currently don't work when run together
Diffstat (limited to 'test_utils/src/relay.rs')
-rw-r--r--test_utils/src/relay.rs196
1 files changed, 196 insertions, 0 deletions
diff --git a/test_utils/src/relay.rs b/test_utils/src/relay.rs
new file mode 100644
index 0000000..6de3618
--- /dev/null
+++ b/test_utils/src/relay.rs
@@ -0,0 +1,196 @@
1use std::collections::HashMap;
2
3use anyhow::{bail, Result};
4use nostr::{ClientMessage, RelayMessage};
5
6use crate::CliTester;
7
8type ListenerFunc<'a> = &'a dyn Fn(&mut Relay, u64, nostr::Event) -> Result<()>;
9
10pub struct Relay<'a> {
11 port: u16,
12 event_hub: simple_websockets::EventHub,
13 clients: HashMap<u64, simple_websockets::Responder>,
14 pub events: Vec<nostr::Event>,
15 event_listener: Option<ListenerFunc<'a>>,
16}
17
18impl<'a> Relay<'a> {
19 pub fn new(port: u16, event_listener: Option<ListenerFunc<'a>>) -> Self {
20 let event_hub = simple_websockets::launch(port)
21 .unwrap_or_else(|_| panic!("failed to listen on port {port}"));
22 Self {
23 port,
24 events: vec![],
25 event_hub,
26 clients: HashMap::new(),
27 event_listener,
28 }
29 }
30 pub fn respond_ok(
31 &self,
32 client_id: u64,
33 event: nostr::Event,
34 error: Option<&str>,
35 ) -> Result<bool> {
36 let responder = self.clients.get(&client_id).unwrap();
37
38 let ok_json = RelayMessage::Ok {
39 event_id: event.id,
40 status: error.is_none(),
41 message: error.unwrap_or("").to_string(),
42 }
43 .as_json();
44 // bail!(format!("{}", &ok_json));
45 Ok(responder.send(simple_websockets::Message::Text(ok_json)))
46 }
47 /// listen, collect events and responds with event_listener to events or
48 /// Ok(eventid) if event_listner is None
49 pub async fn listen_until_close(&mut self) -> Result<()> {
50 loop {
51 println!("polling");
52 match self.event_hub.poll_async().await {
53 simple_websockets::Event::Connect(client_id, responder) => {
54 // add their Responder to our `clients` map:
55 self.clients.insert(client_id, responder);
56 }
57 simple_websockets::Event::Disconnect(client_id) => {
58 // remove the disconnected client from the clients map:
59 println!("{} disconnected", self.port);
60 self.clients.remove(&client_id);
61 break;
62 }
63 simple_websockets::Event::Message(client_id, message) => {
64 println!(
65 "Received a message from client #{}: {:?}",
66 client_id, message
67 );
68
69 if let Ok(event) = get_nevent(message) {
70 self.events.push(event.clone());
71 if let Some(listner) = self.event_listener {
72 listner(self, client_id, event)?;
73 } else {
74 self.respond_ok(client_id, event, None)?;
75 }
76 }
77 }
78 }
79 }
80 println!("stop polling");
81 println!("we may not be polling but the tcplistner is still listening");
82 Ok(())
83 }
84}
85
86fn get_nevent(message: simple_websockets::Message) -> Result<nostr::Event> {
87 if let simple_websockets::Message::Text(s) = message.clone() {
88 let cm_result = ClientMessage::from_json(s);
89 if let Ok(ClientMessage::Event(event)) = cm_result {
90 let e = *event;
91 return Ok(e.clone());
92 }
93 }
94 bail!("not nostr event")
95}
96
97pub enum Message {
98 Event,
99 // Request,
100}
101
102/// leaves trailing whitespace and only compatible with --no-cli-spinners flag
103/// relays tuple: (title,successful,message)
104pub fn expect_send_with_progress(
105 p: &mut CliTester,
106 relays: Vec<(&str, bool, &str)>,
107 event_count: u16,
108) -> Result<()> {
109 p.expect(format!(
110 " - {} -------------------- 0/{event_count}",
111 &relays[0].0
112 ))?;
113 for relay in &relays {
114 // if successful
115 if relay.1 {
116 p.expect_eventually(format!(" y {}", relay.0))?;
117 } else {
118 p.expect_eventually(format!(" x {} {}", relay.0, relay.2))?;
119 }
120 // could check that before only contains titles:
121 // - # y x n/n and whitespace
122 // let before = p.expect_eventually(format!(" â {title}"))?;
123 // assert_eq!("", before.trim());
124 }
125 Ok(())
126}
127
128pub fn expect_send_with_progress_exact_interaction(
129 p: &mut CliTester,
130 titles: Vec<&str>,
131 count: u16,
132) -> Result<()> {
133 let whitespace_mid = " \r\n";
134 let whitespace_end = " \r\r\r";
135
136 p.expect(format!(
137 " - {} -------------------- 0/{count} \r",
138 titles[0]
139 ))?;
140 p.expect(format!(
141 " - {} -------------------- 0/{count}{whitespace_mid}",
142 titles[0]
143 ))?;
144 p.expect(format!(
145 " - {} -------------------- 0/{count} \r\r",
146 titles[1]
147 ))?;
148
149 let generate_text = |title: &str, num: u16, confirmed_complete: bool| -> String {
150 let symbol = if confirmed_complete && num.eq(&count) {
151 "â"
152 } else {
153 "-"
154 };
155 let bar = match (num, count) {
156 (0, _) => "--------------------",
157 (1, 2) => "###########---------",
158 (x, y) => {
159 if x.eq(&y) {
160 "####################"
161 } else {
162 "--unknown--"
163 }
164 }
165 };
166 format!(
167 " {symbol} {title} {bar} {num}/{count}{}",
168 if (&title).eq(titles.last().unwrap()) {
169 whitespace_end
170 } else {
171 whitespace_mid
172 }
173 )
174 };
175 let mut nums: HashMap<&str, u16> = HashMap::new();
176 for title in &titles {
177 nums.insert(title, 0);
178 p.expect(generate_text(title, 0, false))?;
179 }
180 loop {
181 for selected_title in &titles {
182 for title in &titles {
183 if title.eq(selected_title) {
184 let new_num = nums.get(title).unwrap() + 1;
185 if new_num.gt(&count) {
186 return Ok(());
187 }
188 nums.insert(title, new_num);
189 p.expect(generate_text(title, *nums.get(title).unwrap(), false))?;
190 } else {
191 p.expect(generate_text(title, *nums.get(title).unwrap(), true))?;
192 }
193 }
194 }
195 }
196}