feat: add POST /sessions/bulk endpoint for bulk archive, unarchive, and delete
Made-with: Cursor
This commit is contained in:
@@ -171,3 +171,134 @@ describe('POST /api/sessions/:id/unarchive', () => {
|
||||
expect(res.status).toBe(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/sessions/bulk', () => {
|
||||
beforeEach(() => {
|
||||
cleanDb();
|
||||
});
|
||||
|
||||
test('bulk archive multiple sessions', async () => {
|
||||
const s1 = seedSession({ is_active: 0, notes: null });
|
||||
const s2 = seedSession({ is_active: 0, notes: null });
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'archive', ids: [s1.id, s2.id] });
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.success).toBe(true);
|
||||
expect(res.body.affected).toBe(2);
|
||||
|
||||
const list = await request(app).get('/api/sessions?filter=archived');
|
||||
expect(list.body).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('bulk unarchive multiple sessions', async () => {
|
||||
const s1 = seedSession({ is_active: 0, notes: null });
|
||||
const s2 = seedSession({ is_active: 0, notes: null });
|
||||
const db = require('../helpers/test-utils').db;
|
||||
db.prepare('UPDATE sessions SET archived = 1 WHERE id IN (?, ?)').run(s1.id, s2.id);
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'unarchive', ids: [s1.id, s2.id] });
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.affected).toBe(2);
|
||||
|
||||
const list = await request(app).get('/api/sessions?filter=all');
|
||||
expect(list.body.every(s => s.archived === 0)).toBe(true);
|
||||
});
|
||||
|
||||
test('bulk delete multiple sessions', async () => {
|
||||
const s1 = seedSession({ is_active: 0, notes: null });
|
||||
const s2 = seedSession({ is_active: 0, notes: null });
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'delete', ids: [s1.id, s2.id] });
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.affected).toBe(2);
|
||||
|
||||
const list = await request(app).get('/api/sessions?filter=all');
|
||||
expect(list.body).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('rejects archive of active sessions', async () => {
|
||||
const active = seedSession({ is_active: 1, notes: null });
|
||||
const closed = seedSession({ is_active: 0, notes: null });
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'archive', ids: [active.id, closed.id] });
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
expect(res.body.activeIds).toContain(active.id);
|
||||
|
||||
const list = await request(app).get('/api/sessions?filter=all');
|
||||
expect(list.body).toHaveLength(2);
|
||||
expect(list.body.every(s => s.archived === 0)).toBe(true);
|
||||
});
|
||||
|
||||
test('rejects delete of active sessions', async () => {
|
||||
const active = seedSession({ is_active: 1, notes: null });
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'delete', ids: [active.id] });
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
|
||||
test('returns 400 for empty ids array', async () => {
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'archive', ids: [] });
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
|
||||
test('returns 400 for invalid action', async () => {
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'nuke', ids: [1] });
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
|
||||
test('returns 400 for non-array ids', async () => {
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'archive', ids: 'not-array' });
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
|
||||
test('returns 404 if any session ID does not exist', async () => {
|
||||
const s1 = seedSession({ is_active: 0, notes: null });
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.set('Authorization', getAuthHeader())
|
||||
.send({ action: 'archive', ids: [s1.id, 9999] });
|
||||
|
||||
expect(res.status).toBe(404);
|
||||
});
|
||||
|
||||
test('returns 401 without auth', async () => {
|
||||
const res = await request(app)
|
||||
.post('/api/sessions/bulk')
|
||||
.send({ action: 'archive', ids: [1] });
|
||||
|
||||
expect(res.status).toBe(401);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user