GWT RequestBuilder fails with SSL connections (in tests). Why? Are there any workarounds? - gwt

I try to connect to a (local) web service using the GWT RequestBuilder with a secure connection (SSL), but the connection isn't established... When I connect using a plain HTTP connection everything works fine.
Some details
everything works fine when I'm using my browser to view the pages,
I use an auto signed SSL certificate on my local machine,
the tests fail because the actual response code (responseCode) is not set,
the tests work fine if I'm using a plain HTTP connection (no SSL).
Code
package com.example.services;
import com.google.gwt.http.client.*;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Timer;
public class RequestBuilderTest extends GWTTestCase {
private static String SERVER_URL = "https://127.0.0.1/api";
private static final int ASSERT_DELAY_IN_MS = 15000;
private static final int TEST_DURATION_IN_MS = 20000;
private int statusCode;
public void testGet() throws Exception {
new RequestBuilder(RequestBuilder.GET, SERVER_URL).sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable e) {
fail(e.getMessage());
}
public void onResponseReceived(Request request, Response response) {
statusCode = response.getStatusCode();
}
});
delayTestFinish(TEST_DURATION_IN_MS);
new Timer() {
#Override
public void run() {
assertEquals(Response.SC_OK, statusCode);
finishTest();
}
}.schedule(ASSERT_DELAY_IN_MS);
}
#Override
public String getModuleName() {
return "com.example.services.RequestBuilder";
}
}
Results
test passes with SERVER_URL = "http://127.0.0.1/api";
test fails with SERVER_URL = "https://127.0.0.1/api";
This is the stack trace for junit:
junit.framework.AssertionFailedError: Remote test failed at 127.0.0.1
expected=200 actual=0
Any ideas on what could be wrong and how can I make the tests work with SSL?
EDIT
How can I force the tests to run in secure mode? I use eclipse... I tried setting some "Program arguments" in the "Run configurations" (for the junit tests), but they don't work... Here are the arguments:
-noserver -startupUrl https://192.168.8.147/com.example.services.RequestBuilderTest.JUnit/ -bindAddress 0.0.0.0
Is it better if I just deactivate the SSL on the server? These tests are meant to be launched on the continuous integration server and I wanted to test them using SSL.

It sounds like you're running into a same-origin policy problem. Embedding a URL into the app like that is inherently unreliable. Instead, use GWT.getModuleBaseUrl().

Related

WebTestClient mutateWith apparently not mutating

