Skip to content

Commit

Permalink
chore: Setup new test suites
Browse files Browse the repository at this point in the history
- Update planx-core
- Move shared helpers
- Scope test lifecycle hooks
- Add JWT helper methods
  • Loading branch information
DafyddLlyr committed Sep 18, 2023
1 parent dc46e96 commit 4c6b04a
Show file tree
Hide file tree
Showing 13 changed files with 297 additions and 140 deletions.
6 changes: 5 additions & 1 deletion e2e/tests/api-driven/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
},
"dependencies": {
"@cucumber/cucumber": "^9.3.0",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#4e3d09f",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#17f3bf5",
"axios": "^1.4.0",
"dotenv": "^16.3.1",
"dotenv-expand": "^10.0.0",
"graphql-request": "^6.1.0",
"jsonwebtoken": "^9.0.2",
"lodash.zipobject": "^4.1.3",
"nock": "^13.3.1"
},
"devDependencies": {
"@types/lodash.zipobject": "^4.1.7",
"@types/node": "18.16.1",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
Expand Down
192 changes: 145 additions & 47 deletions e2e/tests/api-driven/pnpm-lock.yaml

Large diffs are not rendered by default.

19 changes: 18 additions & 1 deletion e2e/tests/api-driven/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import assert from "node:assert";
import { CoreDomainClient } from "@opensystemslab/planx-core";
import { TEST_EMAIL } from "../../ui-driven/src/helpers";
import { buildJWT } from "./jwt";

// check env variables are defined
assert(process.env.HASURA_GRAPHQL_ADMIN_SECRET);
Expand All @@ -11,6 +13,21 @@ const targetURL = process.env.HASURA_GRAPHQL_URL!.replace(
);

export const $admin = new CoreDomainClient({
hasuraSecret: process.env.HASURA_GRAPHQL_ADMIN_SECRET!,
auth: { adminSecret: process.env.HASURA_GRAPHQL_ADMIN_SECRET! },
targetURL,
});

/**
* Get client authorised to the permissions level of the test user
*/
export const getClient = async () => {
const jwt = await buildJWT(TEST_EMAIL);
if (!jwt) throw Error("Unable to generate JWT for test user");

const client = new CoreDomainClient({
targetURL: process.env.HASURA_GRAPHQL_URL!,
auth: { jwt },
});

return client;
};
61 changes: 61 additions & 0 deletions e2e/tests/api-driven/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { TEST_EMAIL } from "../../ui-driven/src/helpers";
import { $admin } from "./client";

export async function createTeam() {
return $admin.team.create({
name: "E2E Test Team",
slug: "E2E",
logo: "https://raw.githubusercontent.com/theopensystemslab/planx-team-logos/main/planx-testing.svg",
primaryColor: "#444444",
submissionEmail: TEST_EMAIL,
homepage: "planx.uk",
});
}

export async function createUser() {
return $admin.user.create({
firstName: "Test",
lastName: "Test",
email: TEST_EMAIL,
});
}

export async function tearDownTestContext({
teamId,
userId,
flowId,
publishedFlowId,
sessionId,
paymentRequestId,
}: {
teamId?: number;
userId?: number;
flowId?: string;
publishedFlowId?: number;
sessionId?: string;
paymentRequestId?: string;
}) {
if (paymentRequestId) {
await $admin.paymentRequest._destroy(paymentRequestId);
}
if (sessionId) {
await $admin.application._destroyAll(sessionId);
await $admin.session._destroy(sessionId);
}
if (publishedFlowId) {
await $admin.flow._destroyPublished(publishedFlowId);
}
if (flowId) {
await $admin.flow._destroy(flowId);
}
if (userId) {
await $admin.user._destroy(userId);
}
if (teamId) {
await $admin.team._destroy(teamId);
}
}

export async function getTestUser() {
return await $admin.user.getByEmail(TEST_EMAIL);
}
55 changes: 0 additions & 55 deletions e2e/tests/api-driven/src/invite-to-pay/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,6 @@ export async function setUpMocks() {
});
}

export async function createTeam() {
return $admin.team.create({
name: "E2E Test Team",
slug: "E2E",
logo: "https://raw.githubusercontent.com/theopensystemslab/planx-team-logos/main/planx-testing.svg",
primaryColor: "#444444",
submissionEmail: TEST_EMAIL,
homepage: "planx.uk",
});
}

export async function createUser() {
return $admin.user.create({
firstName: "Test",
lastName: "Test",
email: TEST_EMAIL,
});
}

