package play.api.test import play.api.libs.ws._ import play.api.libs.ws.ning.{ NingWSClientConfig, NingWSClient } import play.api.mvc.Call trait WsTestClient { type Port = Int /** * Constructs a WS request holder for the given reverse route. Optionally takes a WSClient. Note that the WS client used * by default requires a running Play application (use WithApplication for tests). * * For example: * {{{ * "work" in new WithApplication() { implicit app => * wsCall(controllers.routes.Application.index()).get() * } * }}} */ def wsCall(call: Call)(implicit port: Port, client: WSClient = WS.client(play.api.Play.current)): WSRequest = wsUrl(call.url) /** * Constructs a WS request holder for the given relative URL. Optionally takes a port and WSClient. Note that the WS client used * by default requires a running Play application (use WithApplication for tests). */ def wsUrl(url: String)(implicit port: Port, client: WSClient = WS.client(play.api.Play.current)) = { WS.clientUrl("http://localhost:" + port + url) } /** * Run the given block of code with a client. * * The client passed to the block of code supports absolute path relative URLs passed to the url method. If an * absolute path relative URL is used, the protocol is assumed to be http, the host localhost, and the port is the * implicit port parameter passed to this method. This is designed to work smoothly with the Server.with* methods, * for example: * * {{{ * Server.withRouter() { * case GET(p"/hello/$who") => Action(Ok("Hello " + who)) * } { implicit port => * withClient { ws => * await(ws.url("/hello/world").get()).body must_== "Hello world" * } * } * }}} * * @param block The block of code to run * @param port The port * @return The result of the block of code */ def withClient[T](block: WSClient => T)(implicit port: play.api.http.Port = new play.api.http.Port(-1)) = { // Don't retry for tests val client = NingWSClient(NingWSClientConfig(maxRequestRetry = 0)) val wrappedClient = new WSClient { def underlying[T] = client.underlying.asInstanceOf[T] def url(url: String) = { if (url.startsWith("/") && port.value != -1) { client.url(s"http://localhost:$port$url") } else { client.url(url) } } def close() = () } try { block(wrappedClient) } finally { client.close() } } } object WsTestClient extends WsTestClient