89 lines
2.5 KiB
JavaScript
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();
|
|
});
|
|
});
|