Skip to content

Commit

Permalink
Merge pull request #1898 from softwaremill/1862_Bady_serializer_for_J…
Browse files Browse the repository at this point in the history
…SON_AST_types

Add tests to check serialization and deserialization
  • Loading branch information
adamw authored Jul 24, 2023
2 parents a53a0a8 + f642903 commit 23b69a3
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class BackendStubCirceTests extends AnyFlatSpec with Matchers with ScalaFutures {

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(uri"http://example.org").response(asJson[Person]).send(backend)
Expand Down
17 changes: 13 additions & 4 deletions json/circe/src/test/scala/sttp/client4/circe/CirceTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ import org.scalatest._
import sttp.client4.internal._
import sttp.client4._
import sttp.model._

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class CirceTests extends AnyFlatSpec with Matchers with EitherValues {
// Needed for the implicit to work in Scala3. Normally this is imported explicitly, only in tests we are in the same package
import sttp.client4.circe.circeBodySerializer
import EitherDecoders._

"The circe module" should "encode arbitrary bodies given an encoder" in {
val body = Outer(Inner(42, true, "horses"), "cats")
Expand Down Expand Up @@ -105,6 +101,19 @@ class CirceTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some("horses/cats")
}

it should "serialize from JsonObject using implicit circeBodySerializer" in {
import io.circe.syntax.EncoderOps
import io.circe.JsonObject
import sttp.model.Uri

val jObject: JsonObject = JsonObject(("location", "hometown".asJson), ("bio", "Scala programmer".asJson))
val result = basicRequest.get(Uri("http://example.org")).body(jObject).body.show

val expectedResult = "string: {\"location\":\"hometown\",\"bio\":\"Scala programmer\"}"

result should be(expectedResult)
}

case class Inner(a: Int, b: Boolean, c: String)

object Inner {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package sttp.client4

import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client4.testing.SyncBackendStub
import sttp.model.Uri
import org.json4s.{native, DefaultFormats}

case class Person(name: String)

class BackendStubJson4sTests extends AnyFlatSpec with Matchers with ScalaFutures {

implicit val serialization = native.Serialization
implicit val formats = DefaultFormats

import json4s._

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(Uri("http://example.org")).response(asJson[Person]).send(backend)

r.is200 should be(true)
r.body should be(Right(Person("John")))
}
}
12 changes: 11 additions & 1 deletion json/json4s/src/test/scala/sttp/client4/Json4sTests.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package sttp.client4

import org.json4s.JsonAST.JString
import org.json4s.ParserUtil.ParseException
import org.json4s.{native, DefaultFormats, MappingException}
import org.json4s.{DefaultFormats, JField, JObject, MappingException, native}
import org.scalatest._
import sttp.client4.internal._
import sttp.model._
Expand Down Expand Up @@ -80,6 +81,15 @@ class Json4sTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some(MediaType.ApplicationJson.copy(charset = Some(Utf8)).toString)
}

it should "serialize from JObject using implicit json4sBodySerializer" in {
val jObject: JObject = JObject(JField("location", JString("hometown")), JField("bio", JString("Scala programmer")))
val result = basicRequest.get(Uri("http://example.org")).body(jObject).body.show

val expectedResult = "string: {\"location\":\"hometown\",\"bio\":\"Scala programmer\"}"

result should be(expectedResult)
}

def extractBody[T](request: PartialRequest[T]): String =
request.body match {
case StringBody(body, "utf-8", MediaType.ApplicationJson) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package sttp.client4.jsoniter

import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client4.testing.SyncBackendStub
import sttp.model.Uri
import com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker

case class Person(name: String)

object Person {
implicit val personJsonValueCodec: JsonValueCodec[Person] = JsonCodecMaker.make
}

class BackendStubJsoniterTests extends AnyFlatSpec with Matchers with ScalaFutures {

import sttp.client4.basicRequest

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(Uri("http://example.org")).response(asJson[Person]).send(backend)

r.is200 should be(true)
r.body should be(Right(Person("John")))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ class JsoniterJsonTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some("horses/cats")
}

it should "serialize from case class Person using implicit jsoniterBodySerializer" in {
val person = Person("John")
val result = basicRequest.get(Uri("http://example.org")).body(person).body.show

val expectedResult = "string: {\"name\":\"John\"}"

result should be(expectedResult)
}

def extractBody[T](request: PartialRequest[T]): String =
request.body match {
case StringBody(body, "utf-8", MediaType.ApplicationJson) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package sttp.client4

import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client4.testing.SyncBackendStub
import sttp.model.Uri
import play.api.libs.json.Json
import play.api.libs.json.OFormat
import playJson._

case class Person(name: String)

object Person {
implicit val personFormat: OFormat[Person] = Json.format[Person]
}

class BackendStubPlayJsonTests extends AnyFlatSpec with Matchers with ScalaFutures {

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(Uri("http://example.org")).response(asJson[Person]).send(backend)

r.is200 should be(true)
r.body should be(Right(Person("John")))
}
}
11 changes: 11 additions & 0 deletions json/play-json/src/test/scala/sttp/client4/PlayJsonTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ class PlayJsonTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some("horses/cats")
}

it should "serialize from JsObject using implicit playJsonBodySerializer" in {
val fields: Seq[(String, JsValue)] =
Seq[(String, JsValue)](("location", JsString("hometown")), ("bio", JsString("Scala programmer")))
val json: JsObject = JsObject(fields)
val result = basicRequest.get(Uri("http://example.org")).body(json).body.show

val expectedResult = "string: {\"location\":\"hometown\",\"bio\":\"Scala programmer\"}"

result should be(expectedResult)
}

case class Inner(a: Int, b: Boolean, c: String)

object Inner {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package sttp.client4

import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client4.testing.SyncBackendStub
import sttp.model.Uri
import spray.json.DefaultJsonProtocol.{jsonFormat1, StringJsonFormat}
import spray.json.RootJsonFormat
import sprayJson._

case class Person(name: String)

object Person {
implicit val personRootJsonFormat: RootJsonFormat[Person] = jsonFormat1(Person.apply)
}

class BackendStubSprayJsonTests extends AnyFlatSpec with Matchers with ScalaFutures {

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(Uri("http://example.org")).response(asJson[Person]).send(backend)

r.is200 should be(true)
r.body should be(Right(Person("John")))
}
}
12 changes: 12 additions & 0 deletions json/spray-json/src/test/scala/sttp/client4/SprayJsonTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ class SprayJsonTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some(MediaType.ApplicationJson.copy(charset = Some(Utf8)).toString)
}

