mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 15:30:56 +00:00
96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
/**
|
|
* Auth model (see apps/edr-freight-api + freight web apps):
|
|
* - POST {api}/api/auth/login { email, password }
|
|
* → flattened body { success, token, refreshToken } (response interceptor
|
|
* flattens /api/auth responses — no .data nesting).
|
|
* - Both web apps read cookies `auth-token` / `refresh-token` and attach
|
|
* `Authorization: Bearer <token>`.
|
|
* - Cookies are port-agnostic on localhost, so portal and backoffice share
|
|
* one cookie jar. cy.session snapshots/restores cookies per session id,
|
|
* which keeps staff and customer sessions from clobbering each other —
|
|
* but inside a single test, switching apps requires re-invoking the
|
|
* matching login command first (see flows specs).
|
|
*/
|
|
|
|
export interface LoginBody {
|
|
success: boolean;
|
|
token: string;
|
|
refreshToken: string;
|
|
}
|
|
|
|
const apiUrl = () => Cypress.env("apiUrl") as string;
|
|
const password = () => Cypress.env("defaultPassword") as string;
|
|
|
|
function apiLogin(email: string, pass?: string): Cypress.Chainable<LoginBody> {
|
|
return cy
|
|
.request<LoginBody>("POST", `${apiUrl()}/api/auth/login`, {
|
|
email,
|
|
password: pass ?? password(),
|
|
})
|
|
.then((response) => {
|
|
expect(response.status).to.eq(201);
|
|
expect(response.body.token, "login token").to.be.a("string");
|
|
return cy.wrap(response.body, { log: false });
|
|
});
|
|
}
|
|
|
|
function sessionFor(app: "backoffice" | "portal", email: string, pass?: string) {
|
|
cy.session(
|
|
[app, email],
|
|
() => {
|
|
apiLogin(email, pass).then(({ token, refreshToken }) => {
|
|
cy.setCookie("auth-token", token);
|
|
cy.setCookie("refresh-token", refreshToken);
|
|
});
|
|
},
|
|
{
|
|
cacheAcrossSpecs: true,
|
|
validate() {
|
|
cy.getCookie("auth-token").then((cookie) => {
|
|
expect(cookie, "auth-token cookie").to.exist;
|
|
cy.request({
|
|
url: `${apiUrl()}/api/me`,
|
|
headers: { Authorization: `Bearer ${cookie!.value}` },
|
|
})
|
|
.its("status")
|
|
.should("eq", 200);
|
|
});
|
|
},
|
|
},
|
|
);
|
|
}
|
|
|
|
Cypress.Commands.add("apiLogin", (email: string, pass?: string) => apiLogin(email, pass));
|
|
|
|
Cypress.Commands.add("loginBackoffice", (email = "ceo@edr.local", pass?: string) => {
|
|
sessionFor("backoffice", email, pass);
|
|
});
|
|
|
|
Cypress.Commands.add("loginPortal", (email = "user@gmail.com", pass?: string) => {
|
|
// Demo portal users are seeded with a hardcoded password (DemoUsersSeeder),
|
|
// unlike staff users which use DEFAULT_PASSWORD.
|
|
sessionFor("portal", email, pass ?? (Cypress.env("demoPassword") as string));
|
|
});
|
|
|
|
Cypress.Commands.add("visitPortal", (path = "/") => {
|
|
cy.visit(`${Cypress.env("portalUrl")}${path}`);
|
|
});
|
|
|
|
declare global {
|
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
namespace Cypress {
|
|
interface Chainable {
|
|
/** POST /api/auth/login, returns the flattened token body. */
|
|
apiLogin(email: string, pass?: string): Chainable<LoginBody>;
|
|
/** Cached programmatic staff session (default ceo@edr.local). */
|
|
loginBackoffice(email?: string, pass?: string): Chainable<void>;
|
|
/** Cached programmatic customer session (default user@gmail.com). */
|
|
loginPortal(email?: string, pass?: string): Chainable<void>;
|
|
/** cy.visit against the portal origin (env.portalUrl). */
|
|
visitPortal(path?: string): Chainable<void>;
|
|
}
|
|
}
|
|
}
|
|
|
|
export {};
|