Skip to content

Commit e1a8a1c

Browse files
authored
Merge pull request #3164 from ilandikov/refactor-test-date-editor
refactor: test `DateEditor` svelte component
2 parents 48ed4b2 + c59ebdc commit e1a8a1c

File tree

5 files changed

+175
-23
lines changed

5 files changed

+175
-23
lines changed

src/ui/DateEditor.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
export let forwardOnly: boolean;
1111
export let accesskey: string | null;
1212
13-
let parsedDate: string;
13+
// Use this for testing purposes only
14+
export let parsedDate: string = '';
1415
// let inputElement: HTMLInputElement;
1516
// let flatpickrInstance: any;
1617
//

tests/ui/DateEditor.test.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
import { fireEvent, render } from '@testing-library/svelte';
5+
import moment from 'moment/moment';
6+
import DateEditorWrapper from './DateEditorWrapper.svelte';
7+
8+
import { getAndCheckRenderedElement } from './RenderingTestHelpers';
9+
10+
window.moment = moment;
11+
12+
function renderDateEditorWrapper(componentOptions: { forwardOnly: boolean }) {
13+
const { container } = render(DateEditorWrapper, componentOptions);
14+
15+
expect(() => container).toBeTruthy();
16+
17+
return container;
18+
}
19+
20+
function testInputValue(container: HTMLElement, inputId: string, expectedText: string) {
21+
const input = getAndCheckRenderedElement<HTMLInputElement>(container, inputId);
22+
expect(input.value).toEqual(expectedText);
23+
}
24+
25+
async function testTypingInput(
26+
{
27+
userTyped,
28+
expectedLeftText,
29+
expectedRightText,
30+
expectedReturnedDate,
31+
}: {
32+
userTyped: string;
33+
expectedLeftText: string;
34+
expectedRightText: string;
35+
expectedReturnedDate: string;
36+
},
37+
{ forwardOnly }: { forwardOnly: boolean } = { forwardOnly: true },
38+
) {
39+
const container = renderDateEditorWrapper({ forwardOnly });
40+
41+
const dueDateInput = getAndCheckRenderedElement<HTMLInputElement>(container, 'due');
42+
await fireEvent.input(dueDateInput, { target: { value: userTyped } });
43+
44+
testInputValue(container, 'due', expectedLeftText);
45+
testInputValue(container, 'parsedDateFromDateEditor', expectedRightText);
46+
testInputValue(container, 'dueDateFromDateEditor', expectedReturnedDate);
47+
}
48+
49+
beforeEach(() => {
50+
jest.useFakeTimers();
51+
jest.setSystemTime(new Date('2024-04-20'));
52+
});
53+
54+
afterEach(() => {
55+
jest.useRealTimers();
56+
});
57+
58+
describe('date editor wrapper tests', () => {
59+
it('should initialise fields correctly', () => {
60+
const container = renderDateEditorWrapper({ forwardOnly: true });
61+
62+
testInputValue(container, 'due', '');
63+
testInputValue(container, 'parsedDateFromDateEditor', '<i>no due date</i>');
64+
testInputValue(container, 'dueDateFromDateEditor', '');
65+
});
66+
67+
it('should replace an empty date field with typed date value', async () => {
68+
await testTypingInput({
69+
userTyped: '2024-10-01',
70+
expectedLeftText: '2024-10-01',
71+
expectedRightText: '2024-10-01',
72+
expectedReturnedDate: '2024-10-01',
73+
});
74+
});
75+
76+
it('should replace an empty date field with typed abbreviation', async () => {
77+
await testTypingInput({
78+
userTyped: 'tm ',
79+
expectedLeftText: 'tomorrow',
80+
expectedRightText: '2024-04-21',
81+
expectedReturnedDate: 'tomorrow',
82+
});
83+
});
84+
85+
it('should show an error message for invalid date', async () => {
86+
await testTypingInput({
87+
userTyped: 'blah',
88+
expectedLeftText: 'blah',
89+
expectedRightText: '<i>invalid due date</i>',
90+
expectedReturnedDate: 'blah',
91+
});
92+
});
93+
94+
it('should select a forward date', async () => {
95+
await testTypingInput(
96+
{
97+
userTyped: 'friday',
98+
expectedLeftText: 'friday',
99+
expectedRightText: '2024-04-26',
100+
expectedReturnedDate: 'friday',
101+
},
102+
{ forwardOnly: true },
103+
);
104+
});
105+
106+
it('should select a backward/earlier date', async () => {
107+
await testTypingInput(
108+
{
109+
userTyped: 'friday',
110+
expectedLeftText: 'friday',
111+
expectedRightText: '2024-04-19',
112+
expectedReturnedDate: 'friday',
113+
},
114+
{ forwardOnly: false },
115+
);
116+
});
117+
});

