package com.sebastian_daschner.jaxrs_analyzer.backend.swagger;
import com.sebastian_daschner.jaxrs_analyzer.model.Types;
import com.sebastian_daschner.jaxrs_analyzer.model.rest.TypeIdentifier;
import com.sebastian_daschner.jaxrs_analyzer.model.rest.TypeRepresentation;
import org.junit.Before;
import org.junit.Test;
import javax.json.Json;
import javax.json.JsonObject;
import java.util.HashMap;
import java.util.Map;
import static com.sebastian_daschner.jaxrs_analyzer.analysis.results.TypeUtils.*;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
public class SchemaBuilderTest {
private static final TypeIdentifier INTEGER_IDENTIFIER = TypeIdentifier.ofType(Types.INTEGER);
private static final TypeIdentifier INT_LIST_IDENTIFIER = TypeIdentifier.ofType("Ljava/util/List<Ljava/lang/Integer;>;");
private SchemaBuilder cut;
private final Map<TypeIdentifier, TypeRepresentation> representations = new HashMap<>();
@Before
public void resetRepresentations() {
representations.clear();
}
@Test
public void testSimpleDefinitions() {
representations.put(INT_LIST_IDENTIFIER, TypeRepresentation.ofCollection(INTEGER_IDENTIFIER, TypeRepresentation.ofConcrete(INTEGER_IDENTIFIER)));
final TypeIdentifier modelIdentifier = MODEL_IDENTIFIER;
final Map<String, TypeIdentifier> modelProperties = new HashMap<>();
modelProperties.put("test1", INT_IDENTIFIER);
modelProperties.put("hello1", STRING_IDENTIFIER);
modelProperties.put("array1", INT_LIST_IDENTIFIER);
representations.put(modelIdentifier, TypeRepresentation.ofConcrete(modelIdentifier, modelProperties));
final Map<String, TypeIdentifier> dynamicProperties = new HashMap<>();
dynamicProperties.put("test2", INT_IDENTIFIER);
dynamicProperties.put("hello2", STRING_IDENTIFIER);
dynamicProperties.put("array2", INT_LIST_IDENTIFIER);
final TypeIdentifier nestedDynamicIdentifier = TypeIdentifier.ofDynamic();
final Map<String, TypeIdentifier> nestedDynamicProperties = new HashMap<>();
nestedDynamicProperties.put("test", INT_IDENTIFIER);
dynamicProperties.put("object2", nestedDynamicIdentifier);
representations.put(nestedDynamicIdentifier, TypeRepresentation.ofConcrete(nestedDynamicIdentifier, nestedDynamicProperties));
representations.put(OBJECT_IDENTIFIER, TypeRepresentation.ofConcrete(OBJECT_IDENTIFIER, dynamicProperties));
cut = new SchemaBuilder(representations);
assertThat(cut.build(modelIdentifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Model").build()));
assertThat(cut.build(OBJECT_IDENTIFIER).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Object").build()));
final JsonObject definitions = cut.getDefinitions();
assertThat(definitions, is(Json.createObjectBuilder()
.add("Model", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array1", Json.createObjectBuilder().add("type", "array").add("items", type("integer")))
.add("hello1", type("string"))
.add("test1", type("integer"))))
.add("JsonObject", Json.createObjectBuilder().add("properties", Json.createObjectBuilder().add("test", type("integer"))))
.add("Object", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array2", Json.createObjectBuilder().add("type", "array").add("items", type("integer")))
.add("hello2", type("string"))
.add("object2", Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject"))
.add("test2", type("integer"))))
.build()));
}
@Test
public void testMultipleDefinitionsNameCollisions() {
final TypeIdentifier lockIdentifier = TypeIdentifier.ofType("Ljava/util/concurrent/locks/Lock;");
final TypeIdentifier anotherLockIdentifier = TypeIdentifier.ofType("Ljavax/ejb/Lock;");
final Map<String, TypeIdentifier> lockProperties = new HashMap<>();
lockProperties.put("test1", INT_IDENTIFIER);
lockProperties.put("hello1", STRING_IDENTIFIER);
lockProperties.put("array1", INT_LIST_IDENTIFIER);
final Map<String, TypeIdentifier> anotherLockProperties = new HashMap<>();
anotherLockProperties.put("test1", INT_IDENTIFIER);
anotherLockProperties.put("hello1", STRING_IDENTIFIER);
anotherLockProperties.put("array1", INT_LIST_IDENTIFIER);
representations.put(INT_LIST_IDENTIFIER, TypeRepresentation.ofCollection(INTEGER_IDENTIFIER, TypeRepresentation.ofConcrete(INTEGER_IDENTIFIER)));
representations.put(lockIdentifier, TypeRepresentation.ofConcrete(lockIdentifier, lockProperties));
representations.put(anotherLockIdentifier, TypeRepresentation.ofConcrete(anotherLockIdentifier, anotherLockProperties));
cut = new SchemaBuilder(representations);
assertThat(cut.build(lockIdentifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Lock").build()));
assertThat(cut.build(anotherLockIdentifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Lock_2").build()));
final JsonObject definitions = cut.getDefinitions();
assertThat(definitions, is(Json.createObjectBuilder()
.add("Lock", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array1", Json.createObjectBuilder().add("type", "array").add("items", type("integer")))
.add("hello1", type("string"))
.add("test1", type("integer"))))
.add("Lock_2", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array1", Json.createObjectBuilder().add("type", "array").add("items", type("integer")))
.add("hello1", type("string"))
.add("test1", type("integer"))))
.build()));
}
@Test
public void testSingleDynamicDefinitionMissingNestedType() {
final TypeIdentifier identifier = TypeIdentifier.ofDynamic();
final Map<String, TypeIdentifier> properties = new HashMap<>();
properties.put("test1", INT_IDENTIFIER);
properties.put("hello1", STRING_IDENTIFIER);
// unknown type identifier
properties.put("array1", INT_LIST_IDENTIFIER);
representations.put(identifier, TypeRepresentation.ofConcrete(identifier, properties));
cut = new SchemaBuilder(representations);
assertThat(cut.build(identifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject").build()));
final JsonObject definitions = cut.getDefinitions();
assertThat(definitions, is(Json.createObjectBuilder()
.add("JsonObject", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array1", Json.createObjectBuilder().add("type", "object"))
.add("hello1", type("string"))
.add("test1", type("integer"))))
.build()));
}
@Test
public void testMultipleDifferentDefinitions() {
final Map<String, TypeIdentifier> properties = new HashMap<>();
properties.put("test1", INT_IDENTIFIER);
properties.put("hello1", STRING_IDENTIFIER);
properties.put("array1", INT_LIST_IDENTIFIER);
representations.put(MODEL_IDENTIFIER, TypeRepresentation.ofConcrete(MODEL_IDENTIFIER, properties));
representations.put(INT_LIST_IDENTIFIER, TypeRepresentation.ofCollection(INTEGER_IDENTIFIER, TypeRepresentation.ofConcrete(INTEGER_IDENTIFIER)));
cut = new SchemaBuilder(representations);
assertThat(cut.build(MODEL_IDENTIFIER).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Model").build()));
assertThat(cut.build(TypeIdentifier.ofType(Types.OBJECT)).build(), is(Json.createObjectBuilder().add("type", "object").build()));
// build with different type identifier instance
assertThat(cut.build(TypeIdentifier.ofType("Lcom/sebastian_daschner/test/Model;")).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Model").build()));
final JsonObject definitions = cut.getDefinitions();
assertThat(definitions, is(Json.createObjectBuilder()
.add("Model", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array1", Json.createObjectBuilder().add("type", "array").add("items", type("integer")))
.add("hello1", type("string"))
.add("test1", type("integer"))))
.build()));
}
@Test
public void testSameDynamicDefinitions() {
final TypeIdentifier firstIdentifier = TypeIdentifier.ofDynamic();
final TypeIdentifier secondIdentifier = TypeIdentifier.ofDynamic();
final Map<String, TypeIdentifier> firstProperties = new HashMap<>();
firstProperties.put("test1", INT_IDENTIFIER);
firstProperties.put("hello1", STRING_IDENTIFIER);
firstProperties.put("array1", INT_LIST_IDENTIFIER);
firstProperties.put("nested", secondIdentifier);
final Map<String, TypeIdentifier> secondProperties = new HashMap<>();
secondProperties.put("nested", firstIdentifier);
representations.put(INT_LIST_IDENTIFIER, TypeRepresentation.ofCollection(INTEGER_IDENTIFIER, TypeRepresentation.ofConcrete(INTEGER_IDENTIFIER)));
representations.put(firstIdentifier, TypeRepresentation.ofConcrete(firstIdentifier, firstProperties));
representations.put(secondIdentifier, TypeRepresentation.ofConcrete(secondIdentifier, secondProperties));
cut = new SchemaBuilder(representations);
assertThat(cut.build(firstIdentifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject").build()));
assertThat(cut.build(firstIdentifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject").build()));
assertThat(cut.build(secondIdentifier).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject_2").build()));
final JsonObject definitions = cut.getDefinitions();
assertThat(definitions, is(Json.createObjectBuilder()
.add("JsonObject", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("array1", Json.createObjectBuilder().add("type", "array").add("items", type("integer")))
.add("hello1", type("string"))
.add("nested", Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject_2"))
.add("test1", type("integer"))))
.add("JsonObject_2", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("nested", Json.createObjectBuilder().add("$ref", "#/definitions/JsonObject"))))
.build()));
}
@Test
public void testEnumDefinitions() {
final TypeIdentifier enumIdentifier = TypeIdentifier.ofType("Lcom/sebastian_daschner/test/Enumeration;");
final Map<String, TypeIdentifier> modelProperties = new HashMap<>();
modelProperties.put("foobar", enumIdentifier);
modelProperties.put("hello1", STRING_IDENTIFIER);
representations.put(MODEL_IDENTIFIER, TypeRepresentation.ofConcrete(MODEL_IDENTIFIER, modelProperties));
representations.put(enumIdentifier, TypeRepresentation.ofEnum(enumIdentifier, "THIRD", "FIRST", "SECOND"));
cut = new SchemaBuilder(representations);
assertThat(cut.build(MODEL_IDENTIFIER).build(), is(Json.createObjectBuilder().add("$ref", "#/definitions/Model").build()));
assertThat(cut.build(enumIdentifier).build(), is(Json.createObjectBuilder().add("type", "string")
.add("enum", Json.createArrayBuilder().add("FIRST").add("SECOND").add("THIRD")).build()));
final JsonObject definitions = cut.getDefinitions();
assertThat(definitions, is(Json.createObjectBuilder()
.add("Model", Json.createObjectBuilder().add("properties", Json.createObjectBuilder()
.add("foobar", Json.createObjectBuilder().add("type", "string").add("enum", Json.createArrayBuilder().add("FIRST").add("SECOND").add("THIRD")))
.add("hello1", type("string"))))
.build()));
}
private static JsonObject type(final String type) {
return Json.createObjectBuilder().add("type", type).build();
}
}