Skip to content

Commit

Permalink
test: test postponed task and date creation (#2473)
Browse files Browse the repository at this point in the history
* test: - test createPostponedTask()

* test: - test TasksDate.postpone()

* test: . extract postponedDate variable

* test: . test TaskDate object to use the formatAsDate() method

* test: - fix test data to reflect the test meaning

* test: . extract expectedPostponedDate variable

* test: - add expectedDateField parameter to the helper

* test: . reorder helper's parameters for readability

* test: . inline variable

* test: - use the helper function in other tests

* test: add failing test for postponing tasks with inferred scheduled dates

* test: . Extract variables for constants in one test

Preparing to extract a helper function

* test: . Extract helper function checkDatePostponesTo()

* test: . Inline constants to make test behaviour clearer

* test: - Adjust tests to use helper function

* test: Confirm that advancing by 1 month works with shorter months

* test: Add some TODOs for future tests

* test: Show that postponing overdue tasks by > 1 day is unhelpful now.

* test: Add a test to visualise postponing by 1 week

* test: . Extract helper function postponeMultipleDatesBy()

* test: . Inline 'amount' and 'unitOfTime'; rename 'output' to indicate intent

* test: Fix the test name

* test: Visualise postponing by 1 day

* test: Move TODO to where needed

* test: Add failing test for postponing future date changing stored date

* test: - Extract function checkPostponingDoesNotModifyOriginalDate()

* test: . Inline variables

* test: Better coverage for checking postpone() does not modify date

---------

Co-authored-by: Clare Macrae <[email protected]>
  • Loading branch information
ilandikov and claremacrae authored Dec 7, 2023
1 parent f952634 commit 27f93ca
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 2 deletions.
53 changes: 51 additions & 2 deletions tests/Scripting/Postponer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
* @jest-environment jsdom
*/
import moment from 'moment';
import type { Task } from 'Task';
import {
type HappensDate,
createPostponedTask,
getDateFieldToPostpone,
postponementSuccessMessage,
shouldShowPostponeButton,
} from '../../src/Scripting/Postponer';
import { TaskBuilder } from '../TestingTools/TaskBuilder';
import { StatusConfiguration, StatusType } from '../../src/StatusConfiguration';
import { Status } from '../../src/Status';
import { StatusConfiguration, StatusType } from '../../src/StatusConfiguration';
import { TaskBuilder } from '../TestingTools/TaskBuilder';

window.moment = moment;

Expand Down Expand Up @@ -67,6 +69,8 @@ describe('postpone - date field choice', () => {
const taskBuilder = new TaskBuilder().scheduledDate(date).startDate(date);
checkPostponeField(taskBuilder, 'scheduledDate');
});

// TODO Check it refuses to postpone an invalid date (failing test)
});

describe('postpone - whether to show button', () => {
Expand Down Expand Up @@ -142,6 +146,51 @@ describe('postpone - whether to show button', () => {
});
});

describe('postpone - new task creation', () => {
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2023-12-03'));
});

afterEach(() => {
jest.useRealTimers();
});

function testPostponedTaskAndDate(task: Task, expectedDateField: HappensDate, expectedPostponedDate: string) {
const { postponedDate, newTasks } = createPostponedTask(task, expectedDateField, 'day', 1);
expect(postponedDate.format('YYYY-MM-DD')).toEqual(expectedPostponedDate);
expect(newTasks[expectedDateField]?.format('YYYY-MM-DD')).toEqual(expectedPostponedDate);

// If the scheduled date was inferred from the filename, and it is the scheduledDate that was postponed,
// we must ensure that the 'inferred' flag has been reset to false.
// Otherwise, the new scheduled date will be ignored in some locations, like rendering of dates.
if (task.scheduledDateIsInferred && expectedDateField === 'scheduledDate') {
expect(newTasks.scheduledDateIsInferred).toEqual(false);
}
}

it('should postpone an overdue task to today', () => {
const task = new TaskBuilder().dueDate('2023-11-01').build();
const expectedPostponedDate = '2023-12-04';
testPostponedTaskAndDate(task, 'dueDate', expectedPostponedDate);
});

it('should postpone a task scheduled today to tomorrow', () => {
const task = new TaskBuilder().scheduledDate('2023-12-03').build();
testPostponedTaskAndDate(task, 'scheduledDate', '2023-12-04');
});

it.failing('should postpone a task scheduled today to tomorrow, when the scheduled date is inferred', () => {
const task = new TaskBuilder().scheduledDate('2023-12-03').scheduledDateIsInferred(true).build();
testPostponedTaskAndDate(task, 'scheduledDate', '2023-12-04');
});

it('should postpone a task that starts in the future to the next day', () => {
const task = new TaskBuilder().startDate('2024-03-05').build();
testPostponedTaskAndDate(task, 'startDate', '2024-03-06');
});
});