it should "serialize from JsObject using implicit sprayBodySerializer" in {
val json: JsObject = JsObject(
"location" -> "hometown".toJson,
"bio" -> "Scala programmer".toJson
)
val result = basicRequest.get(Uri("http://example.org")).body(json).body.show

val expectedResult = "string: {\"bio\":\"Scala programmer\",\"location\":\"hometown\"}"

result should be(expectedResult)
}

def extractBody[T](request: PartialRequest[T]): String =
request.body match {
case StringBody(body, "utf-8", MediaType.ApplicationJson) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ class BackendStubUpickleTests extends AnyFlatSpec with Matchers with ScalaFuture
r.is200 should be(true)
r.body should be(Right(Person("John")))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import org.scalatest._
import sttp.client4.internal._
import sttp.client4._
import sttp.model._

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import ujson.Obj

class UpickleTests extends AnyFlatSpec with Matchers with EitherValues {
"The upickle module" should "encode arbitrary bodies given an encoder" in {
Expand Down Expand Up @@ -88,6 +88,18 @@ class UpickleTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some("horses/cats")
}

it should "serialize ujson.Obj using implicit upickleBodySerializer" in {
val json: Obj = ujson.Obj(
"location" -> "hometown",
"bio" -> "Scala programmer"
)
val result = basicRequest.get(Uri("http://example.org")).body(json).body.show

val expectedResult = "string: {\"location\":\"hometown\",\"bio\":\"Scala programmer\"}"

result should be(expectedResult)
}

case class Inner(a: Int, b: Boolean, c: String)

object Inner {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package sttp.client4.ziojson

import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client4.basicRequest
import sttp.client4.testing.SyncBackendStub
import sttp.model.Uri
import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder}

case class Person(name: String)

object Person {
implicit val encoder: JsonEncoder[Person] = DeriveJsonEncoder.gen[Person]
implicit val codec: JsonDecoder[Person] = DeriveJsonDecoder.gen[Person]
}

class BackendStubJson4sTests extends AnyFlatSpec with Matchers with ScalaFutures {

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(Uri("http://example.org")).response(asJson[Person]).send(backend)

r.is200 should be(true)
r.body should be(Right(Person("John")))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import org.scalatest.matchers.should.Matchers
import zio.json._
import sttp.client4._
import sttp.client4.internal.Utf8

import sttp.model._
import zio.Chunk
import zio.json.ast.Json

class ZioJsonTests extends AnyFlatSpec with Matchers with EitherValues {

Expand Down Expand Up @@ -90,6 +91,16 @@ class ZioJsonTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some("horses/cats")
}

it should "serialize from Json.Obj using implicit zioJsonBodySerializer" in {
val fields: Chunk[(String, Json)] = Chunk(("location", Json.Str("hometown")), ("bio", Json.Str("Scala programmer")))
val jObject: Json.Obj = Json.Obj(fields)
val result = basicRequest.get(Uri("http://example.org")).body(jObject).body.show

val expectedResult = "string: {\"location\":\"hometown\",\"bio\":\"Scala programmer\"}"

result should be(expectedResult)
}

def extractBody[T](request: PartialRequest[T]): String =
request.body match {
case StringBody(body, "utf-8", MediaType.ApplicationJson) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package sttp.client4.ziojson

import org.scalatest.concurrent.ScalaFutures
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client4.testing.SyncBackendStub
import sttp.model.Uri
import sttp.client4.basicRequest
import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder}

case class Person(name: String)

object Person {
implicit val encoder: JsonEncoder[Person] = DeriveJsonEncoder.gen[Person]
implicit val codec: JsonDecoder[Person] = DeriveJsonDecoder.gen[Person]
}

class BackendStubJson4sTests extends AnyFlatSpec with Matchers with ScalaFutures {

it should "deserialize to json using a string stub" in {
val backend = SyncBackendStub.whenAnyRequest.thenRespond("""{"name": "John"}""")
val r = basicRequest.get(Uri("http://example.org")).response(asJson[Person]).send(backend)

r.is200 should be(true)
r.body should be(Right(Person("John")))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import org.scalatest.matchers.should.Matchers
import zio.json._
import sttp.client4._
import sttp.client4.internal.Utf8

import sttp.model._
import zio.Chunk
import zio.json.ast.Json

class ZioJsonTests extends AnyFlatSpec with Matchers with EitherValues {

Expand Down Expand Up @@ -90,6 +91,16 @@ class ZioJsonTests extends AnyFlatSpec with Matchers with EitherValues {
ct shouldBe Some("horses/cats")
}

it should "serialize from Json.Obj using implicit zioJsonBodySerializer" in {
val fields: Chunk[(String, Json)] = Chunk(("location", Json.Str("hometown")), ("bio", Json.Str("Scala programmer")))
val jObject: Json.Obj = Json.Obj(fields)
val result = basicRequest.get(Uri("http://example.org")).body(jObject).body.show

val expectedResult = "string: {\"location\":\"hometown\",\"bio\":\"Scala programmer\"}"

result should be(expectedResult)
}

def extractBody[T](request: PartialRequest[T]): String =
request.body match {
case StringBody(body, "utf-8", MediaType.ApplicationJson) =>
Expand Down

0 comments on commit 23b69a3

Please sign in to comment.