Skip to content

Commit

Permalink
Merge pull request #292 from symphony-mariacristina/MML-291
Browse files Browse the repository at this point in the history
MML-291 Add multi-submit attribute to form element

Goal of this PR is to add a new attribute to the form element called "multi-submit". This attribute accepts only two values depending if the user wants to reset or not the previous submit input. More info on this are available here: #291.
Also a new BI item has been introduce to track usage of multi-submit forms.
  • Loading branch information
symphony-mariacristina authored Jul 22, 2021
2 parents daebdca + 2d5b32e commit 226e2b6
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public enum BiFields {
TYPE_MASKED_TRUE("masked", BiEventType.MESSAGEML_ELEMENT_SENT),
TYPE_MASKED_FALSE("normal", BiEventType.MESSAGEML_ELEMENT_SENT),
ENTITY_TYPE("entity_type", BiEventType.MESSAGEML_ELEMENT_SENT),
MULTI_SUBMIT("is_multi_submit", BiEventType.MESSAGEML_ELEMENT_SENT),
LABEL("has_label", BiEventType.MESSAGEML_ELEMENT_SENT),
OPTIONS_COUNT("options_count", BiEventType.MESSAGEML_ELEMENT_SENT),
VALIDATION("validation", BiEventType.MESSAGEML_ELEMENT_SENT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@
import static org.symphonyoss.symphony.messageml.elements.Button.ACTION_TYPE;
import static org.symphonyoss.symphony.messageml.elements.FormElement.TYPE_ATTR;

import org.symphonyoss.symphony.messageml.MessageMLContext;
import org.symphonyoss.symphony.messageml.MessageMLParser;
import org.symphonyoss.symphony.messageml.bi.BiContext;
import org.symphonyoss.symphony.messageml.bi.BiFields;
import org.symphonyoss.symphony.messageml.bi.BiItem;
import org.symphonyoss.symphony.messageml.exceptions.InvalidInputException;
import org.symphonyoss.symphony.messageml.markdown.nodes.form.FormNode;
import org.symphonyoss.symphony.messageml.util.XmlPrintStream;
import org.w3c.dom.Node;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* Class representing a Symphony Elements form
Expand All @@ -26,9 +31,12 @@ public class Form extends Element {
public static final String MESSAGEML_TAG = "form";

private static final String ID_ATTR = "id";
private static final String MULTI_SUBMIT = "multi-submit";
private static final String PRESENTATIONML_MULTI_SUBMIT = "data-multi-submit";
private static final int MAX_COUNT_PER_CHILD_TYPE = 50;

private static final int MAX_LENGTH = 64;
private static final String ERR_MSG_MISSING_ACTION_BTN = "The form with id '%s' should have at least one action button";
private static final List<String> ALLOWED_MULTI_SUBMIT = Arrays.asList("reset", "no-reset");

public Form(Element parent, FormatEnum format) {
super(parent, MESSAGEML_TAG, format);
Expand All @@ -49,15 +57,21 @@ public void validate() throws InvalidInputException {
if (!getParent().getClass().equals(Dialog.class)) {
assertAtLeastOneActionButton();
}
if(getAttribute(MULTI_SUBMIT) != null) {
assertAttributeMaxLength(MULTI_SUBMIT, MAX_LENGTH);
assertAttributeValue(MULTI_SUBMIT, ALLOWED_MULTI_SUBMIT);
}
}

@Override
protected void buildAttribute(MessageMLParser parser,
Node item) throws InvalidInputException {
if (ID_ATTR.equals(item.getNodeName())) {
setAttribute(ID_ATTR, getStringAttribute(item));
} else {
throwInvalidInputException(item);
protected void buildAttribute(MessageMLParser parser, Node item) throws InvalidInputException {
switch (item.getNodeName()) {
case ID_ATTR:
case MULTI_SUBMIT:
setAttribute(item.getNodeName(), getStringAttribute(item));
break;
default:
throwInvalidInputException(item);
}
}

Expand All @@ -77,6 +91,26 @@ private void assertAtLeastOneActionButton() throws InvalidInputException {

@Override
void updateBiContext(BiContext context) {
context.addItem(new BiItem(BiFields.FORM.getValue(), new HashMap<>()));
Map<String, Object> formMap = new HashMap<>();
if(getAttribute(MULTI_SUBMIT) != null){
formMap.put(BiFields.MULTI_SUBMIT.getValue(), 1);
}
context.addItem(new BiItem(BiFields.FORM.getValue(), formMap));
}

@Override
void asPresentationML(XmlPrintStream out, MessageMLContext context) {
Map<String, String> presentationAttrs = new LinkedHashMap<>();
if (getAttribute(ID_ATTR) != null) {
presentationAttrs.put(ID_ATTR, getAttribute(ID_ATTR));
}
if (getAttribute(MULTI_SUBMIT) != null) {
presentationAttrs.put(PRESENTATIONML_MULTI_SUBMIT, getAttribute(MULTI_SUBMIT));
}
out.openElement(getPresentationMLTag(), presentationAttrs);
for (Element child : getChildren()) {
child.asPresentationML(out, context);
}
out.closeElement();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public String getAnnotation() {
*/
@Deprecated
public void setAnnotation(String name) {
this.annotation = annotation;
this.annotation = name;
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
package org.symphonyoss.symphony.messageml.elements.form;

import org.junit.Test;
import org.symphonyoss.symphony.messageml.bi.BiFields;
import org.symphonyoss.symphony.messageml.bi.BiItem;
import org.symphonyoss.symphony.messageml.elements.*;
import org.symphonyoss.symphony.messageml.exceptions.InvalidInputException;
import org.symphonyoss.symphony.messageml.exceptions.ProcessingException;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;

public class FormTest extends ElementTest {
private static final String ID_ATTR = "id";

private static final String MESSAGE_ML_WITH_MULTI_SUBMIT = "<messageML>"
+ "<form id=\"formID\" multi-submit=\"reset\">"
+ "<text-field name=\"name_01\" required=\"true\" placeholder=\"Name\"/>"
+ "<button name=\"submit_button\" type=\"action\">Submit</button>"
+ "</form>"
+ "</messageML>";

@Test
public void testEmptyForm() {
String id = "empty-form";
Expand All @@ -22,14 +38,14 @@ public void testEmptyForm() {
"The form with id 'empty-form' should have at least one action button", e.getMessage());
}
}

@Test
public void testFormWithoutId() throws Exception {
String input = "<messageML><form></form></messageML>";

expectedException.expect(InvalidInputException.class);
expectedException.expectMessage("The attribute \"id\" is required");

context.parseMessageML(input, null, MessageML.MESSAGEML_VERSION);
}

Expand Down Expand Up @@ -86,31 +102,11 @@ public void testMultipleFormsUsingSameId() throws Exception {
+ "</div></messageML>";

expectedException.expect(InvalidInputException.class);
expectedException.expectMessage("Elements must have unique ids. The following value is not unique: [" + notUniqueId + "].");
expectedException.expectMessage(
"Elements must have unique ids. The following value is not unique: [" + notUniqueId + "].");
context.parseMessageML(message, null, MessageML.MESSAGEML_VERSION);
}

private String getExpectedFormPresentationML(Form form) {
return "<div data-format=\"PresentationML\" data-version=\"2.0\"><form id=\"" +
form.getAttribute(ID_ATTR) + "\"></form></div>";
}

private void verifyFormPresentation(Form form, String id) {
assertEquals(id, form.getAttribute(ID_ATTR));
assertEquals(getExpectedFormPresentationML(form), context.getPresentationML());
}


private String getExpectedFormMarkdown() {
return String.format("Form (log into desktop client to answer):\n---\n\n---\n");
}

private void verifyFormMarkdown() {
String markdown = context.getMarkdown();
String expectedMarkdown = getExpectedFormMarkdown();
assertEquals(expectedMarkdown, markdown);
}

@Test
public void testWithMultipleDialogs() throws Exception {
String input = "<messageML>"
Expand Down Expand Up @@ -156,5 +152,46 @@ public void testWithMultipleDialogs() throws Exception {
assertTrue(presentationML.matches(expectedPattern));
}

@Test
public void testMultiSubmitReset() throws InvalidInputException, IOException, ProcessingException {
String expectedPresentationML = "<div data-format=\"PresentationML\" data-version=\"2.0\">"
+ "<form id=\"formID\" data-multi-submit=\"reset\">"
+ "<input type=\"text\" name=\"name_01\" placeholder=\"Name\" required=\"true\"/>"
+ "<button type=\"action\" name=\"submit_button\">Submit</button>"
+ "</form>"
+ "</div>";
context.parseMessageML(MESSAGE_ML_WITH_MULTI_SUBMIT, null, MessageML.MESSAGEML_VERSION);
assertEquals(context.getPresentationML(), expectedPresentationML);
}

@Test
public void testMultiSubmitNotAllowedValue() throws InvalidInputException, IOException, ProcessingException {
String messageML = "<messageML>"
+ "<form id=\"formID\" multi-submit=\"invalid_value\">"
+ "<text-field name=\"name_01\" required=\"true\" placeholder=\"Name\"/>"
+ "<button name=\"submit_button\" type=\"action\">Submit</button>"
+ "</form>"
+ "</messageML>";
expectedException.expect(InvalidInputException.class);
expectedException.expectMessage("Attribute \"multi-submit\" of element \"form\" can only be one "
+ "of the following values: [reset, no-reset].");
context.parseMessageML(messageML, null, MessageML.MESSAGEML_VERSION);

}

@Test
public void testBiContextWithMultiForm() throws InvalidInputException, IOException, ProcessingException {
context.parseMessageML(MESSAGE_ML_WITH_MULTI_SUBMIT, null, MessageML.MESSAGEML_VERSION);
Map<String, Object> textFieldMap = new HashMap<>();
textFieldMap.put(BiFields.PLACEHOLDER.getValue(), 1);
textFieldMap.put(BiFields.REQUIRED.getValue(), 1);
List<BiItem> expectedBiItems =
Arrays.asList(
new BiItem(BiFields.TEXT_FIELD.getValue(), textFieldMap),
new BiItem(BiFields.BUTTON.getValue(), Collections.singletonMap(BiFields.TYPE.getValue(), "action")),
new BiItem(BiFields.FORM.getValue(), Collections.singletonMap(BiFields.MULTI_SUBMIT.getValue(), 1)),
new BiItem(BiFields.MESSAGE_LENGTH.getValue(), Collections.singletonMap(BiFields.COUNT.getValue(), 190)));
List<BiItem> biItems = context.getBiContext().getItems();
assertIterableEquals(expectedBiItems, biItems);
}
}

0 comments on commit 226e2b6

Please sign in to comment.