feat: Admin Area Players Management 1.00

This commit is contained in:
OpenVelo Agent
2026-07-23 08:43:44 +00:00
parent 62dc88998a
commit f1392963ec
9 changed files with 428 additions and 52 deletions
+53
View File
@@ -453,4 +453,57 @@ describe('Admin /players endpoints (Job 867)', () => {
const stillThere = await ds.getRepository(UserEntity).findOne({ where: { id: admin.id } });
expect(stillThere).not.toBeNull();
});
it('two-admin concurrent role demotion: one succeeds, the other receives 409 LAST_ADMIN (Job 913)', async () => {
await request(app.getHttpServer())
.post('/api/v1/auth/register-first-admin')
.send({ username: 'original', password: 'Sup3rSecret!Pass' })
.expect(201);
const adminAuth = await loginAs(app, 'original', 'Sup3rSecret!Pass');
const adminAgent = request.agent(app.getHttpServer());
await adminAgent.get('/api/v1/auth/csrf');
const adminCsrfCookies: any = adminAgent.jar.getCookies(CookieAccessInfo.All);
const adminCsrf = adminCsrfCookies.find((c: any) => c.name === 'csrf')?.value;
await adminAgent
.post('/api/v1/admin/users')
.set('Authorization', `Bearer ${adminAuth.accessToken}`)
.set('X-CSRF-Token', adminCsrf)
.send({ username: 'bob', password: 'Sup3rSecret!Pass', role: 'admin' })
.expect(201);
const list = await request(app.getHttpServer())
.get('/api/v1/admin/players')
.set('Authorization', `Bearer ${adminAuth.accessToken}`)
.expect(200);
const originalRow = list.body.find((u: any) => u.username === 'original');
const bobRow = list.body.find((u: any) => u.username === 'bob');
expect(originalRow.role).toBe('admin');
expect(bobRow.role).toBe('admin');
const bobAuth = await loginAs(app, 'bob', 'Sup3rSecret!Pass');
const first = await adminAuth.agent
.patch(`/api/v1/admin/players/${originalRow.id}/role`)
.set('Authorization', `Bearer ${adminAuth.accessToken}`)
.set('X-CSRF-Token', adminAuth.csrf)
.send({ role: 'player' })
.expect(200)
.expect((r) => expect(r.body.role).toBe('player'));
const second = await bobAuth.agent
.patch(`/api/v1/admin/players/${bobRow.id}/role`)
.set('Authorization', `Bearer ${bobAuth.accessToken}`)
.set('X-CSRF-Token', bobAuth.csrf)
.send({ role: 'player' })
.expect(409)
.expect((r) => expect(r.body.code).toBe('LAST_ADMIN'));
const ds = app.get(DataSource);
const rowsAfter = await ds.getRepository(UserEntity).find();
const adminCount = rowsAfter.filter((u) => u.role === 'admin').length;
expect(adminCount).toBe(1);
const remainingAdmin = rowsAfter.find((u) => u.role === 'admin');
expect(remainingAdmin?.username).toBe('bob');
});
});