package com.interaction.example.hateoas.restbucks; /* * #%L * interaction-example-odata-airline * %% * 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.assertNull; import static org.junit.Assert.assertTrue; import java.io.InputStreamReader; import java.io.Reader; import java.net.URI; import java.net.URLEncoder; import java.util.List; import java.util.UUID; import javax.ws.rs.core.Response.Status; 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.api.client.WebResource; 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; /** * Test RESTful following of links provided through hypermedia. */ public class LinkRelationsITCase extends JerseyTest { private RepresentationFactory representationFactory; public LinkRelationsITCase() throws Exception { super(); } @Before public void initTest() { // -DTEST_ENDPOINT_URI={someurl} to test with external server webResource = Client.create().resource(ConfigurationHelper.getTestEndpointUri(Configuration.TEST_ENDPOINT_URI)); representationFactory = new StandardRepresentationFactory(); } @After public void tearDown() {} @Test public void testEncodedQueryParameterPassing() throws Exception { ReadableRepresentation resource = get(webResource.path("/123456/history") .queryParam("query", "test%40abc.com") .queryParam("email", "test%40abc.com")); Link orders = resource.getLinkByRel("collection"); assertNotNull("history of 'orders' link relation", orders); assertEquals("http://localhost:8080/example/interaction-hateoas-restbucks.svc/123456/Orders()?query=email+eq+'test%40abc.com'&email=test%40abc.com", orders.getHref()); } @Test public void testOrderHistory() throws Exception { // request root ReadableRepresentation rootResource = get(webResource.path("/123456/shop")); // POST order Link order = rootResource.getLinkByRel("http://relations.restbucks.com/order"); assertNotNull("'order' link relation", order); UUID id = UUID.randomUUID(); Representation orderRequest = buildOrderRequest(id.toString()); ReadableRepresentation orderResource = post(webResource.uri(new URI(order.getHref())), orderRequest.toString(MediaType.APPLICATION_HAL_JSON)); // use the link on the order Link history = orderResource.getLinkByRel("http://relations.restbucks.com/history"); assertNotNull(history); webResource = webResource.uri(new URI(history.getHref())); ReadableRepresentation historyResource1 = get(webResource); // get the orders Link orders1 = historyResource1.getLinkByRel("collection"); ReadableRepresentation historyOrders1 = get(webResource.uri(new URI(orders1.getHref()))); assertEquals(1, historyOrders1.getResourceMap().size()); // use the 'history' link on root to find all orders with same email address Link rootHistory = rootResource.getLinkByRel("http://relations.restbucks.com/history"); assertNotNull(rootHistory); webResource = webResource.uri(new URI(rootHistory.getHref())).queryParam("email", URLEncoder.encode(id.toString()+"+test@somewhere.com", "UTF-8")); ReadableRepresentation historyResource2 = get(webResource); // get the orders Link orders2 = historyResource2.getLinkByRel("collection"); ReadableRepresentation historyOrders2 = get(webResource.uri(new URI(orders2.getHref()))); assertEquals(1, historyOrders2.getResourceMap().size()); } @Test public void testOrderStatus() throws Exception { // RB1000 already exists, inserted during test initialisation ReadableRepresentation orderResource = get(webResource.path("/123456/Orders('RB1000')")); // check the availability of the link to make the payment // should be paid and therefore no link to pay Link payment = orderResource.getLinkByRel("http://relations.restbucks.com/payment"); assertNull("'payment' link relation", payment); // should be a link to the payment List<Link> links = orderResource.getLinks(); boolean found = false; for (Link link : links) { if (link.getHref().equals("http://localhost:8080/example/interaction-hateoas-restbucks.svc/123456/Orders(RB1000)/payment")) { found = true; } } assertTrue("Payment link", found); } @Test public void testCupOfCoffee() throws Exception { /* * HypermediaClient client = new HypermediaClient(httpClient); * client.register(hal) * .register(odata); * client.get(new URL("/api")) * .get("orders") * .property("milk", "yes").property("name", "Aaron").property("quantity", 1) * .post("self") * .use() // use the response in the next request payload * .clear() // clear the request payload * .post("payment") */ // request root ReadableRepresentation rootResource = get(webResource.path("/123456/shop")); // POST order Link order = rootResource.getLinkByRel("http://relations.restbucks.com/order"); assertNotNull("'order' link relation", order); UUID id = UUID.randomUUID(); Representation orderRequest = buildOrderRequest(id.toString()); ReadableRepresentation orderResource = post(webResource.uri(new URI(order.getHref())), orderRequest.toString(MediaType.APPLICATION_HAL_JSON)); // check the availability of the link to make the payment Link payment = orderResource.getLinkByRel("http://relations.restbucks.com/payment"); assertNotNull("'payment' link relation", payment); // make the payment Representation paymentRequest = buildPaymentRequest(orderResource.getValue("Id").toString()); ReadableRepresentation paymentResource = post(webResource.uri(new URI(payment.getHref())), paymentRequest.toString(MediaType.APPLICATION_HAL_JSON)); assertNotNull(paymentResource); // confirm the payment was successful, no payment possible ReadableRepresentation updatedOrderResource = get(webResource.uri(new URI(order.getHref()))); assertNull(updatedOrderResource.getLinkByRel("http://relations.restbucks.com/payment")); } private ReadableRepresentation get(WebResource resource) throws Exception { ReadableRepresentation representation; Reader reader = null; ClientResponse response = null; try { response = resource .accept(MediaType.APPLICATION_HAL_JSON) .get(ClientResponse.class); assertEquals(Status.Family.SUCCESSFUL, response.getClientResponseStatus().getFamily()); reader = new InputStreamReader(response.getEntityInputStream()); representation = representationFactory.readRepresentation(MediaType.APPLICATION_HAL_JSON.toString(),reader); } finally { if (reader != null) reader.close(); if (response != null) response.close(); } return representation; } private ReadableRepresentation post(WebResource resource, String payload) throws Exception { ReadableRepresentation representation; Reader reader = null; ClientResponse response = null; try { response = resource .accept(MediaType.APPLICATION_HAL_JSON) .type(MediaType.APPLICATION_HAL_JSON) .post(ClientResponse.class, payload); assertEquals(Status.Family.SUCCESSFUL, response.getClientResponseStatus().getFamily()); reader = new InputStreamReader(response.getEntityInputStream()); representation = representationFactory.readRepresentation(MediaType.APPLICATION_HAL_JSON.toString(),reader); } finally { if (reader != null) reader.close(); if (response != null) response.close(); } return representation; } private Representation buildOrderRequest(String id) { return representationFactory.newRepresentation() .withProperty("Id", id) .withProperty("milk", "yes") .withProperty("name", "Aaron") .withProperty("email", id+"+test@somewhere.com") // keep the + character in the email address to test url encoding .withProperty("quantity", 1); } private Representation buildPaymentRequest(String orderId) { return representationFactory.newRepresentation() .withProperty("orderId", orderId) .withProperty("authorisationCode", "authorised"); } }