package io.dropwizard.jersey;
import com.codahale.metrics.MetricRegistry;
import io.dropwizard.jersey.dummy.DummyResource;
import io.dropwizard.logging.BootstrapLogging;
import org.glassfish.jersey.server.model.Resource;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import static org.assertj.core.api.Assertions.assertThat;
public class DropwizardResourceConfigTest {
static {
BootstrapLogging.bootstrap();
}
private DropwizardResourceConfig rc;
@Before
public void setUp() {
rc = DropwizardResourceConfig.forTesting(new MetricRegistry());
}
@Test
public void findsResourceClassInPackage() {
rc.packages(DummyResource.class.getPackage().getName());
assertThat(rc.getClasses()).contains(DummyResource.class);
}
@Test
public void findsResourceClassesInPackageAndSubpackage() {
rc.packages(getClass().getPackage().getName());
assertThat(rc.getClasses()).contains(
DummyResource.class,
TestResource.class,
ResourceInterface.class);
}
@Test
public void combinesAlRegisteredClasses() {
rc.register(new TestResource());
rc.registerClasses(ResourceInterface.class, ImplementingResource.class);
assertThat(rc.allClasses()).contains(
TestResource.class,
ResourceInterface.class,
ImplementingResource.class
);
}
@Test
public void combinesAlRegisteredClassesPathOnMethodLevel() {
rc.register(new TestResource());
rc.register(new ResourcePathOnMethodLevel());
assertThat(rc.allClasses()).contains(
TestResource.class,
ResourcePathOnMethodLevel.class
);
assertThat(rc.getEndpointsInfo())
.contains("GET /bar (io.dropwizard.jersey.DropwizardResourceConfigTest.ResourcePathOnMethodLevel)")
.contains("GET /dummy (io.dropwizard.jersey.DropwizardResourceConfigTest.TestResource)");
}
@Test
public void logsNoInterfaces() {
rc.packages(getClass().getPackage().getName());
assertThat(rc.getEndpointsInfo()).doesNotContain("io.dropwizard.jersey.DropwizardResourceConfigTest.ResourceInterface");
}
@Test
public void logsNoEndpointsWhenNoResourcesAreRegistered() {
assertThat(rc.getEndpointsInfo()).contains(" NONE");
}
@Test
public void logsEndpoints() {
rc.register(TestResource.class);
rc.register(ImplementingResource.class);
assertThat(rc.getEndpointsInfo())
.contains("GET /dummy (io.dropwizard.jersey.DropwizardResourceConfigTest.TestResource)")
.contains("GET /another (io.dropwizard.jersey.DropwizardResourceConfigTest.ImplementingResource)");
}
@Test
public void logsEndpointsSorted() {
rc.register(DummyResource.class);
rc.register(TestResource2.class);
rc.register(TestResource.class);
rc.register(ImplementingResource.class);
final String expectedLog = String.format(
"The following paths were found for the configured resources:%n"
+ "%n"
+ " GET / (io.dropwizard.jersey.dummy.DummyResource)%n"
+ " GET /another (io.dropwizard.jersey.DropwizardResourceConfigTest.ImplementingResource)%n"
+ " GET /async (io.dropwizard.jersey.dummy.DummyResource)%n"
+ " DELETE /dummy (io.dropwizard.jersey.DropwizardResourceConfigTest.TestResource2)%n"
+ " GET /dummy (io.dropwizard.jersey.DropwizardResourceConfigTest.TestResource)%n"
+ " POST /dummy (io.dropwizard.jersey.DropwizardResourceConfigTest.TestResource2)%n");
assertThat(rc.getEndpointsInfo()).isEqualTo(expectedLog);
}
@Test
public void logsNestedEndpoints() {
rc.register(WrapperResource.class);
assertThat(rc.getEndpointsInfo())
.contains(" GET /wrapper/bar (io.dropwizard.jersey.DropwizardResourceConfigTest.ResourcePathOnMethodLevel)")
.contains(" GET /locator/bar (io.dropwizard.jersey.DropwizardResourceConfigTest.ResourcePathOnMethodLevel)")
.contains(" UNKNOWN /obj/{it} (java.lang.Object)");
}
@Test
public void logsProgrammaticalEndpoints() {
Resource.Builder resourceBuilder = Resource.builder("/prefix");
resourceBuilder.addChildResource(Resource.from(DummyResource.class));
resourceBuilder.addChildResource(Resource.from(TestResource.class));
resourceBuilder.addChildResource(Resource.from(ImplementingResource.class));
rc.registerResources(resourceBuilder.build());
final String expectedLog = String.format(
"The following paths were found for the configured resources:%n"
+ "%n"
+ " GET /prefix/ (io.dropwizard.jersey.dummy.DummyResource)%n"
+ " GET /prefix/another (io.dropwizard.jersey.DropwizardResourceConfigTest.ImplementingResource)%n"
+ " GET /prefix/async (io.dropwizard.jersey.dummy.DummyResource)%n"
+ " GET /prefix/dummy (io.dropwizard.jersey.DropwizardResourceConfigTest.TestResource)%n"
);
assertThat(rc.getEndpointsInfo()).isEqualTo(expectedLog);
}
@Test
public void testEndpointLoggerPathCleaning() {
String dirtyPath = " /this//is///a/dirty//path/ ";
String anotherDirtyPath = "a/l//p/h/ /a/b ///// e/t";
assertThat(rc.cleanUpPath(dirtyPath)).isEqualTo("/this/is/a/dirty/path/");
assertThat(rc.cleanUpPath(anotherDirtyPath)).isEqualTo("a/l/p/h/a/b/e/t");
}
@Test
public void duplicatePathsTest() {
rc.register(TestDuplicateResource.class);
final String expectedLog = String.format("The following paths were found for the configured resources:%n" + "%n"
+ " GET /anotherMe (io.dropwizard.jersey.DropwizardResourceConfigTest.TestDuplicateResource)%n"
+ " GET /callme (io.dropwizard.jersey.DropwizardResourceConfigTest.TestDuplicateResource)%n");
assertThat(rc.getEndpointsInfo()).contains(expectedLog);
assertThat(rc.getEndpointsInfo()).containsOnlyOnce(" GET /callme (io.dropwizard.jersey.DropwizardResourceConfigTest.TestDuplicateResource)");
}
@Path("/dummy")
public static class TestResource {
@GET
public String foo() {
return "bar";
}
}
@Path("/dummy")
public static class TestResource2 {
@POST
public String fooPost() {
return "bar";
}
@DELETE
public String fooDelete() {
return "bar";
}
}
@Path("/")
public static class TestDuplicateResource {
@GET
@Path("callme")
@Produces(MediaType.APPLICATION_JSON)
public String fooGet() {
return "bar";
}
@GET
@Path("callme")
@Produces(MediaType.TEXT_HTML)
public String fooGet2() {
return "bar2";
}
@GET
@Path("callme")
@Produces(MediaType.APPLICATION_XML)
public String fooGet3() {
return "bar3";
}
@GET
@Path("anotherMe")
public String fooGet4() {
return "bar4";
}
}
@Path("/another")
public static interface ResourceInterface {
@GET
public String bar();
}
@Path("/")
public static class WrapperResource {
@Path("wrapper")
public ResourcePathOnMethodLevel getNested() {
return new ResourcePathOnMethodLevel();
}
@Path("locator")
public Class<ResourcePathOnMethodLevel> getNested2() {
return ResourcePathOnMethodLevel.class;
}
@Path("obj/{it}")
public Object getNested3(@PathParam("it") String path) {
if (path.equals("implement")) {
return new ImplementingResource();
}
return new ResourcePathOnMethodLevel();
}
}
public static class ResourcePathOnMethodLevel {
@GET @Path("/bar")
public String bar() {
return "";
}
}
public static class ImplementingResource implements ResourceInterface {
@Override
public String bar() {
return "";
}
}
}