Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DB state check tests for user management backend #2841

1 change: 0 additions & 1 deletion packages/cli/test/integration/auth.endpoints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import config = require('../../config');
import * as utils from './shared/utils';
import { LOGGED_OUT_RESPONSE_BODY } from './shared/constants';
import { Db } from '../../src';
import { User } from '../../src/databases/entities/User';
import { Role } from '../../src/databases/entities/Role';
import { randomEmail, randomValidPassword, randomName } from './shared/random';
import { getGlobalOwnerRole } from './shared/utils';
Expand Down
96 changes: 74 additions & 22 deletions packages/cli/test/integration/me.endpoints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getGlobalOwnerRole } from './shared/utils';
let globalOwnerRole: Role;

describe('/me endpoints', () => {
describe('Shell requests', () => {
describe('Owner shell requests', () => {
let app: express.Application;

beforeAll(async () => {
Expand All @@ -44,11 +44,11 @@ describe('/me endpoints', () => {
return getConnection().close();
});

test('GET /me should return sanitized shell', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
test('GET /me should return sanitized owner shell', async () => {
const ownerShell = await Db.collections.User!.findOneOrFail();
const authOwnerShellAgent = await utils.createAgent(app, { auth: true, user: ownerShell });

const response = await authShellAgent.get('/me');
const response = await authOwnerShellAgent.get('/me');

expect(response.statusCode).toBe(200);

Expand All @@ -75,11 +75,11 @@ describe('/me endpoints', () => {
});

test('PATCH /me should succeed with valid inputs', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const ownerShell = await Db.collections.User!.findOneOrFail();
const authOwnerShellAgent = await utils.createAgent(app, { auth: true, user: ownerShell });

for (const validPayload of VALID_PATCH_ME_PAYLOADS) {
const response = await authShellAgent.patch('/me').send(validPayload);
const response = await authOwnerShellAgent.patch('/me').send(validPayload);

expect(response.statusCode).toBe(200);

Expand All @@ -103,61 +103,84 @@ describe('/me endpoints', () => {
expect(resetPasswordToken).toBeUndefined();
expect(globalRole.name).toBe('owner');
expect(globalRole.scope).toBe('global');

const storedOwnerShell = await Db.collections.User!.findOneOrFail(id);

expect(storedOwnerShell.email).toBe(validPayload.email);
expect(storedOwnerShell.firstName).toBe(validPayload.firstName);
expect(storedOwnerShell.lastName).toBe(validPayload.lastName);
}
});

test('PATCH /me should fail with invalid inputs', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const ownerShell = await Db.collections.User!.findOneOrFail();
const authOwnerShellAgent = await utils.createAgent(app, { auth: true, user: ownerShell });

for (const invalidPayload of INVALID_PATCH_ME_PAYLOADS) {
const response = await authShellAgent.patch('/me').send(invalidPayload);
const response = await authOwnerShellAgent.patch('/me').send(invalidPayload);
expect(response.statusCode).toBe(400);

const storedOwnerShell = await Db.collections.User!.findOneOrFail();
expect(storedOwnerShell.email).toBeNull();
expect(storedOwnerShell.firstName).toBeNull();
expect(storedOwnerShell.lastName).toBeNull();
}
});

test('PATCH /me/password should succeed with valid inputs', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const ownerShell = await Db.collections.User!.findOneOrFail();
const authOwnerShellAgent = await utils.createAgent(app, { auth: true, user: ownerShell });

const validPayloads = Array.from({ length: 3 }, () => ({
password: randomValidPassword(),
}));

for (const validPayload of validPayloads) {
const response = await authShellAgent.patch('/me/password').send(validPayload);
const response = await authOwnerShellAgent.patch('/me/password').send(validPayload);
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);

const storedOwnerShell = await Db.collections.User!.findOneOrFail();
expect(storedOwnerShell.password).not.toBe(validPayload.password);
}
});

test('PATCH /me/password should fail with invalid inputs', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const ownerShell = await Db.collections.User!.findOneOrFail();
const authOwnerShellAgent = await utils.createAgent(app, { auth: true, user: ownerShell });

const invalidPayloads = [
const invalidPayloads: Array<any> = [
...Array.from({ length: 3 }, () => ({ password: randomInvalidPassword() })),
{},
undefined,
'',
];

for (const invalidPayload of invalidPayloads) {
const response = await authShellAgent.patch('/me/password').send(invalidPayload);
const response = await authOwnerShellAgent.patch('/me/password').send(invalidPayload);
expect(response.statusCode).toBe(400);

const storedMember = await Db.collections.User!.findOneOrFail();

if (invalidPayload?.password) {
expect(storedMember.password).not.toBe(invalidPayload.password);
}
}
});

test('POST /me/survey should succeed with valid inputs', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const ownerShell = await Db.collections.User!.findOneOrFail();
const authOwnerShellAgent = await utils.createAgent(app, { auth: true, user: ownerShell });

const validPayloads = [SURVEY, {}];

for (const validPayload of validPayloads) {
const response = await authShellAgent.post('/me/survey').send(validPayload);
const response = await authOwnerShellAgent.post('/me/survey').send(validPayload);
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);

const storedOwnerShell = await Db.collections.User!.findOneOrFail();
expect(storedOwnerShell.personalizationAnswers).toEqual(validPayload);
}
});
});
Expand Down Expand Up @@ -265,6 +288,12 @@ describe('/me endpoints', () => {
expect(resetPasswordToken).toBeUndefined();
expect(globalRole.name).toBe('member');
expect(globalRole.scope).toBe('global');

const storedMember = await Db.collections.User!.findOneOrFail(id);

expect(storedMember.email).toBe(validPayload.email);
expect(storedMember.firstName).toBe(validPayload.firstName);
expect(storedMember.lastName).toBe(validPayload.lastName);
}
});

Expand All @@ -275,6 +304,11 @@ describe('/me endpoints', () => {
for (const invalidPayload of INVALID_PATCH_ME_PAYLOADS) {
const response = await authMemberAgent.patch('/me').send(invalidPayload);
expect(response.statusCode).toBe(400);

const storedMember = await Db.collections.User!.findOneOrFail();
expect(storedMember.email).toBe(TEST_USER.email);
expect(storedMember.firstName).toBe(TEST_USER.firstName);
expect(storedMember.lastName).toBe(TEST_USER.lastName);
}
});

Expand All @@ -290,14 +324,17 @@ describe('/me endpoints', () => {
const response = await authMemberAgent.patch('/me/password').send(validPayload);
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);

const storedMember = await Db.collections.User!.findOneOrFail();
expect(storedMember.password).not.toBe(validPayload.password);
}
});

test('PATCH /me/password should fail with invalid inputs', async () => {
const member = await Db.collections.User!.findOneOrFail();
const authMemberAgent = await utils.createAgent(app, { auth: true, user: member });

const invalidPayloads = [
const invalidPayloads: Array<any> = [
...Array.from({ length: 3 }, () => ({ password: randomInvalidPassword() })),
{},
undefined,
Expand All @@ -307,6 +344,12 @@ describe('/me endpoints', () => {
for (const invalidPayload of invalidPayloads) {
const response = await authMemberAgent.patch('/me/password').send(invalidPayload);
expect(response.statusCode).toBe(400);

const storedMember = await Db.collections.User!.findOneOrFail();

if (invalidPayload?.password) {
expect(storedMember.password).not.toBe(invalidPayload.password);
}
}
});

Expand All @@ -320,6 +363,9 @@ describe('/me endpoints', () => {
const response = await authMemberAgent.post('/me/survey').send(validPayload);
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);

const storedMember = await Db.collections.User!.findOneOrFail();
expect(storedMember.personalizationAnswers).toEqual(validPayload);
}
});
});
Expand Down Expand Up @@ -413,6 +459,12 @@ describe('/me endpoints', () => {
expect(resetPasswordToken).toBeUndefined();
expect(globalRole.name).toBe('owner');
expect(globalRole.scope).toBe('global');

const storedOwner = await Db.collections.User!.findOneOrFail(id);

expect(storedOwner.email).toBe(validPayload.email);
expect(storedOwner.firstName).toBe(validPayload.firstName);
expect(storedOwner.lastName).toBe(validPayload.lastName);
}
});
});
Expand Down
33 changes: 17 additions & 16 deletions packages/cli/test/integration/owner.endpoints.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import express = require('express');
import { getConnection } from 'typeorm';
import validator from 'validator';
import { v4 as uuid } from 'uuid';

