|
19 | 19 |
|
20 | 20 | import io.swagger.v3.oas.models.OpenAPI; |
21 | 21 | import io.swagger.v3.oas.models.Operation; |
| 22 | +import io.swagger.v3.oas.models.PathItem; |
22 | 23 | import io.swagger.v3.oas.models.media.*; |
| 24 | +import io.swagger.v3.oas.models.parameters.RequestBody; |
23 | 25 | import org.openapitools.codegen.*; |
| 26 | +import org.openapitools.codegen.languages.AbstractDartCodegen; |
24 | 27 | import org.openapitools.codegen.languages.DartClientCodegen; |
| 28 | +import org.openapitools.codegen.model.OperationMap; |
| 29 | +import org.openapitools.codegen.model.OperationsMap; |
25 | 30 | import org.testng.Assert; |
26 | 31 | import org.testng.annotations.DataProvider; |
27 | 32 | import org.testng.annotations.Test; |
@@ -564,4 +569,151 @@ public void dateTest() { |
564 | 569 | Assert.assertEquals(op.returnType, "DateTime"); |
565 | 570 | Assert.assertEquals(op.bodyParam.dataType, "DateTime"); |
566 | 571 | } |
| 572 | + |
| 573 | + @Test(description = "useOptional flag wrapping non-required properties") |
| 574 | + public void testUseOptionalFlagWrappingNonRequiredProperties() { |
| 575 | + final Schema model = new Schema() |
| 576 | + .description("a model with required and optional properties") |
| 577 | + .addProperties("id", new IntegerSchema()) |
| 578 | + .addProperties("name", new StringSchema()) |
| 579 | + .addProperties("description", new StringSchema()) |
| 580 | + .addRequiredItem("id"); |
| 581 | + |
| 582 | + final DartClientCodegen codegen = new DartClientCodegen(); |
| 583 | + codegen.setUseOptional(true); |
| 584 | + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); |
| 585 | + codegen.setOpenAPI(openAPI); |
| 586 | + codegen.processOpts(); |
| 587 | + |
| 588 | + final CodegenModel cm = codegen.fromModel("sample", model); |
| 589 | + codegen.postProcessModels(createCodegenModelWrapper(cm)); |
| 590 | + |
| 591 | + final CodegenProperty idProp = cm.vars.get(0); |
| 592 | + Assert.assertEquals(idProp.baseName, "id"); |
| 593 | + Assert.assertFalse(idProp.dataType.startsWith("Optional<"), "Required property should not be wrapped"); |
| 594 | + |
| 595 | + final CodegenProperty nameProp = cm.vars.get(1); |
| 596 | + Assert.assertEquals(nameProp.baseName, "name"); |
| 597 | + Assert.assertTrue(nameProp.dataType.startsWith("Optional<"), "Non-required property should be wrapped"); |
| 598 | + Assert.assertTrue((Boolean) nameProp.vendorExtensions.get("x-is-optional")); |
| 599 | + |
| 600 | + final CodegenProperty descProp = cm.vars.get(2); |
| 601 | + Assert.assertEquals(descProp.baseName, "description"); |
| 602 | + Assert.assertTrue(descProp.dataType.startsWith("Optional<"), "Non-required property should be wrapped"); |
| 603 | + } |
| 604 | + |
| 605 | + @Test(description = "patchOnly mode PATCH schema detection") |
| 606 | + public void testPatchOnlyModePatchSchemaDetection() { |
| 607 | + final Schema patchBodySchema = new Schema() |
| 608 | + .description("PATCH request body schema") |
| 609 | + .addProperties("id", new IntegerSchema()) |
| 610 | + .addProperties("name", new StringSchema()) |
| 611 | + .addRequiredItem("id"); |
| 612 | + |
| 613 | + final Schema postBodySchema = new Schema() |
| 614 | + .description("POST request body schema") |
| 615 | + .addProperties("id", new IntegerSchema()) |
| 616 | + .addProperties("title", new StringSchema()) |
| 617 | + .addRequiredItem("id"); |
| 618 | + |
| 619 | + OpenAPI openAPI = TestUtils.createOpenAPI(); |
| 620 | + openAPI.getComponents().addSchemas("PatchBody", patchBodySchema); |
| 621 | + openAPI.getComponents().addSchemas("PostBody", postBodySchema); |
| 622 | + |
| 623 | + Operation patchOp = new Operation(); |
| 624 | + RequestBody patchRequestBody = new RequestBody(); |
| 625 | + MediaType patchMediaType = new MediaType(); |
| 626 | + patchMediaType.setSchema(new Schema().$ref("#/components/schemas/PatchBody")); |
| 627 | + patchRequestBody.setContent(new Content().addMediaType("application/json", patchMediaType)); |
| 628 | + patchOp.setRequestBody(patchRequestBody); |
| 629 | + patchOp.setOperationId("updateResource"); |
| 630 | + |
| 631 | + Operation postOp = new Operation(); |
| 632 | + RequestBody postRequestBody = new RequestBody(); |
| 633 | + MediaType postMediaType = new MediaType(); |
| 634 | + postMediaType.setSchema(new Schema().$ref("#/components/schemas/PostBody")); |
| 635 | + postRequestBody.setContent(new Content().addMediaType("application/json", postMediaType)); |
| 636 | + postOp.setRequestBody(postRequestBody); |
| 637 | + postOp.setOperationId("createResource"); |
| 638 | + |
| 639 | + PathItem pathItem = new PathItem(); |
| 640 | + pathItem.setPatch(patchOp); |
| 641 | + pathItem.setPost(postOp); |
| 642 | + openAPI.getPaths().addPathItem("/resource", pathItem); |
| 643 | + |
| 644 | + final DartClientCodegen codegen = new DartClientCodegen(); |
| 645 | + codegen.setPatchOnly(true); |
| 646 | + codegen.setOpenAPI(openAPI); |
| 647 | + codegen.processOpts(); |
| 648 | + codegen.preprocessOpenAPI(openAPI); |
| 649 | + |
| 650 | + final CodegenModel patchModel = codegen.fromModel("PatchBody", patchBodySchema); |
| 651 | + codegen.postProcessModels(createCodegenModelWrapper(patchModel)); |
| 652 | + |
| 653 | + final CodegenModel postModel = codegen.fromModel("PostBody", postBodySchema); |
| 654 | + codegen.postProcessModels(createCodegenModelWrapper(postModel)); |
| 655 | + |
| 656 | + final CodegenProperty patchNameProp = patchModel.vars.get(1); |
| 657 | + Assert.assertEquals(patchNameProp.baseName, "name"); |
| 658 | + Assert.assertTrue(patchNameProp.dataType.startsWith("Optional<"), |
| 659 | + "PATCH body non-required property should be wrapped with Optional"); |
| 660 | + |
| 661 | + final CodegenProperty postTitleProp = postModel.vars.get(1); |
| 662 | + Assert.assertEquals(postTitleProp.baseName, "title"); |
| 663 | + Assert.assertFalse(postTitleProp.dataType.startsWith("Optional<"), |
| 664 | + "POST body non-required property should NOT be wrapped when patchOnly=true"); |
| 665 | + } |
| 666 | + |
| 667 | + @Test(description = "patchOnly=true auto-enabling useOptional") |
| 668 | + public void testPatchOnlyTrueAutoEnablingUseOptional() { |
| 669 | + final DartClientCodegen codegen = new DartClientCodegen(); |
| 670 | + codegen.additionalProperties().put(AbstractDartCodegen.PATCH_ONLY, true); |
| 671 | + |
| 672 | + codegen.processOpts(); |
| 673 | + |
| 674 | + Assert.assertTrue((Boolean) codegen.additionalProperties().get(AbstractDartCodegen.USE_OPTIONAL), |
| 675 | + "patchOnly=true should auto-enable useOptional"); |
| 676 | + } |
| 677 | + |
| 678 | + @Test(description = "Parameter unwrapping behavior") |
| 679 | + public void testParameterUnwrappingBehavior() { |
| 680 | + final Schema model = new Schema() |
| 681 | + .description("a model") |
| 682 | + .addProperties("id", new IntegerSchema()) |
| 683 | + .addProperties("name", new StringSchema()); |
| 684 | + |
| 685 | + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); |
| 686 | + |
| 687 | + Operation getOp = new Operation(); |
| 688 | + io.swagger.v3.oas.models.parameters.QueryParameter queryParam = |
| 689 | + new io.swagger.v3.oas.models.parameters.QueryParameter(); |
| 690 | + queryParam.setName("filter"); |
| 691 | + queryParam.setSchema(new StringSchema()); |
| 692 | + queryParam.setRequired(false); |
| 693 | + getOp.addParametersItem(queryParam); |
| 694 | + getOp.setOperationId("getResource"); |
| 695 | + |
| 696 | + PathItem pathItem = new PathItem(); |
| 697 | + pathItem.setGet(getOp); |
| 698 | + openAPI.getPaths().addPathItem("/resource", pathItem); |
| 699 | + |
| 700 | + final DartClientCodegen codegen = new DartClientCodegen(); |
| 701 | + codegen.setUseOptional(true); |
| 702 | + codegen.setOpenAPI(openAPI); |
| 703 | + codegen.processOpts(); |
| 704 | + |
| 705 | + final CodegenOperation op = codegen.fromOperation("/resource", "get", getOp, null); |
| 706 | + |
| 707 | + OperationsMap opsMap = new OperationsMap(); |
| 708 | + OperationMap opMap = new OperationMap(); |
| 709 | + opMap.setOperation(Collections.singletonList(op)); |
| 710 | + opsMap.setOperation(opMap); |
| 711 | + |
| 712 | + codegen.postProcessOperationsWithModels(opsMap, Collections.emptyList()); |
| 713 | + |
| 714 | + Assert.assertFalse(op.queryParams.isEmpty(), "Should have query params"); |
| 715 | + CodegenParameter filterParam = op.queryParams.get(0); |
| 716 | + Assert.assertFalse(filterParam.dataType.startsWith("Optional<"), |
| 717 | + "Query parameter should not be wrapped with Optional"); |
| 718 | + } |
567 | 719 | } |
0 commit comments