Alexander Chepurnoy

The Web of Mind

Play Framework (v. 2.1): How to Test Actions Processing Binary Streams and Set Content Type for FakeRequest

| Comments

I spent few hours on it, and want to help to save few hours of another Scala/Play developer, maybe You :) Developed and tested with Play 2.1, Scala solution given(but Java alternative wouldn’t be far away from it, I guess).

Consider having action like this one:

def filesEndpointPost = Action(parse.temporaryFile) {
    request =>
      request.headers.get(CONTENT_TYPE) match {
        case Some(cType) =>
          val fileExtension = cType.substring(cType.lastIndexOf("/") + 1, cType.length)
          val filename = RandomStringUtils.randomAlphanumeric(5) + "." + fileExtension
          val visibleFilename = filesFolder + "/" + filename
          request.body.moveTo(file(tmpFolder,filename), true)
          Created.withHeaders(LOCATION -> visibleFilename)
        case None =>
          BadRequest("No content type given")

You want to test it. Test should:

  • Send binary stream to the action
  • Set Content-Type header. By default it’s rewritten automatically by the framework, so custom play.api.http.Writeable implementation needed to be given to route() function

With such requirements, a solution is:

"Send binary stream with POST to /files" in new WithApplication {
  val filesPostRoute = route(FakeRequest(POST,
    FakeHeaders(Seq(CONTENT_TYPE -> Seq("application/pdf"))),
    "brokenpdf"))(new Writeable({s: String => s.getBytes}, None))

  val result = filesPostRoute.get
  status(result) mustEqual CREATED
  header(LOCATION, result).getOrElse("") must contain("files/")
  header(LOCATION, result).getOrElse("") must contain(".pdf")