EnumPropertyTest.java
package io.swagger.v3.core.converting;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.converter.ModelConverterContextImpl;
import io.swagger.v3.core.converter.ModelConverters;
import io.swagger.v3.core.jackson.ModelResolver;
import io.swagger.v3.core.jackson.TypeNameResolver;
import io.swagger.v3.core.matchers.SerializationMatchers;
import io.swagger.v3.core.oas.models.JacksonValueBridgeMethodEnum;
import io.swagger.v3.core.oas.models.JacksonValueDefaultMethodEnum;
import io.swagger.v3.core.oas.models.JacksonValuePrivateEnum;
import io.swagger.v3.core.oas.models.Model1979;
import io.swagger.v3.core.oas.models.ModelWithEnumField;
import io.swagger.v3.core.oas.models.ModelWithEnumProperty;
import io.swagger.v3.core.oas.models.ModelWithEnumRefProperty;
import io.swagger.v3.core.oas.models.ModelWithJacksonEnumField;
import io.swagger.v3.oas.models.media.IntegerSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
public class EnumPropertyTest {
private ModelResolver modelResolver;
private ModelConverterContextImpl context;
@BeforeMethod
public void setup() {
ModelResolver.enumsAsRef = false;
modelResolver = new ModelResolver(new ObjectMapper());
context = new ModelConverterContextImpl(modelResolver);
}
@AfterTest
public void afterTest() {
ModelResolver.enumsAsRef = false;
}
@Test(description = "it should read a model with an enum property")
public void testEnumProperty() {
final Map<String, Schema> models = ModelConverters.getInstance().read(ModelWithEnumProperty.class);
final String json = "{" +
" \"ModelWithEnumProperty\":{" +
" \"type\":\"object\"," +
" \"properties\":{" +
" \"enumValue\":{" +
" \"type\":\"string\"," +
" \"enum\":[" +
" \"PRIVATE\"," +
" \"PUBLIC\"," +
" \"SYSTEM\"," +
" \"INVITE_ONLY\"" +
" ]" +
" }" +
" }" +
" }" +
"}";
SerializationMatchers.assertEqualsToJson(models, json);
}
@Test(description = "it should extract enum values from fields")
public void testExtractEnumFields() {
final Map<String, Schema> models = ModelConverters.getInstance().read(ModelWithEnumField.class);
final Schema model = models.get("ModelWithEnumField");
final Schema enumProperty = (Schema) model.getProperties().get("enumValue");
assertTrue(enumProperty instanceof StringSchema);
final StringSchema stringProperty = (StringSchema) enumProperty;
assertEquals(stringProperty.getEnum(), Arrays.asList("PRIVATE", "PUBLIC", "SYSTEM", "INVITE_ONLY"));
}
@Test(description = "it should extract enum values from method return types")
public void testExtractEnumReturnType() {
final Map<String, Schema> models = ModelConverters.getInstance().read(ModelWithEnumProperty.class);
final Schema model = models.get("ModelWithEnumProperty");
final Schema enumProperty = (Schema) model.getProperties().get("enumValue");
assertTrue(enumProperty instanceof StringSchema);
final StringSchema stringProperty = (StringSchema) enumProperty;
assertEquals(stringProperty.getEnum(), Arrays.asList("PRIVATE", "PUBLIC", "SYSTEM", "INVITE_ONLY"));
}
@Test(description = "it should read a model with an enum property as a reference")
public void testEnumRefProperty() {
Schema schema = context.resolve(new AnnotatedType(ModelWithEnumRefProperty.class));
final Map<String, Schema> models = context.getDefinedModels();
final String yaml = "ModelWithEnumRefProperty:\n" +
" type: object\n" +
" properties:\n" +
" a:\n" +
" $ref: \"#/components/schemas/TestEnum\"\n" +
" b:\n" +
" $ref: \"#/components/schemas/TestEnum\"\n" +
" c:\n" +
" $ref: \"#/components/schemas/TestSecondEnum\"\n" +
" d:\n" +
" type: string\n" +
" enum:\n" +
" - A_PRIVATE\n" +
" - A_PUBLIC\n" +
" - A_SYSTEM\n" +
" - A_INVITE_ONLY\n" +
"TestEnum:\n" +
" type: string\n" +
" enum:\n" +
" - PRIVATE\n" +
" - PUBLIC\n" +
" - SYSTEM\n" +
" - INVITE_ONLY\n" +
"TestSecondEnum:\n" +
" type: string\n" +
" enum:\n" +
" - A_PRIVATE\n" +
" - A_PUBLIC\n" +
" - A_SYSTEM\n" +
" - A_INVITE_ONLY\n";
SerializationMatchers.assertEqualsToYaml(models, yaml);
}
@Test(description = "it should read a model with an enum property as a reference with fqn TypeNameResolver")
public void testEnumRefPropertyWithFQNTypeNameResolver() {
TypeNameResolver.std.setUseFqn(true);
Schema schema = context.resolve(new AnnotatedType(ModelWithEnumRefProperty.class));
final Map<String, Schema> models = context.getDefinedModels();
final String yaml = "io.swagger.v3.core.oas.models.ModelWithEnumRefProperty:\n" +
" type: object\n" +
" properties:\n" +
" a:\n" +
" $ref: \"#/components/schemas/io.swagger.v3.core.oas.models.TestEnum\"\n" +
" b:\n" +
" $ref: \"#/components/schemas/io.swagger.v3.core.oas.models.TestEnum\"\n" +
" c:\n" +
" $ref: \"#/components/schemas/io.swagger.v3.core.oas.models.TestSecondEnum\"\n" +
" d:\n" +
" type: string\n" +
" enum:\n" +
" - A_PRIVATE\n" +
" - A_PUBLIC\n" +
" - A_SYSTEM\n" +
" - A_INVITE_ONLY\n" +
"io.swagger.v3.core.oas.models.TestEnum:\n" +
" type: string\n" +
" enum:\n" +
" - PRIVATE\n" +
" - PUBLIC\n" +
" - SYSTEM\n" +
" - INVITE_ONLY\n" +
"io.swagger.v3.core.oas.models.TestSecondEnum:\n" +
" type: string\n" +
" enum:\n" +
" - A_PRIVATE\n" +
" - A_PUBLIC\n" +
" - A_SYSTEM\n" +
" - A_INVITE_ONLY\n";
TypeNameResolver.std.setUseFqn(false);
SerializationMatchers.assertEqualsToYaml(models, yaml);
}
@Test(description = "it should read a model with an enum property as a reference, set via static var or sys prop")
public void testEnumRefPropertyGlobal() {
ModelResolver.enumsAsRef = true;
Schema schema = context.resolve(new AnnotatedType(ModelWithEnumProperty.class));
final Map<String, Schema> models = context.getDefinedModels();
final String yaml = "ModelWithEnumProperty:\n" +
" type: object\n" +
" properties:\n" +
" enumValue:\n" +
" $ref: \"#/components/schemas/TestEnum\"\n" +
"TestEnum:\n" +
" type: string\n" +
" enum:\n" +
" - PRIVATE\n" +
" - PUBLIC\n" +
" - SYSTEM\n" +
" - INVITE_ONLY\n";
SerializationMatchers.assertEqualsToYaml(models, yaml);
ModelResolver.enumsAsRef = false;
}
@Test(description = "it should not affect non-enum models when the enumsAsRef property is enabled globally")
public void testEnumRefPropertyGlobalNotAffectingNonEnums() {
ModelResolver.enumsAsRef = true;
Schema schema = context.resolve(new AnnotatedType(Model1979.class));
final Map<String, Schema> models = context.getDefinedModels();
final String yaml = "Model1979:\n" +
" type: object\n" +
" properties:\n" +
" id:\n" +
" type: string\n" +
" nullable: true";
SerializationMatchers.assertEqualsToYaml(models, yaml);
ModelResolver.enumsAsRef = false;
}
@Test(description = "it should extract enum values from fields using JsonProperty and JsonValue")
public void testExtractJacksonEnumFields() {
final Map<String, Schema> models = ModelConverters.getInstance().read(ModelWithJacksonEnumField.class);
final Schema model = models.get("ModelWithJacksonEnumField");
final Schema firstEnumProperty = (Schema) model.getProperties().get("firstEnumValue");
assertTrue(firstEnumProperty instanceof StringSchema);
final StringSchema stringProperty = (StringSchema) firstEnumProperty;
assertEquals(stringProperty.getEnum(), Arrays.asList("p1", "p2", "SYSTEM", "INVITE_ONLY"));
final Schema secondEnumProperty = (Schema) model.getProperties().get("secondEnumValue");
assertTrue(secondEnumProperty instanceof StringSchema);
final StringSchema secondStringProperty = (StringSchema) secondEnumProperty;
assertEquals(secondStringProperty.getEnum(), Arrays.asList("one", "two", "three"));
final Schema thirdEnumProperty = (Schema) model.getProperties().get("thirdEnumValue");
assertTrue(thirdEnumProperty instanceof IntegerSchema);
final IntegerSchema thirdStringProperty = (IntegerSchema) thirdEnumProperty;
assertEquals(thirdStringProperty.getEnum(), Arrays.asList(2, 4, 6));
final Schema fourthEnumProperty = (Schema) model.getProperties().get("fourthEnumValue");
assertTrue(fourthEnumProperty instanceof StringSchema);
final StringSchema fourthStringProperty = (StringSchema) fourthEnumProperty;
assertEquals(fourthStringProperty.getEnum(), Arrays.asList("one", "two", "three"));
final Schema fifthEnumProperty = (Schema) model.getProperties().get("fifthEnumValue");
assertTrue(fifthEnumProperty instanceof IntegerSchema);
final IntegerSchema fifthStringProperty = (IntegerSchema) fifthEnumProperty;
assertEquals(fifthStringProperty.getEnum(), Arrays.asList(2, 4, 6));
final Schema sixthEnumProperty = (Schema) model.getProperties().get("sixthEnumValue");
assertTrue(sixthEnumProperty instanceof StringSchema);
final StringSchema sixthStringProperty = (StringSchema) sixthEnumProperty;
assertEquals(sixthStringProperty.getEnum(), Arrays.asList("one", "two", "three"));
final Schema seventhEnumProperty = (Schema) model.getProperties().get("seventhEnumValue");
assertTrue(seventhEnumProperty instanceof IntegerSchema);
final IntegerSchema seventhEnumStringProperty = (IntegerSchema) seventhEnumProperty;
assertEquals(seventhEnumStringProperty.getEnum(), Collections.singletonList(10));
final Schema eighthEnumProperty = (Schema) model.getProperties().get("eighthEnumValue");
assertTrue(eighthEnumProperty instanceof StringSchema);
final StringSchema eighthStringProperty = (StringSchema) eighthEnumProperty;
assertEquals(eighthStringProperty.getEnum(), Arrays.asList("alpha", "beta", "gamma"));
}
@Test(description = "it should extract enum values from a private @JsonValue method declared directly on the enum (issue #3998)")
public void testJsonValueOnPrivateMethodIsRecognized() {
final Schema schema = context.resolve(new AnnotatedType(JacksonValuePrivateEnum.class));
assertNotNull(schema);
assertEquals(schema.getType(), "string");
assertEquals(schema.getEnum(), Arrays.asList("one", "two", "three"));
}
@Test(description = "it should extract enum values from a @JsonValue default method declared on an implemented interface")
public void testJsonValueOnInterfaceDefaultMethodIsRecognized() {
final Schema schema = context.resolve(new AnnotatedType(JacksonValueDefaultMethodEnum.class));
assertNotNull(schema);
assertEquals(schema.getType(), "string");
assertEquals(schema.getEnum(), Arrays.asList("alpha", "beta", "gamma"));
}
@Test(description = "it should handle @JsonValue on enum implementing generic interface with bridge method (issue #5127)")
public void testJsonValueWithBridgeMethodFromGenericInterface() {
final Schema schema = context.resolve(new AnnotatedType(JacksonValueBridgeMethodEnum.class));
assertNotNull(schema);
assertEquals(schema.getType(), "string");
assertEquals(schema.getEnum(), Arrays.asList("created", "in_progress", "confirmed"));
}
}