Writing a test case for file uploads in Play 2.1 and Scala

后端 未结 7 1908
猫巷女王i
猫巷女王i 2021-01-02 05:39

I found the following question/answer:

Test MultipartFormData in Play 2.0 FakeRequest

But it seems things have changed in Play 2.1. I\'ve tried adapting the

7条回答
  •  天涯浪人
    2021-01-02 06:14

    Here's my version of Writeable[AnyContentAsMultipartFormData]:

    import java.io.File
    
    import play.api.http.{HeaderNames, Writeable}
    import play.api.libs.Files.TemporaryFile
    import play.api.mvc.MultipartFormData.FilePart
    import play.api.mvc.{AnyContentAsMultipartFormData, Codec, MultipartFormData}
    
    object MultipartFormDataWritable {
      val boundary = "--------ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
    
      def formatDataParts(data: Map[String, Seq[String]]) = {
        val dataParts = data.flatMap { case (key, values) =>
          values.map { value =>
            val name = s""""$key""""
            s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name\r\n\r\n$value\r\n"
          }
        }.mkString("")
        Codec.utf_8.encode(dataParts)
      }
    
      def filePartHeader(file: FilePart[TemporaryFile]) = {
        val name = s""""${file.key}""""
        val filename = s""""${file.filename}""""
        val contentType = file.contentType.map { ct =>
          s"${HeaderNames.CONTENT_TYPE}: $ct\r\n"
        }.getOrElse("")
        Codec.utf_8.encode(s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name; filename=$filename\r\n$contentType\r\n")
      }
    
      val singleton = Writeable[MultipartFormData[TemporaryFile]](
        transform = { form: MultipartFormData[TemporaryFile] =>
          formatDataParts(form.dataParts) ++
            form.files.flatMap { file =>
              val fileBytes = Files.readAllBytes(Paths.get(file.ref.file.getAbsolutePath))
              filePartHeader(file) ++ fileBytes ++ Codec.utf_8.encode("\r\n")
            } ++
            Codec.utf_8.encode(s"--$boundary--")
        },
        contentType = Some(s"multipart/form-data; boundary=$boundary")
      )
    }
    
    implicit val anyContentAsMultipartFormWritable: Writeable[AnyContentAsMultipartFormData] = {
      MultipartFormDataWritable.singleton.map(_.mdf)
    }
    

    It's adapted from (and some bugs fixed): https://github.com/jroper/playframework/blob/multpart-form-data-writeable/framework/src/play/src/main/scala/play/api/http/Writeable.scala#L108

    See the whole post here, if you are interested: http://tech.fongmun.com/post/125479939452/test-multipartformdata-in-play

提交回复
热议问题