]> source.dussan.org Git - vaadin-framework.git/commitdiff
Handle UnparsableDateString correctly (#10803)
authorAnastasia Smirnova <anasmi@utu.fi>
Mon, 16 Apr 2018 07:26:15 +0000 (10:26 +0300)
committerIlia Motornyi <elmot@vaadin.com>
Mon, 16 Apr 2018 07:26:15 +0000 (10:26 +0300)
Resolves #10681

server/src/main/java/com/vaadin/ui/AbstractDateField.java
uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateString.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateStringTest.java [new file with mode: 0644]

index 19b628b1f2281f5e921f0826c10fc93fff60b20e..a4677e6ec33aa6a11b14334eec3770ae364a8a3b 100644 (file)
@@ -38,6 +38,7 @@ import java.util.logging.Logger;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import elemental.json.Json;
 import org.jsoup.nodes.Element;
 
 import com.googlecode.gentyref.GenericTypeReflector;
@@ -119,7 +120,17 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
                         if (resolutions.isEmpty()) {
                             Result<T> parsedDate = handleUnparsableDateString(
                                     dateString);
-                            parsedDate.ifOk(v -> setValue(v, true));
+                            // If handleUnparsableDateString returns the same
+                            // date as current, force update state to display
+                            // correct representation
+                            parsedDate.ifOk(v -> {
+                                if (!setValue(v, true)
+                                        && !isDifferentValue(v)) {
+                                    updateDiffstate("resolutions",
+                                            Json.createObject());
+                                    doSetValue(v);
+                                }
+                            });
                             if (parsedDate.isError()) {
                                 dateString = null;
                                 currentParseErrorMessage = parsedDate
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateString.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateString.java
new file mode 100644 (file)
index 0000000..c6147cd
--- /dev/null
@@ -0,0 +1,83 @@
+package com.vaadin.tests.components.datefield;
+
+import com.vaadin.data.Result;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.DateField;
+import org.apache.commons.lang3.StringUtils;
+
+import java.time.LocalDate;
+import java.time.Year;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+
+public class DateFieldUnparsableDateString extends AbstractTestUI {
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 10681;
+    }
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        DateField dateField1 = new ParsableDateField();
+        dateField1.setDateFormat("dd.MM.yyyy");
+        addComponent(dateField1);
+    }
+
+    public class ParsableDateField extends DateField {
+
+        @Override
+        protected Result<LocalDate> handleUnparsableDateString(
+                String dateString) {
+            try {
+                String parseableString = StringUtils.remove(dateString, ' ');
+                if (parseableString.length() % 2 == 1) {
+                    parseableString = "0" + parseableString;
+                }
+                int cutYear = Year.now().getValue() - 80;
+                LocalDate today = LocalDate.now();
+
+                switch (parseableString.length()) {
+                case 2:
+                    // Only day !!! dd
+                    return Result.ok(LocalDate.parse(parseableString,
+                            new DateTimeFormatterBuilder().appendPattern("dd")
+                                    .parseDefaulting(ChronoField.MONTH_OF_YEAR,
+                                            today.getMonthValue())
+                                    .parseDefaulting(ChronoField.YEAR,
+                                            today.getYear())
+                                    .toFormatter()));
+                case 4:
+                    // Only day + month ddMM
+                    return Result
+                            .ok(LocalDate.parse(parseableString,
+                                    new DateTimeFormatterBuilder()
+                                            .appendPattern("ddMM")
+                                            .parseDefaulting(ChronoField.YEAR,
+                                                    today.getYear())
+                                            .toFormatter()));
+                case 6:
+                    // Short year ddMMyy
+                    return Result.ok(LocalDate.parse(parseableString,
+                            new DateTimeFormatterBuilder().appendPattern("ddMM")
+                                    .appendValueReduced(ChronoField.YEAR, 2, 2,
+                                            cutYear)
+                                    .toFormatter()));
+                case 8:
+                    // Long year ddMMyyyy
+                    parseableString = StringUtils.leftPad(dateString, 8, "0");
+                    return Result
+                            .ok(LocalDate.parse(parseableString,
+                                    new DateTimeFormatterBuilder()
+                                            .appendPattern("ddMMyyyy")
+                                            .toFormatter()));
+                default:
+                    break;
+                }
+            } catch (Exception e) {
+            }
+            return super.handleUnparsableDateString(dateString);
+        }
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateStringTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateStringTest.java
new file mode 100644 (file)
index 0000000..3f5b756
--- /dev/null
@@ -0,0 +1,40 @@
+package com.vaadin.tests.components.datefield;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.AbstractDateFieldElement;
+import com.vaadin.testbench.parallel.Browser;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class DateFieldUnparsableDateStringTest extends MultiBrowserTest {
+
+    @Test
+    public void testInvalidText() throws InterruptedException {
+        openTestURL();
+        waitForElementVisible(By.className("v-datefield"));
+        WebElement dateTextbox = $(AbstractDateFieldElement.class).first()
+                .findElement(By.className("v-textfield"));
+        dateTextbox.sendKeys("0304", Keys.ENTER);
+        findElement(By.tagName("body")).click();
+        assertEquals("03.04.2018", dateTextbox.getAttribute("value"));
+
+        dateTextbox.clear();
+        dateTextbox.sendKeys("0304", Keys.ENTER);
+        findElement(By.tagName("body")).click();
+        assertEquals("03.04.2018", dateTextbox.getAttribute("value"));
+    }
+
+    @Override
+    public List<DesiredCapabilities> getBrowsersToTest() {
+        // Ignoring Phantom JS
+        return getBrowserCapabilities(Browser.IE11, Browser.FIREFOX,
+                Browser.CHROME);
+    }
+}