diff --git a/CHANGES.md b/CHANGES.md index 237b4bfb..9cb883a3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,8 @@ * Support HTTP/2 with rustls #36 +* Allow TestServer to open a websocket on any URL # 433 + ### Fixed * Do not override HOST header for client request #428 @@ -22,7 +24,7 @@ * Add implementation of `FromRequest` for `Option` and `Result` * Allow to handle application prefix, i.e. allow to handle `/app` path - for application with `/app` prefix. + for application with `/app` prefix. Check [`App::prefix()`](https://actix.rs/actix-web/actix_web/struct.App.html#method.prefix) api doc. diff --git a/src/test.rs b/src/test.rs index f94732dd..2ec7a98d 100644 --- a/src/test.rs +++ b/src/test.rs @@ -207,15 +207,23 @@ impl TestServer { self.rt.block_on(fut) } - /// Connect to websocket server - pub fn ws( + /// Connect to websocket server at a given path + pub fn ws_at( &mut self, + path: &str, ) -> Result<(ws::ClientReader, ws::ClientWriter), ws::ClientError> { - let url = self.url("/"); + let url = self.url(path); self.rt .block_on(ws::Client::with_connector(url, self.conn.clone()).connect()) } + /// Connect to a websocket server + pub fn ws( + &mut self, + ) -> Result<(ws::ClientReader, ws::ClientWriter), ws::ClientError> { + self.ws_at("/") + } + /// Create `GET` request pub fn get(&self) -> ClientRequestBuilder { ClientRequest::get(self.url("/").as_str()) diff --git a/tests/test_ws.rs b/tests/test_ws.rs index 1ed80bf7..86717272 100644 --- a/tests/test_ws.rs +++ b/tests/test_ws.rs @@ -64,6 +64,46 @@ fn test_simple() { ); } +// websocket resource helper function +fn start_ws_resource(req: &HttpRequest) -> Result { + ws::start(req, Ws) +} + +#[test] +fn test_simple_path() { + const PATH:&str = "/v1/ws/"; + + // Create a websocket at a specific path. + let mut srv = test::TestServer::new(|app| { + app.resource(PATH, |r| r.route().f(start_ws_resource)); + }); + // fetch the sockets for the resource at a given path. + let (reader, mut writer) = srv.ws_at(PATH).unwrap(); + + writer.text("text"); + let (item, reader) = srv.execute(reader.into_future()).unwrap(); + assert_eq!(item, Some(ws::Message::Text("text".to_owned()))); + + writer.binary(b"text".as_ref()); + let (item, reader) = srv.execute(reader.into_future()).unwrap(); + assert_eq!( + item, + Some(ws::Message::Binary(Bytes::from_static(b"text").into())) + ); + + writer.ping("ping"); + let (item, reader) = srv.execute(reader.into_future()).unwrap(); + assert_eq!(item, Some(ws::Message::Pong("ping".to_owned()))); + + writer.close(Some(ws::CloseCode::Normal.into())); + let (item, _) = srv.execute(reader.into_future()).unwrap(); + assert_eq!( + item, + Some(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) + ); +} + + #[test] fn test_empty_close_code() { let mut srv = test::TestServer::new(|app| app.handler(|req| ws::start(req, Ws)));