Repository: obsidian-tasks-group/obsidian-tasks (ts)

Issue:
Postponing of tasks only works once
### Please check that this issue hasn't been reported before.

- [X] I searched previous [Bug Reports](https://github.com/obsidian-tasks-group/obsidian-tasks/issues?q=is%3Aopen+is%3Aissue+label%3A%22type%3A+bug%22+sort%3Acomments-desc) didn't find any similar reports.

### Expected Behavior

The new 'postpone' button should allow postponing a task multiple times.

### Current behaviour

After the first postponement of a task, any subsequent attempts to postpone it give an error.


### Steps to reproduce


1. In a vault with the development version of tasks build - such as version bb479979619d4ca745920dbd65906f39383837f9....
1. Create a file called, for example, `Postpone Tests.md`
2. Paste in this content:

~~~
## Task

- [ ] #task Do stuff 📅 2025-12-02

## Search

```tasks
path includes {{query.file.path}}
```
~~~

4. View in Live Preview or Reading mode

![image](https://github.com/obsidian-tasks-group/obsidian-tasks/assets/4840096/9bdf29fe-dd6e-45a3-a4b1-31507980a712)

5. Click on the Postpone icon at the end of the Task in the query results
6. **Check**:
    - the date should advance to 2025-12-03 in the markdown line
    - the date should advance to 2025-12-03 in the task in the tasks results
    - a success message should be displayed:
        ![image](https://github.com/obsidian-tasks-group/obsidian-tasks/assets/4840096/f2800ddf-d895-4233-940e-81a5fd9f03e2)

7. Click on the Postpone icon at the end of the Task in the query results again

**Expected result:**
    - the date should advance to 2025-12-04 in the markdown line
    - the date should advance to 2025-12-04 in the task in the tasks results
    - and a success notice should be displayed

**Actual result:**
    - the date in the markdown line stays at 2025-12-04
    - the date tasks results advances to 2025-12-04
    - a success message is displayed, and then a failure message:
        ![image](https://github.com/obsidian-tasks-group/obsidian-tasks/assets/4840096/2003756c-af15-40fb-831a-629f24b13c71)



### Which Operating Systems are you using?

- [ ] Android
- [ ] iPhone/iPad
- [ ] Linux
- [X] macOS
- [ ] Windows

### Obsidian Version

1.5.1

### Tasks Plugin Version

Post 5.2.0 development

### Checks

- [ ] I have tried it with all other plugins disabled and the error still occurs

### Possible solution

_No response_

Pull request:
fix: Postponing now works repeatedly
# Description

Postponing of future tasks no longer modifies the original date, which broke subsequent postponing operations.

The root cause was that the original task date was accidentally being modified.

Note: there is some further tidying up that can be done, like removing the call to `triggerRequestCacheUpdate()`, and removing debug logging. I'll tidy those up in later steps, so that this change is minimal.

## Motivation and Context

Fixes #2471

## How has this been tested?

- Updating tests that were failing
- Manual testing

## Screenshots (if appropriate)


https://github.com/obsidian-tasks-group/obsidian-tasks/assets/4840096/f50dc4d5-7598-4f7c-9db5-4668d610a26d



## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

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

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [ ] My change requires a change to the documentation.
- [ ] I have [updated the documentation](https://publish.obsidian.md/tasks-contributing/Documentation/About+Documentation) accordingly.
- [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/TasksDate.ts b/src/Scripting/TasksDate.ts
index fbb7ecc6..a9384c3f 100644
--- a/src/Scripting/TasksDate.ts
+++ b/src/Scripting/TasksDate.ts
@@ -122,6 +122,6 @@ export class TasksDate {
             return today.add(amount, unitOfTime);
         }
 
-        return this._date.add(amount, unitOfTime);
+        return this._date.clone().add(amount, unitOfTime);
     }
 }


Test patch:
diff --git a/tests/Scripting/TasksDate.test.ts b/tests/Scripting/TasksDate.test.ts
index 00398f79..f4f1936c 100644
--- a/tests/Scripting/TasksDate.test.ts
+++ b/tests/Scripting/TasksDate.test.ts
@@ -128,7 +128,7 @@ describe('TasksDate - postpone', () => {
         expect(postponedDate.formatAsDate()).toEqual(expectedDate);
     }
 
-    it.failing('should not modify the original date when postponing', () => {
+    it('should not modify the original date when postponing', () => {
         function checkPostponingDoesNotModifyOriginalDate(
             initialDate: string,
             amount: number,
@@ -210,13 +210,8 @@ describe('TasksDate - postpone', () => {
             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`;
+                output += `${tasksDate.format(format)} => ${postponedDate.format(format)}\n`;
             });
             return output;
         }