/**
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.seed.rest.internal;
import com.google.common.collect.Lists;
import io.nuun.kernel.api.annotations.Ignore;
import mockit.Expectations;
import mockit.Mocked;
import mockit.integration.junit4.JMockit;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.seedstack.seed.rest.Rel;
import org.seedstack.seed.rest.RestConfig;
import org.seedstack.seed.rest.internal.jsonhome.Resource;
import javax.servlet.ServletContext;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.Map;
/**
* Tests that JAX-RS resources annotated with @Rel on method or class are
* properly scanned.
*/
@Ignore // Tells nuun to not scan the test class
@RunWith(JMockit.class)
public class JsonHomeScanTest {
private static final String SERVLET_CONTEXT_PATH = "/app/";
private static final String REST_PATH = "/rest/";
private static final String BASE_REL = "http://example.org/rel/";
private static final String BASE_PARAM = "http://example.org/param/";
@Ignore
static class MethodResource {
@Rel(value = "/widgets/", home = true)
@Path("/widgets")
@POST
public Response post() {
return null;
}
}
@Ignore
@Path("/catalog1")
static class ClassResource {
@Rel(value = "catalog1", home = true)
@POST
public Response post() {
return null;
}
}
@Ignore
@Rel(value = "shouldNotBeTakenInAccount")
@Path("/catalog2/")
static class ClassAndMethodResource {
@Rel(value = "catalog2", home = true)
@Path("/widgets/")
@POST
public Response post() {
return null;
}
}
@Ignore
@Path("/catalog3/")
static class ClassAndMethodResource2 {
@Rel(value = "catalog3", home = true)
@Path("/widgets/")
@POST
public Response post() {
return null;
}
}
@Ignore
@Rel(value = "catalog4", home = true)
@Path("/catalog4/")
static class ClassAndMethodResource3 {
@Rel("unexposed")
@Path("/widgets/")
@POST
public Response post() {
return null;
}
}
@Ignore
static class FakeResource {
@Rel(value = "", home = true)
@POST
public Response post() {
return null;
}
}
@Ignore
static class FakeResource2 {
@Path("fake")
@POST
public Response post() {
return null;
}
}
@Rel(value = "widget", home = true)
@Path("/widgets/{widgetName: [a-zA-Z][a-zA-Z_0-9]}")
static class MyLinkTemplateResource {
@GET
public Response get(@PathParam("widgetName") String widgetId, @QueryParam("pageSize") Integer pageSize) {
return null;
}
@PUT
public Response put(@PathParam("widgetName") String widgetId) {
return null;
}
}
@Mocked
private RestConfig restConfig;
@Mocked
private ServletContext servletContext;
private Map<String, Resource> resourceMap;
@Before
public void before() {
new Expectations() {
{
restConfig.getPath();
result = REST_PATH;
restConfig.getBaseRel();
result = BASE_REL;
restConfig.getBaseParam();
result = BASE_PARAM;
servletContext.getContextPath();
result = SERVLET_CONTEXT_PATH;
}
};
ResourceScanner resourceScanner = new ResourceScanner(restConfig, servletContext);
resourceScanner.scan(Lists.newArrayList(
MethodResource.class,
ClassResource.class,
ClassAndMethodResource.class,
ClassAndMethodResource2.class,
ClassAndMethodResource3.class
));
resourceMap = resourceScanner.jsonHomeResources();
Assertions.assertThat(resourceMap).isNotNull();
}
@Test
public void scan_json_home_resources() {
// Path on method
Resource widgetResource = resourceMap.get(UriBuilder.uri(BASE_REL, "widgets"));
Assertions.assertThat(widgetResource).isNotNull();
Assertions.assertThat(widgetResource.rel()).isEqualTo(UriBuilder.uri(BASE_REL, "widgets"));
Assertions.assertThat(widgetResource.href()).isEqualTo("/app/rest/widgets");
// Path on class
Resource catalogResource = resourceMap.get(UriBuilder.uri(BASE_REL, "catalog1"));
Assertions.assertThat(catalogResource).isNotNull();
Assertions.assertThat(catalogResource.rel()).isEqualTo(UriBuilder.uri(BASE_REL, "catalog1"));
Assertions.assertThat(catalogResource.href()).isEqualTo("/app/rest/catalog1");
// Path on method and class (with two rel)
Resource catalogWidgetResource = resourceMap.get(UriBuilder.uri(BASE_REL, "catalog2"));
Assertions.assertThat(catalogWidgetResource).isNotNull();
Assertions.assertThat(catalogWidgetResource.rel()).isEqualTo(UriBuilder.uri(BASE_REL, "catalog2"));
Assertions.assertThat(catalogWidgetResource.href()).isEqualTo("/app/rest/catalog2/widgets");
// Path on method and class
Resource catalogWidgetResource2 = resourceMap.get(UriBuilder.uri(BASE_REL, "catalog3"));
Assertions.assertThat(catalogWidgetResource2).isNotNull();
Assertions.assertThat(catalogWidgetResource2.rel()).isEqualTo(UriBuilder.uri(BASE_REL, "catalog3"));
Assertions.assertThat(catalogWidgetResource2.href()).isEqualTo("/app/rest/catalog3/widgets");
// Path on method and class
Resource catalogResource4 = resourceMap.get(UriBuilder.uri(BASE_REL, "catalog4"));
Assertions.assertThat(catalogResource4).isNull();
Resource unexposed = resourceMap.get(UriBuilder.uri(BASE_REL, "unexposed"));
Assertions.assertThat(unexposed).isNull();
}
@Test(expected = Exception.class)
public void test_bad_rel() {
ResourceScanner resourceScanner = new ResourceScanner(restConfig, servletContext);
resourceScanner.scan(Lists.newArrayList(
FakeResource.class,
FakeResource2.class
));
resourceMap = resourceScanner.jsonHomeResources();
}
}