package io.github.azagniotov.stubby4j.handlers;
import io.github.azagniotov.stubby4j.cli.ANSITerminal;
import io.github.azagniotov.stubby4j.handlers.strategy.stubs.UnauthorizedResponseHandlingStrategy;
import io.github.azagniotov.stubby4j.stubs.StubRepository;
import io.github.azagniotov.stubby4j.stubs.StubRequest;
import io.github.azagniotov.stubby4j.stubs.StubResponse;
import io.github.azagniotov.stubby4j.stubs.StubSearchResult;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpStatus.Code;
import org.eclipse.jetty.server.Request;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import static io.github.azagniotov.stubby4j.handlers.strategy.stubs.UnauthorizedResponseHandlingStrategy.NO_AUTHORIZATION_HEADER;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SuppressWarnings("serial")
@RunWith(MockitoJUnitRunner.class)
public class StubsPortalHandlerTest {
private static final String SOME_RESULTS_MESSAGE = "we have results";
@Mock
private StubResponse mockStubResponse;
@Mock
private StubRequest mockAssertionRequest;
@Mock
private StubSearchResult mockStubSearchResult;
@Mock
private PrintWriter mockPrintWriter;
@Mock
private HttpServletResponse mockHttpServletResponse;
@Mock
private StubRepository mockStubRepository;
@Mock
private HttpServletRequest mockHttpServletRequest;
@Mock
private Request mockRequest;
@BeforeClass
public static void beforeClass() throws Exception {
ANSITerminal.muteConsole(true);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithNoResults() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.GET.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.NOT_FOUND);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.NOT_FOUND_404);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandlePostRequestWithNoResults() throws Exception {
final String postData = "postData";
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.POST.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.NOT_FOUND);
final InputStream inputStream = new ByteArrayInputStream(postData.getBytes());
when(mockHttpServletRequest.getInputStream()).thenReturn(getServletInputStream(inputStream));
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.NOT_FOUND_404);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandlePostRequestWithMissingPostData() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.POST.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.OK);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.BAD_REQUEST_400);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandlePostRequestWithEmptyPostData() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.POST.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.OK);
final InputStream inputStream = new ByteArrayInputStream("".getBytes());
when(mockHttpServletRequest.getInputStream()).thenReturn(getServletInputStream(inputStream));
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.BAD_REQUEST_400);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithSomeResults() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.GET.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.OK);
when(mockStubResponse.getResponseBodyAsBytes()).thenReturn(null);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithNoAuthorizationHeaderSet() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.GET.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.UNAUTHORIZED);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.UNAUTHORIZED_401);
verify(mockHttpServletResponse, times(1)).sendError(HttpStatus.UNAUTHORIZED_401, NO_AUTHORIZATION_HEADER);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithEmptyBasicAuthorizationHeaderSet() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.GET.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.UNAUTHORIZED);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.UNAUTHORIZED_401);
verify(mockHttpServletResponse, times(1)).sendError(HttpStatus.UNAUTHORIZED_401, UnauthorizedResponseHandlingStrategy.NO_AUTHORIZATION_HEADER);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithEmptyBearerAuthorizationHeaderSet() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.GET.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.UNAUTHORIZED);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.UNAUTHORIZED_401);
verify(mockHttpServletResponse, times(1)).sendError(HttpStatus.UNAUTHORIZED_401, UnauthorizedResponseHandlingStrategy.NO_AUTHORIZATION_HEADER);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandlePostRequestWithMatch() throws Exception {
final String postData = "postData";
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.POST.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.OK);
when(mockStubResponse.getResponseBodyAsBytes()).thenReturn(null);
final InputStream inputStream = new ByteArrayInputStream(postData.getBytes());
when(mockHttpServletRequest.getInputStream()).thenReturn(getServletInputStream(inputStream));
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithLatency() throws Exception {
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(HttpMethod.GET.asString());
when(mockHttpServletRequest.getPathInfo()).thenReturn(requestPathInfo);
when(mockStubResponse.getLatency()).thenReturn("50");
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.OK);
when(mockStubResponse.getResponseBodyAsBytes()).thenReturn(new byte[]{});
when(mockHttpServletResponse.getOutputStream()).thenReturn(SERVLET_OUTPUT_STREAM);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.OK_200);
}
@Test
public void verifyBehaviourDuringHandleGetRequestWithInvalidLatency() throws Exception {
final String method = HttpMethod.GET.asString();
final String requestPathInfo = "/path/1";
when(mockHttpServletRequest.getMethod()).thenReturn(method);
when(mockStubResponse.getLatency()).thenReturn("43rl4knt3l");
when(mockStubResponse.getHttpStatusCode()).thenReturn(Code.OK);
setUpStubSearchMockExpectations(requestPathInfo);
verify(mockHttpServletResponse, times(1)).setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
verify(mockHttpServletResponse, never()).setStatus(HttpStatus.OK_200);
verify(mockPrintWriter, never()).println(SOME_RESULTS_MESSAGE);
}
private void setUpStubSearchMockExpectations(final String requestPathInfo) throws Exception {
when(mockStubRepository.toStubRequest(mockHttpServletRequest)).thenCallRealMethod();
final StubRequest assertionStubRequest = mockStubRepository.toStubRequest(mockHttpServletRequest);
when(mockStubRepository.search(mockHttpServletRequest)).thenReturn(mockStubSearchResult);
when(mockStubSearchResult.getInvariant()).thenReturn(assertionStubRequest);
when(mockStubSearchResult.getMatch()).thenReturn(mockStubResponse);
final StubsPortalHandler stubsPortalHandler = new StubsPortalHandler(mockStubRepository);
stubsPortalHandler.handle(requestPathInfo, mockRequest, mockHttpServletRequest, mockHttpServletResponse);
}
private ServletInputStream getServletInputStream(final InputStream inputStream) {
return new ServletInputStream() {
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(final ReadListener readListener) {
}
};
}
private static final ServletOutputStream SERVLET_OUTPUT_STREAM = new ServletOutputStream() {
@Override
public void write(final int i) throws IOException {
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(final WriteListener writeListener) {
}
};
}