/** * Copyright 2015 Grant Forrester * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.grantjforrester.bdd.rest; import static com.github.dreamhead.moco.Moco.and; import static com.github.dreamhead.moco.Moco.by; import static com.github.dreamhead.moco.Moco.eq; import static com.github.dreamhead.moco.Moco.header; import static com.github.dreamhead.moco.Moco.method; import static com.github.dreamhead.moco.Moco.status; import static com.github.dreamhead.moco.Moco.text; import static com.github.dreamhead.moco.Moco.uri; import static com.github.dreamhead.moco.Moco.with; import static com.github.grantjforrester.bdd.rest.Method.DELETE; import static com.github.grantjforrester.bdd.rest.Method.GET; import static com.github.grantjforrester.bdd.rest.Method.HEAD; import static com.github.grantjforrester.bdd.rest.Method.OPTIONS; import static com.github.grantjforrester.bdd.rest.Method.PATCH; import static com.github.grantjforrester.bdd.rest.Method.POST; import static com.github.grantjforrester.bdd.rest.Method.PUT; import static com.googlecode.catchexception.throwable.CatchThrowable.catchThrowable; import static com.googlecode.catchexception.throwable.CatchThrowable.caughtThrowable; import static com.googlecode.catchexception.throwable.apis.CatchThrowableHamcrestMatchers.hasMessage; import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertThat; import org.junit.After; import org.junit.Before; import org.junit.Test; public class RestStepsTest { private static final int OK = 200; private final String uri = "/someResource"; private final String representation = "someRepresentation"; private final String filename = "src/test/resources/com/github/grantjforrester/bdd/rest/resource.txt"; private final String header = "someHeader"; private final String value = "someValue"; private RestSteps testee; private TestServerHelper testServer; @Before public void setUp() throws Exception { testee = new RestSteps(); testServer = new TestServerHelper(); testServer.start(); } @After public void tearDown() throws Exception { testServer.stop(); testee.resetRestClient(); } @Test public void shouldSendHeadRequestToUrl() throws Exception { testServer.expect().request(and(by(method("HEAD")), by(uri(uri)))).response(status(200)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(HEAD, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendOptionsRequestToUrl() throws Exception { testServer.expect().request(and(by(method("OPTIONS")), by(uri(uri)))).response(status(200)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(OPTIONS, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendGetRequestToUrl() throws Exception { testServer.expect().get(by(uri(uri))).response(representation); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendGetRequestWithHeaderToUrl() throws Exception { testServer.expect().get(and(by(uri(uri)), eq(header(header), value))).response(representation); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theRequestHasAHeaderWithValue(header, value); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendPostRequestWithContentToUrl() throws Exception { testServer.expect().post(and(by(uri(uri)), by(representation))).response(status(OK)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(POST, uri); testee.theRequestHasContent(representation); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendPostRequestWithContentFromFileToUrl() throws Exception { testServer.expect().post(and(by(uri(uri)), by(representation))).response(status(OK)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(POST, uri); testee.theRequestHasContentFromFile(filename); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendPutRequestWithContentToUrl() throws Exception { testServer.expect().put(and(by(uri(uri)), by(representation))).response(status(OK)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(PUT, uri); testee.theRequestHasContent(representation); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendDeleteRequestToUrl() throws Exception { testServer.expect().delete(by(uri(uri))).response(status(OK)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(DELETE, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldSendPatchRequestToUrl() throws Exception { testServer.expect().request(and(by(method("PATCH")), by(uri(uri)))).response(status(OK)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(PATCH, uri); testee.theRequestHasContent(representation); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); } @Test public void shouldFailWhenResponseHasIncorrectStatusCode() throws Exception { testServer.expect().get(by(uri(uri))).response(status(418)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); catchThrowable(testee).theResponseWillHaveTheStatusCode(OK); assertThat(caughtThrowable(), instanceOf(AssertionError.class)); assertThat(caughtThrowable(), hasMessage("Expected status code " + OK + " but was 418")); } @Test public void shouldPassWhenResponseHasExpectedHeader() throws Exception { testServer.expect().get(by(uri(uri))).response(with(text(representation)), header(header, value)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); testee.theResponseWillHaveAHeaderWithValue(header, value); } @Test public void shouldFailWhenResponseMissingExpectedHeader() throws Exception { testServer.expect().get(by(uri(uri))).response(representation); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); catchThrowable(testee).theResponseWillHaveAHeaderWithValue(header, value); assertThat(caughtThrowable(), instanceOf(AssertionError.class)); assertThat(caughtThrowable(), hasMessage("No header '" + header + "' with value '" + value + "' found")); } @Test public void shouldPassWhenResponseDoesNotHaveBannedHeader() throws Exception { testServer.expect().get(by(uri(uri))).response(representation); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); testee.theResponseWillNotHaveAHeaderWithValue(header, value); } @Test public void shouldFailWhenResponseHasForbiddenHeader() throws Exception { testServer.expect().get(by(uri(uri))).response(with(text(representation)), header(header, value)); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); catchThrowable(testee).theResponseWillNotHaveAHeaderWithValue(header, value); assertThat(caughtThrowable(), instanceOf(AssertionError.class)); assertThat(caughtThrowable(), hasMessage("Found forbidden header '" + header + "' with value '" + value + "'")); } @Test public void shouldPassWhenContentMatches() throws Exception { testServer.expect().get(by(uri(uri))).response(representation); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); testee.theResponseContentWillMatch(representation); } @Test public void shouldFailWhenContentDoesNotMatch() throws Exception { testServer.expect().get(by(uri(uri))).response("wrongRepresentation"); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); catchThrowable(testee).theResponseContentWillMatch(representation); assertThat(caughtThrowable(), instanceOf(AssertionError.class)); assertThat(caughtThrowable(), hasMessage("Actual content does not match expected content")); } @Test public void shouldPassWhenContentFromFileMatches() throws Exception { testServer.expect().get(by(uri(uri))).response(representation); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); testee.theResponseContentWillMatchTheFile(filename); } @Test public void shouldFailWhenContentFromFileDoesNotMatch() throws Exception { testServer.expect().get(by(uri(uri))).response("wrongRepresentation"); testee.aServiceRunningOn(testServer.baseUri()); testee.aRequestToTheResource(GET, uri); testee.theResponseIsReceived(); testee.theResponseWillHaveTheStatusCode(OK); catchThrowable(testee).theResponseContentWillMatch(representation); assertThat(caughtThrowable(), instanceOf(AssertionError.class)); assertThat(caughtThrowable(), hasMessage("Actual content does not match expected content")); } }