Skip to content

Commit d72726c

Browse files
committed
Add behavioral tests
* useOptional flag wrapping non-required properties * patchOnly mode PATCH schema detection * patchOnly=true auto-enabling useOptional * Parameter unwrapping behavior
1 parent b522254 commit d72726c

1 file changed

Lines changed: 152 additions & 0 deletions

File tree

modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@
1919

2020
import io.swagger.v3.oas.models.OpenAPI;
2121
import io.swagger.v3.oas.models.Operation;
22+
import io.swagger.v3.oas.models.PathItem;
2223
import io.swagger.v3.oas.models.media.*;
24+
import io.swagger.v3.oas.models.parameters.RequestBody;
2325
import org.openapitools.codegen.*;
26+
import org.openapitools.codegen.languages.AbstractDartCodegen;
2427
import org.openapitools.codegen.languages.DartClientCodegen;
28+
import org.openapitools.codegen.model.OperationMap;
29+
import org.openapitools.codegen.model.OperationsMap;
2530
import org.testng.Assert;
2631
import org.testng.annotations.DataProvider;
2732
import org.testng.annotations.Test;
@@ -564,4 +569,151 @@ public void dateTest() {
564569
Assert.assertEquals(op.returnType, "DateTime");
565570
Assert.assertEquals(op.bodyParam.dataType, "DateTime");
566571
}
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+
}
567719
}

0 commit comments

Comments
 (0)