@Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithMultipleHeaders()
      throws Exception {

    final String location = "/invoice/123";
    final String contentType = "application-json";

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .newStubbedResponse()
            .withHeaderContentType(contentType)
            .withHeaderLocation(location)
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubResponse actualResponse = actualHttpLifecycle.getResponse(true);
    final MapEntry headerOneEntry = MapEntry.entry("location", location);
    final MapEntry headerTwoEntry = MapEntry.entry("content-type", contentType);

    assertThat(actualResponse.getHeaders()).contains(headerOneEntry);
    assertThat(actualResponse.getHeaders()).contains(headerTwoEntry);
  }
  @Test
  public void shouldContainTheSameResourceIdHeader_ForEachSequencedResponse() throws Exception {

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodPut()
            .withUrl("/invoice")
            .newStubbedResponse()
            .withSequenceResponseStatus("200")
            .withSequenceResponseHeaders("headerOne", "valueOne")
            .withSequenceResponseLiteralBody("BodyContent")
            .withSequenceResponseStatus("200")
            .withSequenceResponseHeaders("headerTwo", "valueTwo")
            .withSequenceResponseLiteralBody("BodyContentTwo")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    assertThat(loadedHttpCycles.size()).isEqualTo(1);

    final StubHttpLifecycle cycle = loadedHttpCycles.get(0);
    final List<StubResponse> allResponses = cycle.getAllResponses();

    for (int idx = 0; idx < allResponses.size(); idx++) {
      final StubResponse sequenceStubResponse = allResponses.get(idx);
      assertThat(sequenceStubResponse.getHeaders())
          .containsKey(StubResponse.STUBBY_RESOURCE_ID_HEADER);
      assertThat(sequenceStubResponse.getHeaders().get(StubResponse.STUBBY_RESOURCE_ID_HEADER))
          .isEqualTo(String.valueOf(0));
    }
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithMultipleQueryParams()
      throws Exception {

    final String expectedParamOne = "paramOne";
    final String expectedParamOneValue = "one";
    final String fullQueryOne = String.format("%s=%s", expectedParamOne, expectedParamOneValue);

    final String expectedParamTwo = "paramTwo";
    final String expectedParamTwoValue = "two";
    final String fullQueryTwo = String.format("%s=%s", expectedParamTwo, expectedParamTwoValue);

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .withQuery(expectedParamOne, expectedParamOneValue)
            .withQuery(expectedParamTwo, expectedParamTwoValue)
            .newStubbedResponse()
            .withStatus("500")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubRequest actualRequest = actualHttpLifecycle.getRequest();
    final MapEntry queryEntryOne = MapEntry.entry(expectedParamOne, expectedParamOneValue);
    final MapEntry queryEntryTwo = MapEntry.entry(expectedParamTwo, expectedParamTwoValue);

    assertThat(actualRequest.getUrl()).contains(fullQueryOne);
    assertThat(actualRequest.getUrl()).contains(fullQueryTwo);
    assertThat(actualRequest.getQuery()).contains(queryEntryOne, queryEntryTwo);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithOneSequenceResponse()
      throws Exception {

    final String sequenceResponseHeaderKey = "content-type";
    final String sequenceResponseHeaderValue = "application/json";
    final String sequenceResponseStatus = "200";
    final String sequenceResponseBody = "OK";

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodPut()
            .withUrl("/invoice")
            .newStubbedResponse()
            .withSequenceResponseStatus(sequenceResponseStatus)
            .withSequenceResponseHeaders(sequenceResponseHeaderKey, sequenceResponseHeaderValue)
            .withSequenceResponseLiteralBody(sequenceResponseBody)
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubResponse actualResponse = actualHttpLifecycle.getResponse(true);

    final MapEntry sequenceHeaderEntry =
        MapEntry.entry(sequenceResponseHeaderKey, sequenceResponseHeaderValue);

    assertThat(actualResponse).isInstanceOf(StubResponse.class);
    assertThat(actualResponse.getHeaders()).contains(sequenceHeaderEntry);
    assertThat(actualResponse.getStatus()).isEqualTo(sequenceResponseStatus);
    assertThat(actualResponse.getBody()).isEqualTo(sequenceResponseBody);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithFileFailedToLoadAndBodySet()
      throws Exception {

    final String stubbedResponseFile = "../../very.big.soap.response.xml";

    final String expectedBody = "{\"message\", \"Hello, this is HTTP response body\"}";
    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .newStubbedResponse()
            .withFoldedBody(expectedBody)
            .withFile(stubbedResponseFile)
            .withStatus("201")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);

    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubResponse actualResponse = actualHttpLifecycle.getResponse(true);

    assertThat(actualResponse.getFile()).isEqualTo(new byte[] {});
    assertThat(StringUtils.newStringUtf8(actualResponse.getResponseBodyAsBytes()))
        .isEqualTo(expectedBody);
  }
  @Test
  public void
      shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WitQueryParamIsArrayHavingSingleQuotes()
          throws Exception {

    final String expectedParamOne = "fruits";
    final String expectedParamOneValue = "['apple','orange','banana']";
    final String fullQueryOne = String.format("%s=%s", expectedParamOne, expectedParamOneValue);

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .withQuery(expectedParamOne, String.format("\"%s\"", expectedParamOneValue))
            .newStubbedResponse()
            .withStatus("201")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubRequest actualRequest = actualHttpLifecycle.getRequest();
    final MapEntry queryEntryOne = MapEntry.entry(expectedParamOne, expectedParamOneValue);

    assertThat(actualRequest.getUrl()).contains(fullQueryOne);
    assertThat(actualRequest.getQuery()).contains(queryEntryOne);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithEmptyAuthorizationHeader()
      throws Exception {

    final String authorization = "";

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .withHeaderAuthorization("")
            .newStubbedResponse()
            .withStatus("301")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubRequest actualRequest = actualHttpLifecycle.getRequest();

    final String encodedAuthorizationHeader =
        String.format("%s %s", "Basic", StringUtils.encodeBase64(authorization));
    final MapEntry headerOneEntry = MapEntry.entry("authorization", encodedAuthorizationHeader);

    assertThat(actualRequest.getHeaders()).contains(headerOneEntry);
  }
  @Test
  public void
      shouldContainExpectedResourceIdHeaderUponSuccessfulYamlMarshall_WhenMultipleAndSqequencedResponses()
          throws Exception {

    final String cycleOne =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri/1")
            .withQuery("paramName1", "paramValue1")
            .newStubbedResponse()
            .withStatus("200")
            .build();

    final String cycleTwo =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodPut()
            .withUrl("/invoice")
            .newStubbedResponse()
            .withSequenceResponseStatus("200")
            .withSequenceResponseHeaders("headerOne", "valueOne")
            .withSequenceResponseLiteralBody("BodyContent")
            .withSequenceResponseStatus("200")
            .withSequenceResponseHeaders("headerTwo", "valueTwo")
            .withSequenceResponseLiteralBody("BodyContentTwo")
            .build();

    final String cycleThree =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri/2")
            .withQuery("paramName2", "paramValue2")
            .newStubbedResponse()
            .withStatus("201")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles =
        unmarshall(String.format("%s%s%s%s%s", cycleOne, BR, cycleTwo, BR, cycleThree));
    assertThat(loadedHttpCycles.size()).isEqualTo(3);

    for (int resourceId = 0; resourceId < loadedHttpCycles.size(); resourceId++) {
      final StubHttpLifecycle cycle = loadedHttpCycles.get(resourceId);
      final List<StubResponse> allResponses = cycle.getAllResponses();

      for (int sequence = 0; sequence < allResponses.size(); sequence++) {
        final StubResponse sequenceStubResponse = allResponses.get(sequence);
        assertThat(sequenceStubResponse.getHeaders())
            .containsKey(StubResponse.STUBBY_RESOURCE_ID_HEADER);
        assertThat(sequenceStubResponse.getHeaders().get(StubResponse.STUBBY_RESOURCE_ID_HEADER))
            .isEqualTo(String.valueOf(resourceId));
      }
    }
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithNoProperties() throws Exception {

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodPut()
            .withUrl("/invoice")
            .newStubbedResponse()
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);

    assertThat(actualHttpLifecycle.getAllResponses()).hasSize(1);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithDefaultHTTPResponseStatus()
      throws Exception {

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .newStubbedResponse()
            .withLiteralBody("hello")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubResponse actualResponse = actualHttpLifecycle.getResponse(true);

    assertThat(actualResponse.getStatus()).isEqualTo(String.valueOf(200));
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithMultipleHTTPMethods()
      throws Exception {

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withMethodHead()
            .newStubbedResponse()
            .withStatus("301")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubRequest actualRequest = actualHttpLifecycle.getRequest();

    assertThat(actualRequest.getMethod()).contains(HttpMethods.GET, HttpMethods.HEAD);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithUrlAsRegex() throws Exception {

    final String url = "^/[a-z]{3}/[0-9]+/?$";
    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl(url)
            .newStubbedResponse()
            .withStatus("301")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubRequest actualRequest = actualHttpLifecycle.getRequest();

    assertThat(actualRequest.getUrl()).isEqualTo(url);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithLiteralBody() throws Exception {

    final String stubbedResponseBody = "This is a sentence";

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .newStubbedResponse()
            .withLiteralBody(stubbedResponseBody)
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubResponse actualResponse = actualHttpLifecycle.getResponse(true);

    assertThat(actualResponse.getBody()).isEqualTo(stubbedResponseBody);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithLiteralPost() throws Exception {

    final String stubbedRequestPost = "Hello, this is a request post";

    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri")
            .withLiteralPost(stubbedRequestPost)
            .newStubbedResponse()
            .withStatus("201")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubRequest actualRequest = actualHttpLifecycle.getRequest();

    assertThat(actualRequest.getPost()).isEqualTo(stubbedRequestPost);
  }
  @Test
  public void shouldUnmarshallYamlIntoObjectTree_WhenYAMLValid_WithNoSequenceResponses()
      throws Exception {

    final String expectedStatus = "301";
    final String yaml =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodPut()
            .withUrl("/invoice")
            .newStubbedResponse()
            .withStatus(expectedStatus)
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles = unmarshall(yaml);
    final StubHttpLifecycle actualHttpLifecycle = loadedHttpCycles.get(0);
    final StubResponse actualResponse = actualHttpLifecycle.getResponse(true);

    assertThat(actualHttpLifecycle.getAllResponses()).hasSize(1);
    assertThat(actualResponse.getStatus()).isEqualTo(expectedStatus);
  }
  @Test
  public void
      shouldContainExpectedResourceIdHeaderUponSuccessfulYamlMarshall_WhenMultipleResponses()
          throws Exception {

    final String cycleOne =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri/1")
            .withQuery("paramName1", "paramValue1")
            .newStubbedResponse()
            .withStatus("200")
            .build();

    final String cycleTwo =
        YAML_BUILDER
            .newStubbedRequest()
            .withMethodGet()
            .withUrl("/some/uri/2")
            .withQuery("paramName2", "paramValue2")
            .newStubbedResponse()
            .withStatus("201")
            .build();

    final List<StubHttpLifecycle> loadedHttpCycles =
        unmarshall(String.format("%s\n%s", cycleOne, cycleTwo));
    assertThat(loadedHttpCycles.size()).isEqualTo(2);

    for (int idx = 0; idx < loadedHttpCycles.size(); idx++) {
      final StubHttpLifecycle cycle = loadedHttpCycles.get(idx);
      final StubResponse cycleResponse = cycle.getResponse(true);

      assertThat(cycleResponse.getHeaders()).containsKey(StubResponse.STUBBY_RESOURCE_ID_HEADER);
      assertThat(cycleResponse.getHeaders().get(StubResponse.STUBBY_RESOURCE_ID_HEADER))
          .isEqualTo(String.valueOf(idx));
    }
  }
  public boolean hasNotAuthorized(final StubHttpLifecycle assertingLifecycle) {
    final String stubbedAuthorization = getAuthorizationHeader();
    final String assertingAuthorization = assertingLifecycle.getAuthorizationHeader();

    return !stubbedAuthorization.equals(assertingAuthorization);
  }