mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
Approver opens the drawer at the Measures section, picks a measure from the catalogue dropdown, submits, and the spec asserts the optimistic chip, the POST payload + response shape, and that the approval log surfaces the new approval row. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
93 lines
3.6 KiB
JavaScript
93 lines
3.6 KiB
JavaScript
/**
|
|
* Live Tracking — Instruct measure flow (issue #253)
|
|
*
|
|
* Verifies the approver flow for instructing a measure that the
|
|
* coordinator did not propose:
|
|
* 1. the approver opens the property drawer at the Measures section,
|
|
* 2. picks a measure from the canonical catalogue dropdown and submits,
|
|
* 3. the drawer reflects the new instructed measure (optimistic chip),
|
|
* 4. the POST hits the instructed-measures route which pushes
|
|
* `instructed_measures` back to HubSpot,
|
|
* 5. the approval log surface shows a row for the new approval.
|
|
*
|
|
* Mirrors `halted-state.cy.js` / `domna-survey.cy.js`. The spec uses
|
|
* `cy.intercept` so the HubSpot push side-effect is observable without a
|
|
* real CRM round-trip.
|
|
*/
|
|
|
|
const PORTFOLIO_SLUG = Cypress.env("LIVE_PORTFOLIO_SLUG");
|
|
const TARGET_DEAL_NAME = Cypress.env("LIVE_INSTRUCT_DEAL_NAME");
|
|
const INSTRUCT_MEASURE = "Loft insulation";
|
|
|
|
describe("Instruct measure — approver flow", function () {
|
|
before(function () {
|
|
if (!PORTFOLIO_SLUG) {
|
|
cy.log(
|
|
"LIVE_PORTFOLIO_SLUG env var not set — skipping live tracking specs",
|
|
);
|
|
this.skip();
|
|
}
|
|
});
|
|
|
|
function openDrawerForTargetDeal() {
|
|
cy.visit(`/portfolio/${PORTFOLIO_SLUG}/your-projects/live`);
|
|
|
|
// Switch to the Measures tab — the easiest way into the drawer at the
|
|
// Measures section.
|
|
cy.contains("button, [role=tab]", "Measures").click();
|
|
|
|
if (TARGET_DEAL_NAME) {
|
|
cy.contains("[data-testid=measures-row]", TARGET_DEAL_NAME).click();
|
|
} else {
|
|
cy.get("[data-testid=measures-row]").first().click();
|
|
}
|
|
|
|
cy.get("[data-testid=property-detail-drawer]").should("be.visible");
|
|
cy.get("[data-testid=drawer-section-measures]").should("exist");
|
|
}
|
|
|
|
it("lets an approver instruct a measure and reflects it in the drawer + approval log", () => {
|
|
// Capture the API call so we can assert the payload that would be
|
|
// pushed to HubSpot under `instructed_measures`.
|
|
cy.intercept(
|
|
"POST",
|
|
`/api/portfolio/*/instructed-measures`,
|
|
).as("instructMeasure");
|
|
|
|
openDrawerForTargetDeal();
|
|
|
|
// Approver-only form is visible at the bottom of the Measures section.
|
|
cy.get("[data-testid=instruct-measure-select]").should("be.visible");
|
|
|
|
cy.get("[data-testid=instruct-measure-select]").select(INSTRUCT_MEASURE);
|
|
cy.get("[data-testid=instruct-measure-submit]")
|
|
.should("not.be.disabled")
|
|
.click();
|
|
|
|
// Wait for the POST to land and assert the body shape that the
|
|
// service uses to drive the HubSpot push.
|
|
cy.wait("@instructMeasure").then((intercepted) => {
|
|
expect(intercepted.request.body).to.deep.include({
|
|
measureName: INSTRUCT_MEASURE,
|
|
});
|
|
// Response from our route signals the HubSpot sync outcome — it is
|
|
// either "ok" (mock recorded the push) or "failed" (network error).
|
|
// We accept either here so the spec stays portable across envs.
|
|
expect(intercepted.response.statusCode).to.be.oneOf([200, 201]);
|
|
expect(intercepted.response.body).to.have.property("ok", true);
|
|
expect(intercepted.response.body).to.have.property("hubspotSync");
|
|
});
|
|
|
|
// Drawer reflects the instructed measure as an optimistic chip.
|
|
cy.get("[data-testid=instructed-measures-list]").should("be.visible");
|
|
cy.get("[data-testid=instructed-measure-chip]")
|
|
.should("contain.text", INSTRUCT_MEASURE);
|
|
|
|
// No error banner.
|
|
cy.get("[data-testid=instruct-measure-error]").should("not.exist");
|
|
|
|
// Approval log section reveals the new approval row when expanded.
|
|
cy.contains("Approval Log").click();
|
|
cy.contains(INSTRUCT_MEASURE).should("exist");
|
|
});
|
|
});
|