From 8c70090aa01442c3e09193e468917adfa0aa2286 Mon Sep 17 00:00:00 2001 From: pawelsadlo <106806258+pawelsadlo@users.noreply.github.com> Date: Wed, 11 Sep 2024 14:54:08 +0200 Subject: [PATCH] Fixing partial provision of environment to Routes when resulting env is intersection type. (#3128) --- .../src/test/scala/zio/http/RouteSpec.scala | 45 +++++++++++++++++++ .../http/RoutesCompanionVersionSpecific.scala | 2 - 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/zio-http/jvm/src/test/scala/zio/http/RouteSpec.scala b/zio-http/jvm/src/test/scala/zio/http/RouteSpec.scala index 82b4b2a3ab..a0fc0f8b0a 100644 --- a/zio-http/jvm/src/test/scala/zio/http/RouteSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/RouteSpec.scala @@ -19,6 +19,9 @@ package zio.http import zio._ import zio.test._ +import zio.http.codec.{HttpCodec, StatusCodec} +import zio.http.endpoint.{AuthType, Endpoint} + object RouteSpec extends ZIOHttpSpec { def extractStatus(response: Response): Status = response.status @@ -163,6 +166,48 @@ object RouteSpec extends ZIOHttpSpec { bodyString <- response.body.asString } yield assertTrue(extractStatus(response) == Status.InternalServerError, bodyString == "error") }, + test( + "Routes with context can eliminate environment type partially when elimination produces intersection type environment", + ) { + + val authContext: HandlerAspect[Any, String] = HandlerAspect.customAuthProviding[String] { request => + { + request.headers.get(Header.Authorization).flatMap { + case Header.Authorization.Basic(uname, secret) if uname.reverse == secret.value.mkString => + Some(uname) + case _ => + None + } + } + } + + val endpoint = Endpoint(RoutePattern(Method.GET, Path.root)) + .outCodec[String](StatusCodec.Ok ++ HttpCodec.content[String]) + .auth(AuthType.Basic) + + val effectWithTwoDependency: ZIO[Int & Long, Nothing, String] = for { + int <- ZIO.service[Int] + long <- ZIO.service[Long] + } yield s"effectWithTwoDependencyResult $int $long" + + val route: Route[Int & Long & String, Nothing] = + endpoint.implement((_: Unit) => withContext((_: String) => "") *> effectWithTwoDependency) + val routes = Routes(route).@@[Int & Long](authContext) + + val env: ZEnvironment[Int with Long] = ZEnvironment(1).add(2L) + val expected = "\"effectWithTwoDependencyResult 1 2\"" + for { + response <- routes + .provideEnvironment(env) + .apply( + Request( + headers = Headers("accept", "text") ++ Headers(Header.Authorization.Basic("123", "321")), + method = Method.GET, + ).path(Path.root), + ) + bodyString <- response.body.asString + } yield assertTrue(bodyString == expected) + }, ), ) } diff --git a/zio-http/shared/src/main/scala-2/zio/http/RoutesCompanionVersionSpecific.scala b/zio-http/shared/src/main/scala-2/zio/http/RoutesCompanionVersionSpecific.scala index b225afdeb5..d08191ee52 100644 --- a/zio-http/shared/src/main/scala-2/zio/http/RoutesCompanionVersionSpecific.scala +++ b/zio-http/shared/src/main/scala-2/zio/http/RoutesCompanionVersionSpecific.scala @@ -6,8 +6,6 @@ trait RoutesCompanionVersionSpecific { private[http] class ApplyContextAspect[-Env, +Err, Env0](private val self: Routes[Env, Err]) { def apply[Env1, Env2 <: Env, Ctx: Tag](aspect: HandlerAspect[Env1, Ctx])(implicit ev: Env0 with Ctx <:< Env, - tag: Tag[Env0], - tag1: Tag[Env1], ): Routes[Env0 with Env1, Err] = self.transform(_.@@[Env0](aspect)) }