From 554660c6a4a1e4b1a7cbf1f1733aecc985c37409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Femen=C3=ADa?= <131800808+pablf@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:30:51 +0200 Subject: [PATCH] Modify JS client and fix tests (#2909) modify js client and fix tests --- .../zio/http/ZClientPlatformSpecific.scala | 38 ++++++++++++------- .../test/scala/zio/http/JSClientSpec.scala | 24 +++++++++--- .../zio/http/ZClientPlatformSpecific.scala | 17 ++++++++- .../src/main/scala/zio/http/ZClient.scala | 17 --------- 4 files changed, 60 insertions(+), 36 deletions(-) diff --git a/zio-http/js/src/main/scala/zio/http/ZClientPlatformSpecific.scala b/zio-http/js/src/main/scala/zio/http/ZClientPlatformSpecific.scala index 4503581450..1f9a3459c1 100644 --- a/zio-http/js/src/main/scala/zio/http/ZClientPlatformSpecific.scala +++ b/zio-http/js/src/main/scala/zio/http/ZClientPlatformSpecific.scala @@ -2,28 +2,40 @@ package zio.http import zio._ +import zio.http.ZClient.Config import zio.http.internal.FetchDriver trait ZClientPlatformSpecific { -// def customized: ZLayer[Config with ClientDriver with DnsResolver, Throwable, Client] + lazy val customized: ZLayer[Config with ZClient.Driver[Any, Throwable], Throwable, Client] = { + implicit val trace: Trace = Trace.empty + ZLayer.scoped { + for { + config <- ZIO.service[Config] + driver <- ZIO.service[ZClient.Driver[Any, Throwable]] + baseClient = ZClient.fromDriver(driver) + } yield + if (config.addUserAgentHeader) + baseClient.addHeader(ZClient.defaultUAHeader) + else + baseClient + } + } - lazy val live: ZLayer[ZClient.Config, Throwable, Client] = - default + lazy val live: ZLayer[ZClient.Config, Throwable, Client] = { + implicit val trace: Trace = Trace.empty + FetchDriver.live >>> customized + }.fresh - // TODO should probably exist in js too -// def configured( -// path: NonEmptyChunk[String] = NonEmptyChunk("zio", "http", "client"), -// )(implicit trace: Trace): ZLayer[DnsResolver, Throwable, Client] = -// ( -// ZLayer.service[DnsResolver] ++ -// ZLayer(ZIO.config(Config.config.nested(path.head, path.tail: _*))) ++ -// ZLayer(ZIO.config(NettyConfig.config.nested(path.head, path.tail: _*))) -// ).mapError(error => new RuntimeException(s"Configuration error: $error")) >>> live + def configured( + path: NonEmptyChunk[String] = NonEmptyChunk("zio", "http", "client"), + )(implicit trace: Trace): ZLayer[Any, Throwable, Client] = + ZLayer(ZIO.config(Config.config.nested(path.head, path.tail: _*))) + .mapError(error => new RuntimeException(s"Configuration error: $error")) >>> live lazy val default: ZLayer[Any, Throwable, Client] = { implicit val trace: Trace = Trace.empty - FetchDriver.live >>> ZLayer(ZIO.serviceWith[FetchDriver](driver => ZClient.fromDriver(driver))) + ZLayer.succeed(Config.default) >>> live } } diff --git a/zio-http/js/src/test/scala/zio/http/JSClientSpec.scala b/zio-http/js/src/test/scala/zio/http/JSClientSpec.scala index 0b74c56630..a60b9fbcdb 100644 --- a/zio-http/js/src/test/scala/zio/http/JSClientSpec.scala +++ b/zio-http/js/src/test/scala/zio/http/JSClientSpec.scala @@ -6,14 +6,28 @@ import zio.test._ object JSClientSpec extends ZIOSpecDefault { override def spec: Spec[TestEnvironment with Scope, Any] = - suite("ClientSpec")( + suite("JSClientSpec")( suite("HTTP")( - test("Get") { + test("Get without User Agent") { for { + res <- (for { + response <- ZIO.serviceWithZIO[Client] { _.url(url"https://example.com").get("") } + string <- response.body.asString + } yield (response, string)) + .provideSome[Scope](ZLayer.succeed(ZClient.Config.default.addUserAgentHeader(false)) >>> ZClient.live) + (response, string) = res + } yield assertTrue(response.status.isSuccess, string.startsWith("")) + }, + test("Get with User Agent") { + // Should not fail after fixing regex of Header + val client = (for { response <- ZIO.serviceWithZIO[Client] { _.url(url"https://example.com").get("") } string <- response.body.asString - } yield assertTrue(response.status.isSuccess, string.startsWith("")) - } @@ flaky, // calling a real website is not the best idea. + } yield (response, string)).provideSome[Scope](ZClient.default) + for { + isFailure <- client.isFailure + } yield assertTrue(isFailure) + }, // calling a real website is not the best idea. // Should be replaced with a local server, as soon as we have js server support ), // suite("WebSocket")( @@ -48,5 +62,5 @@ object JSClientSpec extends ZIOSpecDefault { // } yield assertTrue(consoleMessages.contains("Server: Hello, World!")) // }.provideSome[Scope & Client](ZLayer(Queue.bounded[String](100))), // ), - ).provideSome[Scope](ZClient.default) + ) } diff --git a/zio-http/jvm/src/main/scala/zio/http/ZClientPlatformSpecific.scala b/zio-http/jvm/src/main/scala/zio/http/ZClientPlatformSpecific.scala index 1cf3ec0ff9..6d6a3e8df8 100644 --- a/zio-http/jvm/src/main/scala/zio/http/ZClientPlatformSpecific.scala +++ b/zio-http/jvm/src/main/scala/zio/http/ZClientPlatformSpecific.scala @@ -8,7 +8,22 @@ import zio.http.netty.client.NettyClientDriver trait ZClientPlatformSpecific { - def customized: ZLayer[Config with ClientDriver with DnsResolver, Throwable, Client] + lazy val customized: ZLayer[Config with ClientDriver with DnsResolver, Throwable, Client] = { + implicit val trace: Trace = Trace.empty + ZLayer.scoped { + for { + config <- ZIO.service[Config] + driver <- ZIO.service[ClientDriver] + dnsResolver <- ZIO.service[DnsResolver] + connectionPool <- driver.createConnectionPool(dnsResolver, config.connectionPool) + baseClient = ZClient.fromDriver(new ZClient.DriverLive(driver)(connectionPool)(config)) + } yield + if (config.addUserAgentHeader) + baseClient.addHeader(ZClient.defaultUAHeader) + else + baseClient + } + } lazy val live: ZLayer[ZClient.Config with NettyConfig with DnsResolver, Throwable, Client] = { implicit val trace: Trace = Trace.empty diff --git a/zio-http/shared/src/main/scala/zio/http/ZClient.scala b/zio-http/shared/src/main/scala/zio/http/ZClient.scala index 6d207a9986..4a6a3a550a 100644 --- a/zio-http/shared/src/main/scala/zio/http/ZClient.scala +++ b/zio-http/shared/src/main/scala/zio/http/ZClient.scala @@ -249,23 +249,6 @@ final case class ZClient[-Env, -In, +Err, +Out]( object ZClient extends ZClientPlatformSpecific { - val customized: ZLayer[Config with ClientDriver with DnsResolver, Throwable, Client] = { - implicit val trace: Trace = Trace.empty - ZLayer.scoped { - for { - config <- ZIO.service[Config] - driver <- ZIO.service[ClientDriver] - dnsResolver <- ZIO.service[DnsResolver] - connectionPool <- driver.createConnectionPool(dnsResolver, config.connectionPool) - baseClient = fromDriver(new DriverLive(driver)(connectionPool)(config)) - } yield - if (config.addUserAgentHeader) - baseClient.addHeader(defaultUAHeader) - else - baseClient - } - } - def fromDriver[Env, Err](driver: Driver[Env, Err]): ZClient[Env, Body, Err, Response] = ZClient( Version.Default,