import test from 'ava'; import { setupApp } from '../../helpers/test-helper'; import dbInit from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import User from '../../../../lib/user'; import UserStore from '../../../../lib/db/user-store'; import { AccessStore, IRole } from '../../../../lib/db/access-store'; import { RoleName } from '../../../../lib/services/access-service'; let stores; let db; let userStore: UserStore; let accessStore: AccessStore; let editorRole: IRole; let adminRole: IRole; test.before(async () => { db = await dbInit('user_admin_api_serial', getLogger); stores = db.stores; userStore = stores.userStore; accessStore = stores.accessStore; const roles = await accessStore.getRootRoles(); editorRole = roles.find(r => r.name === RoleName.EDITOR); adminRole = roles.find(r => r.name === RoleName.ADMIN); }); test.after.always(async () => { await db.destroy(); }); test.afterEach.always(async () => { const users = await userStore.getAll(); const deleteAll = users.map((u: User) => userStore.delete(u.id)); await Promise.all(deleteAll); }); test.serial('returns empty list of users', async t => { t.plan(1); const request = await setupApp(stores); return request .get('/api/admin/user-admin') .expect('Content-Type', /json/) .expect(200) .expect(res => { t.is(res.body.users.length, 0); }); }); test.serial('creates and returns all users', async t => { t.plan(2); const request = await setupApp(stores); const createUserRequests = [...Array(20).keys()].map(i => request .post('/api/admin/user-admin') .send({ email: `some${i}@getunleash.ai`, name: `Some Name ${i}`, rootRole: editorRole.id, }) .set('Content-Type', 'application/json'), ); await Promise.all(createUserRequests); return request .get('/api/admin/user-admin') .expect('Content-Type', /json/) .expect(200) .expect(res => { t.is(res.body.users.length, 20); t.is(res.body.users[2].rootRole, editorRole.id); }); }); test.serial('creates editor-user without password', async t => { t.plan(3); const request = await setupApp(stores); return request .post('/api/admin/user-admin') .send({ email: 'some@getunelash.ai', name: 'Some Name', rootRole: editorRole.id, }) .set('Content-Type', 'application/json') .expect(201) .expect(res => { t.is(res.body.email, 'some@getunelash.ai'); t.is(res.body.rootRole, editorRole.id); t.truthy(res.body.id); }); }); test.serial('creates admin-user with password', async t => { t.plan(6); const request = await setupApp(stores); const { body } = await request .post('/api/admin/user-admin') .send({ email: 'some@getunelash.ai', name: 'Some Name', password: 'some-strange-pass-123-GH', rootRole: adminRole.id, }) .set('Content-Type', 'application/json') .expect(201); t.is(body.rootRole, adminRole.id); const user = await userStore.get({ id: body.id }); t.is(user.email, 'some@getunelash.ai'); t.is(user.name, 'Some Name'); const passwordHash = userStore.getPasswordHash(body.id); t.truthy(passwordHash); const roles = await stores.accessStore.getRolesForUserId(body.id); t.is(roles.length, 1); t.is(roles[0].name, RoleName.ADMIN); }); test.serial('requires known root role', async t => { t.plan(0); const request = await setupApp(stores); return request .post('/api/admin/user-admin') .send({ email: 'some@getunelash.ai', name: 'Some Name', rootRole: 'Unknown', }) .set('Content-Type', 'application/json') .expect(400); }); test.serial('update user name', async t => { t.plan(3); const request = await setupApp(stores); const { body } = await request .post('/api/admin/user-admin') .send({ email: 'some@getunelash.ai', name: 'Some Name', rootRole: editorRole.id, }) .set('Content-Type', 'application/json'); return request .put(`/api/admin/user-admin/${body.id}`) .send({ name: 'New name', }) .set('Content-Type', 'application/json') .expect(200) .expect(res => { t.is(res.body.email, 'some@getunelash.ai'); t.is(res.body.name, 'New name'); t.is(res.body.id, body.id); }); }); test.serial('should delete user', async t => { t.plan(0); const user = await userStore.insert(new User({ email: 'some@mail.com' })); const request = await setupApp(stores); return request.delete(`/api/admin/user-admin/${user.id}`).expect(200); }); test.serial('validator should require strong password', async t => { t.plan(0); const request = await setupApp(stores); return request .post('/api/admin/user-admin/validate-password') .send({ password: 'simple' }) .expect(400); }); test.serial('validator should accept strong password', async t => { t.plan(0); const request = await setupApp(stores); return request .post('/api/admin/user-admin/validate-password') .send({ password: 'simple123-_ASsad' }) .expect(200); }); test.serial('should change password', async t => { t.plan(0); const user = await userStore.insert(new User({ email: 'some@mail.com' })); const request = await setupApp(stores); return request .post(`/api/admin/user-admin/${user.id}/change-password`) .send({ password: 'simple123-_ASsad' }) .expect(200); }); test.serial('should search for users', async t => { t.plan(2); await userStore.insert(new User({ email: 'some@mail.com' })); await userStore.insert(new User({ email: 'another@mail.com' })); await userStore.insert(new User({ email: 'another2@mail.com' })); const request = await setupApp(stores); return request .get('/api/admin/user-admin/search?q=another') .expect(200) .expect(res => { t.is(res.body.length, 2); t.true(res.body.some(u => u.email === 'another@mail.com')); }); });