Struts2 Junit4 tests accumulate JSON responses with every action execution - struts2

I've written a few Junit4 tests, which looks like this :
public class TestCampaignList extends StrutsJUnit4TestCase<Object> {
public static final Logger LOG = Logger.getLogger(TestCampaignList.class.getName());
#Before
public void loginAdmin() throws ServletException, UnsupportedEncodingException {
request.setParameter("email", "nitin.cool4urchat#gmail.com");
request.setParameter("password", "22");
String response = executeAction("/login/admin");
System.out.println("Login Response : " + response);
}
#Test
public void testList() throws Exception {
request.setParameter("iDisplayStart", "0");
request.setParameter("iDisplayLength", "10");
String response = executeAction("/campaign/list");
System.out.println("Reponse : " + response);
}
}
Both actions return JSON results and executeAction javadoc says :
For this to work the configured result for the action needs to be FreeMarker, or Velocity (JSPs can be used with the Embedded JSP plugin)
Seems like it's unable to handle JSON results and hence, the second action execution shows accumulated result, such that result_for_second_action= result1 concatenate result2
Is there a solution to get the executeAction() return the actual JSON response, rather than concatenating JSON responses from all previous executions.

This is happening because you are executing action in #Before method. In that way the setUp method of StrutsJUnit4TestCase is not getting called in between your loginAdmin and test method and you previous request parameters are passed to it again. You can call setUp method by yourself in your tests method.
In your case you can actually call initServletMockObjects method to create new mock servlet objects such as request.
#Test
public void testList() throws Exception {
setUp();
// or
// initServletMockObjects();
request.setParameter("iDisplayStart", "0");
request.setParameter("iDisplayLength", "10");
String response = executeAction("/campaign/list");
System.out.println("Reponse : " + response);
}

Related

How to get both HTTP response body and Status when using Reactor Netty HTTP Client