tests/ui/DateEditorWrapper.svelte

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script lang="ts">
2+
import { TASK_FORMATS } from '../../src/Config/Settings';
3+
import DateEditor from '../../src/ui/DateEditor.svelte';
4+
5+
export let forwardOnly: boolean;
6+
7+
let dateFromDateEditor: string = '';
8+
let parsedDateFromDateEditor: string = '';
9+
let isDueDateValid = true;
10+
</script>
11+
12+
<DateEditor
13+
id="due"
14+
dateSymbol={TASK_FORMATS.tasksPluginEmoji.taskSerializer.symbols.dueDateSymbol}
15+
bind:date={dateFromDateEditor}
16+
bind:isDateValid={isDueDateValid}
17+
{forwardOnly}
18+
accesskey={null}
19+
on:open={() => {}}
20+
on:close={() => {}}
21+
bind:parsedDate={parsedDateFromDateEditor}
22+
/>
23+
<input bind:value={dateFromDateEditor} id="dueDateFromDateEditor" />
24+
<input bind:value={parsedDateFromDateEditor} id="parsedDateFromDateEditor" />
25+
26+
<style>
27+
</style>

tests/ui/EditTask.test.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ import { verifyWithFileExtension } from '../TestingTools/ApprovalTestHelpers';
1414
import { verifyAllCombinations3Async } from '../TestingTools/CombinationApprovalsAsync';
1515
import { prettifyHTML } from '../TestingTools/HTMLHelpers';
1616
import { TaskBuilder } from '../TestingTools/TaskBuilder';
17+
import {
18+
getAndCheckApplyButton,
19+
getAndCheckRenderedDescriptionElement,
20+
getAndCheckRenderedElement,
21+
} from './RenderingTestHelpers';
1722

1823
window.moment = moment;
1924
/**
@@ -50,28 +55,6 @@ function renderAndCheckModal(task: Task, onSubmit: (updatedTasks: Task[]) => voi
5055
return { result, container };
5156
}
5257

53-
/**
54-
* Find the element with the given id.
55-
* Template type T might be, for example, HTMLInputElement or HTMLSelectElement
56-
* @param container
57-
* @param elementId
58-
*/
59-
function getAndCheckRenderedElement<T>(container: HTMLElement, elementId: string) {
60-
const element = container.ownerDocument.getElementById(elementId) as T;
61-
expect(() => element).toBeTruthy();
62-
return element;
63-
}
64-
65-
function getAndCheckRenderedDescriptionElement(container: HTMLElement): HTMLInputElement {
66-
return getAndCheckRenderedElement<HTMLInputElement>(container, 'description');
67-
}
68-
69-
function getAndCheckApplyButton(result: RenderResult<EditTask>): HTMLButtonElement {
70-
const submit = result.getByText('Apply') as HTMLButtonElement;
71-
expect(submit).toBeTruthy();
72-
return submit;
73-
}
74-
7558
async function editInputElement(inputElement: HTMLInputElement, newValue: string) {
7659
await fireEvent.input(inputElement, { target: { value: newValue } });
7760
}

tests/ui/RenderingTestHelpers.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { RenderResult } from '@testing-library/svelte';
2+
import type EditTask from '../../src/ui/EditTask.svelte';
3+
4+
/**
5+
* Find the element with the given id.
6+
* Template type T might be, for example, HTMLInputElement or HTMLSelectElement
7+
* @param container
8+
* @param elementId
9+
*/
10+
export function getAndCheckRenderedElement<T>(container: HTMLElement, elementId: string) {
11+
const element = container.ownerDocument.getElementById(elementId) as T;
12+
expect(() => element).toBeTruthy();
13+
return element;
14+
}
15+
16+
export function getAndCheckRenderedDescriptionElement(container: HTMLElement): HTMLInputElement {
17+
return getAndCheckRenderedElement<HTMLInputElement>(container, 'description');
18+
}
19+
20+
export function getAndCheckApplyButton(result: RenderResult<EditTask>): HTMLButtonElement {
21+
const submit = result.getByText('Apply') as HTMLButtonElement;
22+
expect(submit).toBeTruthy();
23+
return submit;
24+
}

0 commit comments

Comments
 (0)