Browse Source

Handle UnparsableDateString correctly (#10803)

Resolves #10681
tags/8.5.0.alpha1
Anastasia Smirnova 6 years ago
parent
commit
4dec38e73d

+ 12
- 1
server/src/main/java/com/vaadin/ui/AbstractDateField.java View 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

+ 83
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateString.java View File

@@ -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);
}
}
}

+ 40
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldUnparsableDateStringTest.java View File

@@ -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);
}
}

Loading…
Cancel
Save