Skip to content

Commit 29a5c6f

Browse files
committed
Fixed the sync, added a test to cover the issue
1 parent ec32e46 commit 29a5c6f

2 files changed

Lines changed: 27 additions & 8 deletions

File tree

playwright/app.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ test.describe("Goaly App", () => {
107107
await expect(page.getByRole("heading", { name: "Your Active Goals" }))
108108
.toBeVisible();
109109

110+
// Create a goal first so that there are instances to delete during sync
111+
await page.getByRole("button", { name: "Add Goal" }).click();
112+
await expect(page.getByRole("heading", { name: "New Goal" })).toBeVisible();
113+
114+
const testGoalName = `Sync Test Goal ${Date.now()}`;
115+
await page.getByRole("textbox", { name: "I want to..." }).fill(testGoalName);
116+
await page.locator("label").filter({ hasText: "Morning 6am - 12pm" }).click();
117+
await page.getByRole("button", { name: "Save Goal" }).click();
118+
119+
await expect(page.getByRole("heading", { name: testGoalName })).toBeVisible();
120+
110121
page.once("dialog", (dialog) => {
111122
dialog.accept().catch(() => {});
112123
});
@@ -119,6 +130,12 @@ test.describe("Goaly App", () => {
119130
await expect(
120131
page.getByText("Your goals have been re-scheduled into your calendar."),
121132
).toBeVisible();
133+
134+
// Clean up
135+
page.on("dialog", (dialog) => dialog.accept());
136+
await page.locator("details", { hasText: testGoalName }).getByRole("heading", { name: testGoalName }).click();
137+
await page.locator("details", { hasText: testGoalName }).getByRole("button", { name: "Delete Goal" }).click();
138+
await expect(page.getByRole("heading", { name: testGoalName })).not.toBeVisible();
122139
});
123140

124141
test("should allow user to logout", async ({ page }) => {

src/pages/api/goals/sync.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,16 @@ export const POST = async ({ request, redirect }) => {
3636
// Delete these instances from the DB
3737
if (futureInstances.length > 0) {
3838
const deleteStmt = db.prepare("DELETE FROM goal_instances WHERE id = ?");
39-
const deleteTransaction = db.transaction(
40-
(/** @type {any[]} */ instances) => {
41-
for (const instance of instances) {
42-
deleteStmt.run(instance.id);
43-
}
44-
},
45-
);
46-
deleteTransaction(futureInstances);
39+
db.exec("BEGIN TRANSACTION;");
40+
try {
41+
for (const instance of futureInstances) {
42+
deleteStmt.run(instance.id);
43+
}
44+
db.exec("COMMIT;");
45+
} catch (err) {
46+
db.exec("ROLLBACK;");
47+
throw err;
48+
}
4749
}
4850

4951
// 2. Re-schedule phase: Fetch goals ordered by duration (shortest first)

0 commit comments

Comments
 (0)