1pub mod compression;
17pub mod error;
18pub mod handler;
19pub mod heartbeat;
20pub mod pool;
21pub mod pusher;
22pub mod subprotocol;
23
24pub use error::WsError;
25pub use handler::*;
26pub use pusher::*;
27
28#[cfg(feature = "server")]
29pub mod server;
30
31#[cfg(feature = "server")]
32pub use server::WsServer;
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn test_websocket_connection_new() {
40 let conn = WebSocketConnection::new("conn1");
41 assert_eq!(conn.id, "conn1");
42 assert!(!conn.is_authenticated);
43 assert!(conn.user_id.is_none());
44 }
45
46 #[test]
47 fn test_websocket_connection_with_user() {
48 let conn = WebSocketConnection::new("conn1").with_user(123);
49 assert_eq!(conn.user_id, Some(123));
50 assert!(conn.is_authenticated);
51 }
52
53 #[test]
54 fn test_websocket_connection_with_address() {
55 let conn = WebSocketConnection::new("conn1").with_address("127.0.0.1:8080");
56 assert_eq!(conn.remote_addr, Some("127.0.0.1:8080".to_string()));
57 }
58
59 #[test]
60 fn test_websocket_connection_subscribe() {
61 let mut conn = WebSocketConnection::new("conn1");
62 conn.subscribe("room1");
63 conn.subscribe("room2");
64 conn.subscribe("room1");
65
66 assert_eq!(conn.subscriptions.len(), 2);
67 assert!(conn.subscriptions.contains(&"room1".to_string()));
68 assert!(conn.subscriptions.contains(&"room2".to_string()));
69 }
70
71 #[test]
72 fn test_websocket_connection_unsubscribe() {
73 let mut conn = WebSocketConnection::new("conn1");
74 conn.subscribe("room1");
75 conn.subscribe("room2");
76 conn.unsubscribe("room1");
77
78 assert_eq!(conn.subscriptions.len(), 1);
79 assert!(!conn.subscriptions.contains(&"room1".to_string()));
80 }
81
82 #[test]
83 fn test_ws_message_builder_text() {
84 let msg = WsMessageBuilder::new().text("hello").build();
85
86 assert_eq!(msg.msg_type, MessageType::Text);
87 assert_eq!(msg.payload, b"hello");
88 }
89
90 #[test]
91 fn test_ws_message_builder_binary() {
92 let msg = WsMessageBuilder::new().binary(vec![1, 2, 3, 4]).build();
93
94 assert_eq!(msg.msg_type, MessageType::Binary);
95 assert_eq!(msg.payload, vec![1, 2, 3, 4]);
96 }
97
98 #[test]
99 fn test_ws_message_builder_json() {
100 let msg = WsMessageBuilder::new()
101 .json(&serde_json::json!({"key": "value"}))
102 .unwrap()
103 .build();
104
105 assert_eq!(msg.msg_type, MessageType::Text);
106 let parsed: serde_json::Value = serde_json::from_slice(&msg.payload).unwrap();
107 assert_eq!(parsed["key"], "value");
108 }
109
110 #[test]
111 fn test_ws_message_builder_with_sender() {
112 let msg = WsMessageBuilder::new()
113 .text("hello")
114 .with_sender(123)
115 .build();
116
117 assert_eq!(msg.sender_id, Some(123));
118 }
119
120 #[test]
121 fn test_ws_message_builder_with_room() {
122 let msg = WsMessageBuilder::new()
123 .text("hello")
124 .with_room("room1")
125 .build();
126
127 assert_eq!(msg.room_id, Some("room1".to_string()));
128 }
129
130 #[test]
131 fn test_ws_message_builder_notification() {
132 let msg = WsMessageBuilder::new()
133 .text("notice")
134 .notification()
135 .build();
136
137 assert_eq!(msg.msg_type, MessageType::Notification);
138 }
139
140 #[test]
141 fn test_ws_message_builder_system() {
142 let msg = WsMessageBuilder::new().text("system").system().build();
143
144 assert_eq!(msg.msg_type, MessageType::System);
145 }
146
147 #[test]
148 fn test_ws_context_new() {
149 let ctx = WsContext::new("conn1");
150 assert_eq!(ctx.connection_id, "conn1");
151 assert!(ctx.user_id.is_none());
152 }
153
154 #[test]
155 fn test_ws_context_with_user() {
156 let ctx = WsContext::new("conn1").with_user(123);
157 assert_eq!(ctx.user_id, Some(123));
158 }
159
160 #[test]
161 fn test_ws_context_with_metadata() {
162 let ctx = WsContext::new("conn1")
163 .with_metadata("key1", "value1")
164 .with_metadata("key2", "value2");
165
166 assert_eq!(ctx.metadata.get("key1"), Some(&"value1".to_string()));
167 assert_eq!(ctx.metadata.get("key2"), Some(&"value2".to_string()));
168 }
169
170 #[test]
171 fn test_push_result_new() {
172 let result = PushResult::new(10);
173 assert_eq!(result.total, 10);
174 assert_eq!(result.success, 0);
175 assert_eq!(result.failed, 0);
176 }
177
178 #[test]
179 fn test_push_result_add() {
180 let mut result = PushResult::new(10);
181 result.add_success();
182 result.add_success();
183 result.add_failure();
184
185 assert_eq!(result.success, 2);
186 assert_eq!(result.failed, 1);
187 }
188
189 #[test]
190 fn test_push_result_success_rate() {
191 let mut result = PushResult::new(10);
192 result.add_success();
193 result.add_success();
194 result.add_success();
195
196 assert_eq!(result.success_rate(), 30.0);
197 }
198
199 #[test]
200 fn test_push_result_zero_total() {
201 let result = PushResult::new(0);
202 assert_eq!(result.success_rate(), 0.0);
203 }
204
205 #[tokio::test]
206 async fn test_realtime_pusher_new() {
207 let pusher = RealtimePusher::new();
208 let count = pusher.connection_count().await;
209 assert_eq!(count, 0);
210 }
211
212 #[tokio::test]
213 async fn test_realtime_pusher_register_connection() {
214 let pusher = RealtimePusher::new();
215 pusher.register_connection("conn1").await;
216
217 let count = pusher.connection_count().await;
218 assert_eq!(count, 1);
219 }
220
221 #[tokio::test]
222 async fn test_realtime_pusher_unregister_connection() {
223 let pusher = RealtimePusher::new();
224 pusher.register_connection("conn1").await;
225 pusher.unregister_connection("conn1").await;
226
227 let count = pusher.connection_count().await;
228 assert_eq!(count, 0);
229 }
230
231 #[tokio::test]
232 async fn test_realtime_pusher_subscribe() {
233 let pusher = RealtimePusher::new();
234 pusher.register_connection("conn1").await;
235 pusher.subscribe("conn1", "room1").await.unwrap();
236
237 let count = pusher.room_count("room1").await;
238 assert_eq!(count, 1);
239 }
240
241 #[tokio::test]
242 async fn test_realtime_pusher_unsubscribe() {
243 let pusher = RealtimePusher::new();
244 pusher.register_connection("conn1").await;
245 pusher.subscribe("conn1", "room1").await.unwrap();
246 pusher.unsubscribe("conn1", "room1").await;
247
248 let count = pusher.room_count("room1").await;
249 assert_eq!(count, 0);
250 }
251
252 #[tokio::test]
253 async fn test_realtime_pusher_room_list() {
254 let pusher = RealtimePusher::new();
255 pusher.register_connection("conn1").await;
256 pusher.subscribe("conn1", "room1").await.unwrap();
257 pusher.subscribe("conn1", "room2").await.unwrap();
258
259 let rooms = pusher.room_list().await;
260 assert!(rooms.contains(&"room1".to_string()));
261 assert!(rooms.contains(&"room2".to_string()));
262 }
263
264 #[tokio::test]
265 async fn test_realtime_pusher_push_to_room() {
266 let pusher = RealtimePusher::new();
267 pusher.register_connection("conn1").await;
268 pusher.subscribe("conn1", "room1").await.unwrap();
269
270 let result = pusher.push_to_room("room1", vec![1, 2, 3]).await;
271 assert!(result.is_ok());
272 assert_eq!(result.unwrap(), 1, "应向 1 个连接推送成功");
274 }
275
276 #[tokio::test]
277 async fn test_realtime_pusher_broadcast() {
278 let pusher = RealtimePusher::new();
279 pusher.register_connection("conn1").await;
280 pusher.register_connection("conn2").await;
281
282 let result = pusher.broadcast(vec![1, 2, 3]).await;
283 assert!(result.is_ok());
284 assert_eq!(result.unwrap(), 2);
285 }
286
287 #[tokio::test]
288 async fn test_realtime_pusher_push_order_status() {
289 let pusher = RealtimePusher::new();
290 pusher.register_connection_with_user("conn1", 123).await;
291
292 let result = pusher.push_order_status(123, 456, "shipped").await;
293 assert!(result.is_ok());
294 assert_eq!(result.unwrap(), 1, "应向 1 个 user_id=123 的连接推送成功");
296 }
297
298 #[tokio::test]
299 async fn test_realtime_pusher_push_customer_message() {
300 let pusher = RealtimePusher::new();
301 pusher.register_connection("conn1").await;
302 pusher.subscribe("conn1", "room1").await.unwrap();
303
304 let result = pusher.push_customer_message("room1", 123, "hello").await;
305 assert!(result.is_ok());
306 assert_eq!(result.unwrap(), 1, "应向 1 个订阅了 room1 的连接推送成功");
308 }
309}