diff options
author | Anastasia Smirnova <anasmi@utu.fi> | 2018-04-16 10:26:15 +0300 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2018-04-16 10:26:15 +0300 |
commit | 4dec38e73d23e09d193bec02fbd1ce8629098578 (patch) | |
tree | c4ab1044f9b311cc109005029f0c4c3e793533eb | |
parent | 564fa8faf4391b7089369acf8b7f55602bf167f3 (diff) | |
download | vaadin-framework-4dec38e73d23e09d193bec02fbd1ce8629098578.tar.gz vaadin-framework-4dec38e73d23e09d193bec02fbd1ce8629098578.zip |
Handle UnparsableDateString correctly (#10803)
Resolves #10681
3 files changed, 135 insertions, 1 deletions
diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java index 19b628b1f2..a4677e6ec3 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java @@ -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 index 0000000000..c6147cda79 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateString.java @@ -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 index 0000000000..3f5b756785 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateStringTest.java @@ -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); + } +} |