From 3ed94f2cb41dca4d48ce6d4ae38022c2d4b53adc Mon Sep 17 00:00:00 2001 From: sanil-23 Date: Mon, 7 Sep 2026 17:19:32 +0530 Subject: [PATCH] fix(console): pin the create/reset flow against the build that offers it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `main` has been red on the Console job since b8a3e2e97. That commit moved company creation behind one funnel — `canCreateCompanies` is now `!COMPANY_SWITCHING_HIDDEN && carriesPlatformBearer` — and added the test that pins the hide. What it did not do is update the four older files that assert the presence of the very controls it had just hidden, so ten tests across them have been failing ever since: settings-lifecycle-reset-button the Reset button no longer renders create-company-wallet-mode the dialog's preflight no longer runs, create-company-dialog-preflight-race so the wallet field never appears and submit is never held connection-console-switch-known-status the no-company New trigger is gone `COMPANY_SWITCHING_HIDDEN` ships `true`, so those premises are now unreachable rather than wrong — the flow they cover is still in the tree, it is just not offered. So they declare the configuration they need instead of asserting against one the product does not ship. Mocking the flag here does not weaken the hide. That has its own deliberately-unmocked coverage in `product-scope-hidden-surfaces.test.ts` ("company creation is gone from every trigger, not just the switcher"), which is where a regression in the gate belongs and which still passes untouched. What these four keep testing is the flow underneath it — including the #1894 pre-archive guard, whose whole job is to stop a reset archiving a company before it knows the replacement has a usable admin. That is worth failing a build over on the day the flag flips back, and deleting it to get to green would have thrown it away. No production code changes: the gate behaves as intended. npm run typecheck, typecheck:unit — clean npm test — 495 files, 4584 tests, 0 failures Co-Authored-By: Claude Opus 5 --- ...ection-console-switch-known-status.test.ts | 26 +++++++++++++++++++ ...eate-company-dialog-preflight-race.test.ts | 26 +++++++++++++++++++ .../unit/create-company-wallet-mode.test.ts | 26 +++++++++++++++++++ .../settings-lifecycle-reset-button.test.ts | 26 +++++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/frontend/test/unit/connection-console-switch-known-status.test.ts b/frontend/test/unit/connection-console-switch-known-status.test.ts index f7a81f170f..70d417ab79 100644 --- a/frontend/test/unit/connection-console-switch-known-status.test.ts +++ b/frontend/test/unit/connection-console-switch-known-status.test.ts @@ -8,6 +8,32 @@ import type { OpenCompanyClient } from "@/api/client"; import type { AppSpec, CompanyStatus } from "@/api/types"; import { HostsProvider } from "@/connections/HostsContext"; +/** + * These exercise the create/reset flow itself, so they need the build where the + * product offers it. + * + * `canCreateCompanies` is `!COMPANY_SWITCHING_HIDDEN && carriesPlatformBearer` + * (b8a3e2e97), and `COMPANY_SWITCHING_HIDDEN` ships `true` — so in the shipped + * tree every trigger below is hidden and the dialog's own preflight never runs. + * Left unmocked, these files would assert against controls the product + * deliberately does not render, which is what broke them: they would be pinning + * the flag rather than the flow. + * + * The *hide* is not weakened by this. It has its own coverage, deliberately + * unmocked, in `product-scope-hidden-surfaces.test.ts` ("company creation is + * gone from every trigger, not just the switcher"), which is where a regression + * in the gate belongs. What is left here is the flow underneath it — including + * the #1894 pre-archive guard, whose whole job is to keep a reset from + * archiving a company before it knows the replacement has a usable admin. That + * logic is still in the tree and still worth failing a build over the day the + * flag flips back. + */ +vi.mock("@/product-scope", async (importOriginal) => ({ + ...(await importOriginal()), + COMPANY_SWITCHING_HIDDEN: false, +})); + + /** * Codex review on #1828 (PR comment 3864628314): `switchCompany`'s only * caller that already holds fresh data for the company it is entering — diff --git a/frontend/test/unit/create-company-dialog-preflight-race.test.ts b/frontend/test/unit/create-company-dialog-preflight-race.test.ts index 4ffe4df0df..8e15e139de 100644 --- a/frontend/test/unit/create-company-dialog-preflight-race.test.ts +++ b/frontend/test/unit/create-company-dialog-preflight-race.test.ts @@ -8,6 +8,32 @@ import type { OpenCompanyClient } from "@/api/client"; import type { CompanyStatus, ProvisioningInfo } from "@/api/types"; import { CreateCompanyDialog } from "@/components/create-company-dialog"; +/** + * These exercise the create/reset flow itself, so they need the build where the + * product offers it. + * + * `canCreateCompanies` is `!COMPANY_SWITCHING_HIDDEN && carriesPlatformBearer` + * (b8a3e2e97), and `COMPANY_SWITCHING_HIDDEN` ships `true` — so in the shipped + * tree every trigger below is hidden and the dialog's own preflight never runs. + * Left unmocked, these files would assert against controls the product + * deliberately does not render, which is what broke them: they would be pinning + * the flag rather than the flow. + * + * The *hide* is not weakened by this. It has its own coverage, deliberately + * unmocked, in `product-scope-hidden-surfaces.test.ts` ("company creation is + * gone from every trigger, not just the switcher"), which is where a regression + * in the gate belongs. What is left here is the flow underneath it — including + * the #1894 pre-archive guard, whose whole job is to keep a reset from + * archiving a company before it knows the replacement has a usable admin. That + * logic is still in the tree and still worth failing a build over the day the + * flag flips back. + */ +vi.mock("@/product-scope", async (importOriginal) => ({ + ...(await importOriginal()), + COMPANY_SWITCHING_HIDDEN: false, +})); + + /** * Codex review on #1943 (PR comment 3894416362): on a wallet-mode host with a * slow or pending provisioning preflight, the dialog used to open with its diff --git a/frontend/test/unit/create-company-wallet-mode.test.ts b/frontend/test/unit/create-company-wallet-mode.test.ts index dc47e6666d..2b1e937660 100644 --- a/frontend/test/unit/create-company-wallet-mode.test.ts +++ b/frontend/test/unit/create-company-wallet-mode.test.ts @@ -12,6 +12,32 @@ import { type CreateCompanyRequest, } from "@/components/create-company-dialog"; +/** + * These exercise the create/reset flow itself, so they need the build where the + * product offers it. + * + * `canCreateCompanies` is `!COMPANY_SWITCHING_HIDDEN && carriesPlatformBearer` + * (b8a3e2e97), and `COMPANY_SWITCHING_HIDDEN` ships `true` — so in the shipped + * tree every trigger below is hidden and the dialog's own preflight never runs. + * Left unmocked, these files would assert against controls the product + * deliberately does not render, which is what broke them: they would be pinning + * the flag rather than the flow. + * + * The *hide* is not weakened by this. It has its own coverage, deliberately + * unmocked, in `product-scope-hidden-surfaces.test.ts` ("company creation is + * gone from every trigger, not just the switcher"), which is where a regression + * in the gate belongs. What is left here is the flow underneath it — including + * the #1894 pre-archive guard, whose whole job is to keep a reset from + * archiving a company before it knows the replacement has a usable admin. That + * logic is still in the tree and still worth failing a build over the day the + * flag flips back. + */ +vi.mock("@/product-scope", async (importOriginal) => ({ + ...(await importOriginal()), + COMPANY_SWITCHING_HIDDEN: false, +})); + + /** * The wallet-mode create/reset flow (issues #1914, #1894). * diff --git a/frontend/test/unit/settings-lifecycle-reset-button.test.ts b/frontend/test/unit/settings-lifecycle-reset-button.test.ts index cf662b428e..b17dfadd4f 100644 --- a/frontend/test/unit/settings-lifecycle-reset-button.test.ts +++ b/frontend/test/unit/settings-lifecycle-reset-button.test.ts @@ -9,6 +9,32 @@ import type { OpenCompanyClient } from "@/api/client"; import type { CompanyStatus } from "@/api/types"; import { LifecycleControls } from "@/views/SettingsView"; +/** + * These exercise the create/reset flow itself, so they need the build where the + * product offers it. + * + * `canCreateCompanies` is `!COMPANY_SWITCHING_HIDDEN && carriesPlatformBearer` + * (b8a3e2e97), and `COMPANY_SWITCHING_HIDDEN` ships `true` — so in the shipped + * tree every trigger below is hidden and the dialog's own preflight never runs. + * Left unmocked, these files would assert against controls the product + * deliberately does not render, which is what broke them: they would be pinning + * the flag rather than the flow. + * + * The *hide* is not weakened by this. It has its own coverage, deliberately + * unmocked, in `product-scope-hidden-surfaces.test.ts` ("company creation is + * gone from every trigger, not just the switcher"), which is where a regression + * in the gate belongs. What is left here is the flow underneath it — including + * the #1894 pre-archive guard, whose whole job is to keep a reset from + * archiving a company before it knows the replacement has a usable admin. That + * logic is still in the tree and still worth failing a build over the day the + * flag flips back. + */ +vi.mock("@/product-scope", async (importOriginal) => ({ + ...(await importOriginal()), + COMPANY_SWITCHING_HIDDEN: false, +})); + + /** * The Reset / Start clean button (#1807, SettingsView.tsx `LifecycleControls`) * had no render test of its own — tinysweeper flagged the gap (PR comment