From a98b0642a6a00a862bf393aaff9128cb2ef4671a Mon Sep 17 00:00:00 2001 From: Ikshu Jain Date: Thu, 14 May 2026 23:54:57 +0530 Subject: [PATCH 1/3] FORMS-25002: Adding Support for Adobe Sign Block, Signature Step, Summary Step, Enable Adobe Sign via AF --- .../internal/form/FormConstants.java | 6 + .../models/v1/form/SignatureStepImpl.java | 111 ++++++++ .../models/v1/form/SummaryStepImpl.java | 81 ++++++ .../models/v2/form/FormContainerImpl.java | 105 ++++++++ .../components/models/form/FormContainer.java | 24 ++ .../components/models/form/SignatureStep.java | 66 +++++ .../components/models/form/SummaryStep.java | 48 ++++ .../components/models/form/package-info.java | 2 +- .../models/v1/form/SignatureStepImplTest.java | 136 ++++++++++ .../models/v1/form/SummaryStepImplTest.java | 108 ++++++++ .../models/v2/form/FormContainerImplTest.java | 51 ++++ .../form/formcontainer/test-page-content.json | 20 ++ .../form/signaturestep/test-content.json | 22 ++ .../form/summarystep/test-content.json | 20 ++ .../form/signaturestep/.content.xml | 7 + .../form/signaturestep/_cq_template.xml | 9 + .../components/form/summarystep/.content.xml | 7 + .../form/summarystep/_cq_template.xml | 7 + .../samples/signaturestep/.content.xml | 5 + .../samples/signaturestep/basic/.content.xml | 95 +++++++ .../samples/summarystep/.content.xml | 5 + .../samples/summarystep/basic/.content.xml | 94 +++++++ .../.content.xml | 2 +- .../v2/container/_cq_dialog/.content.xml | 248 +++++++++++++++++- .../v2/container/clientlibs/editor/css.txt | 18 ++ .../clientlibs/editor/css/editDialog.css | 39 +++ .../clientlibs/editor/js/editDialog.js | 229 +++++++++++++++- .../form/signaturestep/.content.xml | 23 ++ .../form/signaturestep/v1/.content.xml | 3 + .../v1/signaturestep/.content.xml | 24 ++ .../v1/signaturestep/_cq_dialog/.content.xml | 117 +++++++++ .../v1/signaturestep/_cq_template.xml | 9 + .../v1/signaturestep/clientlibs/.content.xml | 3 + .../clientlibs/site/.content.xml | 6 + .../v1/signaturestep/clientlibs/site/css.txt | 2 + .../clientlibs/site/css/signaturestepview.css | 50 ++++ .../v1/signaturestep/clientlibs/site/js.txt | 2 + .../clientlibs/site/js/signaturestepview.js | 174 ++++++++++++ .../v1/signaturestep/signaturestep.html | 54 ++++ .../v1/signaturestep/signaturestep.js | 34 +++ .../components/form/summarystep/.content.xml | 23 ++ .../form/summarystep/v1/.content.xml | 3 + .../summarystep/v1/summarystep/.content.xml | 24 ++ .../v1/summarystep/_cq_dialog/.content.xml | 90 +++++++ .../v1/summarystep/_cq_template.xml | 7 + .../v1/summarystep/clientlibs/.content.xml | 3 + .../summarystep/clientlibs/site/.content.xml | 6 + .../v1/summarystep/clientlibs/site/css.txt | 2 + .../clientlibs/site/css/summarystepview.css | 35 +++ .../v1/summarystep/clientlibs/site/js.txt | 2 + .../clientlibs/site/js/summarystepview.js | 84 ++++++ .../v1/summarystep/summarystep.html | 40 +++ .../summarystep/v1/summarystep/summarystep.js | 34 +++ .../signaturestep.runtime.spec.js | 71 +++++ .../summarystep/summarystep.runtime.spec.js | 67 +++++ 55 files changed, 2552 insertions(+), 5 deletions(-) create mode 100644 bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java create mode 100644 bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java create mode 100644 bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java create mode 100644 bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java create mode 100644 bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java create mode 100644 bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java create mode 100644 bundles/af-core/src/test/resources/form/signaturestep/test-content.json create mode 100644 bundles/af-core/src/test/resources/form/summarystep/test-content.json create mode 100644 examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml create mode 100644 examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml create mode 100644 examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml create mode 100644 examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml create mode 100644 it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml create mode 100644 it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/basic/.content.xml create mode 100644 it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/summarystep/.content.xml create mode 100644 it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/summarystep/basic/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editor/css.txt create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/editor/css/editDialog.css create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_dialog/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/_cq_template.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css.txt create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/css/signaturestepview.css create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js.txt create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/clientlibs/site/js/signaturestepview.js create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.html create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/signaturestep/v1/signaturestep/signaturestep.js create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_dialog/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/_cq_template.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/.content.xml create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css.txt create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/css/summarystepview.css create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js.txt create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/clientlibs/site/js/summarystepview.js create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.html create mode 100644 ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/summarystep/v1/summarystep/summarystep.js create mode 100644 ui.tests/test-module/specs/signaturestep/signaturestep.runtime.spec.js create mode 100644 ui.tests/test-module/specs/summarystep/summarystep.runtime.spec.js diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java index 5d7c410231..e4dacc8229 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java @@ -146,4 +146,10 @@ private FormConstants() { /** The resource type for date time input field v1 */ public static final String RT_FD_FORM_DATETIME_V1 = RT_FD_FORM_PREFIX + "datetime/v1/datetime"; + /** The resource type for signature step v1 */ + public static final String RT_FD_FORM_SIGNATURE_STEP_V1 = RT_FD_FORM_PREFIX + "signaturestep/v1/signaturestep"; + + /** The resource type for summary step v1 */ + public static final String RT_FD_FORM_SUMMARY_STEP_V1 = RT_FD_FORM_PREFIX + "summarystep/v1/summarystep"; + } diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java new file mode 100644 index 0000000000..0a11b38956 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImpl.java @@ -0,0 +1,111 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Default; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SignatureStep; +import com.adobe.cq.forms.core.components.util.AbstractBaseImpl; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { SignatureStep.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_SIGNATURE_STEP_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class SignatureStepImpl extends AbstractBaseImpl implements SignatureStep { + + static final String PROP_SIGNING_SERVICE = "signingService"; + static final String PROP_CLOUD_SERVICE_CONFIG = "cq:cloudserviceconfigs"; + static final String PROP_DISPLAY_MSG = "displayMsg"; + static final String PROP_TARGET_VERSION = "fd:targetVersion"; + + static final String DEFAULT_SIGNING_SERVICE = "echosign"; + static final String DEFAULT_DISPLAY_MSG = ""; + static final String DEFAULT_TARGET_VERSION = ""; + + static final String VIEW_TYPE_SIGNATURE_STEP = "signature-step"; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_SIGNING_SERVICE) + @Default(values = DEFAULT_SIGNING_SERVICE) + private String signingService; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_CLOUD_SERVICE_CONFIG) + @Nullable + private String cloudServiceConfig; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_DISPLAY_MSG) + @Nullable + private String displayMsg; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_TARGET_VERSION) + @Nullable + private String targetVersion; + + @Override + public String getSigningService() { + return signingService; + } + + @Override + public String getCloudServiceConfig() { + return cloudServiceConfig != null ? cloudServiceConfig : ""; + } + + @Override + public String getDisplayMsg() { + return displayMsg; + } + + @Override + public String getTargetVersion() { + return targetVersion; + } + + @Override + public String getFieldType() { + return super.getFieldType(FieldType.PLAIN_TEXT); + } + + @Override + public @NotNull Map getProperties() { + Map properties = super.getProperties(); + properties.put("fd:signingService", getSigningService()); + if (!getCloudServiceConfig().isEmpty()) { + properties.put("fd:cloudServiceConfig", getCloudServiceConfig()); + } + if (getDisplayMsg() != null) { + properties.put("fd:displayMsg", getDisplayMsg()); + } + if (getTargetVersion() != null && !getTargetVersion().isEmpty()) { + properties.put("fd:targetVersion", getTargetVersion()); + } + return properties; + } +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java new file mode 100644 index 0000000000..397c84ab21 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImpl.java @@ -0,0 +1,81 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Default; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SummaryStep; +import com.adobe.cq.forms.core.components.util.AbstractBaseImpl; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { SummaryStep.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_SUMMARY_STEP_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class SummaryStepImpl extends AbstractBaseImpl implements SummaryStep { + + static final String PROP_DISPLAY_MSG = "displayMsg"; + static final String PROP_AUTO_SUBMIT = "autoSubmit"; + + static final String VIEW_TYPE_SUMMARY_STEP = "summary-step"; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_DISPLAY_MSG) + @Nullable + private String displayMsg; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PROP_AUTO_SUBMIT) + @Default(booleanValues = false) + private boolean autoSubmit; + + @Override + public String getDisplayMsg() { + return displayMsg; + } + + @Override + public boolean isAutoSubmit() { + return autoSubmit; + } + + @Override + public String getFieldType() { + return super.getFieldType(FieldType.PLAIN_TEXT); + } + + @Override + public @NotNull Map getProperties() { + Map properties = super.getProperties(); + if (getDisplayMsg() != null) { + properties.put("fd:displayMsg", getDisplayMsg()); + } + properties.put("fd:autoSubmit", isAutoSubmit()); + return properties; + } +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java index ee8580198c..a1d277efa8 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImpl.java @@ -15,6 +15,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ package com.adobe.cq.forms.core.components.internal.models.v2.form; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; @@ -88,6 +89,30 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont private static final String FD_DATA_URL = "fd:dataUrl"; private static final String FD_VIEW_PRINT_PATH = "fd:view/print"; private static final String EXCLUDE_FROM_DOR_IF_HIDDEN = "excludeFromDoRIfHidden"; + private static final String PN_USE_SIGNED_PDF = "_useSignedPdf"; + private static final String PN_SIGNER_INFO = "signerInfo"; + private static final String PN_FIRST_SIGNER_FORM_FILLER = "firstSignerFormFiller"; + private static final String PN_CLOUD_SERVICE_PATH = "cloudServicePath"; + private static final String PN_SIGNING_ORDER_TYPE = "signingOrderType"; + private static final String PN_EXPIRATION_DAYS = "expirationDays"; + private static final String PN_SIGNERS = "signers"; + private static final String PN_SIGNER_TITLE = "signerTitle"; + private static final String PN_IS_FORM_FILLER = "isFormFiller"; + private static final String PN_SIGNER_EMAIL_TYPE = "signerEmailType"; + private static final String PN_SIGNER_EMAIL_REF = "signerEmailRef"; + private static final String PN_SIGNER_EMAIL = "signerEmail"; + private static final String PN_AUTHENTICATION_METHOD = "authenticationMethod"; + private static final String PN_COUNTRY_CODE_SOURCE = "countryCodeSource"; + private static final String PN_COUNTRY_CODE = "countryCode"; + private static final String PN_PHONE_SOURCE = "phoneSource"; + private static final String PN_PHONE = "phone"; + private static final String PN_SIGNATURE_TYPE = "signatureType"; + private static final String FD_USE_SIGNED_PDF = "fd:useSignedPdf"; + private static final String FD_IS_FORM_FILLER_FIRST_SIGNER = "fd:isFormFillerFirstSigner"; + private static final String FD_SIGNING_CLOUD_SERVICE = "fd:signingCloudService"; + private static final String FD_SIGNING_ORDER_TYPE = "fd:signingOrderType"; + private static final String FD_EXPIRATION_DAYS = "fd:expirationDays"; + private static final String FD_SIGNERS = "fd:signers"; /** Constant representing email submit action type */ private static final String SS_EMAIL = "email"; @@ -159,6 +184,16 @@ public class FormContainerImpl extends AbstractContainerImpl implements FormCont @Self(injectionStrategy = InjectionStrategy.OPTIONAL) private AutoSaveConfiguration autoSaveConfig; + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = PN_USE_SIGNED_PDF) + @Default(booleanValues = false) + private boolean useSignedPdf; + + private boolean formFillerFirstSigner = false; + private String signingCloudService = null; + private String signingOrderType = "sequential"; + private int expirationDays = 1; + private List> signers = new ArrayList<>(); + @Inject private ResourceResolver resourceResolver; @@ -199,6 +234,52 @@ private void initExcludeFromDoRIfHidden() { } } + @PostConstruct + private void initSignerInfo() { + Resource signerInfoResource = resource.getChild(PN_SIGNER_INFO); + if (signerInfoResource != null) { + ValueMap vm = signerInfoResource.getValueMap(); + formFillerFirstSigner = vm.get(PN_FIRST_SIGNER_FORM_FILLER, false); + signingCloudService = vm.get(PN_CLOUD_SERVICE_PATH, String.class); + signingOrderType = vm.get(PN_SIGNING_ORDER_TYPE, "sequential"); + expirationDays = vm.get(PN_EXPIRATION_DAYS, 1); + Resource signersResource = signerInfoResource.getChild(PN_SIGNERS); + if (signersResource != null) { + for (Resource signerItem : signersResource.getChildren()) { + ValueMap signerVm = signerItem.getValueMap(); + Map signerMap = new LinkedHashMap<>(); + + String title = signerVm.get(PN_SIGNER_TITLE, String.class); + String isFormFillerVal = signerVm.get(PN_IS_FORM_FILLER, "true"); + String emailType = signerVm.get(PN_SIGNER_EMAIL_TYPE, "fromForm"); + String emailRef = signerVm.get(PN_SIGNER_EMAIL_REF, String.class); + String signerEmail = signerVm.get(PN_SIGNER_EMAIL, String.class); + String authMethod = signerVm.get(PN_AUTHENTICATION_METHOD, "NONE"); + String countryCodeSource = signerVm.get(PN_COUNTRY_CODE_SOURCE, "form"); + String countryCode = signerVm.get(PN_COUNTRY_CODE, String.class); + String phoneSource = signerVm.get(PN_PHONE_SOURCE, "form"); + String phone = signerVm.get(PN_PHONE, String.class); + String sigType = signerVm.get(PN_SIGNATURE_TYPE, "ESIGN"); + + if (title != null) signerMap.put(PN_SIGNER_TITLE, title); + signerMap.put(PN_IS_FORM_FILLER, Boolean.parseBoolean(isFormFillerVal)); + signerMap.put(PN_SIGNER_EMAIL_TYPE, emailType); + if (emailRef != null) signerMap.put(PN_SIGNER_EMAIL_REF, emailRef); + if (signerEmail != null) signerMap.put(PN_SIGNER_EMAIL, signerEmail); + signerMap.put(PN_AUTHENTICATION_METHOD, authMethod); + if ("PHONE".equals(authMethod)) { + signerMap.put(PN_COUNTRY_CODE_SOURCE, countryCodeSource); + if (countryCode != null) signerMap.put(PN_COUNTRY_CODE, countryCode); + signerMap.put(PN_PHONE_SOURCE, phoneSource); + if (phone != null) signerMap.put(PN_PHONE, phone); + } + signerMap.put(PN_SIGNATURE_TYPE, sigType); + signers.add(signerMap); + } + } + } + } + @Override public void setContextPath(String contextPath) { this.contextPath = contextPath; @@ -420,6 +501,18 @@ public String getLanguageDirection() { if (submitProperties != null && !submitProperties.isEmpty()) { properties.put(ReservedProperties.FD_SUBMIT_PROPERTIES, submitProperties); } + if (isAdobeSignEnabled()) { + properties.put(FD_USE_SIGNED_PDF, true); + properties.put(FD_IS_FORM_FILLER_FIRST_SIGNER, isFormFillerFirstSigner()); + if (signingCloudService != null) { + properties.put(FD_SIGNING_CLOUD_SERVICE, signingCloudService); + } + properties.put(FD_SIGNING_ORDER_TYPE, signingOrderType); + properties.put(FD_EXPIRATION_DAYS, expirationDays); + if (!signers.isEmpty()) { + properties.put(FD_SIGNERS, signers); + } + } return properties; } @@ -488,6 +581,18 @@ public AutoSaveConfiguration getAutoSaveConfig() { return autoSaveConfig; } + @JsonIgnore + @Override + public boolean isAdobeSignEnabled() { + return useSignedPdf; + } + + @JsonIgnore + @Override + public boolean isFormFillerFirstSigner() { + return formFillerFirstSigner; + } + private Map getSubmitProperties() { Map submitProps = null; diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java index a617157c7b..20396013f5 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/FormContainer.java @@ -402,4 +402,28 @@ default AutoSaveConfiguration getAutoSaveConfig() { return null; } + /** + * Returns whether Adobe Sign (echosign) is enabled for this form. + * Reads the {@code _useSignedPdf} JCR property on the form container node. + * + * @return {@code true} if Adobe Sign is enabled, {@code false} otherwise + * @since com.adobe.cq.forms.core.components.models.form 5.12.5 + */ + @JsonIgnore + default boolean isAdobeSignEnabled() { + return false; + } + + /** + * Returns whether the form filler is the first signer in the Adobe Sign workflow. + * Reads the {@code firstSignerFormFiller} property from the {@code signerInfo} child resource. + * + * @return {@code true} if the form filler is the first signer, {@code false} otherwise + * @since com.adobe.cq.forms.core.components.models.form 5.12.5 + */ + @JsonIgnore + default boolean isFormFillerFirstSigner() { + return false; + } + } diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java new file mode 100644 index 0000000000..b4267e1445 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SignatureStep.java @@ -0,0 +1,66 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.models.form; + +import org.osgi.annotation.versioning.ConsumerType; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Defines the {@code SignatureStep} Sling Model used for the + * {@code /apps/core/fd/components/form/signaturestep} component. + * + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ +@ConsumerType +public interface SignatureStep extends Base { + + /** + * Returns the signing service configured for this step (e.g. "echosign" for Adobe Sign). + * + * @return the signing service identifier + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getSigningService(); + + /** + * Returns the Adobe Sign cloud service configuration path. + * + * @return cloud service config path, or empty string if not configured + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getCloudServiceConfig(); + + /** + * Returns the template message displayed inside the signing area. + * + * @return display message, or {@code null} if not set + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getDisplayMsg(); + + /** + * Returns the Adobe Sign agreement target version. + * + * @return target version string, or {@code null} if not set + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getTargetVersion(); +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java new file mode 100644 index 0000000000..bd16ac34b7 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/SummaryStep.java @@ -0,0 +1,48 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.models.form; + +import org.osgi.annotation.versioning.ConsumerType; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Defines the {@code SummaryStep} Sling Model used for the + * {@code /apps/core/fd/components/form/summarystep} component. + * + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ +@ConsumerType +public interface SummaryStep extends Base { + + /** + * Returns the rich-text summary message displayed after form submission. + * + * @return HTML display message, or {@code null} if not set + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + String getDisplayMsg(); + + /** + * Returns whether the form should be auto-submitted when this step is reached. + * + * @return {@code true} if auto-submit is enabled + * @since com.adobe.cq.forms.core.components.models.form 5.12.4 + */ + @JsonIgnore + boolean isAutoSubmit(); +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java index 28bc21d5c0..f2979e29a1 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/models/form/package-info.java @@ -35,7 +35,7 @@ *

*/ -@Version("5.12.3") +@Version("5.12.5") package com.adobe.cq.forms.core.components.models.form; import org.osgi.annotation.versioning.Version; diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java new file mode 100644 index 0000000000..bebd1f8e0b --- /dev/null +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SignatureStepImplTest.java @@ -0,0 +1,136 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.adobe.cq.forms.core.Utils; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SignatureStep; +import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(AemContextExtension.class) +public class SignatureStepImplTest { + + private static final String TEST_BASE = "/form/signaturestep"; + private static final String APPS_ROOT = "/apps"; + private static final String PATH_SIGNATURE_STEP = APPS_ROOT + "/signaturestep"; + private static final String PATH_SIGNATURE_STEP_DEFAULTS = APPS_ROOT + "/signaturestep-defaults"; + + private final AemContext context = FormsCoreComponentTestContext.newAemContext(); + + @BeforeEach + void setUp() { + context.load().json(TEST_BASE + FormsCoreComponentTestContext.TEST_CONTENT_JSON, APPS_ROOT); + } + + @Test + void testGetFieldType() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals(FieldType.PLAIN_TEXT.getValue(), signatureStep.getFieldType()); + } + + @Test + void testGetFieldTypeOnNewInstance() { + SignatureStep signatureStep = new SignatureStepImpl(); + assertEquals(FieldType.PLAIN_TEXT.getValue(), signatureStep.getFieldType()); + } + + @Test + void testGetSigningService() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("echosign", signatureStep.getSigningService()); + } + + @Test + void testGetSigningServiceDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertEquals(SignatureStepImpl.DEFAULT_SIGNING_SERVICE, signatureStep.getSigningService()); + } + + @Test + void testGetDisplayMsg() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("Please sign the document", signatureStep.getDisplayMsg()); + } + + @Test + void testGetDisplayMsgDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertNull(signatureStep.getDisplayMsg()); + } + + @Test + void testGetCloudServiceConfig() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("/etc/cloudservices/echosign/myConfig", signatureStep.getCloudServiceConfig()); + } + + @Test + void testGetCloudServiceConfigDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertEquals("", signatureStep.getCloudServiceConfig()); + } + + @Test + void testGetTargetVersion() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("1.0", signatureStep.getTargetVersion()); + } + + @Test + void testGetTargetVersionDefault() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + assertNull(signatureStep.getTargetVersion()); + } + + @Test + void testGetProperties() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + Map properties = signatureStep.getProperties(); + assertNotNull(properties); + assertEquals("echosign", properties.get("fd:signingService")); + assertEquals("/etc/cloudservices/echosign/myConfig", properties.get("fd:cloudServiceConfig")); + assertEquals("Please sign the document", properties.get("fd:displayMsg")); + assertEquals("1.0", properties.get("fd:targetVersion")); + assertEquals(APPS_ROOT + "/signaturestep", properties.get("fd:path")); + } + + @Test + void testGetPropertiesDefaults() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP_DEFAULTS, SignatureStepImpl.class, context); + Map properties = signatureStep.getProperties(); + assertNotNull(properties); + assertEquals(SignatureStepImpl.DEFAULT_SIGNING_SERVICE, properties.get("fd:signingService")); + assertFalse(properties.containsKey("fd:cloudServiceConfig")); + assertFalse(properties.containsKey("fd:displayMsg")); + assertFalse(properties.containsKey("fd:targetVersion")); + } + + @Test + void testGetExportedType() { + SignatureStep signatureStep = Utils.getComponentUnderTest(PATH_SIGNATURE_STEP, SignatureStepImpl.class, context); + assertEquals("core/fd/components/form/signaturestep/v1/signaturestep", signatureStep.getExportedType()); + } +} diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java new file mode 100644 index 0000000000..02fa701bfc --- /dev/null +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/SummaryStepImplTest.java @@ -0,0 +1,108 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2024 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.adobe.cq.forms.core.Utils; +import com.adobe.cq.forms.core.components.models.form.FieldType; +import com.adobe.cq.forms.core.components.models.form.SummaryStep; +import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(AemContextExtension.class) +public class SummaryStepImplTest { + + private static final String TEST_BASE = "/form/summarystep"; + private static final String APPS_ROOT = "/apps"; + private static final String PATH_SUMMARY_STEP = APPS_ROOT + "/summarystep"; + private static final String PATH_SUMMARY_STEP_DEFAULTS = APPS_ROOT + "/summarystep-defaults"; + + private final AemContext context = FormsCoreComponentTestContext.newAemContext(); + + @BeforeEach + void setUp() { + context.load().json(TEST_BASE + FormsCoreComponentTestContext.TEST_CONTENT_JSON, APPS_ROOT); + } + + @Test + void testGetFieldType() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertEquals(FieldType.PLAIN_TEXT.getValue(), summaryStep.getFieldType()); + } + + @Test + void testGetFieldTypeOnNewInstance() { + SummaryStep summaryStep = new SummaryStepImpl(); + assertEquals(FieldType.PLAIN_TEXT.getValue(), summaryStep.getFieldType()); + } + + @Test + void testGetDisplayMsg() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertEquals("

Thank you for submitting the form.

", summaryStep.getDisplayMsg()); + } + + @Test + void testGetDisplayMsgDefault() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP_DEFAULTS, SummaryStepImpl.class, context); + assertNull(summaryStep.getDisplayMsg()); + } + + @Test + void testIsAutoSubmit() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertTrue(summaryStep.isAutoSubmit()); + } + + @Test + void testIsAutoSubmitDefault() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP_DEFAULTS, SummaryStepImpl.class, context); + assertFalse(summaryStep.isAutoSubmit()); + } + + @Test + void testGetProperties() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + Map properties = summaryStep.getProperties(); + assertNotNull(properties); + assertEquals("

Thank you for submitting the form.

", properties.get("fd:displayMsg")); + assertEquals(true, properties.get("fd:autoSubmit")); + assertEquals(APPS_ROOT + "/summarystep", properties.get("fd:path")); + } + + @Test + void testGetPropertiesDefaults() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP_DEFAULTS, SummaryStepImpl.class, context); + Map properties = summaryStep.getProperties(); + assertNotNull(properties); + assertFalse(properties.containsKey("fd:displayMsg")); + assertEquals(false, properties.get("fd:autoSubmit")); + } + + @Test + void testGetExportedType() { + SummaryStep summaryStep = Utils.getComponentUnderTest(PATH_SUMMARY_STEP, SummaryStepImpl.class, context); + assertEquals("core/fd/components/form/summarystep/v1/summarystep", summaryStep.getExportedType()); + } +} diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java index 43b2d53428..ca68999abb 100644 --- a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v2/form/FormContainerImplTest.java @@ -117,6 +117,8 @@ public class FormContainerImplTest { private static final String SS_SPREADSHEET = "spreadsheet"; private static final String PATH_FORM_EXCLUDE_FROM_DOR_IF_HIDDEN = "/content/forms/af/demo/jcr:content/formcontainerv2-excludeFromDoRIfHidden"; + private static final String PATH_FORM_WITH_ADOBE_SIGN = CONTENT_ROOT + "/formcontainerv2WithAdobeSign"; + private static final String PATH_FORM_WITH_ADOBE_SIGN_NO_FIRST_SIGNER = CONTENT_ROOT + "/formcontainerv2WithAdobeSignNoFirstSigner"; private final AemContext context = FormsCoreComponentTestContext.newAemContext(); @@ -917,4 +919,53 @@ void testSetLang() throws Exception { formContainer.setLang(null); assertEquals(formContainer.getLang(), "en"); } + + @Test + void testIsAdobeSignEnabled() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN, FormContainer.class, context); + assertTrue(formContainer.isAdobeSignEnabled()); + } + + @Test + void testIsAdobeSignEnabledDefault() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context); + assertFalse(formContainer.isAdobeSignEnabled()); + } + + @Test + void testIsFormFillerFirstSigner() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN, FormContainer.class, context); + assertTrue(formContainer.isFormFillerFirstSigner()); + } + + @Test + void testIsFormFillerFirstSignerDefault() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context); + assertFalse(formContainer.isFormFillerFirstSigner()); + } + + @Test + void testIsFormFillerFirstSignerWhenFalse() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN_NO_FIRST_SIGNER, FormContainer.class, context); + assertTrue(formContainer.isAdobeSignEnabled()); + assertFalse(formContainer.isFormFillerFirstSigner()); + } + + @Test + void testGetPropertiesWithAdobeSign() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_WITH_ADOBE_SIGN, FormContainer.class, context); + Map properties = formContainer.getProperties(); + assertNotNull(properties); + assertTrue((Boolean) properties.get("fd:useSignedPdf")); + assertTrue((Boolean) properties.get("fd:isFormFillerFirstSigner")); + } + + @Test + void testGetPropertiesWithoutAdobeSign() throws Exception { + FormContainer formContainer = Utils.getComponentUnderTest(PATH_FORM_1, FormContainer.class, context); + Map properties = formContainer.getProperties(); + assertNotNull(properties); + assertFalse(properties.containsKey("fd:useSignedPdf")); + assertFalse(properties.containsKey("fd:isFormFillerFirstSigner")); + } } diff --git a/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json b/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json index 7a9ca98bf2..5bcfc1612b 100644 --- a/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json +++ b/bundles/af-core/src/test/resources/form/formcontainer/test-page-content.json @@ -210,6 +210,26 @@ "visible": false }, "actionType": "fd/af/components/guidesubmittype/rest" + }, + "formcontainerv2WithAdobeSign": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/container/v2/container", + "fieldType": "form", + "_useSignedPdf": true, + "signerInfo": { + "jcr:primaryType": "nt:unstructured", + "firstSignerFormFiller": true + } + }, + "formcontainerv2WithAdobeSignNoFirstSigner": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/container/v2/container", + "fieldType": "form", + "_useSignedPdf": true, + "signerInfo": { + "jcr:primaryType": "nt:unstructured", + "firstSignerFormFiller": false + } } } } diff --git a/bundles/af-core/src/test/resources/form/signaturestep/test-content.json b/bundles/af-core/src/test/resources/form/signaturestep/test-content.json new file mode 100644 index 0000000000..e16ef24ee7 --- /dev/null +++ b/bundles/af-core/src/test/resources/form/signaturestep/test-content.json @@ -0,0 +1,22 @@ +{ + "signaturestep": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Signature Step", + "id": "signaturestep-test", + "name": "signaturestep1", + "fieldType": "plain-text", + "signingService": "echosign", + "displayMsg": "Please sign the document", + "cq:cloudserviceconfigs": "/etc/cloudservices/echosign/myConfig", + "fd:targetVersion": "1.0", + "sling:resourceType": "core/fd/components/form/signaturestep/v1/signaturestep" + }, + "signaturestep-defaults": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Signature Step Defaults", + "id": "signaturestep-defaults-test", + "name": "signaturestepDefaults", + "fieldType": "plain-text", + "sling:resourceType": "core/fd/components/form/signaturestep/v1/signaturestep" + } +} diff --git a/bundles/af-core/src/test/resources/form/summarystep/test-content.json b/bundles/af-core/src/test/resources/form/summarystep/test-content.json new file mode 100644 index 0000000000..e53063e967 --- /dev/null +++ b/bundles/af-core/src/test/resources/form/summarystep/test-content.json @@ -0,0 +1,20 @@ +{ + "summarystep": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Summary Step", + "id": "summarystep-test", + "name": "summarystep1", + "fieldType": "plain-text", + "displayMsg": "

Thank you for submitting the form.

", + "autoSubmit": true, + "sling:resourceType": "core/fd/components/form/summarystep/v1/summarystep" + }, + "summarystep-defaults": { + "jcr:primaryType": "nt:unstructured", + "jcr:title": "Summary Step Defaults", + "id": "summarystep-defaults-test", + "name": "summarystepDefaults", + "fieldType": "plain-text", + "sling:resourceType": "core/fd/components/form/summarystep/v1/summarystep" + } +} diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml new file mode 100644 index 0000000000..3014749074 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/.content.xml @@ -0,0 +1,7 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml new file mode 100644 index 0000000000..45edf9ec5f --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/signaturestep/_cq_template.xml @@ -0,0 +1,9 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml new file mode 100644 index 0000000000..ccfce437c5 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/.content.xml @@ -0,0 +1,7 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml new file mode 100644 index 0000000000..2bb7f769e9 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/summarystep/_cq_template.xml @@ -0,0 +1,7 @@ + + diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml new file mode 100644 index 0000000000..bbf62ed22c --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/signaturestep/.content.xml @@ -0,0 +1,5 @@ + +