Java tutorial
/* * Copyright (c) 2014 * Mikol Faro <mikol.faro@gmail.com> * Simone Mangano <simone.mangano@ieee.org> * Mattia Tortorelli <mattia.tortorelli@gmail.com> * * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ package org.biokoframework.http.scenario; import com.jayway.restassured.http.ContentType; import com.jayway.restassured.response.Response; import com.jayway.restassured.specification.RequestSpecification; import org.apache.commons.beanutils.MethodUtils; import org.biokoframework.http.HttpMethodEnum; import org.biokoframework.http.scenario.mail.MailScenarioStep; import org.biokoframework.http.scenario.push.PushScenarioStep; import org.biokoframework.system.KILL_ME.commons.HttpMethod; import org.biokoframework.system.services.push.impl.TestPushNotificationService; import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.hamcrest.core.IsCollectionContaining; import org.jvnet.mock_javamail.Mailbox; import javax.mail.Message; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import static com.jayway.restassured.RestAssured.expect; import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; import static org.apache.commons.lang3.StringEscapeUtils.unescapeJava; import static org.biokoframework.http.matcher.Matchers.exists; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.fail; public class ScenarioRunner { private Scenario fScenario; public ScenarioRunner(Scenario scenario) { fScenario = scenario; Mailbox.clearAll(); } public void test(String baseUrl) throws Exception { System.out.println("=== SCENARIO COLLECTOR: " + fScenario.scenarioName()); for (Entry<String, ScenarioStep> eachScenario : fScenario.scenarioSteps()) { System.out.println("\t------ SCENARIO: " + eachScenario.getKey() + " --------"); // Polymorphic visitor? try { MethodUtils.invokeMethod(this, "test", new Object[] { baseUrl, eachScenario.getValue(), }, new Class[] { String.class, eachScenario.getValue().getClass() }); } catch (NoSuchMethodException exception) { fail("[EASY MAN] '" + fScenario.scenarioName() + "' not testable, probably wrong class"); } catch (InvocationTargetException exception) { if (exception.getCause() != null) { if (exception.getCause() instanceof Exception) { throw (Exception) exception.getCause(); } else if (exception.getCause() instanceof Error) { throw (Error) exception.getCause(); } } else { throw exception; } } System.out.println("\t------ END -------"); } System.out.println("=== END ==="); } public void test(String baseUrl, PushScenarioStep pushScenario) throws Exception { System.out.println("\tUser token: " + pushScenario._userToken); System.out.println("\t------ EXPECTATION -------"); System.out.println("\tExpected Message:\n\t" + pushScenario._messageMatcher.toString()); String scenarioExecutionMessage = scenarioExecution(pushScenario); System.out.println("\t------ RESPONSE -------"); System.out.println("\t" + scenarioExecutionMessage); } private String scenarioExecution(PushScenarioStep pushScenario) { List<String> pushMessages = TestPushNotificationService.getMessagesForUser(pushScenario._userToken); assertThat(pushMessages, IsCollectionContaining.<String>hasItem(pushScenario._messageMatcher)); for (Iterator<String> it = pushMessages.iterator(); it.hasNext();) { String aMessage = it.next(); if (pushScenario._messageMatcher.matches(aMessage)) { it.remove(); return aMessage; } } // It cannot reach this point, // if there is no match it has already failed return null; } public void test(String baseUrl, MailScenarioStep mailScenario) throws Exception { System.out.println("\tMail box address: " + mailScenario._mailBoxAddress); System.out.println("\t------ EXPECTATION -------"); System.out.println("\tExpected Message:\n\t" + mailScenario._messageMatcher.toString()); Message scenarioExecutionMessage = scenarioExecution(mailScenario); System.out.println("\t------ RESPONSE -------"); System.out.println("\t" + prettify(scenarioExecutionMessage)); } private Message scenarioExecution(MailScenarioStep mailScenario) throws Exception { Mailbox inspectedBox = Mailbox.get(mailScenario._mailBoxAddress); assertThat(inspectedBox, exists()); assertThat("Mailbox does not contain mails", inspectedBox, is(not(Matchers.<Message>empty()))); assertThat(inspectedBox, Matchers.<Message>hasItem(mailScenario._messageMatcher)); for (Iterator<Message> it = inspectedBox.iterator(); it.hasNext();) { Message aMessage = it.next(); if (mailScenario._messageMatcher.matches(aMessage)) { it.remove(); return aMessage; } } // It cannot reach this point, // if there is no match it has already failed return null; } public void test(String baseUrl, ExecutionScenarioStep executionScenario) throws Exception { System.out.println("\tRunning ExecutionScenarioStep code"); executionScenario.execute(); } public void test(String baseUrl, HttpScenarioStep httpScenario) { System.out.println("\tURL: " + httpScenario.fPartialRestURL); System.out.println("\tHTTP Method: " + httpScenario.fHttpMethod); System.out.println("\tHeaders: " + httpScenario.fHeaders); System.out.println("\tParameters: " + httpScenario.fParameters); System.out.println("\tBody:" + httpScenario.fRequestBodyJson); System.out.println("\t------ EXPECTATION -------"); System.out.println("\tExpected Http Status Code:" + httpScenario.fExpectedHttpStatusCode); System.out.println("\tExpected Body Response:\n\t" + prettify(httpScenario.fExpectedJsonBodyMatcher)); Response scenarioExecutionResponse = scenarioExecution(httpScenario, baseUrl); System.out.println("\t------ RESPONSE -------"); System.out.println("\t" + scenarioExecutionResponse.asString()); } public void test(String baseUrl, HttpMultipartScenarioStep httpScenario) throws IOException { System.out.println("\tURL: " + httpScenario._partialRestURL); System.out.println("\tHTTP Method: " + httpScenario._httpMethod); System.out.println("\tHeaders: " + httpScenario._headers); System.out.println("\tParameters: " + httpScenario._parameters); System.out.println("\t# parts:" + httpScenario._parts.size()); System.out.println("\t------ EXPECTATION -------"); System.out.println("\tExpected Http Status Code:" + httpScenario._expectedHttpStatusCode); System.out.println("\tExpected Body Response:\n\t" + prettify(httpScenario._expectedJsonBodyMatcher)); Response scenarioExecutionResponse = scenarioExecution(httpScenario, baseUrl); System.out.println("\t------ RESPONSE -------"); System.out.println("\t" + scenarioExecutionResponse.asString()); } private Response scenarioExecution(HttpMultipartScenarioStep multipartScenario, String baseUrl) throws IOException { RequestSpecification specification = expect().statusCode(multipartScenario._expectedHttpStatusCode) .body(multipartScenario._expectedJsonBodyMatcher).when().given().headers(multipartScenario._headers) .queryParameters(multipartScenario._parameters); for (Entry<String, Object> part : multipartScenario._parts.entrySet()) { String name = part.getKey(); Object value = part.getValue(); if (value instanceof String) { specification.multiPart(name, (String) value); //specification.multiPart(name, new StringBody((String) value)); //specification.multiPart(part.getKey(), (String) value, GenericFieldValues.TEXT_CONTENT_TYPE); // specification.multiPart(part.getKey(), null, IOUtils.toInputStream((String) value), GenericFieldValues.TEXT_CONTENT_TYPE); // formParam ha un comportamento del cazzo // specification.formParam(name, (String) value); } else if (value instanceof InputStream) { String contentType = multipartScenario._partContentTypes.get(name); specification.multiPart(part.getKey(), "", (InputStream) value, contentType); } else { throw new UnsupportedOperationException("parts can only be String or InputStreams. part: " + name); } } specification.log().body(); if (multipartScenario._httpMethod.equals(HttpMethod.POST.toString())) { return specification.post(baseUrl + multipartScenario._partialRestURL); } else if (multipartScenario._httpMethod.equals(HttpMethod.PUT.toString())) { return specification.put(baseUrl + multipartScenario._partialRestURL); } else { throw new UnsupportedOperationException("Multipart only works with POST and PUT"); } } private Response scenarioExecution(HttpScenarioStep httpScenario, String baseUrl) { switch (HttpMethodEnum.valueOf(httpScenario.fHttpMethod)) { case GET: return executeGet(httpScenario, baseUrl); case POST: return executePost(httpScenario, baseUrl); case PUT: return executePut(httpScenario, baseUrl); case DELETE: return executeDelete(httpScenario, baseUrl); case OPTIONS: return executeOptions(httpScenario, baseUrl); } return null; } public Response executeDelete(HttpScenarioStep httpScenario, String baseUrl) { return expect().statusCode(httpScenario.fExpectedHttpStatusCode).headers(httpScenario.fExpectedHeadersMap) .body(httpScenario.fExpectedJsonBodyMatcher).when().given().log().body().request() .headers(httpScenario.fHeaders).parameters(httpScenario.fParameters) .delete(baseUrl + httpScenario.fPartialRestURL); } public Response executePut(HttpScenarioStep httpScenario, String baseUrl) { return expect().statusCode(httpScenario.fExpectedHttpStatusCode).headers(httpScenario.fExpectedHeadersMap) .body(httpScenario.fExpectedJsonBodyMatcher).when().given().log().body().request() .contentType(ContentType.JSON).headers(httpScenario.fHeaders).parameters(httpScenario.fParameters) .body(httpScenario.fRequestBodyJson).put(baseUrl + httpScenario.fPartialRestURL); } public Response executePost(HttpScenarioStep httpScenario, String baseUrl) { if (httpScenario.fRequestBodyJson != null) { return expect().statusCode(httpScenario.fExpectedHttpStatusCode) .headers(httpScenario.fExpectedHeadersMap).body(httpScenario.bodyMatcher()).when().given().log() .body().request().contentType(ContentType.JSON).headers(httpScenario.fHeaders) .queryParameters(httpScenario.fParameters).body(httpScenario.fRequestBodyJson) .post(baseUrl + httpScenario.fPartialRestURL); } else { return expect().statusCode(httpScenario.fExpectedHttpStatusCode) .headers(httpScenario.fExpectedHeadersMap).body(httpScenario.bodyMatcher()).when().given().log() .body().request().headers(httpScenario.fHeaders).queryParameters(httpScenario.fParameters) .post(baseUrl + httpScenario.fPartialRestURL); } } public Response executeGet(HttpScenarioStep httpScenario, String baseUrl) { return expect().statusCode(httpScenario.fExpectedHttpStatusCode).body(httpScenario.fExpectedJsonBodyMatcher) .when().given().log().body().request().headers(httpScenario.fHeaders) .parameters(httpScenario.fParameters).get(baseUrl + httpScenario.fPartialRestURL); } public Response executeOptions(HttpScenarioStep httpScenario, String baseUrl) { return expect().statusCode(httpScenario.fExpectedHttpStatusCode).body(httpScenario.fExpectedJsonBodyMatcher) .when().given().log().body().request().headers(httpScenario.fHeaders) .parameters(httpScenario.fParameters).options(baseUrl + httpScenario.fPartialRestURL); } public void test(String baseUrl, HttpScenarioStepBinary binaryScenario) { System.out.println("\tURL: " + binaryScenario._partialRestURL); System.out.println("\tHTTP Method: " + binaryScenario._httpMethod); System.out.println("\tHeaders: " + binaryScenario._headers); System.out.println("\tParameters: " + binaryScenario._parameters); System.out.println("\t------ EXPECTATION -------"); System.out.println("\tExpected Http Status Code:" + binaryScenario._expectedHttpStatusCode); System.out.println("\tExpected Body Response:\n\t" + prettify(binaryScenario._expectedJsonBodyMatcher)); scenarioExecution(binaryScenario, baseUrl); } private Response scenarioExecution(HttpScenarioStepBinary binaryScenario, String baseUrl) { RequestSpecification specification = expect().statusCode(binaryScenario._expectedHttpStatusCode) .body(binaryScenario._expectedJsonBodyMatcher).when().given() .multiPart(binaryScenario._filePartName, "", binaryScenario._requestBody, binaryScenario._requestBodyContentType) .headers(binaryScenario._headers).queryParameters(binaryScenario._parameters); if (binaryScenario._httpMethod.equals(HttpMethod.POST.toString())) { return specification.post(baseUrl + binaryScenario._partialRestURL); } else if (binaryScenario._httpMethod.equals(HttpMethod.PUT.toString())) { return specification.put(baseUrl + binaryScenario._partialRestURL); } else { throw new UnsupportedOperationException("Binary only works with POST and PUT"); } } private String prettify(Matcher<? extends Object> matcher) { String unescaped = unescapeJava(matcher.toString()); if (unescaped.matches("^\".+\"$")) { unescaped = unescaped.substring(1).substring(0, unescaped.length() - 2); } return unescaped; } private String prettify(Message scenarioExecutionMessage) throws Exception { StringBuilder builder = new StringBuilder(); builder.append("(\"").append(scenarioExecutionMessage.getSubject()).append("\" and \"") .append(escapeJava(scenarioExecutionMessage.getContent().toString())).append("\")"); return builder.toString(); } public void test(String baseUrl, BinaryRequestStep binaryScenarioStep) { System.out.println("\tURL: " + binaryScenarioStep.fRestUrl); System.out.println("\tHTTP Method: " + binaryScenarioStep.fHttpMethod); // System.out.println("\tHeaders: " + binaryScenario.); System.out.println("\tParameters: " + binaryScenarioStep.fParameters); System.out.println("\t------ EXPECTATION -------"); // System.out.println("\tExpected Http Status Code:" + binaryScenario._expectedHttpStatusCode); System.out.println("\tExpected Response Media Type:\n\t" + binaryScenarioStep.fExpectedContentType); scenarioExecution(binaryScenarioStep, baseUrl); } private Response scenarioExecution(BinaryRequestStep binaryScenarioStep, String baseUrl) { return expect().statusCode(200).contentType(binaryScenarioStep.fExpectedContentType).given() .parameters(binaryScenarioStep.fParameters).get(baseUrl + binaryScenarioStep.fRestUrl); } }