He guys,
I'm having issues with testing play controller that handles multipart form data. It expects text field and some files.
The controller uses temporary files def insert(): Action[MultipartFormData[TemporaryFile]]
.
It works fine on production but I'm trying to add tests and I can't figure out how to properly create test request.
I first tried:
val formData: MultipartFormData[TemporaryFile] = MultipartFormData(
dataParts = Map(
"json" -> Seq(Json.stringify(Json.toJson(newCreateRequest(name = "library".some))))
),
files = Seq(filePart),
badParts = Seq.empty
)
val request = requestWithToken.withMultipartFormDataBody(formData)
val result = controller.insert()(request)
but it tells me boundary is missing so I tried explicitly setting content type header:
FakeRequest()
.withHeaders(
"Content-Type" -> "multipart/form-data; boundary=----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3")
Now it doesn't make sense as MultipartFormData
doesn't know boundary I used and I don't see any way to set it there. Anyway I'm getting bad request "Unexpected end of input".
I gave up with this approach and started creating raw request just to see if I get any other result.
val boundary = "----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3"
val body = """------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3
|Content-Disposition: form-data; name="json"
|
|{"name":"test"}
|------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3--
|""".stripMargin
And obviously creating request with content type and content length headers.
Nothing seems to work.
Since I added boundary I'm getting "Unexpected end of input".
I tried everything using ByteString
instead of string body, using string body but replacing line endings.
I even tried running the test in a loop where iterator is being used to set content length in case the length is being calculated differently.
I obviously also tried with empty request (empty files or empty both text and file fields).
Nothing. I'm aways getting Unexpected end of input.
Has anyone had any luck with testing this stuff?
I'm running scala 2.13.16 and play 3.0.6.
He guys,
I'm having issues with testing play controller that handles multipart form data. It expects text field and some files.
The controller uses temporary files def insert(): Action[MultipartFormData[TemporaryFile]]
.
It works fine on production but I'm trying to add tests and I can't figure out how to properly create test request.
I first tried:
val formData: MultipartFormData[TemporaryFile] = MultipartFormData(
dataParts = Map(
"json" -> Seq(Json.stringify(Json.toJson(newCreateRequest(name = "library".some))))
),
files = Seq(filePart),
badParts = Seq.empty
)
val request = requestWithToken.withMultipartFormDataBody(formData)
val result = controller.insert()(request)
but it tells me boundary is missing so I tried explicitly setting content type header:
FakeRequest()
.withHeaders(
"Content-Type" -> "multipart/form-data; boundary=----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3")
Now it doesn't make sense as MultipartFormData
doesn't know boundary I used and I don't see any way to set it there. Anyway I'm getting bad request "Unexpected end of input".
I gave up with this approach and started creating raw request just to see if I get any other result.
val boundary = "----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3"
val body = """------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3
|Content-Disposition: form-data; name="json"
|
|{"name":"test"}
|------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3--
|""".stripMargin
And obviously creating request with content type and content length headers.
Nothing seems to work.
Since I added boundary I'm getting "Unexpected end of input".
I tried everything using ByteString
instead of string body, using string body but replacing line endings.
I even tried running the test in a loop where iterator is being used to set content length in case the length is being calculated differently.
I obviously also tried with empty request (empty files or empty both text and file fields).
Nothing. I'm aways getting Unexpected end of input.
Has anyone had any luck with testing this stuff?
I'm running scala 2.13.16 and play 3.0.6.
Share Improve this question edited Mar 20 at 18:16 Gaël J 15.6k5 gold badges22 silver badges45 bronze badges asked Mar 20 at 14:15 g-tg-t 1,53312 silver badges17 bronze badges1 Answer
Reset to default 0As per one of the test available in Play Framework codebase, you should be able to write something like the following:
val boundary = "-----------------------------14568445977970839651285587160"
val header =
s"--$boundary\r\n" +
"Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"uploadedfile.txt\"\r\n" +
"Content-Type: application/octet-stream\r\n" +
"\r\n"
val content = Array.ofDim[Byte](fileSize)
val footer =
"\r\n" +
"\r\n" +
s"--$boundary--\r\n"
val body = Source(
ByteString(header) ::
ByteString(content) ::
ByteString(footer) ::
Nil
)
val bodySize = header.length + fileSize + footer.length
val request = FakeRequest(
method = "POST",
uri = "/x",
headers = FakeHeaders(
Seq("Content-Type" -> s"multipart/form-data; boundary=$boundary", "Content-Length" -> bodySize.toString)
),
body = body
)