From fff14443d3b78c74f785ddad133db1334d19f64a Mon Sep 17 00:00:00 2001 From: Tony <43834836+lofoyet@users.noreply.github.com> Date: Wed, 11 Oct 2023 09:24:56 -0700 Subject: [PATCH] IHRDS 3159 handle bad request body for /users/groups/query (#872) * handle invalid request body for endpoint "users" / "groups" / "query" * added test case (don't expect them to be in the right format) --- .../thomas/http4s/abtest/AbtestService.scala | 5 +- .../iheart/thomas/abtest/EndpointSuite.scala | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 tests/src/it/scala/com/iheart/thomas/abtest/EndpointSuite.scala diff --git a/http4s/src/main/scala/com/iheart/thomas/http4s/abtest/AbtestService.scala b/http4s/src/main/scala/com/iheart/thomas/http4s/abtest/AbtestService.scala index 4a289fac..e77eea4b 100644 --- a/http4s/src/main/scala/com/iheart/thomas/http4s/abtest/AbtestService.scala +++ b/http4s/src/main/scala/com/iheart/thomas/http4s/abtest/AbtestService.scala @@ -128,8 +128,9 @@ class AbtestService[F[_]: Async]( def public = HttpRoutes.of[F] { case req @ POST -> Root / "users" / "groups" / "query" => - req.as[UserGroupQuery] >>= (ugq => - respond( + req.as[UserGroupQuery] redeemWith ( // redeemWith handles all body parsing errors + _ => BadRequest("Invalid Request Body"), + ugq => respond( api .getGroupsWithMeta(ugq) .flatTap(r => logger(AbTestRequestServed(ugq, r))) diff --git a/tests/src/it/scala/com/iheart/thomas/abtest/EndpointSuite.scala b/tests/src/it/scala/com/iheart/thomas/abtest/EndpointSuite.scala new file mode 100644 index 00000000..c2f24f69 --- /dev/null +++ b/tests/src/it/scala/com/iheart/thomas/abtest/EndpointSuite.scala @@ -0,0 +1,54 @@ +package com.iheart.thomas.abtest + +import cats.effect.IO +import cats.effect.testing.scalatest.AsyncIOSpec +import com.iheart.thomas.abtest.TestUtils.withAlg +import com.iheart.thomas.http4s.abtest.AbtestService +import com.iheart.thomas.tracking.EventLogger +import fs2._ +import org.http4s.Status._ +import org.http4s.{Method, Request} +import org.scalatest.freespec.AsyncFreeSpec +import org.scalatest.matchers.should.Matchers +import org.typelevel.log4cats.slf4j.Slf4jLogger +import org.http4s.implicits.http4sLiteralsSyntax + +class EndpointSuite extends AsyncFreeSpec with AsyncIOSpec with Matchers { + implicit val logger: EventLogger[IO] = EventLogger.catsLogger(Slf4jLogger.getLogger[IO]) + + "/users/groups/query endpoint should handle different request bodies appropriately" - { + "good request body json should return OK" in { + withAlg { alg => + val data: String = """{"meta":{"country":"us"},"userId":"123"}""" + val body: Stream[IO, Byte] = Stream.emit(data).through(text.utf8.encode) + new AbtestService(alg).public.orNotFound.run( + Request(method = Method.POST, uri = uri"/users/groups/query", body = body) + ) + }.asserting { response => + response.status shouldBe Ok + } + } + + "empty request body json should return BadRequest" in { + withAlg { alg => + new AbtestService(alg).public.orNotFound.run( + Request(method = Method.POST, uri = uri"/users/groups/query") + ) + }.asserting { response => + response.status shouldBe BadRequest + } + } + + "bad request body json should return BadRequest" in { + withAlg { alg => + val data: String = """{"meta":{"country":"us", "deviceId": {}},"userId":"123"}""" + val body: Stream[IO, Byte] = Stream.emit(data).through(text.utf8.encode) + new AbtestService(alg).public.orNotFound.run( + Request(method = Method.POST, uri = uri"/users/groups/query", body = body) + ) + }.asserting { response => + response.status shouldBe BadRequest + } + } + } +}