My (Cucumber) BDD unit test using WebTestClient is failing (with a 403 Forbidden), when I believe it should be passing. After some debugging, I established that this is because the CSRF check is failing, which suggests the mutateWith(csrf()) operation is not working. What am I doing wrong?
My test scenario:
Scenario Outline: Login
Given that player "<player>" exists with password "<password>"
And presenting a valid CSRF token
When log in as "<player>" using password "<password>"
Then program accepts the login
My test steps code (note the presence of client.mutateWith(csrf())):
#SpringBootTest(...)
#AutoConfigureWebTestClient
public class WebSteps {
#Autowired
private WebTestClient client;
...
private WebTestClient.ResponseSpec response;
#Given("presenting a valid CSRF token")
public void presenting_a_valid_CSRF_token() {
client.mutateWith(csrf());
}
#When("log in as {string} using password {string}")
public void log_in_as_using_password(final String player,
final String password) {
response = client.post().uri("/login")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(BodyInserters.fromFormData("username", player)
.with("password", password))
.exchange();
}
#Then("program accepts the login")
public void program_accepts_the_login() {
response.expectStatus().isFound().expectHeader().valueEquals("Location",
"/");
}
...
Despite its name, the mutateWith() method does not really mutate its object. Rather, it returns a new object that has had the mutation applied. Therefore instead of writing
#Given("presenting a valid CSRF token")
public void presenting_a_valid_CSRF_token() {
client.mutateWith(csrf());
}
write
#Given("presenting a valid CSRF token")
public void presenting_a_valid_CSRF_token() {
client = client.mutateWith(csrf());
}
This error is more likely to occur in a Cucumber test because of the way that test steps alter shared state (The client object), rather than use a fluent API with a long chain of calls.

REST API script taking longer time to execute

I am new to API automation. When trying to execute the basic script in selenium I am getting the below error. Can some one please help me with it.
package GetRequest;
import static io.restassured.RestAssured.given;
import io.restassured.RestAssured;
public class trying {
public static void main(String[] args) {
// base url
RestAssured.baseURI="https://maps.googleapis.com";
given().
param("location","-33.8670522,151.1957362").
param("radius","1500").
param("Key","AIzaSyBBuJ-3wBy1VKGUMtNqO8PpAHWGESIItAo").
when().
get("/maps/api/place/nearbysearch/json").
then().
assertThat().statusCode(200);
}
}
What is the port you are connecting at ? Have you specified that somewhere ? Are you using proxy ?
Why not try something like?
#BeforeClass
public void setProxy()
{
System.setProperty("http.proxyHost", YOUR_PROXY_HOST_HERE);
System.setProperty("http.proxyPort", YOUR_PROXY_PORT_HERE);
}

When using MockRestServiceServer cannot precisely test number of service calls

I am coding some retry logic for a service call, and attempting to test that the Rest Template is attempting to hit the service a certain number of times, in a unit test. I am using the following code to perform the test.
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(ExpectedCount.times(5), method(HttpMethod.GET))
.andRespond(withServerError());
service.call();
I have the retry logic set to only make two attempts. The above test code requires that it occur five times, but the test always passes. In fact, the only way I can get this test to fail is by setting the expected count to one (anything less than the number of actual invocations). The same sort of problem occurs when I use ExpectedCount.min or ExpectedCount.between in that the test will only fail when actual invocations exceed expectation.
I need to be able to test for an exact number of service calls, preferably without the use of Mockito.
This is what finally worked for me, testing with a max attempts of 4:
MockRestServiceServer server;
#Before
public void setUp() {
server = MockRestServiceServer.bindTo(restTemplate).build();
}
#After
public void serverVerify() {
server.verify();
}
#Test
public void doWork_retryThenSuccess() throws Exception {
final String responseBody = "<some valid response JSON>";
final String url = BASE_URL + "/doWork";
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(ExceptionResponseCreator.withException(new SocketTimeoutException("first")));
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(ExceptionResponseCreator.withException(new IOException("second")));
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(ExceptionResponseCreator.withException(new RemoteAccessException("third")));
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
final MyResponseClass response = myService.call();
assertThat(response, notNullValue());
// other asserts here...
}
We are constrained to use Spring Test 5.0.10, which doesn't have MockRequestResponseCreators.withException() (method was added in 5.2.2). Borrowing from Spring 5.2.7 code, this works well:
package com.company.test;
import java.io.IOException;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.test.web.client.ResponseCreator;
import org.springframework.test.web.client.response.MockRestResponseCreators;
public class ExceptionResponseCreator extends MockRestResponseCreators {
public static ResponseCreator withException(IOException ex) {
return request -> { throw ex; };
}
public static ResponseCreator withException(RemoteAccessException ex) {
return request -> { throw ex; };
}
}
You can create your own ResponseCreator with the logic you want. For example:
class DelegateResponseCreator implements ResponseCreator {
private final ResponseCreator[] delegates;
private int toExecute = 0;
public DelegateResponseCreator(final ResponseCreator... delegates) {
this.delegates = delegates;
}
#Override
public ClientHttpResponse createResponse(final ClientHttpRequest request) throws IOException {
ClientHttpResponse ret = this.delegates[this.toExecute % this.delegates.length].createResponse(request);
this.toExecute++;
return ret;
}
}
This delegator executes the ResponseDelegates in order.
So you can mock the response for the call number you want
mockServer.expect(ExpectedCount.times(5), MockRestRequestMatchers.method(HttpMethod.GET))
.andRespond(new DelegateResponseCreator(
MockRestResponseCreators.withServerError(),
MockRestResponseCreators.withServerError(),
MockRestResponseCreators.withServerError(),
MockRestResponseCreators.withServerError(),
MockRestResponseCreators.withSuccess()
));
In this example, the first four calls will return a server error whereas the fifth will be a success.
You need to call mockServer.verify() after making all your requests to check if the expectations are met. Otherwise, you can get away with never making any requests.

Logging static file access to Eclipse console in Google AppEngine DevServer

Is it possible to have the AppEngine dev server output a quick log message to the eclipse console every time it serves a static file?
For example, if my website loads "background.gif" (as a static file from the file system), I would like to see a line like "GET request for static file /war/resources/images/background.gif by 127.0.0.1" show up in the Eclipse console.
Maybe there is a command-line switch for tomcat (the server that appengine uses locally)? I couldn't find anything relevant here... But I did find some documentation about an "access log valve (?!?)" which might look promising, but I don't know if this does what I am looking for, or even if it does, how I can get any potential output to show up in the Eclipse console.
You can use a servlet Filter to intercept all requests:
public class LoggingFilter implements Filter {
private static final Logger log = Logger.getLogger(LoggingFilter.class.getName());
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = ((HttpServletRequest) request);
log.info(httpRequest.getMethod() + " request for " + httpRequest.getRequestURI() + " from " + httpRequest.getRemoteAddr());
request.getRequestDispatcher(httpRequest.getRequestURI()).forward(request, response);
}
#Override
public void destroy() {
}
}
The only problem is that you can not distinguish between requests static and dynamic content. In order to do so, you could put all static content under one directory and that map this Filter to only that path.

Play 2 Java, play-authenticate and Eclipse JUnit tests

I have a new Play 2 project with play-authenticate. I wrote some simple test cases for the REST API. Tests pass fine on the console but I cannot make some of them pass in Eclipse.
#Test
public void testWithoutAuth() {
running(testServer(3333), new Runnable() {
#Override
public void run() {
Response response = WS.url("http://localhost:3333/secretarea").get().get();
assertThat(response.getStatus()).isEqualTo(FORBIDDEN);
}
});
}
This example passes fine on the console but in Eclipse fails with response error code 500. it looks like the application setup is not ok (e.g. my own AuthProvider not found). Has anyone managed to get such tests working in Eclipse?
Finally sorted this out. The trick is to create FakeApplicatio with custom config. In my case the setup is like this:
#Test
public void testWithoutAuth() {
List<String> plugins = new ArrayList<String>();
plugins.add("be.objectify.deadbolt.DeadboltPlugin");
plugins.add("service.MyUserServicePlugin");
plugins.add("providers.MyUsernamePasswordAuthProvider");
FakeApplication fa = fakeApplication(new HashMap<String,String>(), plugins);
running(testServer(3333, fa), new Runnable() {
#Override
public void run() {
Response response = WS.url("http://localhost:3333/secretarea").get().get();
assertThat(response.getStatus()).isEqualTo(FORBIDDEN);
}
});
}