From 7ee5332ee2b5e656bbc7521e1fed5eb3443ed637 Mon Sep 17 00:00:00 2001 From: Daniel Bell Date: Wed, 26 Jul 2023 11:51:01 +0200 Subject: [PATCH] fix bug where lenient decoding would never occur (#4108) * fix bug where lenient decoding would never occur * make two instances of decoder so it's not created every time / is clearer * change the way an either is constructed * scalafmt --- .../delta/routes/ResourcesRoutesSpec.scala | 8 ++-- .../delta/sdk/resources/NexusSource.scala | 41 ++++++++++--------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/delta/app/src/test/scala/ch/epfl/bluebrain/nexus/delta/routes/ResourcesRoutesSpec.scala b/delta/app/src/test/scala/ch/epfl/bluebrain/nexus/delta/routes/ResourcesRoutesSpec.scala index 1d43894bb8..337ae755b8 100644 --- a/delta/app/src/test/scala/ch/epfl/bluebrain/nexus/delta/routes/ResourcesRoutesSpec.scala +++ b/delta/app/src/test/scala/ch/epfl/bluebrain/nexus/delta/routes/ResourcesRoutesSpec.scala @@ -64,12 +64,13 @@ class ResourcesRoutesSpec extends BaseRouteSpec { private val myId2 = nxv + "myid2" // Resource created against schema1 with id present on the payload private val myId3 = nxv + "myid3" // Resource created against no schema with id passed and present on the payload private val myId4 = nxv + "myid4" // Resource created against schema1 with id passed and present on the payload + private val myId5 = nxv + "myid5" // Resource created against schema1 with id passed and present on the payload private val myIdEncoded = UrlUtils.encode(myId.toString) private val myId2Encoded = UrlUtils.encode(myId2.toString) private val payload = jsonContentOf("resources/resource.json", "id" -> myId) private val payloadWithBlankId = jsonContentOf("resources/resource.json", "id" -> "") private val payloadWithUnderscoreFields = - jsonContentOf("resources/resource-with-underscore-fields.json", "id" -> myId) + jsonContentOf("resources/resource-with-underscore-fields.json", "id" -> myId5) private val payloadWithMetadata = jsonContentOf("resources/resource-with-metadata.json", "id" -> myId) private val aclCheck = AclSimpleCheck().accepted @@ -195,10 +196,7 @@ class ResourcesRoutesSpec extends BaseRouteSpec { val lenientDecodingRoutes = routesWithDecodingOption(DecodingOption.Lenient) Post("/v1/resources/myorg/myproject/_/", payloadWithUnderscoreFields.toEntity) ~> lenientDecodingRoutes ~> check { - response.status shouldEqual StatusCodes.BadRequest - response.asJson shouldEqual jsonContentOf( - "/resources/errors/underscore-fields.json" - ) + response.status shouldEqual StatusCodes.Created } } diff --git a/delta/sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/resources/NexusSource.scala b/delta/sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/resources/NexusSource.scala index acd3471599..79faa5707e 100644 --- a/delta/sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/resources/NexusSource.scala +++ b/delta/sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/resources/NexusSource.scala @@ -42,29 +42,30 @@ object NexusSource { } } - implicit def nexusSourceDecoder(implicit decodingOption: DecodingOption): Decoder[NexusSource] = { - - new Decoder[NexusSource] { - private val decoder = implicitly[Decoder[Json]] - - println(decodingOption) + private val strictDecoder = new Decoder[NexusSource] { + private val decoder = implicitly[Decoder[Json]] - override def apply(c: HCursor): Result[NexusSource] = { - decoder(c).flatMap { json => - val underscoreFields = json.asObject.toList.flatMap(_.keys).filter(_.startsWith("_")) - if (underscoreFields.nonEmpty) { - Left( - DecodingFailure( - s"Field(s) starting with _ found in payload: ${underscoreFields.mkString(", ")}", - c.history - ) - ) - } else { - Right(NexusSource(json)) - } - } + override def apply(c: HCursor): Result[NexusSource] = { + decoder(c).flatMap { json => + val underscoreFields = json.asObject.toList.flatMap(_.keys).filter(_.startsWith("_")) + Either.cond( + underscoreFields.isEmpty, + NexusSource(json), + DecodingFailure( + s"Field(s) starting with _ found in payload: ${underscoreFields.mkString(", ")}", + c.history + ) + ) } } } + private val lenientDecoder = implicitly[Decoder[Json]].map(NexusSource(_)) + + implicit def nexusSourceDecoder(implicit decodingOption: DecodingOption): Decoder[NexusSource] = { + decodingOption match { + case DecodingOption.Lenient => lenientDecoder + case DecodingOption.Strict => strictDecoder + } + } }