Skip to content

Commit

Permalink
Merge pull request #1273 from adobe/dev_to_master_13June
Browse files Browse the repository at this point in the history
13June2024 dev_to_master
  • Loading branch information
deepprakash345 authored Jun 13, 2024
2 parents af38109 + 47ef57d commit 292217b
Show file tree
Hide file tree
Showing 43 changed files with 860 additions and 69 deletions.
1 change: 1 addition & 0 deletions .github/workflows/sync-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
git config --global user.name "ci-build"
- name: Sync with Base Branch
if: ${{ github.event.pull_request.base.ref != 'master' }}
run: |
git fetch origin
git checkout ${{ github.event.pull_request.base.ref }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.StringWriter;
import java.io.Writer;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
Expand All @@ -33,7 +34,11 @@
import com.adobe.cq.forms.core.components.models.form.FormStructureParser;
import com.adobe.cq.forms.core.components.util.ComponentUtils;
import com.adobe.cq.forms.core.components.views.Views;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;

@Model(
adaptables = { SlingHttpServletRequest.class, Resource.class },
Expand Down Expand Up @@ -118,6 +123,7 @@ public String getFormDefinition() {
FormContainer formContainer = resource.adaptTo(FormContainer.class);
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule().addSerializer(String.class, new FormStructureParserImpl.EncodeHTMLSerializer()));
Writer writer = new StringWriter();
// return publish view specific properties only for runtime
mapper.writerWithView(Views.Publish.class).writeValue(writer, formContainer);
Expand All @@ -127,4 +133,14 @@ public String getFormDefinition() {
}
return result;
}

private static class EncodeHTMLSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (value != null) {
String escapedValue = StringEscapeUtils.escapeHtml4(value);
jsonGenerator.writeString(escapedValue);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import com.adobe.cq.forms.core.components.util.AbstractContainerImpl;
import com.adobe.cq.forms.core.components.util.ComponentUtils;
import com.day.cq.commons.LanguageUtil;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.fasterxml.jackson.annotation.JsonIgnore;
Expand All @@ -72,6 +73,7 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont
private static final String FD_SCHEMA_TYPE = "fd:schemaType";
private static final String FD_SCHEMA_REF = "fd:schemaRef";
public static final String FD_FORM_DATA_ENABLED = "fd:formDataEnabled";
public static final String FD_ROLE_ATTRIBUTE = "fd:roleAttribute";

@SlingObject(injectionStrategy = InjectionStrategy.OPTIONAL)
@Nullable
Expand Down Expand Up @@ -104,6 +106,10 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont
@Nullable
private String prefillService;

@ValueMapValue(name = FD_ROLE_ATTRIBUTE, injectionStrategy = InjectionStrategy.OPTIONAL)
@Nullable
private String roleAttribute;

@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
@Nullable
private String data;
Expand Down Expand Up @@ -209,14 +215,16 @@ public String getEncodedCurrentPagePath() {

@Override
public String getId() {
if (getCurrentPage() != null) {
if (GuideWCMUtils.isForms(getCurrentPage().getPath())) {
return ComponentUtils.getEncodedPath(getCurrentPage().getPath());
} else {
return ComponentUtils.getEncodedPath(getPath());
}
String parentPagePath = getParentPagePath();
if (GuideWCMUtils.isForms(parentPagePath)) {
return ComponentUtils.getEncodedPath(parentPagePath);
} else {
return super.getId();
// handling use-case when AF is used in iframe mode inside embed form component
if (request != null && request.getAttribute("formRenderingInsideEmbedContainer") != null) {
return ComponentUtils.getEncodedPath(StringUtils.replace(getPath(), "/" + JcrConstants.JCR_CONTENT + "/"
+ GuideConstants.GUIDE_CONTAINER_NODE_NAME, ""));
}
return ComponentUtils.getEncodedPath(getPath());
}
}

Expand All @@ -237,25 +245,20 @@ public String getPrefillService() {
return prefillService;
}

@Override
public String getRoleAttribute() {
return roleAttribute;
}

@Override
public String getAction() {
if (getCurrentPage() != null) {
return getContextPath() + ADOBE_GLOBAL_API_ROOT + FORMS_RUNTIME_API_GLOBAL_ROOT + "/submit/" + getId();
} else {
return null;
}
return getContextPath() + ADOBE_GLOBAL_API_ROOT + FORMS_RUNTIME_API_GLOBAL_ROOT + "/submit/" + getId();
}

@Override
@JsonIgnore
public String getDataUrl() {
if (getCurrentPage() != null) {
return getContextPath() + ADOBE_GLOBAL_API_ROOT + FORMS_RUNTIME_API_GLOBAL_ROOT + "/data/" + ComponentUtils.getEncodedPath(
getCurrentPage()
.getPath());
} else {
return null;
}
return getContextPath() + ADOBE_GLOBAL_API_ROOT + FORMS_RUNTIME_API_GLOBAL_ROOT + "/data/" + getId();
}

@Override
Expand Down Expand Up @@ -308,6 +311,7 @@ public String getLanguageDirection() {
(request != null && StringUtils.isNotBlank(request.getParameter(GuideConstants.AF_DATA_REF)))) {
formDataEnabled = true;
}
properties.put(FD_ROLE_ATTRIBUTE, getRoleAttribute());
properties.put(FD_FORM_DATA_ENABLED, formDataEnabled);
return properties;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ default String getAppliedCssClasses() {
return null;
}

/**
* @return returns the role attribute that will be applied on the container.
* @since com.adobe.cq.forms.core.components.models.form 5.4.3
*/
@Nullable
@JsonIgnore
default String getRoleAttribute() {
return null;
}

// the below mentioned interface methods are copied from ResponsiveGridExporter
// done because CM throws this, the product interface com.day.cq.wcm.foundation.model.responsivegrid.export.ResponsiveGridExporter
// annotated with @ProviderType should not be implemented by custom code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public interface DateConstraint extends FormatConstraint {
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("minimum")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER, timezone = "UTC")
Date getMinimumDate();

/**
Expand All @@ -50,7 +50,7 @@ public interface DateConstraint extends FormatConstraint {
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("maximum")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER, timezone = "UTC")
Date getMaximumDate();

/**
Expand All @@ -61,7 +61,7 @@ public interface DateConstraint extends FormatConstraint {
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("exclusiveMaximum")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER, timezone = "UTC")
Date getExclusiveMaximumDate();

/**
Expand All @@ -72,7 +72,7 @@ public interface DateConstraint extends FormatConstraint {
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("exclusiveMinimum")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER, timezone = "UTC")
Date getExclusiveMinimumDate();

default String getFormat() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public interface DatePicker extends Field, DateConstraint {
* @see Field#getDefault()
* @since com.adobe.cq.forms.core.components.models.form 2.0.0
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = Base.DATE_FORMATTER, timezone = "UTC")
@Override
default Object[] getDefault() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* </p>
*/

@Version("5.4.2") // aligning this with release/650 since af2-rest-api is compiled with 5.2.0 in release/650
@Version("5.4.3") // aligning this with release/650 since af2-rest-api is compiled with 5.2.0 in release/650
package com.adobe.cq.forms.core.components.models.form;

import org.osgi.annotation.versioning.Version;
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ void testGetModel() {
assertEquals(Collections.emptyMap(), formContainerMock.getModel());
}

@Test
void testGetRoleAttribute() throws Exception {
FormContainer formContainerMock = Mockito.mock(FormContainer.class);
assertEquals(formContainerMock.getRoleAttribute(), null);
}

@Test
void testGetDocumentPath() {
FormContainer formContainerMock = Mockito.mock(FormContainer.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -100,6 +101,19 @@ void testFormDefinition() throws JsonProcessingException {
assertEquals(formJson.get("fieldType"), "form");
}

@Test
void testFormDefinitionWithHTMLEncoding() throws JsonProcessingException {
String path = FORM_CONTAINER_PATH;
FormStructureParser formStructureParser = getFormStructureParserUnderTest(path);
String formDef = formStructureParser.getFormDefinition();
HashMap<String, Object> formJson = (HashMap<String, Object>) new ObjectMapper().readValue(formDef,
new TypeReference<Map<String, Object>>() {});
Assertions.assertNotNull(formStructureParser.getFormDefinition());
Map<String, Object> datepicker = (Map<String, Object>) ((Map<String, Object>) formJson.get(":items")).get("datepicker");
Assertions.assertEquals(datepicker.get("description"), "&lt;p&gt;dummy&lt;/p&gt;");
Assertions.assertEquals(datepicker.get("tooltip"), "&lt;p&gt;test-short-description&lt;/p&gt;");
}

@Test
void testFormContainerPathEmbedWithoutIframe() {
FormStructureParser formStructureParser = getFormStructureParserUnderTest(JCR_CONTENT_PATH, FORM_CONTAINER_PATH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ void testGetId() throws Exception {
assertNotNull(panel.getId());
}

@Test
void testGetRoleAttribute() throws Exception {
Panel panel = Utils.getComponentUnderTest(PATH_PANEL, Panel.class, context);
assertEquals(null, panel.getRoleAttribute());
}

@Test
void testGetName() throws Exception {
Panel panel = Utils.getComponentUnderTest(PATH_PANEL, Panel.class, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
package com.adobe.cq.forms.core.components.internal.models.v2.form;

import java.lang.reflect.Method;
import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
Expand All @@ -39,7 +45,10 @@
import com.adobe.cq.export.json.SlingModelFilter;
import com.adobe.cq.forms.core.Utils;
import com.adobe.cq.forms.core.components.internal.form.FormConstants;
import com.adobe.cq.forms.core.components.models.form.*;
import com.adobe.cq.forms.core.components.models.form.FormClientLibManager;
import com.adobe.cq.forms.core.components.models.form.FormContainer;
import com.adobe.cq.forms.core.components.models.form.TextInput;
import com.adobe.cq.forms.core.components.models.form.ThankYouOption;
import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext;
import com.day.cq.i18n.I18n;
import com.day.cq.wcm.api.NameConstants;
Expand All @@ -55,7 +64,9 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@ExtendWith(AemContextExtension.class)
public class FormContainerImplTest {
Expand Down Expand Up @@ -187,6 +198,12 @@ void testGetDorProperties() throws Exception {
assertEquals("xyz", formContainer.getDorProperties().get("dorTemplateRef"));
}

@Test
void testGetIdWithFormRenderingInsideEmbedContainer() throws Exception {
FormContainer formContainer = getFormContainerWithLocaleUnderTest(FORM_CONTAINER_PATH_IN_SITES);
assertNotNull(formContainer.getId());
}

@Test
void testGetLocalizedValue() throws Exception {
FormContainer formContainer = getFormContainerWithLocaleUnderTest(PATH_FORM_1);
Expand Down Expand Up @@ -251,6 +268,12 @@ void testGetPrefillService() throws Exception {
assertEquals("FDM", formContainer.getPrefillService());
}

@Test
void testGetRoleAttribute() throws Exception {
FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context);
assertEquals(formContainer.getRoleAttribute(), "test-role-attribute");
}

@Test
void testGetContextPath() throws Exception {
FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context);
Expand Down Expand Up @@ -343,6 +366,7 @@ private FormContainer getFormContainerWithLocaleUnderTest(String resourcePath) t
}
});
MockSlingHttpServletRequest request = context.request();
request.setAttribute("formRenderingInsideEmbedContainer", "");
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(GuideConstants.AF_LANGUAGE_PARAMETER, "de");
request.setParameterMap(paramMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"fd:path": "/content/forms/af/demo/jcr:content/formcontainerv2",
"fd:schemaType": "BASIC",
"fd:roleAttribute":"test-role-attribute",
"fd:formDataEnabled": true
},
"events": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"jcr:primaryType": "nt:unstructured",
"sling:resourceType" : "core/fd/components/form/container/v2/container",
"thankYouMessage": "Thank you for submitting.",
"fd:roleAttribute": "test-role-attribute",
"thankYouOption": "message",
"redirect": "/content/wknd",
"prefillService": "FDM",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
"name": "abc",
"jcr:title": "def",
"hideTitle": false,
"description": "dummy",
"visible": false
"description": "<p>dummy</p>",
"tooltip": "<p>test-short-description</p>",
"visible": false,
"fieldType": "datepicker"
},
"container1": {
"jcr:primaryType": "nt:unstructured",
Expand Down
Loading

0 comments on commit 292217b

Please sign in to comment.