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

fix: refactor restore func to use kc admin api #185

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 54 additions & 102 deletions app/__tests__/api/delete-realm.test.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
import { createMocks } from 'node-mocks-http';
import deleteHandler from '../../pages/api/realms/[id]';
import githubResponseHandler from '../../pages/api/realms/pending';
import prisma from 'utils/prisma';
import { CustomRealmProfiles, MockHttpRequest } from '../fixtures';
import { getServerSession } from 'next-auth';
import { deleteCustomRealm, removeUserAsRealmAdmin } from 'controllers/keycloak';
import { sendDeletionCompleteEmail } from 'utils/mailer';
import { manageCustomRealm, removeUserAsRealmAdmin } from 'controllers/keycloak';
import { ssoTeamEmail } from 'utils/mailer';
import { createMockSendEmail, mockAdminSession, mockSession } from './utils/mocks';
import { createEvent } from 'utils/helpers';
import { EventEnum } from 'validators/create-realm';

jest.mock('../../controllers/keycloak', () => {
jest.mock('../../utils/helpers', () => {
return {
removeUserAsRealmAdmin: jest.fn(),
createCustomRealm: jest.fn(() => true),
disableCustomRealm: jest.fn(() => true),
deleteCustomRealm: jest.fn(() => true),
...jest.requireActual('../../utils/helpers'),
createEvent: jest.fn(),
};
});

jest.mock('../../utils/mailer', () => {
return {
sendUpdateEmail: jest.fn(),
sendDeleteEmail: jest.fn(),
sendDeletionCompleteEmail: jest.fn(() => Promise.resolve(true)),
};
});
jest.mock('utils/ches');

jest.mock('../../utils/github', () => {
jest.mock('../../controllers/keycloak', () => {
return {
createCustomRealmPullRequest: jest.fn(() => Promise.resolve({ data: { number: 1 } })),
mergePullRequest: jest.fn(() => Promise.resolve({ data: { merged: true } })),
deleteBranch: jest.fn(),
removeUserAsRealmAdmin: jest.fn(() => true),
createCustomRealm: jest.fn(() => true),
disableCustomRealm: jest.fn(() => true),
deleteCustomRealm: jest.fn(() => true),
manageCustomRealm: jest.fn(() => true),
};
});

Expand All @@ -38,16 +33,6 @@ jest.mock('next/config', () => () => ({
},
}));

const mockSession = {
expires: new Date(Date.now() + 2 * 86400).toISOString(),
user: {
username: 'test',
family_name: 'test',
idir_username: 'test',
},
status: 'authenticated',
};

jest.mock('next-auth/next', () => {
return {
__esModule: true,
Expand All @@ -62,19 +47,7 @@ jest.mock('../../pages/api/auth/[...nextauth]', () => {
};
});

const mockAdminSession = () => {
(getServerSession as jest.Mock).mockImplementation(() => {
return {
...mockSession,
user: {
...mockSession.user,
client_roles: ['sso-admin'],
},
};
});
};

describe('Realm Delete Request', () => {
describe('Delete Realm Permissions', () => {
beforeEach(() => {
jest.clearAllMocks();
// Mock prisma find/update functions
Expand All @@ -99,91 +72,70 @@ describe('Realm Delete Request', () => {
mockAdminSession();
await deleteHandler(req, res);
expect(res.statusCode).toBe(200);
expect(deleteCustomRealm).toHaveBeenCalledTimes(3);
expect(manageCustomRealm).toHaveBeenCalledTimes(1);
let rosterUpdateArgs = (prisma.roster.update as jest.Mock).mock.calls[0][0];
expect(rosterUpdateArgs.data.status).toBe('planned');
rosterUpdateArgs = (prisma.roster.update as jest.Mock).mock.calls[1][0];
expect(rosterUpdateArgs.data.archived).toBe(true);
expect(rosterUpdateArgs.data.status).toBe('applied');
});
});

describe('delete realms', () => {
const mockToken = 'secret';
describe('Delete Realms', () => {
beforeEach(() => {
jest.clearAllMocks();
(prisma.roster.findUnique as jest.Mock).mockImplementation(() => {
return Promise.resolve({ ...CustomRealmProfiles[0], id: 1, archived: true });
});
});
const requestData = {
method: 'PUT' as 'PUT',
body: {
ids: [1],
action: 'tf_apply',
success: 'true',
},
headers: {
Authorization: mockToken,
},
};

it('requires api token', async () => {
let { req, res }: MockHttpRequest = createMocks(requestData);
await githubResponseHandler(req, res);
expect(res.statusCode).toBe(200);

// Remove auth header
({ req, res } = createMocks({ ...requestData, headers: { Authorization: 'empty' } }));
await githubResponseHandler(req, res);
expect(res.statusCode).toBe(401);
});
it('successfully deletes realm in all environments and sends email', async () => {
mockAdminSession();
const { req, res }: MockHttpRequest = createMocks({
method: 'DELETE',
query: { id: 1 },
});

it('Removes technical contact and product owner from all envirionments', async () => {
const { req, res }: MockHttpRequest = createMocks(requestData);
await githubResponseHandler(req, res);
expect(res.statusCode).toBe(200);
const emailList = createMockSendEmail();

// Email only sent once
expect(sendDeletionCompleteEmail).toHaveBeenCalledTimes(1);
await deleteHandler(req, res);

expect(res.statusCode).toBe(200);
expect(manageCustomRealm).toHaveBeenCalledTimes(1);
// PO email and technical contact email removed in each realm
['dev', 'test', 'prod'].forEach((env) => {
expect(removeUserAsRealmAdmin).toHaveBeenCalledWith(['[email protected]', '[email protected]'], env, 'realm 1');
CustomRealmProfiles[0].environments.forEach((env) => {
expect(removeUserAsRealmAdmin).toHaveBeenCalledWith(
[CustomRealmProfiles[0].productOwnerEmail, CustomRealmProfiles[0].technicalContactEmail],
env,
CustomRealmProfiles[0].realm,
);
});
// No extra calls
expect(removeUserAsRealmAdmin).toHaveBeenCalledTimes(3);
expect(emailList.length).toBe(1);
expect(emailList[0].subject).toContain(
`Notification: Custom Realm ${CustomRealmProfiles[0].realm} has now been Deleted.`,
);
expect(emailList[0].to).toEqual(
expect.arrayContaining([CustomRealmProfiles[0].productOwnerEmail, CustomRealmProfiles[0].technicalContactEmail]),
);
expect(emailList[0].cc).toEqual(expect.arrayContaining([ssoTeamEmail]));
});

it('Only sends deletion complete email if all users removed successfully', async () => {
const { req, res }: MockHttpRequest = createMocks(requestData);
(removeUserAsRealmAdmin as jest.Mock).mockImplementationOnce(() => Promise.reject(new Error('failure')));
await githubResponseHandler(req, res);
it('does not send email if deleting realm in all environments fails', async () => {
mockAdminSession();

expect(res.statusCode).toBe(500);
expect(sendDeletionCompleteEmail).not.toHaveBeenCalled();
});
(manageCustomRealm as jest.Mock).mockImplementationOnce(() => Promise.reject('some error'));

it('calls kc admin api to disable realm in all environments', async () => {
(prisma.roster.findUnique as jest.Mock).mockImplementation(() => {
return Promise.resolve(CustomRealmProfiles[0]);
});
(getServerSession as jest.Mock).mockImplementation(() => {
return {
expires: new Date(Date.now() + 2 * 86400).toISOString(),
user: {
username: 'test',
client_roles: ['sso-admin'],
},
status: 'authenticated',
};
});
const { req, res }: MockHttpRequest = createMocks({
method: 'DELETE',
query: { id: 1 },
});
await deleteHandler(req, res);

expect(res.statusCode).toBe(200);
expect(deleteCustomRealm).toHaveBeenCalledTimes(3);
const emailList = createMockSendEmail();

await deleteHandler(req, res);
const createEventArgs = (createEvent as jest.Mock).mock.calls[0][0];
expect(createEventArgs.eventCode).toBe(EventEnum.REQUEST_DELETE_FAILED);
expect(res.statusCode).toBe(422);
expect(manageCustomRealm).toHaveBeenCalledTimes(1);
expect(emailList.length).toBe(0);
});
});
Loading