fix(localize): don't set modelValue to unparseable if date has a negative timezone
Co-authored-by: Danny Moerkerke<Danny.Moerkerke@ing.com>
This commit is contained in:
parent
a47a6e615b
commit
13185da02a
5 changed files with 112 additions and 45 deletions
5
.changeset/clever-parrots-sniff.md
Normal file
5
.changeset/clever-parrots-sniff.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/ui': patch
|
||||
---
|
||||
|
||||
don't set unparseable for negative timezones
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import { expect } from '@open-wc/testing';
|
||||
import { localize } from '@lion/ui/localize.js';
|
||||
import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
|
||||
import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
|
||||
|
||||
import { formatAmount } from '@lion/ui/input-amount.js';
|
||||
|
||||
describe('formatAmount()', () => {
|
||||
const localizeManager = getLocalizeManager();
|
||||
|
||||
afterEach(() => {
|
||||
localizeTearDown();
|
||||
});
|
||||
|
|
@ -67,9 +69,9 @@ describe('formatAmount()', () => {
|
|||
});
|
||||
|
||||
it('fallbacks to global locale and EUR by default', async () => {
|
||||
localize.locale = 'en-GB';
|
||||
localizeManager.locale = 'en-GB';
|
||||
expect(formatAmount(12345678)).to.equal('12,345,678.00');
|
||||
localize.locale = 'nl-NL';
|
||||
localizeManager.locale = 'nl-NL';
|
||||
expect(formatAmount(12345678)).to.equal('12.345.678,00');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { html } from 'lit';
|
||||
import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
|
||||
import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
|
||||
import { MaxDate } from '@lion/ui/form-core.js';
|
||||
import { MinDate, MaxDate } from '@lion/ui/form-core.js';
|
||||
import { expect, fixture as _fixture } from '@open-wc/testing';
|
||||
import { getInputMembers } from '@lion/ui/input-test-helpers.js';
|
||||
import '@lion/ui/define/lion-input-date.js';
|
||||
|
|
@ -67,49 +67,95 @@ describe('<lion-input-date>', () => {
|
|||
expect(el.validationStates.error).not.to.have.property('MaxDate');
|
||||
});
|
||||
|
||||
it('uses formatOptions.locale', async () => {
|
||||
const el = await fixture(html`
|
||||
<lion-input-date
|
||||
.formatOptions="${{ locale: 'en-GB' }}"
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017');
|
||||
describe('locale', () => {
|
||||
it('uses formatOptions.locale', async () => {
|
||||
const el = await fixture(html`
|
||||
<lion-input-date
|
||||
.formatOptions="${{ locale: 'en-GB' }}"
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017');
|
||||
|
||||
const el2 = await fixture(html`
|
||||
<lion-input-date
|
||||
.formatOptions="${{ locale: 'en-US' }}"
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el2.formattedValue).to.equal('06/15/2017');
|
||||
const el2 = await fixture(html`
|
||||
<lion-input-date
|
||||
.formatOptions="${{ locale: 'en-US' }}"
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el2.formattedValue).to.equal('06/15/2017');
|
||||
});
|
||||
|
||||
it('uses global locale when formatOptions.locale is not defined', async () => {
|
||||
localizeManager.locale = 'fr-FR';
|
||||
const el = await fixture(html`
|
||||
<lion-input-date .modelValue=${new Date('2017/06/15')}></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017');
|
||||
|
||||
localizeManager.locale = 'en-US';
|
||||
const el2 = await fixture(html`
|
||||
<lion-input-date .modelValue=${new Date('2017/06/15')}></lion-input-date>
|
||||
`);
|
||||
expect(el2.formattedValue).to.equal('06/15/2017');
|
||||
});
|
||||
|
||||
it('ignores global locale change if formatOptions.locale is provided', async () => {
|
||||
const el = await fixture(html`
|
||||
<lion-input-date
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
.formatOptions="${{ locale: 'en-GB' }}"
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017'); // british
|
||||
localizeManager.locale = 'en-US';
|
||||
await el.updateComplete;
|
||||
expect(el.formattedValue).to.equal('15/06/2017'); // should stay british
|
||||
});
|
||||
});
|
||||
|
||||
it('uses global locale when formatOptions.locale is not defined', async () => {
|
||||
localizeManager.locale = 'fr-FR';
|
||||
const el = await fixture(html`
|
||||
<lion-input-date .modelValue=${new Date('2017/06/15')}></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017');
|
||||
describe('timezones', async () => {
|
||||
const dateAmsterdam = new Date(
|
||||
new Date('2017/06/15').toLocaleString('en-US', { timeZone: 'Europe/Amsterdam' }),
|
||||
);
|
||||
const dateManila = new Date(
|
||||
new Date('2017/06/15').toLocaleString('en-US', { timeZone: 'Asia/Manila' }),
|
||||
);
|
||||
const dateNewYork = new Date(
|
||||
new Date('2017/06/15').toLocaleString('en-US', { timeZone: 'America/New_York' }),
|
||||
);
|
||||
|
||||
localizeManager.locale = 'en-US';
|
||||
const el2 = await fixture(html`
|
||||
<lion-input-date .modelValue=${new Date('2017/06/15')}></lion-input-date>
|
||||
`);
|
||||
expect(el2.formattedValue).to.equal('06/15/2017');
|
||||
});
|
||||
it('works with different timezones', async () => {
|
||||
const el = await fixture(html`
|
||||
<lion-input-date .modelValue=${dateAmsterdam}></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017', 'Europe/Amsterdam');
|
||||
|
||||
it('ignores global locale change if formatOptions.locale is provided', async () => {
|
||||
const el = await fixture(html`
|
||||
<lion-input-date
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
.formatOptions="${{ locale: 'en-GB' }}"
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017'); // british
|
||||
localizeManager.locale = 'en-US';
|
||||
await el.updateComplete;
|
||||
expect(el.formattedValue).to.equal('15/06/2017'); // should stay british
|
||||
el.modelValue = dateManila;
|
||||
expect(el.formattedValue).to.equal('15/06/2017', 'Asia/Manila');
|
||||
|
||||
el.modelValue = dateNewYork;
|
||||
expect(el.formattedValue).to.equal('14/06/2017', 'America/New_York');
|
||||
});
|
||||
|
||||
it('validators work with different timezones', async () => {
|
||||
const el = await fixture(html`
|
||||
<lion-input-date
|
||||
.modelValue=${new Date('2017/06/15')}
|
||||
.validators=${[new MinDate(new Date('2017/06/14'))]}
|
||||
></lion-input-date>
|
||||
`);
|
||||
expect(el.formattedValue).to.equal('15/06/2017', 'Europe/Amsterdam');
|
||||
expect(el.hasFeedbackFor).not.to.include('error', 'Europe/Amsterdam');
|
||||
|
||||
el.modelValue = dateManila;
|
||||
expect(el.formattedValue).to.equal('15/06/2017', 'Asia/Manila');
|
||||
expect(el.hasFeedbackFor).not.to.include('error', 'Asia/Manila');
|
||||
|
||||
el.modelValue = dateNewYork;
|
||||
expect(el.formattedValue).to.equal('14/06/2017', 'America/New_York');
|
||||
expect(el.hasFeedbackFor).not.to.include('error', 'America/New_York');
|
||||
});
|
||||
});
|
||||
|
||||
it('is accessible', async () => {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export function parseDate(dateString) {
|
|||
}
|
||||
|
||||
const [year, month, day] = parsedString.split('/').map(Number);
|
||||
const parsedDate = new Date(Date.UTC(year, month - 1, day));
|
||||
const parsedDate = new Date(new Date(year, month - 1, day));
|
||||
|
||||
// Check if parsedDate is not `Invalid Date` or that the date has changed (e.g. the not existing 31.02.2020)
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
|
|||
/**
|
||||
*
|
||||
* @param {Date | undefined} value
|
||||
* @param {Date} date
|
||||
* @param {Date | undefined} date
|
||||
*/
|
||||
function equalsDate(value, date) {
|
||||
return (
|
||||
Object.prototype.toString.call(value) === '[object Date]' && // is Date Object
|
||||
value &&
|
||||
value.getDate() === date.getDate() && // day
|
||||
value.getDate() === date?.getDate() && // day
|
||||
value.getMonth() === date.getMonth() && // month
|
||||
value.getFullYear() === date.getFullYear() // year
|
||||
);
|
||||
|
|
@ -52,6 +52,20 @@ describe('parseDate()', () => {
|
|||
expect(equalsDate(parseDate('12-31-1976'), new Date('1976/12/31'))).to.equal(true);
|
||||
});
|
||||
|
||||
it('handles timezones of the browser and parsed date correctly', () => {
|
||||
const referenceDate = new Date('2020/01/30');
|
||||
localizeManager.locale = 'nl-NL';
|
||||
const parsedDate = parseDate('30-01-2020');
|
||||
// time zone offset of parsed date: this value is dependent on the browser (basically where the ci or local machine it runs in is located)
|
||||
const parseDateOffset = parsedDate?.getTimezoneOffset();
|
||||
// The parseDate time zone should be equal to the default offset of the browser
|
||||
const browserTimeZoneOffset = referenceDate.getTimezoneOffset();
|
||||
// This will pass, since parseDate respects browser timezone, and not UTC format
|
||||
expect(parseDateOffset).to.equal(browserTimeZoneOffset);
|
||||
// Optional: verify we are dealing with the same date (this is already tested in other tests?)
|
||||
expect(equalsDate(referenceDate, parsedDate)).to.be.true;
|
||||
});
|
||||
|
||||
it('return undefined when no valid date provided', () => {
|
||||
expect(parseDate('12.12.1976.,')).to.equal(undefined); // wrong delimiter
|
||||
expect(parseDate('foo')).to.equal(undefined); // no date
|
||||
|
|
|
|||
Loading…
Reference in a new issue