pekko/akka-http-tests/src/test/scala/akka/http/scaladsl/marshalling/MarshallingSpec.scala

152 lines
7.1 KiB
Scala

/**
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.http.scaladsl.marshalling
import scala.collection.immutable.ListMap
import org.scalatest.{ BeforeAndAfterAll, FreeSpec, Matchers }
import akka.util.ByteString
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Source
import akka.http.scaladsl.testkit.MarshallingTestUtils
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._
import akka.http.impl.util._
import akka.http.scaladsl.model._
import headers._
import HttpCharsets._
import MediaTypes._
class MarshallingSpec extends FreeSpec with Matchers with BeforeAndAfterAll with MultipartMarshallers with MarshallingTestUtils {
implicit val system = ActorSystem(getClass.getSimpleName)
implicit val materializer = ActorMaterializer()
import system.dispatcher
"The PredefinedToEntityMarshallers." - {
"StringMarshaller should marshal strings to `text/plain` content in UTF-8" in {
marshal("Ha“llo") shouldEqual HttpEntity("Ha“llo")
}
"DoneMarshaller should enable marshalling of akka.Done" in {
marshal(akka.Done) shouldEqual HttpEntity("")
}
"CharArrayMarshaller should marshal char arrays to `text/plain` content in UTF-8" in {
marshal("Ha“llo".toCharArray) shouldEqual HttpEntity("Ha“llo")
}
"FormDataMarshaller should marshal FormData instances to application/x-www-form-urlencoded content" in {
marshal(FormData(Map("name" -> "Bob", "pass" -> "hällo", "admin" -> ""))) shouldEqual
HttpEntity(`application/x-www-form-urlencoded` withCharset `UTF-8`, "name=Bob&pass=h%C3%A4llo&admin=")
}
}
"The GenericMarshallers." - {
"optionMarshaller should enable marshalling of Option[T]" in {
marshal(Some("Ha“llo")) shouldEqual HttpEntity("Ha“llo")
marshal(None: Option[String]) shouldEqual HttpEntity.Empty
}
"eitherMarshaller should enable marshalling of Either[A, B]" in {
marshal[Either[Array[Char], String]](Right("right")) shouldEqual HttpEntity("right")
marshal[Either[Array[Char], String]](Left("left".toCharArray)) shouldEqual HttpEntity("left")
}
}
"The MultipartMarshallers." - {
"multipartMarshaller should correctly marshal multipart content with" - {
"one empty part" in {
marshal(Multipart.General(`multipart/mixed`, Multipart.General.BodyPart.Strict(""))) shouldEqual HttpEntity(
contentType = `multipart/mixed` withBoundary randomBoundary withCharset `UTF-8`,
string = s"""--$randomBoundary
|Content-Type: text/plain; charset=UTF-8
|
|
|--$randomBoundary--""".stripMarginWithNewline("\r\n"))
}
"one non-empty part" in {
marshal(Multipart.General(`multipart/alternative`, Multipart.General.BodyPart.Strict(
entity = HttpEntity(ContentTypes.`text/plain(UTF-8)`, "test@there.com"),
headers = `Content-Disposition`(ContentDispositionTypes.`form-data`, Map("name" -> "email")) :: Nil))) shouldEqual
HttpEntity(
contentType = `multipart/alternative` withBoundary randomBoundary withCharset `UTF-8`,
string = s"""--$randomBoundary
|Content-Type: text/plain; charset=UTF-8
|Content-Disposition: form-data; name=email
|
|test@there.com
|--$randomBoundary--""".stripMarginWithNewline("\r\n"))
}
"two different parts" in {
marshal(Multipart.General(`multipart/related`,
Multipart.General.BodyPart.Strict(HttpEntity(`text/plain` withCharset `US-ASCII`, "first part, with a trailing linebreak\r\n")),
Multipart.General.BodyPart.Strict(
HttpEntity(`application/octet-stream`, ByteString("filecontent")),
RawHeader("Content-Transfer-Encoding", "binary") :: Nil))) shouldEqual
HttpEntity(
contentType = `multipart/related` withBoundary randomBoundary withCharset `UTF-8`,
string = s"""--$randomBoundary
|Content-Type: text/plain; charset=US-ASCII
|
|first part, with a trailing linebreak
|
|--$randomBoundary
|Content-Type: application/octet-stream
|Content-Transfer-Encoding: binary
|
|filecontent
|--$randomBoundary--""".stripMarginWithNewline("\r\n"))
}
}
"multipartFormDataMarshaller should correctly marshal 'multipart/form-data' content with" - {
"two fields" in {
marshal(Multipart.FormData(ListMap(
"surname" -> HttpEntity("Mike"),
"age" -> marshal(<int>42</int>)))) shouldEqual
HttpEntity(
contentType = `multipart/form-data` withBoundary randomBoundary withCharset `UTF-8`,
string = s"""--$randomBoundary
|Content-Type: text/plain; charset=UTF-8
|Content-Disposition: form-data; name=surname
|
|Mike
|--$randomBoundary
|Content-Type: text/xml; charset=UTF-8
|Content-Disposition: form-data; name=age
|
|<int>42</int>
|--$randomBoundary--""".stripMarginWithNewline("\r\n"))
}
"two fields having a custom `Content-Disposition`" in {
marshal(Multipart.FormData(Source(List(
Multipart.FormData.BodyPart("attachment[0]", HttpEntity(`text/csv` withCharset `UTF-8`, "name,age\r\n\"John Doe\",20\r\n"),
Map("filename" -> "attachment.csv")),
Multipart.FormData.BodyPart("attachment[1]", HttpEntity("naice!".getBytes),
Map("filename" -> "attachment2.csv"), List(RawHeader("Content-Transfer-Encoding", "binary"))))))) shouldEqual
HttpEntity(
contentType = `multipart/form-data` withBoundary randomBoundary withCharset `UTF-8`,
string = s"""--$randomBoundary
|Content-Type: text/csv; charset=UTF-8
|Content-Disposition: form-data; filename=attachment.csv; name="attachment[0]"
|
|name,age
|"John Doe",20
|
|--$randomBoundary
|Content-Type: application/octet-stream
|Content-Disposition: form-data; filename=attachment2.csv; name="attachment[1]"
|Content-Transfer-Encoding: binary
|
|naice!
|--$randomBoundary--""".stripMarginWithNewline("\r\n"))
}
}
}
override def afterAll() = system.terminate()
protected class FixedRandom extends java.util.Random {
override def nextBytes(array: Array[Byte]): Unit = "my-stable-boundary".getBytes("UTF-8").copyToArray(array)
}
override protected val multipartBoundaryRandom = new FixedRandom // fix for stable value
}