@Test
  public void anEmptyRequestIsRejectedWithBadRequest() throws IOException {
    underTest.processPayment(request, response);

    verify(webApiResponses)
        .writeError(response, HttpServletResponse.SC_BAD_REQUEST, "Failed to deserialise request");
  }
  @Test
  public void aRequestWhereNoSessionIsPresentIsRejectedWithUnauthorised() throws IOException {
    reset(lobbySessionCache);

    underTest.processPayment(request, response);

    verify(webApiResponses).writeError(response, HttpServletResponse.SC_UNAUTHORIZED, "No session");
  }
  @Test
  public void anInsecureRequestIsRejectedAsABadRequest() throws IOException {
    reset(request);
    when(request.isSecure()).thenReturn(false);

    underTest.processPayment(request, response);

    verify(webApiResponses)
        .writeError(response, HttpServletResponse.SC_BAD_REQUEST, "Request must be secure");
  }
  @Test
  public void aBlockedRequestLogsTheUserOut() throws IOException {
    setRequestTo(json.serialize(aValidCreditCardForm().build()));
    when(creditCardService.completePurchase(
            any(PaymentContext.class), any(CreditCardDetails.class), any(InetAddress.class)))
        .thenReturn(aPurchaseResponseFor(PurchaseOutcome.PLAYER_BLOCKED));

    underTest.processPayment(request, response);

    verify(logoutHelper).logout(session, request, response);
  }
  @Test
  public void aDeclinedRequestReturnsAnDeclinedResponse() throws IOException {
    setRequestTo(json.serialize(aValidCreditCardForm().build()));
    when(creditCardService.completePurchase(
            any(PaymentContext.class), any(CreditCardDetails.class), any(InetAddress.class)))
        .thenReturn(aPurchaseResponseFor(PurchaseOutcome.DECLINED));

    underTest.processPayment(request, response);

    verify(webApiResponses)
        .write(response, HttpServletResponse.SC_OK, aJsonResponseFor(PurchaseOutcome.DECLINED));
  }
  @Test
  public void aInvalidRequestReturnsAValidationFailedResponseAndAListOfErrors() throws IOException {
    final CreditCardForm invalidForm =
        aValidCreditCardForm().withCvc2("3").withCreditCardNumber("4200000000000001").build();
    setRequestTo(json.serialize(invalidForm));
    when(creditCardService.completePurchase(
            any(PaymentContext.class), any(CreditCardDetails.class), any(InetAddress.class)))
        .thenReturn(aPurchaseResponseFor(PurchaseOutcome.APPROVED));

    underTest.processPayment(request, response);

    final Map<String, Object> jsonResponse = new HashMap<>();
    jsonResponse.put("outcome", PurchaseOutcome.VALIDATION_ERROR.name());
    jsonResponse.put("errors", asList("Invalid Credit Card Number, Security Code entered."));
    verify(webApiResponses).write(response, HttpServletResponse.SC_OK, jsonResponse);
  }
  @Test
  public void aValidRequestIsPassedToTheCreditCardService() throws IOException {
    setRequestTo(json.serialize(aValidCreditCardForm().build()));
    when(creditCardService.completePurchase(
            any(PaymentContext.class), any(CreditCardDetails.class), any(InetAddress.class)))
        .thenReturn(aPurchaseResponseFor(PurchaseOutcome.APPROVED));

    underTest.processPayment(request, response);

    final CreditCardForm creditCardForm = aValidCreditCardForm().build();
    verify(creditCardService)
        .completePurchase(
            creditCardForm.toPaymentContext(aLobbySession()),
            creditCardForm.toCreditCardDetails(),
            InetAddress.getByAddress(new byte[] {10, 9, 8, 11}));
  }