export async function buildITPFlow({
userId,
teamId,
Expand Down Expand Up @@ -146,39 +127,3 @@ export async function getSessionSubmittedAt(
const detailedSession = await $admin.session.findDetails(sessionId);
return detailedSession?.submittedAt;
}

export async function tearDownTestContext({
teamId,
userId,
flowId,
publishedFlowId,
sessionId,
paymentRequestId,
}: {
teamId?: number;
userId?: number;
flowId?: string;
publishedFlowId?: number;
sessionId?: string;
paymentRequestId?: string;
}) {
if (paymentRequestId) {
await $admin.paymentRequest._destroy(paymentRequestId);
}
if (sessionId) {
await $admin.application._destroyAll(sessionId);
await $admin.session._destroy(sessionId);
}
if (publishedFlowId) {
await $admin.flow._destroyPublished(publishedFlowId);
}
if (flowId) {
await $admin.flow._destroy(flowId);
}
if (userId) {
await $admin.user._destroy(userId);
}
if (teamId) {
await $admin.team._destroy(teamId);
}
}
27 changes: 4 additions & 23 deletions e2e/tests/api-driven/src/invite-to-pay/steps.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
import { strict as assert } from "node:assert";
import {
Given,
When,
Then,
BeforeAll,
After,
AfterAll,
} from "@cucumber/cucumber";
import { Given, When, Then, Before, After } from "@cucumber/cucumber";
import {
setUpMocks,
createTeam,
createUser,
buildITPFlow,
buildSessionForFlow,
buildPaymentRequestForSession,
markPaymentRequestAsPaid,
getSendResponse,
getSessionSubmittedAt,
waitForResponse,
tearDownTestContext,
} from "./helpers";
import { createTeam, createUser, tearDownTestContext } from "../helpers";

const context: {
teamId?: number;
Expand All @@ -30,7 +21,7 @@ const context: {
paymentRequestId?: string;
} = {};

BeforeAll(async () => {
Before("@invite-to-pay", async () => {
await setUpMocks();
context.teamId = await createTeam();
if (!context.teamId) {
Expand All @@ -43,17 +34,7 @@ BeforeAll(async () => {
});

// tear down each example but not user and team
After(async () => {
await tearDownTestContext({
flowId: context.flowId,
publishedFlowId: context.publishedFlowId,
sessionId: context.sessionId,
paymentRequestId: context.paymentRequestId,
});
});

// tear down everything
AfterAll(async () => {
After("@invite-to-pay", async () => {
await tearDownTestContext(context);
});

Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/api-driven/src/invite-to-pay/submissions.feature
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Feature: Invite to Pay Submissions

@regression
@regression @invite-to-pay
Scenario: Modified `paid_at` on sessions with a valid payment request
Given a session with a payment request for an invite to pay flow where "<DESTINATION>" is a send destination
When the payment request's `paid_at` date is set
Expand Down
51 changes: 51 additions & 0 deletions e2e/tests/api-driven/src/jwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { sign } from "jsonwebtoken";
import { User, Role } from "@opensystemslab/planx-core/types";
import { $admin } from "./client";

// This code is copied from api.planx.uk/modules/auth/service.ts

export const buildJWT = async (email: string): Promise<string | undefined> => {
const user = await $admin.user.getByEmail(email);
if (!user) return;

const data = {
sub: user.id.toString(),
"https://hasura.io/jwt/claims": generateHasuraClaimsForUser(user),
};

const jwt = sign(data, process.env.JWT_SECRET!);
return jwt;
};

const generateHasuraClaimsForUser = (user: User) => ({
"x-hasura-allowed-roles": getAllowedRolesForUser(user),
"x-hasura-default-role": getDefaultRoleForUser(user),
"x-hasura-user-id": user.id.toString(),
});

/**
* Get all possible roles for this user
* Requests made outside this scope will not be authorised by Hasura
*/
const getAllowedRolesForUser = (user: User): Role[] => {
const teamRoles = user.teams.map((teamRole) => teamRole.role);
const allowedRoles: Role[] = [
"public", // Allow public access
"teamEditor", // Least privileged role for authenticated users - required for Editor access
...teamRoles, // User specific roles
];
if (user.isPlatformAdmin) allowedRoles.push("platformAdmin");

return [...new Set(allowedRoles)];
};

/**
* The default role is used for all requests
* Can be overwritten on a per-request basis in the client using the x-hasura-role header
* set to a role in the x-hasura-allowed-roles list
*
* This is the role of least privilege for the user
*/
const getDefaultRoleForUser = (user: User): Role => {
return user.isPlatformAdmin ? "platformAdmin" : "teamEditor";
};
2 changes: 1 addition & 1 deletion e2e/tests/ui-driven/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"postinstall": "./install-dependencies.sh"
},
"dependencies": {
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#4e3d09f",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#17f3bf5",
"axios": "^1.4.0",
"dotenv": "^16.3.1",
"eslint": "^8.44.0",
Expand Down
8 changes: 4 additions & 4 deletions e2e/tests/ui-driven/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion e2e/tests/ui-driven/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function getCoreDomainClient(): CoreDomainClient {
);
const SECRET = process.env.HASURA_GRAPHQL_ADMIN_SECRET!;
return new CoreDomainClient({
hasuraSecret: SECRET,
auth: { adminSecret: SECRET },
targetURL: API,
});
}
Expand Down
2 changes: 1 addition & 1 deletion editor.planx.uk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@mui/styles": "^5.14.5",
"@mui/utils": "^5.14.5",
"@opensystemslab/map": "^0.7.5",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#4e3d09f",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#17f3bf5",
"@tiptap/core": "^2.0.3",
"@tiptap/extension-bold": "^2.0.3",
"@tiptap/extension-bubble-menu": "^2.1.6",
Expand Down
10 changes: 5 additions & 5 deletions editor.planx.uk/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4c6b04a

Please sign in to comment.