feat: Redesign git changes to split stage/unstaged files. (#1359)
* feat: Redesign git changes to split stage/unstaged files. Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> * refactor: streamline git changes panel * fix: label staged and working diff tabs * fix: isolate staged and working diff files * fix: scope staged and working diff updates * fix: scope git row revert to working changes --------- Signed-off-by: Paolo Insogna <paolo@cowtech.it> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Bohdan Triapitsyn
parent
9af0de0056
commit
e16097b05d
@@ -0,0 +1,137 @@
|
||||
import { beforeEach, describe, expect, it, mock } from 'bun:test';
|
||||
|
||||
const gitLibraries = {
|
||||
stageFiles: mock(),
|
||||
unstageFiles: mock(),
|
||||
};
|
||||
|
||||
mock.module('./index.js', () => ({
|
||||
stageFiles: gitLibraries.stageFiles,
|
||||
unstageFiles: gitLibraries.unstageFiles,
|
||||
}));
|
||||
|
||||
const { registerGitRoutes } = await import('./routes.js');
|
||||
|
||||
const createRouteRegistry = () => {
|
||||
const routes = new Map();
|
||||
|
||||
return {
|
||||
app: {
|
||||
get(routePath, handler) {
|
||||
routes.set(`GET ${routePath}`, handler);
|
||||
},
|
||||
post(routePath, handler) {
|
||||
routes.set(`POST ${routePath}`, handler);
|
||||
},
|
||||
put(routePath, handler) {
|
||||
routes.set(`PUT ${routePath}`, handler);
|
||||
},
|
||||
delete(routePath, handler) {
|
||||
routes.set(`DELETE ${routePath}`, handler);
|
||||
},
|
||||
},
|
||||
getRoute(method, routePath) {
|
||||
return routes.get(`${method} ${routePath}`);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const createMockResponse = () => {
|
||||
let statusCode = 200;
|
||||
let body = null;
|
||||
|
||||
return {
|
||||
status(code) {
|
||||
statusCode = code;
|
||||
return this;
|
||||
},
|
||||
json(payload) {
|
||||
body = payload;
|
||||
return this;
|
||||
},
|
||||
get statusCode() {
|
||||
return statusCode;
|
||||
},
|
||||
get body() {
|
||||
return body;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
describe('git routes index mutations', () => {
|
||||
beforeEach(() => {
|
||||
gitLibraries.stageFiles.mockReset();
|
||||
gitLibraries.unstageFiles.mockReset();
|
||||
});
|
||||
|
||||
it('accepts legacy stage path payloads', async () => {
|
||||
const { app, getRoute } = createRouteRegistry();
|
||||
registerGitRoutes(app);
|
||||
const response = createMockResponse();
|
||||
|
||||
await getRoute('POST', '/api/git/stage')(
|
||||
{ query: { directory: '/repo' }, body: { path: 'a.ts' } },
|
||||
response,
|
||||
);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(gitLibraries.stageFiles).toHaveBeenCalledWith('/repo', ['a.ts']);
|
||||
});
|
||||
|
||||
it('accepts bulk stage paths payloads', async () => {
|
||||
const { app, getRoute } = createRouteRegistry();
|
||||
registerGitRoutes(app);
|
||||
const response = createMockResponse();
|
||||
|
||||
await getRoute('POST', '/api/git/stage')(
|
||||
{ query: { directory: '/repo' }, body: { paths: ['a.ts', 'b.ts'] } },
|
||||
response,
|
||||
);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(gitLibraries.stageFiles).toHaveBeenCalledWith('/repo', ['a.ts', 'b.ts']);
|
||||
});
|
||||
|
||||
it('accepts legacy unstage path payloads', async () => {
|
||||
const { app, getRoute } = createRouteRegistry();
|
||||
registerGitRoutes(app);
|
||||
const response = createMockResponse();
|
||||
|
||||
await getRoute('POST', '/api/git/unstage')(
|
||||
{ query: { directory: '/repo' }, body: { path: 'a.ts' } },
|
||||
response,
|
||||
);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(gitLibraries.unstageFiles).toHaveBeenCalledWith('/repo', ['a.ts']);
|
||||
});
|
||||
|
||||
it('accepts bulk unstage paths payloads', async () => {
|
||||
const { app, getRoute } = createRouteRegistry();
|
||||
registerGitRoutes(app);
|
||||
const response = createMockResponse();
|
||||
|
||||
await getRoute('POST', '/api/git/unstage')(
|
||||
{ query: { directory: '/repo' }, body: { paths: ['a.ts', 'b.ts'] } },
|
||||
response,
|
||||
);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(gitLibraries.unstageFiles).toHaveBeenCalledWith('/repo', ['a.ts', 'b.ts']);
|
||||
});
|
||||
|
||||
it('rejects invalid path payloads before calling git', async () => {
|
||||
const { app, getRoute } = createRouteRegistry();
|
||||
registerGitRoutes(app);
|
||||
const response = createMockResponse();
|
||||
|
||||
await getRoute('POST', '/api/git/stage')(
|
||||
{ query: { directory: '/repo' }, body: { paths: [' ', null] } },
|
||||
response,
|
||||
);
|
||||
|
||||
expect(response.statusCode).toBe(400);
|
||||
expect(response.body).toEqual({ error: 'path parameter is required' });
|
||||
expect(gitLibraries.stageFiles).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user