blob: 378859db819aa2549338175006935b45a93dbbb0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.microprofile.openapi.impl.processor;
import org.apache.geronimo.microprofile.openapi.config.GeronimoOpenAPIConfig;
import org.apache.geronimo.microprofile.openapi.impl.model.OpenAPIImpl;
import org.apache.geronimo.microprofile.openapi.impl.processor.reflect.ClassElement;
import org.apache.geronimo.microprofile.openapi.impl.processor.reflect.MethodElement;
import org.apache.geronimo.microprofile.openapi.impl.processor.spi.NamingStrategy;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import org.eclipse.microprofile.openapi.models.PathItem;
import org.eclipse.microprofile.openapi.models.parameters.Parameter;
import org.eclipse.microprofile.openapi.models.responses.APIResponses;
import org.testng.annotations.Test;
import javax.json.JsonPatch;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PATCH;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
public class AnnotationProcessorTest {
@Test
public void ensureParametersAreMapped() {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(GeronimoOpenAPIConfig.create(), new NamingStrategy.Default(), null);
OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(TestResource.class),
Stream.of(TestResource.class.getMethods()).map(MethodElement::new));
PathItem pathItem = openAPI.getPaths().get("/test/{a}");
assertNotNull(pathItem);
List<Parameter> parameters = pathItem.getGET().getParameters();
assertEquals(Parameter.In.PATH, parameters.get(0).getIn());
assertEquals("a", parameters.get(0).getName());
// TODO add more assertions
}
@Test
public void ensureParameterAnnotationsAreMerged() {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(GeronimoOpenAPIConfig.create(), new NamingStrategy.Default(), null);
OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(TestResource.class),
Stream.of(TestResource.class.getMethods()).map(MethodElement::new));
PathItem pathItem = openAPI.getPaths().get("/test/bye");
assertNotNull(pathItem);
List<Parameter> parameters = pathItem.getGET().getParameters();
assertEquals(Parameter.In.QUERY, parameters.get(0).getIn());
assertEquals("b", parameters.get(0).getName());
}
@Test
public void ensureResponsesMediaTypeIsSetForDefaultResponses() {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(GeronimoOpenAPIConfig.create(), new NamingStrategy.Default(), null);
OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(TestResource.class),
Stream.of(TestResource.class.getMethods()).map(MethodElement::new));
PathItem pathItem = openAPI.getPaths().get("/test/bye");
assertNotNull(pathItem);
APIResponses responses = pathItem.getGET().getResponses();
assertEquals(responses.size(), 2);
assertNotNull(responses.get("default"));
assertNotNull(responses.get("default").getContent().get("text/plain"));
assertNotNull(responses.get("204"));
assertNotNull(responses.get("204").getContent().get("text/plain"));
}
@Test
public void ensureResponsesMediaTypeIsSetForAllResponses() {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(GeronimoOpenAPIConfig.create(), new NamingStrategy.Default(), null);
OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(TestResource.class),
Stream.of(TestResource.class.getMethods()).map(MethodElement::new));
PathItem pathItem = openAPI.getPaths().get("/test/bye");
assertNotNull(pathItem);
APIResponses responses = pathItem.getPATCH().getResponses();
assertEquals(responses.size(), 2);
assertNotNull(responses.get("404"));
assertNotNull(responses.get("404").getContent().get("application/json"));
assertNotNull(responses.get("204"));
assertNotNull(responses.get("204").getContent().get("application/json"));
}
@Test
public void ensureResponsesDefaultMediaTypeIsSet() {
AnnotationProcessor annotationProcessor = new AnnotationProcessor(GeronimoOpenAPIConfig.create(), new NamingStrategy.Default(), null);
OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(TestResource.class),
Stream.of(TestResource.class.getMethods()).map(MethodElement::new));
PathItem pathItem = openAPI.getPaths().get("/test/bye");
assertNotNull(pathItem);
APIResponses responses = pathItem.getDELETE().getResponses();
assertEquals(responses.size(), 1);
assertNotNull(responses.get("204"));
assertNotNull(responses.get("204").getContent().get("*/*"));
}
@Test
public void namingStrategy() {
final Map<NamingStrategy, String> expectations = new HashMap<>();
expectations.put(new NamingStrategy.Default(), "hello");
expectations.put(new NamingStrategy.Qualified(), "org.apache.geronimo.microprofile.openapi.impl.processor.AnnotationProcessorTest$TestResource.hello");
expectations.put(new NamingStrategy.SimpleQualified(), "TestResource.hello");
expectations.put(new NamingStrategy.SimpleQualifiedCamelCase(), "TestResourceHello");
expectations.put(new NamingStrategy.Http(), "GET:/test/{a}");
final GeronimoOpenAPIConfig config = (value, def) -> null;
expectations.forEach((strategy, operationName) -> {
final AnnotationProcessor annotationProcessor = new AnnotationProcessor(config, strategy, null);
final OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(TestResource.class),
Stream.of(TestResource.class.getMethods()).map(MethodElement::new));
assertEquals(openAPI.getPaths().get("/test/{a}").getGET().getOperationId(), operationName);
});
}
@Test
public void rootPath() {
final AnnotationProcessor annotationProcessor = new AnnotationProcessor((value, def) -> null, new NamingStrategy.Default(), null);
final OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(RootPath.class),
Stream.of(RootPath.class.getMethods()).map(MethodElement::new));
assertNotNull(openAPI.getPaths().get("/{a}").getGET().getOperationId()); // we didn't get an index exception
}
@Test
public void patch() {
final AnnotationProcessor annotationProcessor = new AnnotationProcessor((value, def) -> null, new NamingStrategy.Default(), null);
final OpenAPI openAPI = new OpenAPIImpl();
annotationProcessor.processClass("", openAPI, new ClassElement(Patched.class),
Stream.of(Patched.class.getMethods()).map(MethodElement::new));
assertNotNull(openAPI.getPaths().get("/{a}").getPATCH().getOperationId()); // we didn't get an index exception
}
@Path("/")
public class Patched {
@PATCH
@Path("/{a}")
@Produces(MediaType.TEXT_PLAIN)
public String hello(final String foo) {
return null;
}
}
@Path("/")
public class RootPath {
@GET
@Path("/{a}")
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return null;
}
}
@Path("/test")
public class TestResource {
@GET
@Path("/{a}")
@Produces(MediaType.TEXT_PLAIN)
public String hello(@PathParam("a") String a) {
return "hello";
}
@GET
@Path("/bye")
@Produces(MediaType.TEXT_PLAIN)
public void bye(@org.eclipse.microprofile.openapi.annotations.parameters.Parameter(required = true) @QueryParam("b") String b) {
}
@DELETE
@Path("/bye")
@APIResponse(responseCode = "204")
public void bye() {
}
@PATCH
@Path("/bye")
@Produces(MediaType.APPLICATION_JSON)
@APIResponse(responseCode = "204")
@APIResponse(responseCode = "404")
public Response bye(JsonPatch patch) {
return Response.ok().build();
}
}
}