import * as utils from './shared/utils';
import { Db } from '../../src';
import config = require('../../config');
import { Role } from '../../src/databases/entities/Role';
import { randomEmail, randomName, randomValidPassword, randomInvalidPassword } from './shared/random';
import { getGlobalOwnerRole } from './shared/utils';

let globalOwnerRole: Role;
import {
randomEmail,
randomName,
randomValidPassword,
randomInvalidPassword,
} from './shared/random';

describe('/owner endpoints', () => {
describe('Shell requests', () => {
Expand All @@ -19,8 +19,6 @@ describe('/owner endpoints', () => {
beforeAll(async () => {
app = utils.initTestServer({ namespaces: ['owner'], applyAuth: true });
await utils.initTestDb();

globalOwnerRole = await getGlobalOwnerRole();
});

beforeEach(async () => {
Expand All @@ -36,10 +34,10 @@ describe('/owner endpoints', () => {
});

test('POST /owner should create owner and enable hasOwner setting', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const owner = await Db.collections.User!.findOneOrFail();
const authOwnerAgent = await utils.createAgent(app, { auth: true, user: owner });

const response = await authShellAgent.post('/owner').send(TEST_USER);
const response = await authOwnerAgent.post('/owner').send(TEST_USER);

expect(response.statusCode).toBe(200);

Expand All @@ -64,8 +62,11 @@ describe('/owner endpoints', () => {
expect(globalRole.name).toBe('owner');
expect(globalRole.scope).toBe('global');

const owner = await Db.collections.User!.findOneOrFail(id);
expect(owner.password).not.toBe(TEST_USER.password);
const storedOwner = await Db.collections.User!.findOneOrFail(id);
expect(storedOwner.password).not.toBe(TEST_USER.password);
expect(storedOwner.email).toBe(TEST_USER.email);
expect(storedOwner.firstName).toBe(TEST_USER.firstName);
expect(storedOwner.lastName).toBe(TEST_USER.lastName);

const hasOwnerConfig = config.get('userManagement.hasOwner');
expect(hasOwnerConfig).toBe(true);
Expand All @@ -75,11 +76,11 @@ describe('/owner endpoints', () => {
});

test('POST /owner should fail with invalid inputs', async () => {
const shell = await Db.collections.User!.findOneOrFail();
const authShellAgent = await utils.createAgent(app, { auth: true, user: shell });
const owner = await Db.collections.User!.findOneOrFail();
const authOwnerAgent = await utils.createAgent(app, { auth: true, user: owner });

for (const invalidPayload of INVALID_POST_OWNER_PAYLOADS) {
const response = await authShellAgent.post('/owner').send(invalidPayload);
const response = await authOwnerAgent.post('/owner').send(invalidPayload);
expect(response.statusCode).toBe(400);
}
});
Expand Down