Playfarmework testing: Upload file with Fake Request and mulipartFormData - scala

I'm trying to unit test a file upload through multipartFormData and returning status 200 if it returns back the uploaded url. However, I keep getting status 400 and unsure why its been unsucessful.
I've found online of the call needs to be writeable and have included a writeable class which i've imported as lazy val
"return a 200 if successful" in new SetUp {
val fakeFileName = "testImage.png"
val fakeUploadImageUrl = "https://s3.fakeImageUrl.png"
val imageFile = new File(fakeFileName)
val tempFile = TemporaryFile(imageFile)
val multipartFormData = new MultipartFormData(
dataParts = Map(),
files = Seq(FilePart[TemporaryFile]("file", fakeFileName, Some("text/plain"), tempFile)),
badParts = Seq()
)
when(imageService.uploadWebImage(any(), any())).thenReturn(Future.successful(fakeUploadImageUrl))
val request = FakeRequest(HttpVerbs.POST, s"/internal/challengesv2/v1/instances/image/$fakeFileName")
.withBody(multipartFormData)
val response = testController.uploadImage(fakeFileName).apply(request)
assert(status(response.run()) === 200)
assert(contentAsJson(response.run()) === Json.toJson(fakeUploadImageUrl))
}
expect 200 but returning 400

Related

Facing Error "Failed to load PDF document." in scala when send pdf file as bytearray in response (scala)

I write the below code for send pdf file as a response, but I stuck at one point it will give an error "Failed to load PDF document."
Code is :
def downloadResumeFile(downloadFilePath: String, response: HttpServletResponse): ResponseEntity[String] = {
val filename = "somefile.pdf"
val file = new File(filename)
println(file.exists())
val fis = new FileInputStream(file)
var data = new Array[Byte](file.length.asInstanceOf[Int])
fis.read(data)
val bos = new ByteArrayOutputStream()
data = bos.toByteArray
response.setContentType("application/pdf; charset=UTF-8")
response.setHeader("Content-Disposition", s"attachment;filename="+downloadFilePath)
response.setCharacterEncoding("UTF-8")
val servletOutputStream = new PrintWriter(response.getOutputStream)
servletOutputStream.println(data)
fis.close()
bos.flush()
bos.close()
servletOutputStream.flush()
servletOutputStream.close()
ResponseEntity.ok("File downloaded")
}
Can anyone help me get out of this question?
A PrintWriter is useful to write text, but PDFs are binary data.
val out = response.getOutputStream
java.nio.file.Files.copy(file.toPath, out)
out.flush()

Sending a document to Stripe using Play! Scala 2.5

I want to send a file to Stripe using Play! Scala 2.5.
The documentation says that the request should be (curl equivalent) like this:
curl https://uploads.stripe.com/v1/files \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
-F purpose=dispute_evidence \
-F file="#/path/to/a/file.jpg"
Mine is:
def test: Action[MultipartFormData[TemporaryFile]] = Action(parse.multipartFormData) { request =>
val image = request.body.file("picture").get
val info = Map("purpose" -> Seq("identity_document"))
val attachment =
FilePart[TemporaryFile](
key = "file",
filename = "file",
contentType = image.contentType,
ref = image.ref)
val formData: MultipartFormData[TemporaryFile] =
MultipartFormData(
dataParts = info,
files = Seq(attachment),
badParts = Seq.empty)
import services.MultipartFormDataWritable.anyContentAsMultipartFormWritable
wSClient
.url("https://uploads.stripe.com/v1/files")
.withAuth("secret_key", "", WSAuthScheme.BASIC)
.post(formData)
.map(response => println(response.body))
Ok
}
But Stripe returns me this Bad Request error:
"error": {
"type": "invalid_request_error",
"message": "Missing required param: file.",
"param": "file"
}
What am I doing wrong?
This works:
val file = request.body.file("picture").get
val filename = file.filename
val contentType = file.contentType.getOrElse(logAndThrowException("Id card without content type"))
if (contentType != "image/png" && contentType != "image/jpeg" && contentType != "image/jpg") {
logAndThrowException("Wrong content type (jp[e]g or png required)")
}
val tmpFile = file.ref.file
wSClient
.url("https://uploads.stripe.com/v1/files")
.withAuth(stripeTestAPIKey, "", WSAuthScheme.BASIC)
.withHeaders("Stripe-Account" -> stripeAccount)
.post(
Source(
iterable =
FilePart("file", filename, Option("text/plain"),
FileIO.fromPath(tmpFile.toPath)) ::
DataPart("purpose", "identity_document") ::
List()))

