package com.interaction.example.hateoas.banking; /* * #%L * interaction-example-hateoas-banking * %% * Copyright (C) 2012 - 2013 Temenos Holdings N.V. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.InputStreamReader; import java.util.Collection; import java.util.List; import java.util.Map; import javax.ws.rs.core.Response; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.test.framework.JerseyTest; import com.temenos.interaction.media.hal.MediaType; import com.theoryinpractise.halbuilder.api.Link; import com.theoryinpractise.halbuilder.api.ReadableRepresentation; import com.theoryinpractise.halbuilder.api.Representation; import com.theoryinpractise.halbuilder.api.RepresentationFactory; import com.theoryinpractise.halbuilder.standard.StandardRepresentationFactory; public class HypermediaITCase extends JerseyTest { public HypermediaITCase() throws Exception { super(); } @Before public void initTest() { // test with external server webResource = Client.create().resource(Configuration.TEST_ENDPOINT_URI); } @After public void tearDown() {} @Test public void testGetEntryPointLinks() { ClientResponse response = webResource.path("/").accept(MediaType.APPLICATION_HAL_JSON).get(ClientResponse.class); assertEquals(Response.Status.Family.SUCCESSFUL, Response.Status.fromStatusCode(response.getStatus()).getFamily()); RepresentationFactory representationFactory = new StandardRepresentationFactory(); ReadableRepresentation resource = representationFactory.readRepresentation(MediaType.APPLICATION_HAL_JSON.toString(),new InputStreamReader(response.getEntityInputStream())); List<Link> links = resource.getLinks(); assertEquals(5, links.size()); for (Link link : links) { if (link.getRel().equals("self")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/", link.getHref()); } else if (link.getName().equals("home.initial>GET>Preferences.preferences")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/preferences", link.getHref()); } else if (link.getName().equals("home.initial>GET>FundsTransfer.fundstransfers")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/fundtransfers", link.getHref()); } else if (link.getName().equals("home.initial>GET>Customer.customers")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/customers", link.getHref()); } else if (link.getName().equals("home.initial>GET>home.ServiceDocument")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/Banking.svc", link.getHref()); } else { fail("unexpected link [" + link.getName() + "]"); } } } @Test public void testCollectionLinks() { ClientResponse response = webResource.path("/fundtransfers").accept(MediaType.APPLICATION_HAL_JSON).get(ClientResponse.class); assertEquals(Response.Status.Family.SUCCESSFUL, Response.Status.fromStatusCode(response.getStatus()).getFamily()); RepresentationFactory representationFactory = new StandardRepresentationFactory(); ReadableRepresentation resource = representationFactory.readRepresentation(MediaType.APPLICATION_HAL_JSON.toString(),new InputStreamReader(response.getEntityInputStream())); // the links from the collection List<Link> links = resource.getLinks(); assertEquals(2, links.size()); for (Link link : links) { if (link.getRel().equals("self")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/fundtransfers", link.getHref()); } else if (link.getName().equals("FundsTransfer.fundstransfers>POST>FundsTransfer.new")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/fundtransfers/new", link.getHref()); } else { fail("unexpected link [" + link.getName() + "]"); } } // the links on each item Collection<Map.Entry<String, ReadableRepresentation>> subresources = resource.getResources(); assertNotNull(subresources); for (Map.Entry<String, ReadableRepresentation> entry : subresources) { ReadableRepresentation item = entry.getValue(); List<Link> itemLinks = item.getLinks(); assertEquals(1, itemLinks.size()); for (Link link : itemLinks) { if (link.getRel().contains("self")) { assertEquals(Configuration.TEST_ENDPOINT_URI + "/fundtransfers/" + item.getProperties().get("id"), link.getHref()); } else { fail("unexpected link"); } } } } /** * Attempt a DELETE to the resource (a collection resource) */ @Test public void deleteFundTransferMethodNotAllowed() throws Exception { ClientResponse response = webResource.path("/fundtransfers").delete(ClientResponse.class); assertEquals(405, response.getStatus()); assertEquals(3, response.getAllow().size()); assertTrue(response.getAllow().contains("GET")); assertTrue(response.getAllow().contains("OPTIONS")); assertTrue(response.getAllow().contains("HEAD")); } /** * Attempt a PUT to the resource (entity resource) */ @Test public void putFundTransferHalXML() throws Exception { double d = Math.random() * 10000000; String id = Integer.toString((int) d); String resourceUri = "/fundtransfers/" + id; String halRequest = buildHalResource(resourceUri, id).toString(RepresentationFactory.HAL_XML); ClientResponse response = webResource.path(resourceUri).accept(MediaType.APPLICATION_HAL_XML).type(MediaType.APPLICATION_HAL_XML).put(ClientResponse.class, halRequest); assertEquals(200, response.getStatus()); response = webResource.path(resourceUri).accept(MediaType.APPLICATION_HAL_JSON).get(ClientResponse.class); assertEquals(Response.Status.Family.SUCCESSFUL, Response.Status.fromStatusCode(response.getStatus()).getFamily()); } /** * Attempt a PUT to the resource (entity resource) */ @Test public void putFundTransferHalJSON() throws Exception { double d = Math.random() * 10000000; String id = Integer.toString((int) d); String resourceUri = "/fundtransfers/" + id; String halRequest = buildHalResource(resourceUri, id).toString(RepresentationFactory.HAL_JSON); ClientResponse response = webResource.path(resourceUri).accept(MediaType.APPLICATION_HAL_JSON).type(MediaType.APPLICATION_HAL_JSON).put(ClientResponse.class, halRequest); assertEquals(200, response.getStatus()); response = webResource.path("/fundtransfers/" + id).accept(MediaType.APPLICATION_HAL_JSON).get(ClientResponse.class); assertEquals(Response.Status.Family.SUCCESSFUL, Response.Status.fromStatusCode(response.getStatus()).getFamily()); } private Representation buildHalResource(String resourceUri, String id) { RepresentationFactory representationFactory = new StandardRepresentationFactory(); Representation r = representationFactory.newRepresentation(resourceUri); r.withProperty("id", id); r.withProperty("body", "Funds tranfer issued at 01/01/2012"); return r; } /** * Attempt a PUT to the collection resource (which only accepts post in this example) */ @Test public void putMethodNotAllowed() throws Exception { RepresentationFactory representationFactory = new StandardRepresentationFactory(); ReadableRepresentation r = representationFactory.newRepresentation("/fundtransfers"); String halRequest = r.toString(RepresentationFactory.HAL_XML); // attempt to put to the notes collection, rather than an individual ClientResponse response = webResource.path("/fundtransfers").type(MediaType.APPLICATION_HAL_XML).put(ClientResponse.class, halRequest); assertEquals(405, response.getStatus()); assertEquals(3, response.getAllow().size()); assertTrue(response.getAllow().contains("GET")); assertTrue(response.getAllow().contains("OPTIONS")); assertTrue(response.getAllow().contains("HEAD")); } /** * Test to ensure that having a different self link from the target resource does * not prevent successful processing. * @throws Exception */ @Test public void putFundTransferHalJSONWithDifferentSelfLink() throws Exception { double d = Math.random() * 10000000; String id = Integer.toString((int) d); String halRequest = buildHalResource("DifferentSelfLink", id).toString(RepresentationFactory.HAL_JSON); String resourceUri = "/fundtransfers/" + id; ClientResponse response = webResource.path(resourceUri).accept(MediaType.APPLICATION_HAL_JSON).type(MediaType.APPLICATION_HAL_JSON).put(ClientResponse.class, halRequest); assertEquals(200, response.getStatus()); response = webResource.path("/fundtransfers/" + id).accept(MediaType.APPLICATION_HAL_JSON).get(ClientResponse.class); assertEquals(Response.Status.Family.SUCCESSFUL, Response.Status.fromStatusCode(response.getStatus()).getFamily()); } }