fix: await copy move conflict detection (#5978)

This commit is contained in:
Puneet Dixit 2026-06-04 20:46:30 +05:30 committed by GitHub
parent 0bb2768754
commit c1abe8f561
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 129 additions and 2 deletions

View file

@ -92,6 +92,7 @@ export default {
to: this.dest + encodeURIComponent(this.req.items[item].name),
name: this.req.items[item].name,
size: this.req.items[item].size,
isDir: this.req.items[item].isDir,
modified: this.req.items[item].modified,
overwrite: false,
rename: this.$route.path === this.dest,
@ -122,7 +123,7 @@ export default {
});
};
const conflict = upload.checkConflict(items, this.dest);
const conflict = await upload.checkConflict(items, this.dest);
if (conflict.length > 0) {
this.showHover({

View file

@ -98,6 +98,7 @@ export default {
to: this.dest + encodeURIComponent(this.req.items[item].name),
name: this.req.items[item].name,
size: this.req.items[item].size,
isDir: this.req.items[item].isDir,
modified: this.req.items[item].modified,
overwrite: false,
rename: false,
@ -122,7 +123,7 @@ export default {
});
};
const conflict = upload.checkConflict(items, this.dest);
const conflict = await upload.checkConflict(items, this.dest);
if (conflict.length > 0) {
this.showHover({

View file

@ -0,0 +1,125 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import CopyPrompt from "@/components/prompts/Copy.vue";
import MovePrompt from "@/components/prompts/Move.vue";
import { files as api } from "@/api";
import { checkConflict } from "@/utils/upload";
vi.mock("@/api", () => ({
files: {
copy: vi.fn().mockResolvedValue(undefined),
move: vi.fn().mockResolvedValue(undefined),
},
}));
vi.mock("@/api/utils", () => ({
removePrefix: (value: string) => value.replace(/^\/files/, ""),
}));
vi.mock("@/utils/buttons", () => ({
default: {
loading: vi.fn(),
success: vi.fn(),
done: vi.fn(),
},
}));
vi.mock("@/utils/upload", () => ({
checkConflict: vi.fn(),
}));
const conflict = [
{
index: 0,
name: "/target/file.txt",
origin: { size: 12 },
dest: { size: 10 },
checked: ["origin"],
isSmallerOnServer: true,
},
];
function makeContext() {
return {
selected: [0],
req: {
items: [
{
url: "/files/source/file.txt",
name: "file.txt",
size: 12,
isDir: false,
modified: "2026-06-04T00:00:00Z",
},
],
},
dest: "/files/target/",
user: { redirectAfterCopyMove: false },
$route: { path: "/files/source/" },
$router: { push: vi.fn() },
reload: false,
preselect: "",
showHover: vi.fn(),
closeHovers: vi.fn(),
$showError: vi.fn(),
};
}
const event = {
preventDefault: vi.fn(),
};
describe("copy and move conflict prompts", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(checkConflict).mockResolvedValue(conflict);
});
it("waits for copy conflict detection before calling the copy API", async () => {
const context = makeContext();
await (CopyPrompt as any).methods.copy.call(context, event);
expect(checkConflict).toHaveBeenCalledWith(
[
expect.objectContaining({
to: "/files/target/file.txt",
isDir: false,
}),
],
"/files/target/"
);
expect(context.showHover).toHaveBeenCalledWith(
expect.objectContaining({
prompt: "resolve-conflict",
props: { conflict },
})
);
expect(api.copy).not.toHaveBeenCalled();
});
it("waits for move conflict detection before calling the move API", async () => {
const context = makeContext();
await (MovePrompt as any).methods.move.call(context, event);
expect(checkConflict).toHaveBeenCalledWith(
[
expect.objectContaining({
to: "/files/target/file.txt",
isDir: false,
}),
],
"/files/target/"
);
expect(context.showHover).toHaveBeenCalledWith(
expect.objectContaining({
prompt: "resolve-conflict",
props: expect.objectContaining({
conflict,
files: expect.any(Array),
}),
})
);
expect(api.move).not.toHaveBeenCalled();
});
});