The idea is to be able to unit test websocket endpoints on a router service. Any other kind of endpoint is fairly easy to test with a Request
, but I can't figure out a way of easily testing websocket responses, as hitting the endpoint with a Request
will give you a 501 error since you don't have any corresponding socket to handshake with.
This is the router I'm using
def router(averages: IO[SomeAverages]): HttpRoutes[F] =
HttpRoutes.of[F] {
case GET -> Root =>
val toClient: Stream[F, WebSocketFrame] = {
Stream
.awakeEvery[F](5.seconds)
.map(_ => {
val avg = averages.unsafeRunSync
WebSocketFrame.Text(avg.toString)
})
}
val fromClient: Pipe[F, WebSocketFrame, Unit] = _.evalMap {
case WebSocketFrame.Text(t, _) => F.delay(println(t))
case f => F.delay(println(s"Unknown type: $f"))
}
WebSocketBuilder[F].build(toClient, fromClient)
}
The idea is to get something akin to the below code to work with websockets
val server = Server.initServer[IO]
val router = server.router
val request = Request[IO](Method.GET, uri"/")
val io = router.orNotFound.run(request)
val response = io.unsafeRunSync
// response.status should be 200
// will return 501 if a websocket endpoint
I've tried variations of this such as adding headers like
val request = Request[IO](
Method.GET,
uri"/",
Headers(Header("Connection", "Upgrade"), Header("Upgrade", "websocket")
)
Though any Request
will return a 501.
I'm not sure where to go from here, so if anyone has any suggestions I'd be glad to hear. I think it has something to do with creating a websocket client, but I don't know of a way to do that in http4s.
SomeAverages
), and so on. So that someone who has an http4s project already set up can easily c/p your code, compile it and reproduce your problem immediately. – Johppa