Skip to content

Commit

Permalink
fix(errors): rollback changes after backend returns an error
Browse files Browse the repository at this point in the history
  • Loading branch information
anehx committed Dec 12, 2023
1 parent 0f27656 commit 54ad8eb
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 20 deletions.
9 changes: 6 additions & 3 deletions addon/components/document-delete-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ export default class DocumentDeleteButtonComponent extends Component {
: [this.args.docsToDelete]; // if the supplied argument is not an array we make it one

for (const doc of docs) {
yield doc.destroyRecord();
yield doc.destroyRecord().catch((error) => {
doc.rollbackAttributes();
throw error;
});
this.documents.deselectDocument(doc);
}
}
Expand All @@ -47,13 +50,13 @@ export default class DocumentDeleteButtonComponent extends Component {
this.args.onConfirm(this.args.docsToDelete);
}

this.hideDialog();

this.notification.success(
this.intl.t("alexandria.success.delete-document"),
);
} catch (error) {
new ErrorHandler(this, error).notify("alexandria.errors.delete-document");
} finally {
this.hideDialog();
}
}
}
1 change: 1 addition & 0 deletions addon/components/single-document-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export default class SingleDocumentDetailsComponent extends DocumentCard {
this.resetState();
this.notification.success(this.intl.t("alexandria.success.update"));
} catch (error) {
this.args.document.rollbackAttributes();
new ErrorHandler(this, error).notify("alexandria.errors.update");
}
}
Expand Down
12 changes: 8 additions & 4 deletions addon/services/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export default class TagsService extends Service {
*/
@action async add(document, tagInput) {
let tag = tagInput;
const tags = [...(await document.tags)];

try {
if (typeof tagInput === "string") {
const tagId = dasherize(tagInput.trim());
Expand All @@ -56,15 +58,14 @@ export default class TagsService extends Service {
}
}

const tags = await document.tags;

if (tags.find((t) => t.id === tag.id)) {
return tag;
}

tags.push(tag);
document.tags = [...tags, tag];
await document.save();
} catch (error) {
document.tags = tags;
new ErrorHandler(this, error).notify("alexandria.errors.update");
}

Expand All @@ -84,11 +85,14 @@ export default class TagsService extends Service {
tag = this.store.peekRecord("tag", tag);
}

document.tags = (await document.tags).filter((t) => t !== tag);
const tags = [...(await document.tags)];

document.tags = tags.filter((t) => t !== tag);

try {
await document.save();
} catch (error) {
document.tags = tags;
new ErrorHandler(this, error).notify("alexandria.errors.update");
}

Expand Down
8 changes: 3 additions & 5 deletions tests/integration/components/document-card-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,18 @@ module("Integration | Component | document-card", function (hooks) {
});

test("delete file", async function (assert) {
const destroy = fake();
this.document = {
id: 1,
marks: [],
destroyRecord: fake(),
destroyRecord: async () => destroy(),
};
await render(hbs`<DocumentCard @document={{this.document}}/>`);

await click("[data-test-context-menu-trigger]");
await click("[data-test-delete]");
await click("[data-test-delete-confirm]");
assert.ok(
this.document.destroyRecord.calledOnce,
"destroyRecord was called once",
);
assert.ok(destroy.calledOnce, "destroyRecord was called once");
});

test("thumbnail", async function (assert) {
Expand Down
15 changes: 7 additions & 8 deletions tests/integration/components/single-document-details-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-named-as-default-member */
import Service from "@ember/service";
import { render, click, fillIn, waitFor } from "@ember/test-helpers";
import { tracked } from "@glimmer/tracking";
Expand All @@ -6,7 +7,7 @@ import { hbs } from "ember-cli-htmlbars";
import { setupMirage } from "ember-cli-mirage/test-support";
import { setFlatpickrDate } from "ember-flatpickr/test-support/helpers";
import { module, test } from "qunit";
import { fake } from "sinon";
import sinon from "sinon";

const mockDocumentsService = class DocumentsService extends Service {
deselectDocument() {
Expand Down Expand Up @@ -63,10 +64,11 @@ module("Integration | Component | single-document-details", function (hooks) {
});

test("delete document", async function (assert) {
const destroy = sinon.fake();
this.selectedDocument = {
id: 1,
title: "Test",
destroyRecord: fake(),
destroyRecord: async () => destroy(),
};
await render(
hbs`<SingleDocumentDetails @document={{this.selectedDocument}}/>`,
Expand All @@ -75,18 +77,15 @@ module("Integration | Component | single-document-details", function (hooks) {
await click("[data-test-delete]");
await click("[data-test-delete-confirm]");

assert.ok(
this.selectedDocument.destroyRecord.calledOnce,
"destroyRecord was called once",
);
assert.ok(destroy.calledOnce, "destroyRecord was called once");
});

test("edit document title", async function (assert) {
// To prevent:
// Error: Assertion Failed: You attempted to update [object Object].title to "edited", but it is being tracked by a tracking context, such as a template, computed property, or observer. In order to make sure the context updates properly, you must invalidate the property when updating it. You can mark the property as `@tracked`, or use `@ember/object#set` to do this.
class Document {
@tracked title = "unedited";
save = fake();
save = sinon.fake();
}
this.selectedDocument = new Document();
await render(
Expand Down Expand Up @@ -121,7 +120,7 @@ module("Integration | Component | single-document-details", function (hooks) {
test("edit document date", async function (assert) {
class Document {
@tracked date = "2023-01-01";
save = fake();
save = sinon.fake();
}
this.selectedDocument = new Document();

Expand Down

0 comments on commit 54ad8eb

Please sign in to comment.