zio / zio-http

A next-generation Scala framework for building scalable, correct, and efficient HTTP clients and servers
https://zio.dev/zio-http
Apache License 2.0
794 stars 401 forks source link

Code gen schema import missing #3101

Closed 987Nabil closed 1 month ago

987Nabil commented 1 month ago

Even if the request body is just referencing a component schema, the operation file has its own case class RequestBody which defines a Schema. However it doesn't import zio.schema._.

  1. I would expect it to just use a type alias. The code generated for the component schema ends up being useless and redundant.
  2. In any case since it's using ZIO Schema, it needs to import it.
      test("schema import is added when needed") {
        val oapi =
          OpenAPI(
            openapi = "3.0.0",
            info = OpenAPI.Info(
              title = "XXX",
              description = None,
              termsOfService = None,
              contact = None,
              license = None,
              version = "1.0.0",
            ),
            paths = ListMap(
              OpenAPI.Path(name = "/api/a/b") -> OpenAPI.PathItem(
                ref = None,
                summary = None,
                description = None,
                get = None,
                put = None,
                post = Some(
                  OpenAPI.Operation(
                    summary = None,
                    description = None,
                    externalDocs = None,
                    operationId = None,
                    requestBody = Some(
                      OpenAPI.ReferenceOr.Or(
                        OpenAPI.RequestBody(
                          content = Map(
                            "application/json" -> OpenAPI.MediaType(
                              OpenAPI.ReferenceOr.Or(
                                JsonSchema.Object(
                                  properties = Map(
                                    "h" -> JsonSchema.String(None, None),
                                    "i" -> JsonSchema.String(None, None),
                                    "j" -> JsonSchema.String(None, None),
                                    "k" -> JsonSchema.String(None, None),
                                  ),
                                  additionalProperties = Left(true),
                                  required = Chunk("h", "i", "j", "k"),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
                delete = None,
                options = None,
                head = None,
                patch = None,
                trace = None,
              ),
            ),
            components = None,
            externalDocs = None,
          )

        def suspendAssertion[A](assertion: => Assertion[A]) =
          Assertion(
            TestArrow.suspend((a: A) => TestArrow.succeed(a) >>> assertion.arrow),
          )

        val importsZioSchema: Assertion[Code.File] =
          Assertion.hasField("imports", (_: Code.File).imports, Assertion.contains(Code.Import("zio.schema._")))
        val objectsOwnSchemaIsNone = Assertion.hasField("schema", (_: Code.Object).schema, Assertion.isNone)
        lazy val objectCaseClassesContainNoSchema: Assertion[Code.Object]      =
          Assertion.hasField(
            "caseClasses",
            (_: Code.Object).caseClasses,
            Assertion.forall(caseClassCompanionsContainNoSchema),
          )
        lazy val caseClassCompanionsContainNoSchema: Assertion[Code.CaseClass] =
          Assertion.hasField(
            "companionObject",
            (_: Code.CaseClass).companionObject,
            Assertion.isNone || Assertion.isSome(objectContainsNoSchema),
          )
        lazy val objectObjectsContainNoSchema: Assertion[Code.Object]          =
          Assertion.hasField(
            "objects",
            (_: Code.Object).objects,
            Assertion.forall(objectContainsNoSchema),
          )
        lazy val objectContainsNoSchema: Assertion[Code.Object]                =
          suspendAssertion {
            objectsOwnSchemaIsNone &&
            objectObjectsContainNoSchema &&
            objectCaseClassesContainNoSchema
          }
        val fileObjectsContainNoSchema: Assertion[Code.File]                   =
          Assertion.hasField("objects", (_: Code.File).objects, Assertion.forall(objectContainsNoSchema))
        val fileCaseClassCompanionsContainNoSchema                             =
          Assertion.hasField(
            "caseClasses",
            (_: Code.File).caseClasses,
            Assertion.forall(caseClassCompanionsContainNoSchema),
          )
        val fileContainsNoSchema: Assertion[Code.File]                         =
          fileObjectsContainNoSchema &&
            fileCaseClassCompanionsContainNoSchema

        assert(EndpointGen.fromOpenAPI(oapi, Config.default).files) {
          Assertion.forall(importsZioSchema || fileContainsNoSchema)
        }
      },

see #3098

987Nabil commented 1 month ago

iirc, there was a reason not just to use a reference. But I can't recall,. maybe we can change it

jdegoes commented 1 month ago

/bounty $75 for fix and test case.

algora-pbc[bot] commented 1 month ago

💎 $75 bounty • ZIO

Steps to solve:

  1. Start working: Comment /attempt #3101 with your implementation plan
  2. Submit work: Create a pull request including /claim #3101 in the PR body to claim the bounty
  3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts

Thank you for contributing to zio/zio-http!

Add a bountyShare on socials

Attempt Started (GMT+0) Solution
🟢 @nafg Sep 18, 2024, 11:29:43 PM #3153
nafg commented 1 month ago

/attempt #3101

nafg commented 1 month ago

FTR I spent a lot of time on the test case in #3098 which should be exhaustive since it searches recursively

algora-pbc[bot] commented 1 month ago

💡 @nafg submitted a pull request that claims the bounty. You can visit your bounty board to reward.

algora-pbc[bot] commented 1 month ago

🎉🎈 @nafg has been awarded $75! 🎈🎊