I am using the Reactor Netty HTTP client here as a stand alone dependency, ie not via spring-webflux because I do not want to drag in Spring related dependencies
As can be seen from the documentation it is possible to make a request that returns HttpClientResponse
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.HttpClientResponse;
public class Application {
public static void main(String[] args) {
HttpClientResponse response =
HttpClient.create()
.get()
.uri("http://example.com/")
.response()
.block();
}
}
Thing is HttpClientResponse only contains the headers and the staus. As can be seen from its Java Docs here
Also from the example to consume data one can do
import reactor.netty.http.client.HttpClient;
public class Application {
public static void main(String[] args) {
String response =
HttpClient.create()
.get()
.uri("http://example.com/")
.responseContent()
.aggregate()
.asString()
.block();
}
}
But this only returns the http entity data as string. No information about the headers nor status code.
The problem I have now is I need to make a request and get a response that gives me both the headers, status etc alongside with the http response body.
I cannot seem to find how. Any ideas?qw
Take a look at the following methods:
Flux<V> response(BiFunction<HttpClientResponse,ByteBufFlux,Publisher<V>> receiver)
Mono<V> responseSingle(BiFunction<HttpClientResponse, ByteBufMono, Mono<V>> receiver)
They allow you to access response body, status, and http headers simultaneously.
For example using the responseSingle method you can do the following:
private Mono<Foo> getFoo() {
return httpClient.get()
.uri("foos/1")
.responseSingle(
(response, bytes) ->
bytes.asString()
.map(it -> new Foo(response.status().code(), it))
);
}
The code above translates the response into some domain object Foo defined as follows:
public static class Foo {
int status;
String response;
public Foo(int status, String response) {
this.status = status;
this.response = response;
}
}
The Foo object is null when the http response does not have a body. For example, if HttpStatus 403 is returned, the Foo object is null. I was able to check response code and return just status.
(resp, bytes)-> {
if (resp.status().code()=HttpResponseStatus.OK.code) {
return bytes.asString().map(it->new Foo(resp.status(),it);
} else {
return Mono.just(new Foo(resp.status());
}
}

How to Put request with json payload with rest assured

I want to load the JSON file in a body with rest assured but getting error 415.
Can you please help me?
code is:
public class Entitlement_Creation extends BaseClass {
#Test
public void JsonPayload() throws IOException
{
Path json_data = Paths.get("test.json");
byte[] wikiArray = Files.readAllBytes(json_data);
String wikiString = new String(wikiArray);
System.out.println(wikiString);
given()
.contentType(ContentType.JSON)
.accept(ContentType.JSON)
.body(wikiString)
.when()
.put()
.then()
.statusCode(200)
.extract()
.response();
}
from this snippet, I can't see any information about URL of your service.
You should put your URL as an argument to put() method.

MockWebServer: llegalStateException: start() already called

I try to run a test with MockWebServer.
I would like to make a UI test with mocked response, so I could test for valid\invalid UI changes like logging in, or showing error in a login API.
However, each and every time I ran the code I got the following exception:
java.lang.IllegalStateException: start() already called
Code:
#RunWith(AndroidJUnit4.class)
public class UITestPlayground {
String testUrl = "http://testurl.com/";
MockWebServer server = new MockWebServer();
#Rule
public IntentsTestRule<LoginActivity> mIntentsRule = new IntentsTestRule<>(LoginActivity.class);
#Before
public void beforeHelper() throws IOException {
TestHelper.removeUserAndTokenIfAny(mIntentsRule.getActivity());
URLS.baseUrl = testUrl;
server.url(URLS.baseUrl);
//try to shutting down the server JUT IN CASE...
server.shutdown();
server.start();
}
#After
public void afterHelper() throws IOException {
server.shutdown();
}
#Test
public void invalidLoginDueNotValidJSONResponse() {
server.enqueue(new MockResponse().setBody("Something not valid JSON response"));
String emailToBeTyped = "tester#tester.com";
String passToBeTyped = "passtest";
ViewActions.closeSoftKeyboard();
// Type text and then press the button.
onView(withId(R.id.login_email_edit)).perform(typeText(emailToBeTyped));
ViewActions.closeSoftKeyboard();
onView(withId(R.id.login_pass_edit)).perform(typeText(passToBeTyped));
ViewActions.closeSoftKeyboard();
onView(withId(R.id.log_in_btn)).perform(click());
//TODO: check on valid error message appearing
}
}
What am I doing wrong? The .start() only called once, I even .shutdown() just in
case... I don't understand how could it called more than once.
Thanks in advance.
In the original example at github I have found that the order is reversed.
You actually start the server, THEN sets it's url.
And not setting the url then starting the server.
Interesting.

MVC Post Request how to get Request Content if it's different to that expected by the Default ModelBinder

I have this MVC WebApi action:
PostTrips(List<Trip> trips)
When a list of trips is sent through everything works fine. If, however, someone is trying to post incorrect data, e.g just an object {} then trips is null - this is fine, but I would like to log the data that the user tried to push.
I tried to get it using string requestData = Request.Content.ReadAsStringAsync().Result; but it can only be called once, and I guess the default model binder is calling it to try an map it to my List<Trip>, as when I call it, the result is always null, even though I know I'm passing something in.
Does anyone know of another way to get the posted data again?
I got around this my removing the parameter List<Trip> trips from the action so I had:
public async Task<HttpResponseMessage> PostTrips()
{
}
This bypasses the default model binder and allows you to get the unmodified request content using:
string requestContent = await Request.Content.ReadAsStringAsync();
You can then do what ever you need with this - I wanted to log the data for error tracking.
To create the actual List<Trip> trips I then used Newtonsoft.Json to deserialise the string into a list:
List<TravelTrackerTrip> appTrips = JsonConvert.DeserializeObject<List<TravelTrackerTrip>>(requestContent);
Full example:
public async Task<HttpResponseMessage> PostTrips()
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
List<Trip> appTrips = null;
string requestContent = await Request.Content.ReadAsStringAsync();
try
{
appTrips = JsonConvert.DeserializeObject<List<Trip>>(requestContent);
}
catch(Exception ex)
{
//ERROR LOGGING HERE...
//QUIT - Return failure response
}
try
{
//Success - do whatever we need
}
catch(Exception ex)
{
//ERROR LOGGING HERE...
//QUIT - Return failure response
}
//Return success response
}

Send Template Email Using Struts2 View

I am using Struts2, and I want to send the html output of one of my actions as an email.
In other words, instead of displaying the output html in the browser, I want to send it as an email.
I am using Apache Tiles to create my pages.
EDIT:
In general, can we get the the html result of struts view as a stream and pass it to another action?
First of all, I need to mention that using JSPs as email templates are not a good idea. But, if you need to do this, or you need to log the exact HTML that user sees (or any other reason), you can do this:
Create an interceptor for your action
Get the response from ServletActionContext
Wrap the response
Invoke the action
get (or even change) the response.
return the result.
This is part of my code:
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
//STEP 1
public class EmailInterceptor implements Interceptor {
#Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
// STEP 2
HttpServletResponse response = ServletActionContext.getResponse();
PrintWriter out = response.getWriter();
// STEP 3
CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) response);
ServletActionContext.setResponse(responseWrapper);
// STEP 4
String result = actionInvocation.invoke();
// STEP 5
String servletResponse = new String(responseWrapper.toString());
out.write(servletResponse + "whatever");
// STEP 6
return result;
}
public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response) {
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter() {
return new PrintWriter(output);
}
}
}

Resources