test(FN-4528): add fallback rename/copy diff coverage
Fusion-Task-Id: FN-4528 Fusion-Task-Lineage: 40f587b4-6bf3-4ebd-8870-359ac57b42ea
This commit is contained in:
@@ -398,6 +398,81 @@ describe("FN-4308 multi-commit done task aggregation", () => {
|
||||
expect(response.body.files.length).toBe(response.body.stats.filesChanged);
|
||||
});
|
||||
|
||||
it("returns destination path for renames via branch-ref fallback", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(createTask({ column: "in-progress", worktree: undefined, branch: "feature/rename", baseBranch: "main" }));
|
||||
|
||||
gitResponses({
|
||||
"rev-parse --verify --quiet feature/rename": "rename-sha",
|
||||
"diff --name-status -M origin/main..feature/rename": "R100\told.ts\tnew.ts",
|
||||
"diff origin/main..feature/rename -- new.ts": "rename from old.ts\nrename to new.ts\n+added\n",
|
||||
});
|
||||
|
||||
const app = createServer(store as any);
|
||||
const response = await requestDiff(app);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.files).toHaveLength(1);
|
||||
expect(response.body.files[0].path).toBe("new.ts");
|
||||
expect(response.body.files[0].status).toBe("modified");
|
||||
expect(response.body.stats.filesChanged).toBe(1);
|
||||
});
|
||||
|
||||
it("returns destination path for copies via branch-ref fallback", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(createTask({ column: "in-review", worktree: undefined, branch: "feature/copy", baseBranch: "main" }));
|
||||
|
||||
gitResponses({
|
||||
"rev-parse --verify --quiet feature/copy": "copy-sha",
|
||||
"diff --name-status -M origin/main..feature/copy": "C100\tsrc.ts\tdst.ts",
|
||||
"diff origin/main..feature/copy -- dst.ts": "+copied\n",
|
||||
});
|
||||
|
||||
const app = createServer(store as any);
|
||||
const response = await requestDiff(app);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body.files).toHaveLength(1);
|
||||
expect(response.body.files[0].path).toBe("dst.ts");
|
||||
expect(response.body.stats.filesChanged).toBe(1);
|
||||
});
|
||||
|
||||
it("returns renamed destination and oldPath for /file-diffs branch-ref fallback", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(createTask({ column: "in-review", worktree: undefined, branch: "feature/rename-file-diffs", baseBranch: "main" }));
|
||||
|
||||
gitResponses({
|
||||
"rev-parse --verify --quiet feature/rename-file-diffs": "rename-sha",
|
||||
"diff --name-status -M origin/main..feature/rename-file-diffs": "R100\told.ts\tnew.ts",
|
||||
"diff origin/main..feature/rename-file-diffs -- new.ts": "rename from old.ts\nrename to new.ts\n",
|
||||
});
|
||||
|
||||
const app = createServer(store as any);
|
||||
const response = await requestFileDiffs(app);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toHaveLength(1);
|
||||
expect(response.body[0]).toMatchObject({ path: "new.ts", status: "renamed", oldPath: "old.ts" });
|
||||
});
|
||||
|
||||
it("returns copied destination path as modified for /file-diffs branch-ref fallback", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(createTask({ column: "in-progress", worktree: undefined, branch: "feature/copy-file-diffs", baseBranch: "main" }));
|
||||
|
||||
gitResponses({
|
||||
"rev-parse --verify --quiet feature/copy-file-diffs": "copy-sha",
|
||||
"diff --name-status -M origin/main..feature/copy-file-diffs": "C100\tsrc.ts\tdst.ts",
|
||||
"diff origin/main..feature/copy-file-diffs -- dst.ts": "+copied\n",
|
||||
});
|
||||
|
||||
const app = createServer(store as any);
|
||||
const response = await requestFileDiffs(app);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toHaveLength(1);
|
||||
expect(response.body[0]).toMatchObject({ path: "dst.ts", status: "modified" });
|
||||
});
|
||||
|
||||
it("uses diffBase-to-worktree patching for in-progress committed/staged/unstaged files", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(createTask({ column: "in-progress", worktree: process.cwd() }));
|
||||
|
||||
@@ -71,6 +71,20 @@ class MockStore extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
class RepoBackedStore extends MockStore {
|
||||
constructor(private readonly rootDir: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
override getRootDir(): string {
|
||||
return this.rootDir;
|
||||
}
|
||||
|
||||
override getFusionDir(): string {
|
||||
return join(this.rootDir, ".fusion");
|
||||
}
|
||||
}
|
||||
|
||||
function createTask(overrides: Partial<Task> = {}): Task {
|
||||
return {
|
||||
id: "KB-651",
|
||||
@@ -165,6 +179,64 @@ describe("GET /api/tasks/:id/file-diffs", () => {
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns destination path for renames via branch-ref fallback", async () => {
|
||||
const repoDir = mkdtempSync(join(tmpdir(), "fn-file-diffs-rename-"));
|
||||
|
||||
try {
|
||||
execFileSync("git", ["init", "-b", "main", repoDir], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "config", "user.email", "rename@example.com"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "config", "user.name", "Rename Test"], { stdio: "pipe" });
|
||||
writeFileSync(join(repoDir, "old.ts"), "export const oldValue = 1;\n");
|
||||
execFileSync("git", ["-C", repoDir, "add", "old.ts"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "commit", "-m", "base"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "checkout", "-b", "feature-rename"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "mv", "old.ts", "new.ts"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "commit", "-m", "rename file"], { stdio: "pipe" });
|
||||
|
||||
const store = new RepoBackedStore(repoDir);
|
||||
store.addTask(createTask({ column: "in-review", worktree: undefined, branch: "feature-rename", baseBranch: "main" }));
|
||||
|
||||
const app = createServer(store as any);
|
||||
const response = await requestFileDiffs(app);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toHaveLength(1);
|
||||
expect(response.body[0]).toMatchObject({ path: "new.ts", status: "renamed", oldPath: "old.ts" });
|
||||
} finally {
|
||||
rmSync(repoDir, { recursive: true, force: true });
|
||||
}
|
||||
}, 15_000);
|
||||
|
||||
it("returns destination path for copies via branch-ref fallback", async () => {
|
||||
const repoDir = mkdtempSync(join(tmpdir(), "fn-file-diffs-copy-"));
|
||||
|
||||
try {
|
||||
execFileSync("git", ["init", "-b", "main", repoDir], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "config", "user.email", "copy@example.com"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "config", "user.name", "Copy Test"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "config", "diff.renames", "copies"], { stdio: "pipe" });
|
||||
writeFileSync(join(repoDir, "src.ts"), "export const source = 1;\n");
|
||||
execFileSync("git", ["-C", repoDir, "add", "src.ts"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "commit", "-m", "base"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "checkout", "-b", "feature-copy"], { stdio: "pipe" });
|
||||
writeFileSync(join(repoDir, "dst.ts"), "export const source = 1;\n");
|
||||
execFileSync("git", ["-C", repoDir, "add", "dst.ts"], { stdio: "pipe" });
|
||||
execFileSync("git", ["-C", repoDir, "commit", "-m", "copy file"], { stdio: "pipe" });
|
||||
|
||||
const store = new RepoBackedStore(repoDir);
|
||||
store.addTask(createTask({ column: "in-progress", worktree: undefined, branch: "feature-copy", baseBranch: "main" }));
|
||||
|
||||
const app = createServer(store as any);
|
||||
const response = await requestFileDiffs(app);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toHaveLength(1);
|
||||
expect(response.body[0].path).toBe("dst.ts");
|
||||
} finally {
|
||||
rmSync(repoDir, { recursive: true, force: true });
|
||||
}
|
||||
}, 15_000);
|
||||
});
|
||||
|
||||
describe("resolveDiffBase", () => {
|
||||
|
||||
Reference in New Issue
Block a user