package com.thoughtworks.go.plugin.access;
import com.thoughtworks.go.plugin.api.request.GoPluginApiRequest;
import com.thoughtworks.go.plugin.api.response.DefaultGoApiResponse;
import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse;
import com.thoughtworks.go.plugin.infra.PluginManager;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.HashMap;
import java.util.Map;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class PluginRequestHelperTest {
private PluginManager pluginManager;
private PluginRequestHelper helper;
private boolean[] isSuccessInvoked;
private String pluginId = "pid";
private GoPluginApiResponse response;
private final String requestName = "req";
private final String extensionName = "some-extension";
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setup() {
pluginManager = mock(PluginManager.class);
helper = new PluginRequestHelper(pluginManager, asList("1.0"), extensionName);
isSuccessInvoked = new boolean[]{false};
response = mock(GoPluginApiResponse.class);
when(pluginManager.isPluginOfType(extensionName, pluginId)).thenReturn(true);
}
@Test
public void shouldNotInvokeSuccessBlockOnFailureResponse() {
when(response.responseCode()).thenReturn(DefaultGoApiResponse.INTERNAL_ERROR);
when(response.responseBody()).thenReturn("junk");
when(pluginManager.submitTo(eq(pluginId), any(GoPluginApiRequest.class))).thenReturn(response);
try {
helper.submitRequest(pluginId, requestName, new DefaultPluginInteractionCallback<Object>() {
@Override
public Object onSuccess(String responseBody, String resolvedExtensionVersion) {
isSuccessInvoked[0] = true;
return null;
}
});
fail("should throw exception");
} catch (Exception e) {
assertThat(e.getMessage(), is("Interaction with plugin with id 'pid' implementing 'some-extension' extension failed while requesting for 'req'. Reason: [The plugin sent a response that could not be understood by Go. Plugin returned with code '500' and the following response: 'junk']"));
assertThat(e.getCause().getMessage(), is("The plugin sent a response that could not be understood by Go. Plugin returned with code '500' and the following response: 'junk'"));
assertFalse(isSuccessInvoked[0]);
verify(pluginManager).submitTo(eq(pluginId), any(GoPluginApiRequest.class));
}
}
@Test
public void shouldInvokeSuccessBlockOnSuccessfulResponse() {
when(response.responseCode()).thenReturn(DefaultGoApiResponse.SUCCESS_RESPONSE_CODE);
when(pluginManager.submitTo(eq(pluginId), any(GoPluginApiRequest.class))).thenReturn(response);
helper.submitRequest(pluginId, requestName, new DefaultPluginInteractionCallback<Object>() {
@Override
public Object onSuccess(String responseBody, String resolvedExtensionVersion) {
isSuccessInvoked[0] = true;
return null;
}
});
assertTrue(isSuccessInvoked[0]);
verify(pluginManager).submitTo(eq(pluginId), any(GoPluginApiRequest.class));
}
@Test
public void shouldErrorOutOnValidationFailure() {
when(response.responseCode()).thenReturn(DefaultGoApiResponse.VALIDATION_ERROR);
when(pluginManager.submitTo(eq(pluginId), any(GoPluginApiRequest.class))).thenReturn(response);
thrown.expect(RuntimeException.class);
helper.submitRequest(pluginId, requestName, new DefaultPluginInteractionCallback<Object>() {
@Override
public Object onSuccess(String responseBody, String resolvedExtensionVersion) {
isSuccessInvoked[0] = true;
return null;
}
});
}
@Test
public void shouldConstructTheRequest() {
final String requestBody = "request_body";
when(response.responseCode()).thenReturn(DefaultGoApiResponse.SUCCESS_RESPONSE_CODE);
final GoPluginApiRequest[] generatedRequest = {null};
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
generatedRequest[0] = (GoPluginApiRequest) invocationOnMock.getArguments()[1];
return response;
}
}).when(pluginManager).submitTo(eq(pluginId), any(GoPluginApiRequest.class));
helper.submitRequest(pluginId, requestName, new DefaultPluginInteractionCallback<Object>() {
@Override
public String requestBody(String resolvedExtensionVersion) {
return requestBody;
}
});
assertThat(generatedRequest[0].requestBody(), is(requestBody));
assertThat(generatedRequest[0].extension(), is(extensionName));
assertThat(generatedRequest[0].requestName(), is(requestName));
assertTrue(generatedRequest[0].requestParameters().isEmpty());
}
@Test
public void shouldConstructTheRequestWithRequestParams() {
final String requestBody = "request_body";
when(response.responseCode()).thenReturn(DefaultGoApiResponse.SUCCESS_RESPONSE_CODE);
final GoPluginApiRequest[] generatedRequest = {null};
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
generatedRequest[0] = (GoPluginApiRequest) invocationOnMock.getArguments()[1];
return response;
}
}).when(pluginManager).submitTo(eq(pluginId), any(GoPluginApiRequest.class));
helper.submitRequest(pluginId, requestName, new PluginInteractionCallback<Object>() {
@Override
public String requestBody(String resolvedExtensionVersion) {
return requestBody;
}
@Override
public Map<String, String> requestParams(String resolvedExtensionVersion) {
final HashMap params = new HashMap();
params.put("p1", "v1");
params.put("p2", "v2");
return params;
}
@Override
public Map<String, String> requestHeaders(String resolvedExtensionVersion) {
return null;
}
@Override
public Object onSuccess(String responseBody, String resolvedExtensionVersion) {
return null;
}
});
assertThat(generatedRequest[0].requestBody(), is(requestBody));
assertThat(generatedRequest[0].extension(), is(extensionName));
assertThat(generatedRequest[0].requestName(), is(requestName));
assertThat(generatedRequest[0].requestParameters().size(), is(2));
assertThat(generatedRequest[0].requestParameters().get("p1"), is("v1"));
assertThat(generatedRequest[0].requestParameters().get("p2"), is("v2"));
}
}