Skip to content

Commit

Permalink
Merge pull request #1304 from bcgov/test
Browse files Browse the repository at this point in the history
chore: release production
  • Loading branch information
jlangy authored Sep 25, 2024
2 parents eb309ee + d1646d7 commit b997525
Show file tree
Hide file tree
Showing 36 changed files with 28,080 additions and 9,073 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-gh-pages-maintenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
ENABLE_GOLD=true
MAINTENANCE_MODE_ACTIVE=${{github.event.inputs.maintenanceEnabled}}
INCLUDE_BC_SERVICES_CARD=true
ALLOW_BC_SERVICES_CARD_PROD=false
ALLOW_BC_SERVICES_CARD_PROD=true
EOF
- name: Checkout 🛎️
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
MAINTENANCE_MODE_ACTIVE=false
INCLUDE_DIGITAL_CREDENTIAL=true
INCLUDE_BC_SERVICES_CARD=true
ALLOW_BC_SERVICES_CARD_PROD=false
ALLOW_BC_SERVICES_CARD_PROD=true
EOF
- name: Set env to preview
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ jobs:
INCLUDE_DIGITAL_CREDENTIAL=true
INCLUDE_BC_SERVICES_CARD=true
ALLOW_BC_SERVICES_CARD_PROD=false
ALLOW_BC_SERVICES_CARD_PROD=true
BCSC_INITIAL_ACCESS_TOKEN_DEV=${{secrets.BCSC_INITIAL_ACCESS_TOKEN_TEST}}
BCSC_INITIAL_ACCESS_TOKEN_TEST=${{secrets.BCSC_INITIAL_ACCESS_TOKEN_TEST}}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ lambda/jest-stare/*

# Migration script
role-migration/migrate-roles.sql
.vscode
31 changes: 30 additions & 1 deletion lambda/__tests__/20.bcsc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TEAM_ADMIN_IDIR_EMAIL_01, TEAM_ADMIN_IDIR_USERID_01, formDataDev, formD
import { bcscIdpMappers } from '@lambda-app/utils/constants';
import { submitNewIntegration } from './helpers/modules/integrations';
import { IntegrationData } from '@lambda-shared/interfaces';
import { getDefaultClientScopes } from '@lambda-app/keycloak/integration';

jest.mock('@lambda-app/controllers/bc-services-card', () => {
return {
Expand Down Expand Up @@ -282,14 +283,42 @@ describe('Build Github Dispatch', () => {
// Leaves other idp alone
expect(processedIntegration.prodIdps.includes('idir')).toBe(true);

// Keeps VC in dev and test
// Keeps BCSC in dev and test
expect(processedIntegration.testIdps.includes('bcservicescard')).toBe(true);
expect(processedIntegration.devIdps.includes('bcservicescard')).toBe(true);
});

it('Does not add the idp scope if not in the production idp list', () => {
const result = getDefaultClientScopes(
{
...bcscProdIntegration,
clientId: 'myClient',
devIdps: ['bcservicescard', 'idir'],
testIdps: ['bcservicescard', 'idir'],
prodIdps: ['idir'],
},
'prod',
);
expect(result.includes('myClient')).toBeFalsy();
});

it('Keeps bc services card in production IDP list if approved', () => {
const approvedIntegration = { ...bcscProdIntegration, bcServicesCardApproved: true };
const processedIntegration = buildGitHubRequestData(approvedIntegration);
expect(processedIntegration.prodIdps.includes('bcservicescard')).toBe(true);
});

it('Does add the idp scope if included in the production idp list', () => {
const result = getDefaultClientScopes(
{
...bcscProdIntegration,
clientId: 'myClient',
devIdps: ['bcservicescard', 'idir'],
testIdps: ['bcservicescard', 'idir'],
prodIdps: ['idir', 'bcservicescard'],
},
'prod',
);
expect(result.includes('myClient')).toBeTruthy();
});
});
226 changes: 226 additions & 0 deletions lambda/__tests__/25.idp-approver.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
import { log } from 'console';
import {
TEAM_ADMIN_IDIR_USERID_01,
TEAM_ADMIN_IDIR_EMAIL_01,
BCEID_ADMIN_IDIR_EMAIL_01,
BCEID_ADMIN_IDIR_USERID_01,
GITHUB_ADMIN_IDIR_EMAIL_01,
GITHUB_ADMIN_IDIR_USERID_01,
BCSC_ADMIN_IDIR_EMAIL_01,
BCSC_ADMIN_IDIR_USERID_01,
} from './helpers/fixtures';
import { buildIntegration } from './helpers/modules/common';
import {
deleteIntegration,
getEvents,
getRequestsForAdmins,
restoreIntegration,
updateIntegration,
} from './helpers/modules/integrations';
import { cleanUpDatabaseTables, createMockAuth } from './helpers/utils';

jest.mock('../app/src/authenticate');

jest.mock('../shared/utils/ches', () => {
return {
sendEmail: jest.fn(),
};
});

jest.mock('../app/src/keycloak/integration', () => {
const original = jest.requireActual('../app/src/keycloak/integration');
return {
...original,
keycloakClient: jest.fn(() => Promise.resolve(true)),
};
});

jest.mock('@lambda-app/controllers/bc-services-card', () => {
return {
getPrivacyZones: jest.fn(() => Promise.resolve([{ privacy_zone_uri: 'zone1', privacy_zone_name: 'zone1' }])),
getAttributes: jest.fn(() =>
Promise.resolve([
{
name: 'age',
scope: 'profile',
},
{
name: 'postal_code',
scope: 'address',
},
]),
),
};
});

jest.mock('@lambda-app/bcsc/client', () => {
const original = jest.requireActual('@lambda-app/bcsc/client');
return {
...original,
createBCSCClient: jest.fn(() =>
Promise.resolve({
data: {
client_secret: 'secret',
client_id: 'client_id',
registration_access_token: 'token',
},
}),
),
updateBCSCClient: jest.fn(() =>
Promise.resolve({
data: {
client_secret: 'secret',
client_id: 'client_id',
registration_access_token: 'token',
},
}),
),
};
});

// TODO: IDP approver tests
describe('IDP Approver', () => {
let bceidIntegration, githubIntegration, bcServicesCardIntegration;
beforeAll(async () => {
createMockAuth(TEAM_ADMIN_IDIR_USERID_01, TEAM_ADMIN_IDIR_EMAIL_01);
await cleanUpDatabaseTables();
bceidIntegration = await buildIntegration({
projectName: 'bceid',
submitted: true,
bceid: true,
prodEnv: true,
});
githubIntegration = await buildIntegration({
projectName: 'github',
submitted: true,
github: true,
prodEnv: true,
});
bcServicesCardIntegration = await buildIntegration({
projectName: 'bc-services-card',
submitted: true,
bcServicesCard: true,
prodEnv: true,
});
});
beforeEach(() => {
jest.clearAllMocks();
});

it('BCeID approver can view and approve any bceid integration but cannot edit/delete/restore', async () => {
createMockAuth(BCEID_ADMIN_IDIR_USERID_01, BCEID_ADMIN_IDIR_EMAIL_01, ['bceid-admin']);
const requests = await getRequestsForAdmins();

expect(requests.status).toEqual(200);
expect(requests.body.count).toEqual(1);
expect(requests.body.rows[0].projectName).toEqual('bceid');
expect(requests.body.rows[0].bceidApproved).toEqual(false);

const approveRes = await updateIntegration(
{ ...requests.body.rows[0], bceidApproved: true, devValidRedirectUris: ['https://other-application-route'] },
true,
);

expect(approveRes.status).toEqual(200);
expect(approveRes.body.bceidApproved).toEqual(true);
expect(approveRes.body.devValidRedirectUris).not.toEqual(['https://other-application-route']);

const deleteRes = await deleteIntegration(requests.body.rows[0].id);
expect(deleteRes.status).toEqual(401);

const eventsRes = await getEvents(requests.body.rows[0].id);
expect(eventsRes.status).toEqual(403);

const restoreRes = await restoreIntegration(requests.body.rows[0].id, BCEID_ADMIN_IDIR_EMAIL_01);
expect(restoreRes.status).toEqual(403);
});

it('bceid approver can edit/approve/delete owned integrations', async () => {
createMockAuth(BCEID_ADMIN_IDIR_USERID_01, BCEID_ADMIN_IDIR_EMAIL_01, ['bceid-admin']);
const bceidApproverIntegration = await buildIntegration({
projectName: 'bceid-approver',
submitted: true,
bceid: true,
prodEnv: true,
});

expect(bceidApproverIntegration.status).toEqual(200);

const requests = await getRequestsForAdmins();
const createdReq = requests.body.rows.find((row) => row.projectName === 'bceid-approver');
expect(requests.status).toEqual(200);
expect(createdReq).toBeTruthy();

const approveRes = await updateIntegration(
{ ...createdReq, bceidApproved: true, devValidRedirectUris: ['https://other-application-route'] },
true,
);

expect(approveRes.status).toEqual(200);
expect(approveRes.body.bceidApproved).toEqual(true);
expect(approveRes.body.devValidRedirectUris).toEqual(['https://other-application-route']);

const deleteRes = await deleteIntegration(createdReq.id);
expect(deleteRes.status).toEqual(200);
});

it('GitHub approver can view and approve any github integration but cannot edit/delete/restore', async () => {
createMockAuth(GITHUB_ADMIN_IDIR_USERID_01, GITHUB_ADMIN_IDIR_EMAIL_01, ['github-admin']);
const requests = await getRequestsForAdmins();
expect(requests.status).toEqual(200);
expect(requests.body.count).toEqual(1);
expect(requests.body.rows[0].projectName).toEqual('github');
expect(requests.body.rows[0].githubApproved).toEqual(false);

const approveRes = await updateIntegration(
{ ...requests.body.rows[0], githubApproved: true, devValidRedirectUris: ['https://other-application-route'] },
true,
);

expect(approveRes.status).toEqual(200);
expect(approveRes.body.githubApproved).toEqual(true);
expect(approveRes.body.devValidRedirectUris).not.toEqual(['https://other-application-route']);

const deleteRes = await deleteIntegration(requests.body.rows[0].id);
expect(deleteRes.status).toEqual(401);

const eventsRes = await getEvents(requests.body.rows[0].id);
expect(eventsRes.status).toEqual(403);

const restoreRes = await restoreIntegration(requests.body.rows[0].id, GITHUB_ADMIN_IDIR_EMAIL_01);
expect(restoreRes.status).toEqual(403);
});

it('BC Services Card approver can view and approve any bcsc integration but cannot edit/delete/restore', async () => {
createMockAuth(BCSC_ADMIN_IDIR_USERID_01, BCSC_ADMIN_IDIR_EMAIL_01, ['bc-services-card-admin']);
const requests = await getRequestsForAdmins();
expect(requests.status).toEqual(200);
expect(requests.body.count).toEqual(1);
expect(requests.body.rows[0].projectName).toEqual('bc-services-card');
expect(requests.body.rows[0].bcServicesCardApproved).toEqual(null);

const approveRes = await updateIntegration(
{
...requests.body.rows[0],
bcServicesCardApproved: true,
devValidRedirectUris: ['https://other-application-route'],
},
true,
);

expect(approveRes.status).toEqual(200);
expect(approveRes.body.bcServicesCardApproved).toEqual(true);
expect(approveRes.body.devValidRedirectUris).not.toEqual(['https://other-application-route']);

const deleteRes = await deleteIntegration(requests.body.rows[0].id);
expect(deleteRes.status).toEqual(401);

const eventsRes = await getEvents(requests.body.rows[0].id);
expect(eventsRes.status).toEqual(403);

const restoreRes = await restoreIntegration(requests.body.rows[0].id, BCSC_ADMIN_IDIR_EMAIL_01);
expect(restoreRes.status).toEqual(403);
});
});

// TODO: IDP approver can only update approved flag but can edit other fields for owned integrations
9 changes: 9 additions & 0 deletions lambda/__tests__/helpers/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import createHttpError from 'http-errors';
export const SSO_ADMIN_USERID_01 = 'SSO_ADMIN_USER_01';
export const SSO_ADMIN_EMAIL_01 = 'sso.admin.user-01@gov.bc.ca';

export const BCEID_ADMIN_IDIR_USERID_01 = 'BCEID_ADMIN_USER_01';
export const BCEID_ADMIN_IDIR_EMAIL_01 = 'bceid.admin.user-01@gov.bc.ca';

export const GITHUB_ADMIN_IDIR_USERID_01 = 'GITHUB_ADMIN_USER_01';
export const GITHUB_ADMIN_IDIR_EMAIL_01 = 'github.admin.user-01@gov.bc.ca';

export const BCSC_ADMIN_IDIR_USERID_01 = 'BCSC_ADMIN_USER_01';
export const BCSC_ADMIN_IDIR_EMAIL_01 = 'bcsc.admin.user-01@gov.bc.ca';

export const TEAM_ADMIN_IDIR_USERNAME_01 = 'TEAMADMINIDIRUSER01';
export const TEAM_ADMIN_IDIR_USERID_01 = 'TEAM_ADMIN_IDIR_USER_01';
export const TEAM_ADMIN_IDIR_EMAIL_01 = 'team.admin.idir.user-01@gov.bc.ca';
Expand Down
32 changes: 32 additions & 0 deletions lambda/__tests__/helpers/modules/integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,35 @@ export const submitNewIntegration = async (integration: IntegrationData) => {
.send({ ...integration, id })
.set('Accept', 'application/json');
};

export const getRequestsForAdmins = async () => {
return await supertest(app)
.post(`${APP_BASE_PATH}/requests-all`)
.send({
searchField: ['id', 'projectName', 'clientId'],
searchKey: '',
order: [
['updatedAt', 'desc'],
['status', 'desc'],
],
limit: 5,
page: 1,
status: [],
archiveStatus: [],
realms: null,
environments: null,
types: ['gold'],
devIdps: null,
})
.set('Accept', 'application/json');
};

export const getEvents = async (requestId: number, eventCode: string = 'all') => {
return await supertest(app)
.post(`${APP_BASE_PATH}/events`)
.send({
requestId,
eventCode,
})
.set('Accept', 'application/json');
};
1 change: 1 addition & 0 deletions lambda/__tests__/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ process.env.API_AUTH_SECRET = 'test';
process.env.NODE_ENV = 'development';
process.env.INCLUDE_DIGITAL_CREDENTIAL = true;
process.env.INCLUDE_BC_SERVICES_CARD = true;
process.env.ALLOW_BC_SERVICES_CARD_PROD = true;

afterAll(async () => {
return sequelize.close();
Expand Down
Loading

0 comments on commit b997525

Please sign in to comment.