/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.impl; import org.everrest.core.ApplicationContext; import org.everrest.core.ObjectFactory; import org.everrest.core.ResourcePublicationException; import org.everrest.core.resource.ResourceDescriptor; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MultivaluedHashMap; import java.util.List; import static com.google.common.collect.Lists.newArrayList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; public class ResourceBinderImplTest { @Rule public ExpectedException thrown = ExpectedException.none(); private ResourceBinderImpl resourceBinder; @Before public void setUp() throws Exception { resourceBinder = new ResourceBinderImpl(); } @Test public void bindsPerRequestResource() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertEquals(EchoResource.class, resourceFactory.getObjectModel().getObjectClass()); } @Test public void throwsResourcePublicationExceptionWhenResourceClassIsNotAnnotatedWithPathAnnotation() throws Exception { thrown.expect(ResourcePublicationException.class); resourceBinder.addResource(NoPathAnnotationResource.class, new MultivaluedHashMap<>()); } @Test public void bindsPerRequestResourceWithNewPath() throws Exception { resourceBinder.addResource("/x/y", EchoResource.class, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/x/y", newArrayList()); assertEquals(EchoResource.class, resourceFactory.getObjectModel().getObjectClass()); } @Test public void bindsSingletonResource() throws Exception { EchoResource resource = new EchoResource(); resourceBinder.addResource(resource, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertSame(resource, resourceFactory.getInstance(mock(ApplicationContext.class))); } @Test public void throwsResourcePublicationExceptionWhenResourceIsNotAnnotatedWithPathAnnotation() throws Exception { thrown.expect(ResourcePublicationException.class); resourceBinder.addResource(new NoPathAnnotationResource(), new MultivaluedHashMap<>()); } @Test public void bindsSingletonResourceWithNewPath() throws Exception { EchoResource resource = new EchoResource(); resourceBinder.addResource("x/y", resource, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/x/y", newArrayList()); assertSame(resource, resourceFactory.getInstance(mock(ApplicationContext.class))); } @Test public void throwsPerRequestResourcePublicationExceptionWhenTryRegisterTwoResourcesWithTheSamePath() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); thrown.expect(ResourcePublicationException.class); resourceBinder.addResource(OtherEchoResource.class, new MultivaluedHashMap<>()); } @Test public void ignoresMultipleAttemptsToRegisterPerRequestResourcesOfTheSameClass() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); assertSame(resourceFactory, resourceBinder.getMatchedResource("/a/b", newArrayList())); } @Test public void clearsAllRegisteredResources() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); assertEquals(1, resourceBinder.getSize()); resourceBinder.clear(); assertEquals(0, resourceBinder.getSize()); } @Test public void bindsResourceWithSubResourceMethod() throws Exception { resourceBinder.addResource(EchoResourceWithSubResourceMethod.class, new MultivaluedHashMap<>()); List<String> parameterValues = newArrayList(); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", parameterValues); assertEquals(EchoResourceWithSubResourceMethod.class, resourceFactory.getObjectModel().getObjectClass()); assertEquals(newArrayList("/b"), parameterValues); } @Test public void resourceWithLongerPathTakesPrecedenceOverResourceWithSorterPathInCaseIfTwoResourcesAreMatched() throws Exception { resourceBinder.addResource(EchoResourceWithSubResourceMethod.class, new MultivaluedHashMap<>()); resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); assertEquals(2, resourceBinder.getSize()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertEquals(EchoResource.class, resourceFactory.getObjectModel().getObjectClass()); } @Test public void returnsNullIfNoMatchedResources() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/x/y", newArrayList()); assertNull(resourceFactory); } @Test public void returnsListOfAllRegisteredResourcesAndAnyChangesOnThisListDoNotImpactOriginalList() throws Exception { resourceBinder.addResource(EchoResourceWithSubResourceMethod.class, new MultivaluedHashMap<>()); resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); assertEquals(2, resourceBinder.getSize()); resourceBinder.getResources().clear(); assertEquals(2, resourceBinder.getSize()); } @Test public void removesBoundResourceByClass() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertNotNull(resourceFactory); resourceBinder.removeResource(EchoResource.class); resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertNull(resourceFactory); } @Test public void removesBoundResourceByPath() throws Exception { resourceBinder.addResource(EchoResource.class, new MultivaluedHashMap<>()); ObjectFactory<ResourceDescriptor> resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertNotNull(resourceFactory); resourceBinder.removeResource("a/b"); resourceFactory = resourceBinder.getMatchedResource("/a/b", newArrayList()); assertNull(resourceFactory); } @Path("a/b") public static class EchoResource { @Consumes("text/plain") @Produces("text/xml") @POST public String echo(String phrase) { return phrase; } } @Path("a/b") public static class OtherEchoResource { @Consumes("text/plain") @Produces("text/xml") @POST public String echo(String phrase) { return phrase; } } @Path("a") public static class EchoResourceWithSubResourceMethod { @Consumes("text/plain") @Produces("text/xml") @POST @Path("b") public String echo(String phrase) { return phrase; } } public static class NoPathAnnotationResource { @Consumes("text/plain") @Produces("text/xml") @GET public void m() { } } }