Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,17 @@ class {{classname}} {{#parentSchema}}extends {{{parent}}}{{/parentSchema}}{{^par
public const {{#lambda.uppercase}}{{discriminator.propertyName}}_{{#lambda.snakecase}}{{mappingName}}{{/lambda.snakecase}}{{/lambda.uppercase}} = '{{mappingName}}';
{{/discriminator.mappedModels}}
{{/discriminator}}
{{^discriminator}}
{{#vars}}
{{#isEnum}}
{{^isDiscriminator}}
{{#allowableValues}}
{{#enumVars}}
public const {{enumName}}_{{{name}}} = {{{value}}};
{{/enumVars}}
{{/allowableValues}}
{{/isDiscriminator}}
{{/isEnum}}
{{/vars}}
{{/discriminator}}

{{#vars}}
{{#isEnum}}
Expand All @@ -198,15 +198,15 @@ class {{classname}} {{#parentSchema}}extends {{{parent}}}{{/parentSchema}}{{^par
public static function {{getter}}AllowableValues()
{
return [
{{#discriminator}}
{{#isDiscriminator}}
{{#discriminator.mappedModels}}
self::{{#lambda.uppercase}}{{discriminator.propertyName}}_{{#lambda.snakecase}}{{mappingName}}{{/lambda.snakecase}}{{/lambda.uppercase}},{{^-last}}
{{/-last}}{{/discriminator.mappedModels}}
{{/discriminator}}
{{^discriminator}}
{{/isDiscriminator}}
{{^isDiscriminator}}
{{#allowableValues}}{{#enumVars}}self::{{enumName}}_{{{name}}},{{^-last}}
{{/-last}}{{/enumVars}}{{/allowableValues}}
{{/discriminator}}
{{/isDiscriminator}}
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,110 @@ public void testEnumUnknownDefaultCaseDeserializationDisabled() throws Exception
Assert.assertListContains(modelContent, a -> a.equalsIgnoreCase("\"Invalid value '%s' for 'color', must be one of '%s'\","), "");
}

@Test
public void testOneOfDiscriminatorEnumGeneration() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();

OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/bugs/issue_23813.yaml", null, new ParseOptions()).getOpenAPI();

codegen.setOutputDir(output.getAbsolutePath());

ClientOptInput input = new ClientOptInput()
.openAPI(openAPI)
.config(codegen);

DefaultGenerator generator = new DefaultGenerator();
Map<String, File> files = generator.opts(input).generate().stream()
.collect(Collectors.toMap(File::getName, Function.identity()));

Assert.assertNotNull(files.get("PetAnimal.php"));

List<String> combinedModelContent = Files
.readAllLines(files.get("PetAnimal.php").toPath())
.stream()
.map(String::trim)
.collect(Collectors.toList());
int styleAllowableValuesStart = combinedModelContent.indexOf("public static function getStyleAllowableValues()");
Assert.assertTrue(styleAllowableValuesStart >= 0,
"Expected combined oneOf wrapper to declare getStyleAllowableValues");
int styleAllowableValuesEnd = combinedModelContent.subList(styleAllowableValuesStart, combinedModelContent.size()).indexOf("];");
Assert.assertTrue(styleAllowableValuesEnd >= 0,
"Expected combined oneOf wrapper to close the style allowable-values array");
List<String> styleAllowableValuesContent = combinedModelContent.subList(
styleAllowableValuesStart,
styleAllowableValuesStart + styleAllowableValuesEnd + 1);
Assert.assertListContains(combinedModelContent,
a -> a.equals("public const STYLE_PAGE = 'page';"),
"Expected combined oneOf wrapper to declare STYLE_PAGE constant");
Assert.assertListContains(combinedModelContent,
a -> a.equals("public const STYLE_TEXT = 'text';"),
"Expected combined oneOf wrapper to declare STYLE_TEXT constant");
Assert.assertListContains(combinedModelContent,
a -> a.equals("public const STYLE_VIEWPORT = 'viewport';"),
"Expected combined oneOf wrapper to declare STYLE_VIEWPORT constant");
Assert.assertListContains(styleAllowableValuesContent,
a -> a.equals("self::STYLE_PAGE,"),
"Expected combined oneOf wrapper to use style enum values");
Assert.assertListContains(styleAllowableValuesContent,
a -> a.equals("self::STYLE_TEXT,"),
"Expected combined oneOf wrapper to use style enum values");
Assert.assertListContains(styleAllowableValuesContent,
a -> a.equals("self::STYLE_VIEWPORT,"),
"Expected combined oneOf wrapper to use style enum values");
Assert.assertListNotContains(styleAllowableValuesContent,
a -> a.equals("self::TYPE_PET_DOG,"),
"Combined oneOf wrapper should not use type enum values for style");
Assert.assertListNotContains(styleAllowableValuesContent,
a -> a.equals("self::TYPE_PET_CAT,"),
"Combined oneOf wrapper should not use type enum values for style");
}

@Test
public void testDiscriminatorConstantsPreservedForNonEnumDiscriminatorModels() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();

OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/php-nextgen/petstore-with-fake-endpoints-models-for-testing.yaml", null, new ParseOptions())
.getOpenAPI();

codegen.setOutputDir(output.getAbsolutePath());

ClientOptInput input = new ClientOptInput()
.openAPI(openAPI)
.config(codegen);

DefaultGenerator generator = new DefaultGenerator();
Map<String, File> files = generator.opts(input).generate().stream()
.collect(Collectors.toMap(File::getName, Function.identity()));

Assert.assertNotNull(files.get("Animal.php"));
Assert.assertNotNull(files.get("DiscriminatorBase.php"));

List<String> animalModelContent = Files
.readAllLines(files.get("Animal.php").toPath())
.stream()
.map(String::trim)
.collect(Collectors.toList());
Assert.assertListContains(animalModelContent,
a -> a.equals("public const CLASS_NAME_DOG = 'DOG';"),
"Expected Animal to preserve discriminator constant CLASS_NAME_DOG");
Assert.assertListContains(animalModelContent,
a -> a.equals("public const CLASS_NAME_CAT = 'CAT';"),
"Expected Animal to preserve discriminator constant CLASS_NAME_CAT");

List<String> discriminatorBaseModelContent = Files
.readAllLines(files.get("DiscriminatorBase.php").toPath())
.stream()
.map(String::trim)
.collect(Collectors.toList());
Assert.assertListContains(discriminatorBaseModelContent,
a -> a.equals("public const TYPE_DISCRIMINATOR_CHILD = 'DiscriminatorChild';"),
"Expected DiscriminatorBase to preserve inferred discriminator constants");
}

@Test
public void testDifferentResponseSchemasWithEmpty() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
Expand Down
53 changes: 53 additions & 0 deletions modules/openapi-generator/src/test/resources/bugs/issue_23813.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
openapi: 3.0.0
info:
title: php-nextgen oneOf discriminator enum bug
version: 1.0.0

components:
schemas:
Pet:
type: object
properties:
id:
type: string
minLength: 1
animal:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: type
mapping:
pet-dog: '#/components/schemas/Dog'
pet-cat: '#/components/schemas/Cat'
Dog:
type: object
properties:
type:
type: string
enum: ["pet-dog"]
default: "pet-dog"
imageId:
type: string
required:
- type
- imageId
Cat:
type: object
properties:
type:
type: string
enum: ["pet-cat"]
default: "pet-cat"
imageId:
type: string
style:
type: string
enum:
- "page"
- "text"
- "viewport"
required:
- type
- imageId
- style
Loading