Bad Request on AWS ElasticSearch

I'm trying to connect to an IAM controlled ElasticSearch domain, I've created a request, and signed it, and everything works fine for method GET, but on method POST I get a 400 Bad Request
This clearly has something to do with the payload. If I provide a payload empty string ("") it works apporpriately, but anything else results in a bad request.
What am I missing?
val url = s"https://$host/TEST/article/_search"
val serviceName = "es"
val regionName = "us-east-1"
val request = new DefaultRequest(serviceName)
val payload =
"""{"1":"1"}""".trim
val payloadBytes = payload.getBytes(StandardCharsets.UTF_8)
val payloadStream = new ByteArrayInputStream(payloadBytes)
request.setContent(payloadStream)
val endpointUri = URI.create(url)
request.setEndpoint(endpointUri)
request.setHttpMethod(HttpMethodName.POST)
val credProvider = new EnvironmentVariableCredentialsProvider
val credentials = credProvider.getCredentials
val signer = new AWS4Signer
signer.setRegionName(regionName)
signer.setServiceName(serviceName)
signer.sign(request, credentials)
val context = new ExecutionContext(true)
val clientConfiguration = new ClientConfiguration()
val client = new AmazonHttpClient(clientConfiguration)
val rh = new MyHttpResponseHandler
val eh = new MyErrorHandler
val response =
client.execute(request, rh , eh, context);
note: if you run into this problem, inspect the actual content of the response, it may be a result of a mismatch between the index and your query.
My problem was that the specific query I was using was inappropriate for the specified index, and that resulted in a 400

How to form a data using MultiPart/form-data in Play scala?

I don't know how to send multipart data in play scala Test case(Specs2).
In my project, method receives multipart data, code look like this
def school_register() = Action(parse.multipartFormData) { implicit request =>
}
In my test case using Specs2 how to form multipart data manually and want hit the school_register method. Once method hitted values are inserted into DB. I have four parameters regno=100,name="xxxx", address="xxx", std=5. Without multipart its working but i have to use multipart data.
Without Multipart i'm using like this
"com.example.schooladmin" should {
"responds with 200 for addSchoolRegister action with all required parameters" in new WithApplication {
val controller = new TestController()
val result = controller.school_registerr() .apply(FakeRequest().withFormUrlEncodedBody(
“Reg No” -> “100”,“Name” -> “XXX”,“Address” -> “XXXXX”,“std” -> “5”))
status(result) must equalTo(OK)
}
}
Here is how I'm doing this, I create a temporary file and I post it with withMultipartFormDataBody:
val tempFile = TemporaryFile(new java.io.File("../server/idCards/5e7b7c6c-98b3-4245-a5fb-405c9cc904f4"))
val part = FilePart[TemporaryFile](key = "picture", filename = "the.file", contentType = Some("image/jpeg"), ref = tempFile)
val formData = MultipartFormData(dataParts = Map(), files = Seq(part), badParts = Seq(), missingFileParts = Seq())
val Some(result) = route(FakeRequest(userDomain.routes.UserController.createIdCard())
.withMultipartFormDataBody(formData))
status(result) mustEqual OK

How to use scalatest to test file upload in Play Framework?

I am writing tests for an application created using Scala/Play Framework. There is a route with takes file to upload. This is what I have written so far.
val dataFile: File = new File("../TestCSV/product.csv")
val tempFile = TemporaryFile(dataFile)
val part = FilePart[TemporaryFile](key = "dataFile", filename = "product.csv", contentType = Some("application/vnd.ms-excel"), ref = tempFile)
val formData: MultipartFormData[TemporaryFile] = MultipartFormData[TemporaryFile](dataParts = Map(), files = Seq(part), badParts = Seq(), missingFileParts = Seq())
val request: FakeRequest[MultipartFormData[TemporaryFile]] = FakeRequest[MultipartFormData[TemporaryFile]]("POST", "/api/core/v0.1/data-import/uploads/%s/product".format(sandboxId), headers, formData)
val response = route(request).get
status(response) mustBe OK
I am getting this error.
Cannot write an instance of play.api.mvc.MultipartFormData[play.api.libs.Files.TemporaryFile] to HTTP response. Try to define a Writeable[play.api.mvc.MultipartFormData[play.api.libs.Files.TemporaryFile]]
How do I make this class writable?