package in.partake.controller;
import static play.test.Helpers.GET;
import static play.test.Helpers.POST;
import static play.test.Helpers.fakeRequest;
import static play.test.Helpers.routeAndCall;
import in.partake.base.Pair;
import in.partake.controller.base.AbstractPartakeController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import play.mvc.Result;
import play.test.FakeRequest;
import play.test.FakeRequestOperation;
import play.test.Helpers;
public class ActionProxy {
private FakeRequest request;
private Result result;
private Map<String, String> session;
private Map<String, List<String>> formParams;
public static ActionProxy get(String url) {
return new ActionProxy(fakeRequest(GET, url));
}
public static ActionProxy post(String url) {
return new ActionProxy(fakeRequest(POST, url));
}
private ActionProxy(FakeRequest request) {
this.request = request;
this.session = new HashMap<String, String>();
this.formParams = new HashMap<String, List<String>>();
}
public AbstractPartakeController getAction() {
return PartakeTestContext.getAction();
}
public void addSession(String key, String value) {
session.put(key, value);
}
public void addFormParameter(String key, String value) {
List<String> params;
if (formParams.containsKey(key))
params = formParams.get(key);
else
params = new ArrayList<String>();
params.add(value);
formParams.put(key, params);
}
public String session(String key) {
return session.get(key);
}
public void execute() throws Exception {
if (formParams.isEmpty())
request.withFormUrlEncodedBody(new HashMap<String, String>());
else {
// Since request.withFormUrlEncodedBody takes Map<String, String>, we cannot add multiple values for one key.
// It should be Map<String, String[]>, I believe. However, it is converted to (String, String)* and converted
// to (String, Seq[String]) in scala.
// So if we can add multiple keys that are actually the equivalent keys, we can add multiple values actually.
// So IdnetityHashMap really works well here :-) ... This is just a hack.
IdentityHashMap<String, String> map = new IdentityHashMap<String, String>();
for (Entry<String, List<String>> entry : formParams.entrySet()) {
for (String value : entry.getValue()) {
String key = new String(entry.getKey());
map.put(key, value);
}
}
request.withFormUrlEncodedBody(map);
}
if (session.isEmpty())
request.withSession("", "");
else {
List<Pair<String, String>> sessions = new ArrayList<Pair<String,String>>();
for (Entry<String, String> entry: session.entrySet())
sessions.add(new Pair<String, String>(entry.getKey(), entry.getValue()));
FakeRequestOperation.addSession(request, sessions);
}
result = routeAndCall(request);
// Ensure that response has been done to keep backward compatibility:
// from Play! 2.1.x, it might be AsyncResult. To ensure that request
// has been done, we need to call Helpers.xxx()
Helpers.status(result);
}
public Result getResult() {
return result;
}
}