Skip to content

Commit

Permalink
Add discriminator field support + better integration tests in core (#600
Browse files Browse the repository at this point in the history
)

* test(core): add AsyncListener and AsyncPublisher integration test

* feat(asyncapi): handle discriminator field

* chore(core): formatting
  • Loading branch information
timonback authored Feb 16, 2024
1 parent 42eee0e commit 63cf564
Show file tree
Hide file tree
Showing 12 changed files with 234 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ public ComponentSchema mapSchemaOrRef(Schema schema) {
public SchemaObject mapSchema(Schema value) {
SchemaObject.SchemaObjectBuilder builder = SchemaObject.builder();

// TODO: .discriminator(value.getDiscriminator())

io.swagger.v3.oas.models.ExternalDocumentation externalDocs = value.getExternalDocs();
if (externalDocs != null) {
ExternalDocumentation externalDocumentation = ExternalDocumentation.builder()
Expand Down Expand Up @@ -97,6 +95,10 @@ public SchemaObject mapSchema(Schema value) {

builder.required(value.getRequired());

if (value.getDiscriminator() != null) {
builder.discriminator(value.getDiscriminator().getPropertyName());
}

List<Object> allOf = value.getAllOf();
if (allOf != null) {
builder.allOf(allOf.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void testContextWithApplicationProperties() {
assertThat(asyncApiService.getAsyncAPI()).isNotNull();
assertThat(asyncApiService.getAsyncAPI().getInfo().getTitle())
.isEqualTo("Info title was loaded from spring properties");
assertThat(asyncApiService.getAsyncAPI().getDefaultContentType()).isEqualTo("application/yaml");
assertThat(asyncApiService.getAsyncAPI().getDefaultContentType()).isEqualTo("application/json");
assertThat(asyncApiService.getAsyncAPI().getId()).isEqualTo("urn:io:github:stavshamir:springwolf:example");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"springwolf.docket.info.title=Info title was loaded from spring properties",
"springwolf.docket.info.version=1.0.0",
"springwolf.docket.id=urn:io:github:stavshamir:springwolf:example",
"springwolf.docket.default-content-type=application/yaml",
"springwolf.docket.default-content-type=application/json",
"springwolf.docket.base-package=io.github.stavshamir.springwolf.example",
"springwolf.docket.servers.test-protocol.protocol=test",
"springwolf.docket.servers.test-protocol.host=some-server:1234",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
"springwolf.docket.info.title=Info title was loaded from spring properties",
"springwolf.docket.info.version=1.0.0",
"springwolf.docket.id=urn:io:github:stavshamir:springwolf:example",
"springwolf.docket.default-content-type=application/yaml",
"springwolf.docket.base-package=io.github.stavshamir.springwolf.example",
"springwolf.docket.default-content-type=application/json",
"springwolf.docket.base-package=io.github.stavshamir.springwolf.integrationtests.application.basic",
"springwolf.docket.servers.test-protocol.protocol=test",
"springwolf.docket.servers.test-protocol.host=some-server:1234",
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.integrationtests;

import io.github.stavshamir.springwolf.asyncapi.AsyncApiService;
import io.github.stavshamir.springwolf.asyncapi.v3.model.AsyncAPI;
import io.github.stavshamir.springwolf.asyncapi.v3.model.channel.message.Message;
import io.github.stavshamir.springwolf.asyncapi.v3.model.schema.SchemaObject;
import io.github.stavshamir.springwolf.fixtures.MinimalIntegrationTestContextConfiguration;
import io.github.stavshamir.springwolf.integrationtests.application.listener.ListenerApplication;
import io.github.stavshamir.springwolf.integrationtests.application.polymorphic.PolymorphicPayloadApplication;
import io.github.stavshamir.springwolf.integrationtests.application.publisher.PublisherApplication;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

public class AsyncApiDocumentIntegrationTest {

@Nested
@SpringBootTest(classes = ListenerApplication.class)
@MinimalIntegrationTestContextConfiguration
@TestPropertySource(
properties = {
"springwolf.docket.base-package=io.github.stavshamir.springwolf.integrationtests.application.listener",
})
class ListenerAnnotationTest {
@Autowired
private AsyncApiService asyncApiService;

@Test
void asyncListenerAnnotationIsFound() {
AsyncAPI asyncAPI = asyncApiService.getAsyncAPI();
assertThat(asyncAPI).isNotNull();

assertThat(asyncAPI.getChannels()).containsOnlyKeys("listener-channel");
assertThat(asyncAPI.getOperations()).containsOnlyKeys("listener-channel_receive_listen");
assertThat(asyncAPI.getComponents().getMessages()).containsOnlyKeys("java.lang.String");
assertThat(asyncAPI.getComponents().getSchemas()).containsOnlyKeys("HeadersNotDocumented", "String");
}
}

@Nested
@SpringBootTest(classes = PublisherApplication.class)
@MinimalIntegrationTestContextConfiguration
@TestPropertySource(
properties = {
"springwolf.docket.base-package=io.github.stavshamir.springwolf.integrationtests.application.publisher",
})
class PublisherAnnotationTest {
@Autowired
private AsyncApiService asyncApiService;

@Test
void asyncPublisherAnnotationIsFound() {
AsyncAPI asyncAPI = asyncApiService.getAsyncAPI();
assertThat(asyncAPI).isNotNull();

assertThat(asyncAPI.getChannels()).containsOnlyKeys("publisher-channel");
assertThat(asyncAPI.getOperations()).containsOnlyKeys("publisher-channel_send_publish");
assertThat(asyncAPI.getComponents().getMessages()).containsOnlyKeys("java.lang.String");
assertThat(asyncAPI.getComponents().getSchemas()).containsOnlyKeys("HeadersNotDocumented", "String");
}
}

@Nested
@SpringBootTest(classes = PolymorphicPayloadApplication.class)
@MinimalIntegrationTestContextConfiguration
@TestPropertySource(
properties = {
"springwolf.docket.base-package=io.github.stavshamir.springwolf.integrationtests.application.polymorphic",
})
class PolymorphicPayloadTest {
@Autowired
private AsyncApiService asyncApiService;

@Test
void polymorphicDiscriminatorFieldIsHandled() {
// when
AsyncAPI asyncAPI = asyncApiService.getAsyncAPI();

// then
Map<String, Message> messages = asyncAPI.getComponents().getMessages();
assertThat(messages)
.containsOnlyKeys(
"io.github.stavshamir.springwolf.integrationtests.application.polymorphic.PolymorphicPayloadApplication$Payload");
Map<String, SchemaObject> schemas = asyncAPI.getComponents().getSchemas();
assertThat(schemas).containsOnlyKeys("HeadersNotDocumented", "Payload", "Pet", "Cat", "Dog");

assertThat(schemas.get("Pet").getDiscriminator()).isEqualTo("type");
assertThat(schemas.get("Cat").getAllOf().get(0).getReference().getRef())
.isEqualTo("#/components/schemas/Pet");
assertThat(schemas.get("Cat").getAllOf().get(1).getSchema().getProperties())
.containsOnlyKeys("catSpecificField");
assertThat(schemas.get("Dog").getAllOf().get(0).getReference().getRef())
.isEqualTo("#/components/schemas/Pet");
assertThat(schemas.get("Dog").getAllOf().get(1).getSchema().getProperties())
.containsOnlyKeys("dogSpecificField");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import io.github.stavshamir.springwolf.asyncapi.controller.AsyncApiController;
import io.github.stavshamir.springwolf.fixtures.MinimalIntegrationTestContextConfiguration;
import io.github.stavshamir.springwolf.integrationtests.application.basic.TestApplication;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ObjectProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.github.stavshamir.springwolf.asyncapi.DefaultAsyncApiService;
import io.github.stavshamir.springwolf.asyncapi.controller.AsyncApiController;
import io.github.stavshamir.springwolf.fixtures.MinimalIntegrationTestContextConfiguration;
import io.github.stavshamir.springwolf.integrationtests.application.basic.TestApplication;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.integrationtests;
package io.github.stavshamir.springwolf.integrationtests.application.basic;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
class TestApplication {}
public class TestApplication {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.integrationtests.application.listener;

import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncListener;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncOperation;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class ListenerApplication {
@Bean
public Listener listener() {
return new Listener();
}

class Listener {
@AsyncListener(operation = @AsyncOperation(channelName = "listener-channel"))
public void listen(String payload) {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.integrationtests.application.polymorphic;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncListener;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncOperation;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class PolymorphicPayloadApplication {
@Bean
public Listener listener() {
return new Listener();
}

class Listener {
@AsyncListener(operation = @AsyncOperation(channelName = "listener-channel"))
public void listen(Payload payload) {}
}

public record Payload(Pet pet) {}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes(
value = {
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
})
public interface Pet {
public String getType();
}

public record Dog() implements Pet {
@Override
public String getType() {
return "dog";
}

public String getDogSpecificField() {
return "dog-specific-field";
}
}

public record Cat() implements Pet {
@Override
public String getType() {
return "cat";
}

public String getCatSpecificField() {
return "cat-specific-field";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: Apache-2.0
package io.github.stavshamir.springwolf.integrationtests.application.publisher;

import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncOperation;
import io.github.stavshamir.springwolf.asyncapi.scanners.channels.operationdata.annotation.AsyncPublisher;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class PublisherApplication {
@Bean
public Publisher publisher() {
return new Publisher();
}

class Publisher {
@AsyncPublisher(operation = @AsyncOperation(channelName = "publisher-channel"))
public void publish(String payload) {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.stavshamir.springwolf.asyncapi.v3.model.components.ComponentSchema;
import io.github.stavshamir.springwolf.asyncapi.v3.model.schema.SchemaObject;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.media.ObjectSchema;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -344,6 +345,21 @@ void mapRequired() {
assertThat(componentSchema.getRequired()).isEqualTo(schema.getRequired());
}

@Test
void mapDiscriminator() {
// given
ObjectSchema schema = new ObjectSchema();
Discriminator discriminator = new Discriminator();
discriminator.setPropertyName("propertyName");
schema.setDiscriminator(discriminator);

// when
SchemaObject componentSchema = swaggerSchemaUtil.mapSchema(schema);

// then
assertThat(componentSchema.getDiscriminator()).isEqualTo("propertyName");
}

@Test
void mapAllOf() {
// given
Expand All @@ -356,7 +372,7 @@ void mapAllOf() {
SchemaObject componentSchema = swaggerSchemaUtil.mapSchema(schema);

// then
assertThat(((SchemaObject) componentSchema.getAllOf().get(0).getSchema()).getType())
assertThat((componentSchema.getAllOf().get(0).getSchema()).getType())
.isEqualTo(allOf.getType());
}

Expand All @@ -372,7 +388,7 @@ void mapOneOf() {
SchemaObject componentSchema = swaggerSchemaUtil.mapSchema(schema);

// then
assertThat(((SchemaObject) componentSchema.getOneOf().get(0).getSchema()).getType())
assertThat((componentSchema.getOneOf().get(0).getSchema()).getType())
.isEqualTo(oneOf.getType());
}

Expand All @@ -388,7 +404,7 @@ void mapAnyOf() {
SchemaObject componentSchema = swaggerSchemaUtil.mapSchema(schema);

// then
assertThat(((SchemaObject) componentSchema.getAnyOf().get(0).getSchema()).getType())
assertThat((componentSchema.getAnyOf().get(0).getSchema()).getType())
.isEqualTo(anyOf.getType());
}

Expand Down Expand Up @@ -417,8 +433,7 @@ void mapNot() {
SchemaObject componentSchema = swaggerSchemaUtil.mapSchema(schema);

// then
assertThat(((SchemaObject) componentSchema.getNot().getSchema()).getType())
.isEqualTo(not.getType());
assertThat((componentSchema.getNot().getSchema()).getType()).isEqualTo(not.getType());
}

@Test
Expand All @@ -434,8 +449,7 @@ void mapItems() {
SchemaObject componentSchema = swaggerSchemaUtil.mapSchema(schema);

// then
assertThat(((SchemaObject) componentSchema.getItems().getSchema()).getType())
.isEqualTo(item.getType());
assertThat((componentSchema.getItems().getSchema()).getType()).isEqualTo(item.getType());
}

@Test
Expand Down

0 comments on commit 63cf564

Please sign in to comment.