Files
pleno-vue/tests/unit/use-order-metadata-autosave.spec.js
T

89 lines
2.5 KiB
JavaScript

// @vitest-environment jsdom
import { defineComponent, ref } from "vue";
import { mount } from "@vue/test-utils";
import { afterEach, describe, expect, it, vi } from "vitest";
import { useOrderMetadataAutosave } from "@/composables/useOrderMetadataAutosave.js";
const mountAutosave = (options = {}) => {
let autosave;
const source = ref(options.source ?? "saved");
const saveValue = options.saveValue ?? vi.fn(async (value) => value);
const onError = options.onError ?? vi.fn();
const wrapper = mount(
defineComponent({
setup() {
autosave = useOrderMetadataAutosave({
source,
saveValue,
delay: 1,
onError,
});
return {};
},
template: "<div />",
})
);
return { autosave, onError, saveValue, source, wrapper };
};
describe("useOrderMetadataAutosave", () => {
afterEach(() => {
vi.restoreAllMocks();
});
it("does not immediately retry a failed save while the draft remains dirty", async () => {
const saveValue = vi.fn(async () => {
throw new Error("server rejected metadata");
});
const { autosave, onError, wrapper } = mountAutosave({ saveValue });
autosave.draft.value = "rejected";
await expect(autosave.flush()).resolves.toBe(false);
await Promise.resolve();
expect(saveValue).toHaveBeenCalledTimes(1);
expect(saveValue).toHaveBeenCalledWith("rejected");
expect(onError).toHaveBeenCalledTimes(1);
expect(autosave.isDirty.value).toBe(true);
autosave.syncFromSource("rejected");
wrapper.unmount();
});
it("continues saving after a successful request when a newer dirty draft was queued", async () => {
let resolveFirstSave;
const saveValue = vi.fn((value) => {
if (value === "first") {
return new Promise((resolve) => {
resolveFirstSave = () => resolve(value);
});
}
return Promise.resolve(value);
});
const { autosave, wrapper } = mountAutosave({ saveValue });
autosave.draft.value = "first";
const firstFlush = autosave.flush();
autosave.draft.value = "second";
await expect(autosave.flush()).resolves.toBe(false);
resolveFirstSave();
await expect(firstFlush).resolves.toBe(true);
await Promise.resolve();
expect(saveValue).toHaveBeenCalledTimes(2);
expect(saveValue).toHaveBeenNthCalledWith(1, "first");
expect(saveValue).toHaveBeenNthCalledWith(2, "second");
await Promise.resolve();
wrapper.unmount();
});
});