mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-07-27 22:45:03 +00:00
Code review: /onboarding is *user* onboarding, not Portfolio onboarding.
It captures the user's details and their required privacy-policy
acceptance (plus marketing opt-in) and touches no Portfolio at all —
confirmed by the form schema in src/app/onboarding/page.tsx, which has
no portfolio coupling and makes acceptedPrivacy mandatory.
The exemption added in e34f166f was therefore wrong: it let contractor
users into the app without the consent we are required to capture. A
contractor can complete onboarding perfectly well, so nobody needs the
bypass.
Removes the /projects exemption and isProjectsPath(). /projects stays in
the matcher, so the tree is still auth-guarded. Unit and Cypress tests
inverted to assert the corrected behaviour, plus a new case covering an
onboarded contractor reaching /projects.
Refs #406
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
96 lines
3 KiB
JavaScript
96 lines
3 KiB
JavaScript
/**
|
|
* Ara Projects — route shell smoke test (issue #406)
|
|
*
|
|
* Covers the two acceptance criteria for the shell:
|
|
* 1. an unauthenticated visit to /projects is redirected to /,
|
|
* 2. an authenticated user reaches /projects and the layout + nav render.
|
|
*
|
|
* Uses the `cy.login` command from cypress/support/commands.ts, which mints a
|
|
* real next-auth JWE cookie so the *server* middleware sees a session (the
|
|
* /api/auth/session stub alone would not be enough — middleware reads the
|
|
* cookie). Requires NEXTAUTH_JWT_SECRET in the Cypress env, same as the
|
|
* live-tracking specs.
|
|
*/
|
|
|
|
const JWT_SECRET = Cypress.env("NEXTAUTH_JWT_SECRET");
|
|
|
|
describe("Ara Projects route shell", function () {
|
|
before(function () {
|
|
if (!JWT_SECRET) {
|
|
cy.log("NEXTAUTH_JWT_SECRET not set — skipping projects shell spec");
|
|
this.skip();
|
|
}
|
|
});
|
|
|
|
it("redirects an unauthenticated visitor to the sign-in page", function () {
|
|
cy.clearCookies();
|
|
cy.visit("/projects", { failOnStatusCode: false });
|
|
cy.location("pathname").should("eq", "/");
|
|
});
|
|
|
|
it("renders the shell and nav for an authenticated internal user", function () {
|
|
cy.login({
|
|
email: "dev@domna.homes",
|
|
name: "Internal User",
|
|
onboarded: true,
|
|
sub: "cypress-internal",
|
|
});
|
|
|
|
cy.visit("/projects");
|
|
|
|
cy.location("pathname").should("eq", "/projects");
|
|
cy.get("[data-testid=projects-shell]").should("exist");
|
|
cy.get("[data-testid=projects-nav-projects]")
|
|
.should("be.visible")
|
|
.and("have.attr", "aria-current", "page");
|
|
cy.contains("h1", "Projects").should("be.visible");
|
|
});
|
|
|
|
it("sends a non-onboarded user to onboarding", function () {
|
|
// /onboarding captures user details and the required privacy-policy
|
|
// acceptance — it is not Portfolio onboarding, so contractors complete it
|
|
// too and nobody reaches /projects without it.
|
|
cy.login({
|
|
email: "site@contractor.example",
|
|
name: "Contractor User",
|
|
onboarded: false,
|
|
sub: "cypress-contractor",
|
|
});
|
|
|
|
cy.visit("/projects");
|
|
|
|
cy.location("pathname").should("eq", "/onboarding");
|
|
});
|
|
|
|
it("lets an onboarded contractor into /projects", function () {
|
|
cy.login({
|
|
email: "site@contractor.example",
|
|
name: "Contractor User",
|
|
onboarded: true,
|
|
sub: "cypress-contractor",
|
|
});
|
|
|
|
cy.visit("/projects");
|
|
|
|
cy.location("pathname").should("eq", "/projects");
|
|
cy.get("[data-testid=projects-shell]").should("exist");
|
|
});
|
|
|
|
it("renders the per-project dashboard shell and its nav", function () {
|
|
cy.login({
|
|
email: "dev@domna.homes",
|
|
name: "Internal User",
|
|
onboarded: true,
|
|
sub: "cypress-internal",
|
|
});
|
|
|
|
cy.visit("/projects/1");
|
|
|
|
cy.get("[data-testid=project-shell]").should("exist");
|
|
cy.get("[data-testid=project-dashboard-heading]").should("be.visible");
|
|
|
|
["dashboard", "workOrders", "import", "settings"].forEach((item) => {
|
|
cy.get(`[data-testid=projects-nav-${item}]`).should("be.visible");
|
|
});
|
|
});
|
|
});
|