package restx.tests; import static restx.RestxMainRouterFactory.Blade; import java.util.Map; import org.joda.time.DateTime; import com.github.kevinsawicki.http.HttpRequest; import com.google.common.collect.ImmutableMap; import restx.common.UUIDGenerator; import restx.factory.Factory; import restx.security.RestxSessionCookieDescriptor; import restx.security.Signer; /** * HttpTestClient is a helper to create com.github.kevinsawicki.http.HttpRequest * which sets the RestxThreadLocal header to share client thread local components with server one * (when used with a per request factory loading). */ public class HttpTestClient { static { // don't restrict headers when testing (include Origin header, allow to test CORS headers) System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); } public static HttpTestClient withBaseUrl(String baseUrl) { return new HttpTestClient(baseUrl, null, ImmutableMap.<String,String>of()); } private final String baseUrl; private final String principal; private final ImmutableMap<String, String> cookies; private HttpTestClient(String baseUrl, String principal, ImmutableMap<String, String> cookies) { this.baseUrl = baseUrl; this.principal = principal; this.cookies = cookies; } public HttpTestClient authenticatedAs(String principal) { Factory factory = Factory.newInstance(); RestxSessionCookieDescriptor restxSessionCookieDescriptor = factory.getComponent(RestxSessionCookieDescriptor.class); Signer signer = factory.queryByClass(Signer.class).findOneAsComponent().get(); ImmutableMap.Builder<String, String> cookiesBuilder = ImmutableMap.<String, String>builder().putAll(cookies); String uuid = factory.getComponent(UUIDGenerator.class).doGenerate(); String expires = DateTime.now().plusHours(1).toString(); String sessionContent = String.format( "{\"_expires\":\"%s\",\"principal\":\"%s\",\"sessionKey\":\"%s\"}", expires, principal, uuid); cookiesBuilder.put(restxSessionCookieDescriptor.getCookieName(), sessionContent); cookiesBuilder.put(restxSessionCookieDescriptor.getCookieSignatureName(), signer.sign(sessionContent)); return new HttpTestClient(baseUrl, principal, cookiesBuilder.build()); } public HttpTestClient withCookie(String cookieName, String cookieValue) { return new HttpTestClient(baseUrl, principal, ImmutableMap.<String,String>builder().putAll(cookies).put(cookieName, cookieValue).build()); } public HttpRequest http(String method, String url) { HttpRequest httpRequest = new HttpRequest(baseUrl + root(url), method) .header("RestxThreadLocal", Factory.LocalMachines.threadLocal().getId()) .header("RestxBlade", Blade.current()) ; if (!cookies.isEmpty()) { StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> entry : cookies.entrySet()) { sb.append(entry.getKey()).append("=\"").append(entry.getValue().replace("\"", "\\\"")).append("\"; "); } sb.setLength(sb.length() - 2); httpRequest.header("Cookie", sb.toString()); } return httpRequest; } public HttpRequest GET(String url) { return http("GET", url); } public HttpRequest HEAD(String url) { return http("HEAD", url); } public HttpRequest OPTIONS(String url) { return http("OPTIONS", url); } public HttpRequest POST(String url) { return http("POST", url); } public HttpRequest PUT(String url) { return http("PUT", url); } public HttpRequest DELETE(String url) { return http("DELETE", url); } private static String root(String url) { return url.startsWith("http") || url.startsWith("/") ? url : "/" + url; } }