Repository: obsidian-tasks-group/obsidian-tasks
Pull request #2499 (2023-12-12 10:12:31)

fix: better menu items to postpone future dates
# Description

Better menu items to postpone future dates.

## Motivation and Context

Improve usability.

## How has this been tested?

New unit tests + exploratory tests.

## Types of changes

Changes visible to users:

- [x] **Bug fix** (prefix: `fix` - non-breaking change which fixes an issue)

Internal changes:

- [x] **Tests** (prefix: `test` - additions and improvements to unit tests and the smoke tests)

## Checklist

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [x] My change has adequate [Unit Test coverage](https://publish.obsidian.md/tasks-contributing/Testing/About+Testing).

## Terms

<!--
By submitting this pull request, you must agree to follow our
[contributing guide](https://publish.obsidian.md/tasks-contributing) and
[Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md).
Put an x in the boxes to confirm you agree.
-->

- [x] My contribution follow this project's [contributing guide](https://publish.obsidian.md/tasks-contributing)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md)



Patch:
diff --git a/src/Scripting/Postponer.ts b/src/Scripting/Postponer.ts
index 9c6daa55..178806c8 100644
--- a/src/Scripting/Postponer.ts
+++ b/src/Scripting/Postponer.ts
@@ -61,13 +61,19 @@ export function postponeMenuItemTitle(task: Task, amount: number, timeUnit: unit
     function capitalizeFirstLetter(word: string) {
         return word.charAt(0).toUpperCase() + word.slice(1);
     }
+
     const updatedDateType = getDateFieldToPostpone(task)!;
     const dateToUpdate = task[updatedDateType] as Moment;
-    const updatedDateDisplayText = capitalizeFirstLetter(updatedDateType.replace('Date', ''));
 
     const postponedDate = new TasksDate(dateToUpdate).postpone(timeUnit, amount);
     const formattedNewDate = postponedDate.format('ddd Do MMM');
 
     const amountOrArticle = amount > 1 ? amount : 'a';
-    return `${updatedDateDisplayText} in ${amountOrArticle} ${timeUnit}, on ${formattedNewDate}`;
+    if (dateToUpdate.isSameOrBefore(window.moment(), 'day')) {
+        const updatedDateDisplayText = capitalizeFirstLetter(updatedDateType.replace('Date', ''));
+        return `${updatedDateDisplayText} in ${amountOrArticle} ${timeUnit}, on ${formattedNewDate}`;
+    } else {
+        const updatedDateDisplayText = updatedDateType.replace('Date', ' date');
+        return `Postpone ${updatedDateDisplayText} by ${amountOrArticle} ${timeUnit}, to ${formattedNewDate}`;
+    }
 }


Test patch:
diff --git a/tests/Scripting/Postponer.test.ts b/tests/Scripting/Postponer.test.ts
index 16fc7a70..e4807597 100644
--- a/tests/Scripting/Postponer.test.ts
+++ b/tests/Scripting/Postponer.test.ts
@@ -18,7 +18,10 @@ import { TaskBuilder } from '../TestingTools/TaskBuilder';
 
 window.moment = moment;
 
+const yesterday = '2023-12-02';
 const today = '2023-12-03';
+const tomorrow = '2023-12-04';
+
 beforeEach(() => {
     jest.useFakeTimers();
     jest.setSystemTime(new Date(today));
@@ -169,13 +172,26 @@ describe('postpone - UI text', () => {
         );
     });
 
-    it('should include date type and new date in context menu labels', () => {
+    it('should include date type and new date in context menu labels when due today', () => {
         const task = new TaskBuilder().dueDate(today).build();
-        // TODO This text is misleading if the date is already in the future.
-        //      In that case, it should still be 'Postpone'???
+
         expect(postponeMenuItemTitle(task, 1, 'day')).toEqual('Due in a day, on Mon 4th Dec');
         expect(postponeMenuItemTitle(task, 2, 'days')).toEqual('Due in 2 days, on Tue 5th Dec');
     });
+
+    it('should include date type and new date in context menu labels when overdue', () => {
+        const task = new TaskBuilder().scheduledDate(yesterday).build();
+
+        expect(postponeMenuItemTitle(task, 1, 'day')).toEqual('Scheduled in a day, on Mon 4th Dec');
+        expect(postponeMenuItemTitle(task, 2, 'days')).toEqual('Scheduled in 2 days, on Tue 5th Dec');
+    });
+
+    it('should include date type and new date in context menu labels when due in future', () => {
+        const task = new TaskBuilder().startDate(tomorrow).build();
+
+        expect(postponeMenuItemTitle(task, 1, 'day')).toEqual('Postpone start date by a day, to Tue 5th Dec');
+        expect(postponeMenuItemTitle(task, 2, 'days')).toEqual('Postpone start date by 2 days, to Wed 6th Dec');
+    });
 });
 
 describe('postpone - new task creation', () => {