package com.adobe.acs.commons.forms.helpers.impl;
import com.adobe.acs.commons.forms.Form;
import com.adobe.acs.commons.forms.FormsRouter;
import com.adobe.acs.commons.forms.helpers.FormHelper;
import com.adobe.acs.commons.forms.impl.FormsRouterImpl;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.xss.XSSAPI;
import com.google.common.collect.ImmutableMap;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import javax.servlet.http.Cookie;
import java.util.Collections;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class PostRedirectGetWithCookiesFormHelperImplTest {
public static final String RESOURCE_PATH = "/test";
@Rule
public SlingContext slingContext = new SlingContext(ResourceResolverType.RESOURCERESOLVER_MOCK);
@Mock
private XSSAPI xss;
private MockSlingHttpServletRequest request;
private MockSlingHttpServletResponse response;
private Resource requestResource;
private FormHelper formHelper;
private ArgumentCaptor<Cookie> cookieCaptor;
@Before
public void setup() throws LoginException, PersistenceException {
// force resource resolver creation
slingContext.resourceResolver();
slingContext.registerService(XSSAPI.class, xss);
slingContext.registerService(FormsRouter.class, new FormsRouterImpl());
formHelper = slingContext.registerInjectActivateService(new PostRedirectGetWithCookiesFormHelperImpl());
request = slingContext.request();
response = slingContext.response();
requestResource = slingContext.create().resource(RESOURCE_PATH, Collections.<String, Object>emptyMap());
request.setResource(requestResource);
cookieCaptor = ArgumentCaptor.forClass(Cookie.class);
}
@Test
public void shouldSerialiseFormInRedirectUrlParameter() throws Exception {
request.setMethod("POST");
request.setParameterMap(ImmutableMap.<String, Object>of(":form", "x", "hello", "world"));
final SlingHttpServletResponse spiedResponse = spy(response);
final Form form = formHelper.getForm("x", request, response);
form.setError("hello", "Error1");
formHelper.renderForm(form, requestResource, request, spiedResponse);
verify(spiedResponse).addCookie(cookieCaptor.capture());
final Cookie formCookie = cookieCaptor.getValue();
final String formString = decode(formCookie.getValue());
final JSONObject formObject = toJSONObject(formString);
// form name
assertThat(formObject.getString(PostRedirectGetFormHelperImpl.KEY_FORM_NAME), is(equalTo("x")));
// errors
final JSONObject formErrors = formObject.getJSONObject(PostRedirectGetFormHelperImpl.KEY_ERRORS);
assertThat(formErrors.getString("hello"), is(equalTo("Error1")));
// form data
final JSONObject formData = formObject.getJSONObject(PostRedirectGetFormHelperImpl.KEY_FORM);
assertThat(formData.getString("hello"), is(equalTo("world")));
}
@Test
public void shouldInvalidateCookieOnGetRequest() throws Exception {
final SlingHttpServletResponse redirectResponse = spy(slingContext.response());
request.setMethod("GET");
request.addCookie(new Cookie("f_x", encode("{\"n\":\"x\", \"f\": {\"hello\": \"world\"}}")));
formHelper.getForm("x", request, redirectResponse);
// check we a cookie was set
verify(redirectResponse).addCookie(cookieCaptor.capture());
// and that is
assertThat(cookieCaptor.getValue().getMaxAge(), is(0));
}
@Test
public void shouldRemoveCookieDataOnGetRequest() throws Exception {
final SlingHttpServletResponse redirectResponse = spy(slingContext.response());
request.setMethod("GET");
request.addCookie(new Cookie("f_x", encode("{\"n\":\"x\", \"f\": {\"hello\": \"world\"}}")));
formHelper.getForm("x", request, redirectResponse);
// check we a cookie was set
verify(redirectResponse).addCookie(cookieCaptor.capture());
// and that is
assertThat(cookieCaptor.getValue().getMaxAge(), is(0));
}
private JSONObject toJSONObject(String form) throws JSONException {
return new JSONObject(form);
}
private String decode(final String encodedForm) {
return org.apache.sling.commons.json.http.Cookie.unescape(encodedForm);
}
private String encode(final String unencoded) {
return org.apache.sling.commons.json.http.Cookie.escape(unencoded);
}
}