Skip to content

Commit

Permalink
Merge pull request #24 from Visual-Regression-Tracker/109-errorHandli…
Browse files Browse the repository at this point in the history
…ng-fix

109 error handling fix
  • Loading branch information
pashidlos authored Aug 31, 2020
2 parents c569c86 + 65e3153 commit b6ccdbd
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 117 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group 'io.visual-regression-tracker.sdk-java'
version '4.0.2'
version '4.0.3'

apply plugin: 'java'
apply plugin: 'jacoco'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,19 @@
import java.util.Optional;

public class VisualRegressionTracker {
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
String apiKeyHeaderName = "apiKey";
Gson gson = new Gson();
VisualRegressionTrackerConfig visualRegressionTrackerConfig;
String buildId;
String projectId;
OkHttpClient client;
protected static final String apiKeyHeaderName = "apiKey";
protected static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
protected Gson gson;
protected VisualRegressionTrackerConfig visualRegressionTrackerConfig;
protected String buildId;
protected String projectId;
protected OkHttpClient client;

public VisualRegressionTracker(VisualRegressionTrackerConfig visualRegressionTrackerConfig) {
this.visualRegressionTrackerConfig = visualRegressionTrackerConfig;

this.client = new OkHttpClient();
}

protected boolean isStarted() {
return this.buildId != null && this.projectId != null;
this.gson = new Gson();
}

public void start() throws IOException {
Expand All @@ -48,20 +45,9 @@ public void start() throws IOException {
.build();

try (Response response = client.newCall(request).execute()) {
if (response.code() == 401) {
throw new TestRunException("Unauthorized");
}
if (response.code() == 403) {
throw new TestRunException("Api key not authenticated");
}
if (response.code() == 404) {
throw new TestRunException("Project not found");
}

String responseBody = Optional.ofNullable(response.body())
.orElseThrow(() -> new TestRunException("Cannot get response body"))
.string();
BuildResponse buildDTO = gson.fromJson(responseBody, BuildResponse.class);

BuildResponse buildDTO = handleResponse(response, BuildResponse.class);

this.buildId = Optional.ofNullable(buildDTO.getId())
.orElseThrow(() -> new TestRunException("Build id is null"));
this.projectId = Optional.ofNullable(buildDTO.getProjectId())
Expand All @@ -80,7 +66,32 @@ public void stop() throws IOException {
.patch(RequestBody.create(JSON, ""))
.build();

client.newCall(request).execute();
try (Response response = client.newCall(request).execute()) {
handleResponse(response, Object.class);
}
}

public void track(String name, String imageBase64, TestRunOptions testRunOptions) throws IOException {
TestRunResponse testResultDTO = this.submitTestRun(name, imageBase64, testRunOptions);

TestRunStatus status = Optional.ofNullable(testResultDTO.getStatus())
.orElseThrow(() -> new TestRunException("Status is null"));

if (status.equals(TestRunStatus.NEW)) {
throw new TestRunException("No baseline: ".concat(testResultDTO.getUrl()));
}

if (status.equals(TestRunStatus.UNRESOLVED)) {
throw new TestRunException("Difference found: ".concat(testResultDTO.getUrl()));
}
}

public void track(String name, String imageBase64) throws IOException {
this.track(name, imageBase64, TestRunOptions.builder().build());
}

protected boolean isStarted() {
return this.buildId != null && this.projectId != null;
}

protected TestRunResponse submitTestRun(String name, String imageBase64, TestRunOptions testRunOptions) throws IOException {
Expand Down Expand Up @@ -110,29 +121,19 @@ protected TestRunResponse submitTestRun(String name, String imageBase64, TestRun
.build();

try (Response response = client.newCall(request).execute()) {
String responseBody = Optional.ofNullable(response.body())
.orElseThrow(() -> new TestRunException("Cannot get response body"))
.string();
return gson.fromJson(responseBody, TestRunResponse.class);
return handleResponse(response, TestRunResponse.class);
}
}

public void track(String name, String imageBase64, TestRunOptions testRunOptions) throws IOException {
TestRunResponse testResultDTO = this.submitTestRun(name, imageBase64, testRunOptions);

TestRunStatus status = Optional.ofNullable(testResultDTO.getStatus())
.orElseThrow(() -> new TestRunException("Status is null"));
protected <T> T handleResponse(Response response, Class<T> classOfT) throws IOException {
String responseBody = Optional.ofNullable(response.body())
.orElseThrow(() -> new TestRunException("Cannot get response body"))
.string();

if (status.equals(TestRunStatus.NEW)) {
throw new TestRunException("No baseline: ".concat(testResultDTO.getUrl()));
if (!response.isSuccessful()) {
throw new TestRunException(responseBody);
}

if (status.equals(TestRunStatus.UNRESOLVED)) {
throw new TestRunException("Difference found: ".concat(testResultDTO.getUrl()));
}
}

public void track(String name, String imageBase64) throws IOException {
this.track(name, imageBase64, TestRunOptions.builder().build());
return gson.fromJson(responseBody, classOfT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import io.visual_regression_tracker.sdk_java.response.BuildResponse;
import io.visual_regression_tracker.sdk_java.response.TestRunResponse;
import lombok.SneakyThrows;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
Expand Down Expand Up @@ -48,25 +52,6 @@ public void tearDown() {
server.shutdown();
}

@DataProvider(name = "shouldReturnIsStartedCases")
public Object[][] shouldReturnIsStartedCases() {
return new Object[][]{
{null, null, false},
{null, "some", false},
{"some", null, false},
{"some", "some", true},
};
}

@Test(dataProvider = "shouldReturnIsStartedCases")
public void shouldReturnIsStarted(String buildId, String projectId, boolean expectedResult) {
vrt.buildId = buildId;
vrt.projectId = projectId;

boolean result = vrt.isStarted();
MatcherAssert.assertThat(result, CoreMatchers.is(expectedResult));
}

@Test
public void shouldStartBuild() throws IOException, InterruptedException {
String buildId = "123123";
Expand All @@ -86,57 +71,12 @@ public void shouldStartBuild() throws IOException, InterruptedException {
vrt.start();

RecordedRequest request = server.takeRequest();
MatcherAssert.assertThat(request.getHeader(vrt.apiKeyHeaderName), CoreMatchers.is(config.getApiKey()));
MatcherAssert.assertThat(request.getHeader(VisualRegressionTracker.apiKeyHeaderName), CoreMatchers.is(config.getApiKey()));
MatcherAssert.assertThat(request.getBody().readUtf8(), CoreMatchers.is(gson.toJson(buildRequest)));
MatcherAssert.assertThat(vrt.buildId, CoreMatchers.is(buildId));
MatcherAssert.assertThat(vrt.projectId, CoreMatchers.is(projectId));
}

@Test
public void shouldThrowExceptionIfProjectNotFound() throws IOException {
server.enqueue(new MockResponse()
.setResponseCode(404)
.setBody("{\r\n \"statusCode\": 404,\r\n \"message\": \"Project not found\"\r\n}"));

String exceptionMessage = "";
try {
vrt.start();
} catch (TestRunException ex) {
exceptionMessage = ex.getMessage();
}
MatcherAssert.assertThat(exceptionMessage, CoreMatchers.is("Project not found"));
}

@Test
public void shouldThrowExceptionIfUnauthorized() throws IOException {
server.enqueue(new MockResponse()
.setResponseCode(401)
.setBody("{\r\n \"statusCode\": 401,\r\n \"message\": \"Unauthorized\"\r\n}"));

String exceptionMessage = "";
try {
vrt.start();
} catch (TestRunException ex) {
exceptionMessage = ex.getMessage();
}
MatcherAssert.assertThat(exceptionMessage, CoreMatchers.is("Unauthorized"));
}

@Test
public void shouldThrowExceptionIfForbidden() throws IOException {
server.enqueue(new MockResponse()
.setResponseCode(403)
.setBody("{\r\n \"statusCode\": 403,\r\n \"message\": \"Forbidden\"\r\n}"));

String exceptionMessage = "";
try {
vrt.start();
} catch (TestRunException ex) {
exceptionMessage = ex.getMessage();
}
MatcherAssert.assertThat(exceptionMessage, CoreMatchers.is("Api key not authenticated"));
}

@Test
public void shouldStopBuild() throws IOException, InterruptedException {
String buildId = "123123";
Expand All @@ -154,7 +94,7 @@ public void shouldStopBuild() throws IOException, InterruptedException {

RecordedRequest request = server.takeRequest();
MatcherAssert.assertThat(request.getMethod(), CoreMatchers.is("PATCH"));
MatcherAssert.assertThat(request.getHeader(vrt.apiKeyHeaderName), CoreMatchers.is(config.getApiKey()));
MatcherAssert.assertThat(request.getHeader(VisualRegressionTracker.apiKeyHeaderName), CoreMatchers.is(config.getApiKey()));
MatcherAssert.assertThat(Objects.requireNonNull(request.getRequestUrl()).encodedPath(), CoreMatchers.containsString(buildId));
}

Expand Down Expand Up @@ -204,13 +144,13 @@ public void shouldSubmitTestRun() throws IOException, InterruptedException {
TestRunResponse result = vrt.submitTestRun(name, imageBase64, testRunOptions);

RecordedRequest request = server.takeRequest();
MatcherAssert.assertThat(request.getHeader(vrt.apiKeyHeaderName), CoreMatchers.is(config.getApiKey()));
MatcherAssert.assertThat(request.getHeader(VisualRegressionTracker.apiKeyHeaderName), CoreMatchers.is(config.getApiKey()));
MatcherAssert.assertThat(request.getBody().readUtf8(), CoreMatchers.is(gson.toJson(testRunRequest)));
MatcherAssert.assertThat(gson.toJson(result), CoreMatchers.is(gson.toJson(testRunResponse)));
}

@Test
public void shouldNotSubmitTestRunIfNotStarted() throws IOException {
public void submitTestRunShouldThrowIfNotStarted() throws IOException {
VisualRegressionTracker vrtMocked = Mockito.mock(VisualRegressionTracker.class);
Mockito.when(vrtMocked.isStarted()).thenReturn(false);

Expand All @@ -224,8 +164,8 @@ public void shouldNotSubmitTestRunIfNotStarted() throws IOException {
MatcherAssert.assertThat(exceptionMessage, CoreMatchers.is("Visual Regression Tracker has not been started"));
}

@DataProvider(name = "shouldTrackThrowExceptionCases")
public Object[][] shouldTrackThrowExceptionCases() {
@DataProvider(name = "trackShouldThrowExceptionCases")
public Object[][] trackShouldThrowExceptionCases() {
return new Object[][]{
{
TestRunResponse.builder()
Expand All @@ -244,8 +184,8 @@ public Object[][] shouldTrackThrowExceptionCases() {
};
}

@Test(dataProvider = "shouldTrackThrowExceptionCases")
public void shouldTrackThrowException(TestRunResponse testRunResponse, String expectedExceptionMessage) throws IOException {
@Test(dataProvider = "trackShouldThrowExceptionCases")
public void trackShouldThrowException(TestRunResponse testRunResponse, String expectedExceptionMessage) throws IOException {
VisualRegressionTracker vrtMocked = Mockito.mock(VisualRegressionTracker.class);
Mockito.when(vrtMocked.submitTestRun(Mockito.anyString(), Mockito.anyString(), Mockito.any())).thenReturn(testRunResponse);

Expand Down Expand Up @@ -289,4 +229,50 @@ public void shouldTrackOverload() throws IOException {

Mockito.verify(vrtMocked, Mockito.times(1)).track(Mockito.anyString(), Mockito.anyString(), Mockito.any(TestRunOptions.class));
}

@DataProvider(name = "shouldReturnIsStartedCases")
public Object[][] shouldReturnIsStartedCases() {
return new Object[][]{
{null, null, false},
{null, "some", false},
{"some", null, false},
{"some", "some", true},
};
}

@Test(dataProvider = "shouldReturnIsStartedCases")
public void shouldReturnIsStarted(String buildId, String projectId, boolean expectedResult) {
vrt.buildId = buildId;
vrt.projectId = projectId;

boolean result = vrt.isStarted();

MatcherAssert.assertThat(result, CoreMatchers.is(expectedResult));
}

@Test
public void handleRequestShouldThrowIfNotSuccess() throws IOException {
String error = "{\n" +
" \"statusCode\": 404,\n" +
" \"message\": \"Project not found\"\n" +
"}";
Request mockRequest = new Request.Builder()
.url(config.getApiUrl())
.build();

String exceptionMessage = "";
try {
vrt.handleResponse(new Response.Builder()
.request(mockRequest)
.protocol(Protocol.HTTP_2)
.code(401)
.message("Not found")
.body(ResponseBody.create(error, VisualRegressionTracker.JSON))
.build(), Object.class);
} catch (TestRunException ex) {
exceptionMessage = ex.getMessage();
}

MatcherAssert.assertThat(exceptionMessage, CoreMatchers.is(error));
}
}

0 comments on commit b6ccdbd

Please sign in to comment.