1pub mod crypto;
2pub mod dispute;
3pub mod error;
4pub mod message;
5pub mod order;
6pub mod prelude;
7pub mod rating;
8pub mod user;
9#[cfg(test)]
10mod test {
11 use std::vec;
12
13 use crate::error::CantDoReason;
14 use crate::message::{Action, Message, MessageKind, Payload, Peer};
15 use crate::order::{Kind, SmallOrder, Status};
16 use nostr_sdk::Keys;
17 use uuid::uuid;
18
19 #[test]
20 fn test_status_string() {
21 assert_eq!(Status::Active.to_string(), "active");
22 assert_eq!(Status::CompletedByAdmin.to_string(), "completed-by-admin");
23 assert_eq!(Status::FiatSent.to_string(), "fiat-sent");
24 assert_ne!(Status::Pending.to_string(), "Pending");
25 }
26
27 #[test]
28 fn test_kind_string() {
29 assert_ne!(Kind::Sell.to_string(), "active");
30 assert_eq!(Kind::Sell.to_string(), "sell");
31 assert_eq!(Kind::Buy.to_string(), "buy");
32 assert_ne!(Kind::Buy.to_string(), "active");
33 }
34
35 #[test]
36 fn test_order_message() {
37 let uuid = uuid!("308e1272-d5f4-47e6-bd97-3504baea9c23");
38 let payload = Payload::Order(SmallOrder::new(
39 Some(uuid),
40 Some(Kind::Sell),
41 Some(Status::Pending),
42 100,
43 "eur".to_string(),
44 None,
45 None,
46 100,
47 vec!["SEPA".to_string()],
48 1,
49 None,
50 None,
51 None,
52 Some(1627371434),
53 None,
54 None,
55 None,
56 ));
57
58 let test_message = Message::Order(MessageKind::new(
59 Some(uuid),
60 Some(1),
61 Some(2),
62 Action::NewOrder,
63 Some(payload),
64 ));
65 let test_message_json = test_message.as_json().unwrap();
66 let sample_message = r#"{"order":{"version":1,"id":"308e1272-d5f4-47e6-bd97-3504baea9c23","request_id":1,"trade_index":2,"action":"new-order","payload":{"order":{"id":"308e1272-d5f4-47e6-bd97-3504baea9c23","kind":"sell","status":"pending","amount":100,"fiat_code":"eur","fiat_amount":100,"payment_method":["SEPA"],"premium":1,"created_at":1627371434}}}}"#;
67 let message = Message::from_json(sample_message).unwrap();
68 assert!(message.verify());
69 let message_json = message.as_json().unwrap();
70 assert_eq!(message_json, test_message_json);
71 }
72
73 #[test]
74 fn test_payment_request_payload_message() {
75 let uuid = uuid!("308e1272-d5f4-47e6-bd97-3504baea9c23");
76 let test_message = Message::Order(MessageKind::new(
77 Some(uuid),
78 Some(1),
79 Some(3),
80 Action::PayInvoice,
81 Some(Payload::PaymentRequest(
82 Some(SmallOrder::new(
83 Some(uuid),
84 Some(Kind::Sell),
85 Some(Status::WaitingPayment),
86 100,
87 "eur".to_string(),
88 None,
89 None,
90 100,
91 vec!["SEPA".to_string()],
92 1,
93 None,
94 None,
95 None,
96 Some(1627371434),
97 None,
98 None,
99 None,
100 )),
101 "lnbcrt78510n1pj59wmepp50677g8tffdqa2p8882y0x6newny5vtz0hjuyngdwv226nanv4uzsdqqcqzzsxqyz5vqsp5skn973360gp4yhlpmefwvul5hs58lkkl3u3ujvt57elmp4zugp4q9qyyssqw4nzlr72w28k4waycf27qvgzc9sp79sqlw83j56txltz4va44j7jda23ydcujj9y5k6k0rn5ms84w8wmcmcyk5g3mhpqepf7envhdccp72nz6e".to_string(),
102 None,
103 )),
104 ));
105 let sample_message = r#"{"order":{"version":1,"id":"308e1272-d5f4-47e6-bd97-3504baea9c23","request_id":1,"trade_index":3,"action":"pay-invoice","payload":{"payment_request":[{"id":"308e1272-d5f4-47e6-bd97-3504baea9c23","kind":"sell","status":"waiting-payment","amount":100,"fiat_code":"eur","fiat_amount":100,"payment_method":["SEPA"],"premium":1,"created_at":1627371434},"lnbcrt78510n1pj59wmepp50677g8tffdqa2p8882y0x6newny5vtz0hjuyngdwv226nanv4uzsdqqcqzzsxqyz5vqsp5skn973360gp4yhlpmefwvul5hs58lkkl3u3ujvt57elmp4zugp4q9qyyssqw4nzlr72w28k4waycf27qvgzc9sp79sqlw83j56txltz4va44j7jda23ydcujj9y5k6k0rn5ms84w8wmcmcyk5g3mhpqepf7envhdccp72nz6e",null]}}}"#;
106 let message = Message::from_json(sample_message).unwrap();
107 assert!(message.verify());
108 let message_json = message.as_json().unwrap();
109 let test_message_json = test_message.as_json().unwrap();
110 assert_eq!(message_json, test_message_json);
111 }
112
113 #[test]
114 fn test_message_payload_signature() {
115 let uuid = uuid!("308e1272-d5f4-47e6-bd97-3504baea9c23");
116 let peer = Peer::new(
117 "npub1testjsf0runcqdht5apkfcalajxkf8txdxqqk5kgm0agc38ke4vsfsgzf8".to_string(),
118 None,
119 );
120 let payload = Payload::Peer(peer);
121 let test_message = Message::Order(MessageKind::new(
122 Some(uuid),
123 Some(1),
124 Some(2),
125 Action::FiatSentOk,
126 Some(payload),
127 ));
128 assert!(test_message.verify());
129 let test_message_json = test_message.as_json().unwrap();
130 let trade_keys =
132 Keys::parse("110e43647eae221ab1da33ddc17fd6ff423f2b2f49d809b9ffa40794a2ab996c")
133 .unwrap();
134 let sig = Message::sign(test_message_json.clone(), &trade_keys);
135
136 assert!(Message::verify_signature(
137 test_message_json,
138 trade_keys.public_key(),
139 sig
140 ));
141 }
142
143 #[test]
144 fn test_cant_do_message_serialization() {
145 let reasons = vec![
147 CantDoReason::InvalidSignature,
148 CantDoReason::InvalidTradeIndex,
149 CantDoReason::InvalidAmount,
150 CantDoReason::InvalidInvoice,
151 CantDoReason::InvalidPaymentRequest,
152 CantDoReason::InvalidPeer,
153 CantDoReason::InvalidRating,
154 CantDoReason::InvalidTextMessage,
155 CantDoReason::InvalidOrderStatus,
156 CantDoReason::InvalidPubkey,
157 CantDoReason::InvalidParameters,
158 CantDoReason::OrderAlreadyCanceled,
159 CantDoReason::CantCreateUser,
160 CantDoReason::IsNotYourOrder,
161 CantDoReason::NotAllowedByStatus,
162 CantDoReason::OutOfRangeFiatAmount,
163 CantDoReason::OutOfRangeSatsAmount,
164 CantDoReason::IsNotYourDispute,
165 CantDoReason::NotFound,
166 ];
167
168 for reason in reasons {
169 let cant_do = Message::CantDo(MessageKind::new(
170 None,
171 None,
172 None,
173 Action::CantDo,
174 Some(Payload::CantDo(Some(reason.clone()))),
175 ));
176 let message = Message::from_json(&cant_do.as_json().unwrap()).unwrap();
177 assert!(message.verify());
178 assert_eq!(message.as_json().unwrap(), cant_do.as_json().unwrap());
179 }
180
181 let cant_do = Message::CantDo(MessageKind::new(
183 None,
184 None,
185 None,
186 Action::CantDo,
187 Some(Payload::CantDo(None)),
188 ));
189 let message = Message::from_json(&cant_do.as_json().unwrap()).unwrap();
190 assert!(message.verify());
191 assert_eq!(message.as_json().unwrap(), cant_do.as_json().unwrap());
192 }
193}