describe('postpone - postponement success message', () => {
it('should generate a message for a valid date', () => {
const message = postponementSuccessMessage(moment('2023-11-30'), 'scheduledDate');
Expand Down
159 changes: 159 additions & 0 deletions tests/Scripting/TasksDate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import moment from 'moment';

import type { unitOfTime } from 'moment/moment';
import { TasksDate } from '../../src/Scripting/TasksDate';

window.moment = moment;
Expand Down Expand Up @@ -105,3 +106,161 @@ describe('TasksDate', () => {
expect(new TasksDate(moment('2023-02-31')).fromNow.groupText).toEqual('%%320230611%% Invalid date');
});
});

describe('TasksDate - postpone', () => {
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2023-11-28'));
});

afterEach(() => {
jest.useRealTimers();
});

function checkDatePostponesTo(
initialDate: string,
amount: number,
unitOfTime: unitOfTime.DurationConstructor,
expectedDate: string,
) {
const tasksDate = new TasksDate(moment(initialDate));
const postponedDate = new TasksDate(tasksDate.postpone(unitOfTime, amount));
expect(postponedDate.formatAsDate()).toEqual(expectedDate);
}

it.failing('should not modify the original date when postponing', () => {
function checkPostponingDoesNotModifyOriginalDate(
initialDate: string,
amount: number,
unitOfTime: moment.unitOfTime.DurationConstructor,
) {
// Arrange
const initialTasksDate = new TasksDate(moment(initialDate));

// Act
const postponed = new TasksDate(initialTasksDate.postpone(unitOfTime, amount));

// Assert
// We don't care what the new date is; we just need to know that the date has been modified
// or the Assert below would pass spuriously.
expect(postponed.formatAsDate()).not.toEqual(initialDate);

expect(initialTasksDate.formatAsDate()).toEqual(initialDate);
}

checkPostponingDoesNotModifyOriginalDate('2023-11-27', 1, 'day'); // before today
checkPostponingDoesNotModifyOriginalDate('2023-11-28', 1, 'day'); // today
checkPostponingDoesNotModifyOriginalDate('2023-11-30', 1, 'day'); // a future date
});

it('should postpone an older date (before yesterday) to tomorrow', () => {
checkDatePostponesTo('2023-11-20', 1, 'day', '2023-11-29');
});

it('should postpone yesterday date to tomorrow', () => {
checkDatePostponesTo('2023-11-27', 1, 'day', '2023-11-29');

// TODO: Review this behaviour.
// It is not clear that this is the best result - it is just the current result, since #2473.
checkDatePostponesTo('2023-11-27', 1, 'week', '2023-12-05');
checkDatePostponesTo('2023-11-27', 1, 'month', '2023-12-28');
});

it('should postpone today date to tomorrow', () => {
checkDatePostponesTo('2023-11-28', 1, 'day', '2023-11-29');
});

it('should postpone tomorrow date to after tomorrow', () => {
checkDatePostponesTo('2023-11-29', 1, 'day', '2023-11-30');
});

it('should postpone a future date (after tomorrow)', () => {
checkDatePostponesTo('2024-03-20', 1, 'day', '2024-03-21');
});

it('should postpone by a month, to a shorter month (in a leap year)', () => {
checkDatePostponesTo('2024-01-31', 1, 'month', '2024-02-29');
});

// TODO Add more tests for increments other than 1 day

describe('visualise postpone behaviour', () => {
function postponeMultipleDatesBy(amount: number, unitOfTime: unitOfTime.DurationConstructor) {
// Set a date that is easy to decrement and increment
const today = '2023-11-10';
jest.setSystemTime(new Date(today));

const dates = [
'2023-11-01',
'2023-11-02',
'2023-11-03',
'2023-11-04',
'2023-11-05',
'2023-11-06',
'2023-11-07',
'2023-11-08',
'2023-11-09',
'2023-11-10',
'2023-11-11',
'2023-11-12',
'2023-11-13',
];
let output = `[initial] => [postponed on '${today}' by '${amount} ${unitOfTime}']
`;
dates.forEach((date) => {
const tasksDate = new TasksDate(moment(date));
const format = 'YYYY-MM-DD ddd';
// We have to save the date before doing the incrementing,
// as this test revealed that currently TasksDate.postpone() mutates the original date,
// as well as returning the postponed date!!!
const dateFormatted = tasksDate.format(format);

const postponedDate = new TasksDate(tasksDate.postpone(unitOfTime, amount));
output += `${dateFormatted} => ${postponedDate.format(format)}\n`;
});
return output;
}

it('by 1 day', () => {
const postponedDatesDescription = postponeMultipleDatesBy(1, 'day');
expect(postponedDatesDescription).toMatchInlineSnapshot(`
"[initial] => [postponed on '2023-11-10' by '1 day']
2023-11-01 Wed => 2023-11-11 Sat
2023-11-02 Thu => 2023-11-11 Sat
2023-11-03 Fri => 2023-11-11 Sat
2023-11-04 Sat => 2023-11-11 Sat
2023-11-05 Sun => 2023-11-11 Sat
2023-11-06 Mon => 2023-11-11 Sat
2023-11-07 Tue => 2023-11-11 Sat
2023-11-08 Wed => 2023-11-11 Sat
2023-11-09 Thu => 2023-11-11 Sat
2023-11-10 Fri => 2023-11-11 Sat
2023-11-11 Sat => 2023-11-12 Sun
2023-11-12 Sun => 2023-11-13 Mon
2023-11-13 Mon => 2023-11-14 Tue
"
`);
});

it('by 1 week', () => {
const postponedDatesDescription = postponeMultipleDatesBy(1, 'week');
expect(postponedDatesDescription).toMatchInlineSnapshot(`
"[initial] => [postponed on '2023-11-10' by '1 week']
2023-11-01 Wed => 2023-11-17 Fri
2023-11-02 Thu => 2023-11-17 Fri
2023-11-03 Fri => 2023-11-17 Fri
2023-11-04 Sat => 2023-11-17 Fri
2023-11-05 Sun => 2023-11-17 Fri
2023-11-06 Mon => 2023-11-17 Fri
2023-11-07 Tue => 2023-11-17 Fri
2023-11-08 Wed => 2023-11-17 Fri
2023-11-09 Thu => 2023-11-17 Fri
2023-11-10 Fri => 2023-11-17 Fri
2023-11-11 Sat => 2023-11-18 Sat
2023-11-12 Sun => 2023-11-19 Sun
2023-11-13 Mon => 2023-11-20 Mon
"
`);
});
});
});

0 comments on commit 27f93ca

Please sign in to comment.