-
Notifications
You must be signed in to change notification settings - Fork 7
feat: console: gate Settings ▸ Secrets behind secrets-panel dev flag
#2121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import { describe, expect, it } from "vitest"; | ||
|
|
||
| import { visibleSections } from "./sectionGate"; | ||
| import src from "./SettingsSurface.tsx?raw"; | ||
| import flags from "../../../../runtime/flags.py?raw"; | ||
|
|
||
| // Settings ▸ Secrets is gated to the dev channel (ADR 0068). The external secrets manager's | ||
| // connect/test/sync flow stays behind `secrets-panel` until it's exercised end to end, so it | ||
| // only shows on the dev channel / via override (#2120). | ||
| // | ||
| // Behavior first (the QA panel's fix-first on the original head): exercise the REAL filter | ||
| // with the flag both ways — a grep-only test would stay green if the gating itself broke. | ||
| // Source guards second, for the failure mode of someone deleting the `flag:` key during an | ||
| // unrelated edit: that type-checks, renders fine on their machine, and silently re-exposes a | ||
| // pre-release panel on the prod channel. | ||
|
|
||
| const SECTIONS = [ | ||
| { id: "identity" }, | ||
| { id: "secrets", flag: "secrets-panel" }, | ||
| { id: "plugins" }, | ||
| ]; | ||
|
|
||
| describe("Settings ▸ Secrets is flag-gated (#2120)", () => { | ||
| it("flag off → the secrets section is dropped; unflagged sections survive", () => { | ||
| const out = visibleSections(SECTIONS, () => false); | ||
| expect(out.find((s) => s.id === "secrets")).toBeUndefined(); | ||
| expect(out.map((s) => s.id)).toEqual(["identity", "plugins"]); | ||
| }); | ||
|
|
||
| it("flag on → the secrets section is present, nothing else changes", () => { | ||
| const out = visibleSections(SECTIONS, (id) => id === "secrets-panel"); | ||
| expect(out.find((s) => s.id === "secrets")).toBeDefined(); | ||
| expect(out).toHaveLength(SECTIONS.length); | ||
| }); | ||
|
|
||
| it("the real secrets Section carries the flag (order-insensitive)", () => { | ||
| // Extract the one object literal containing id: "secrets" and assert the flag key is | ||
| // inside it — survives key reordering and reformatting, unlike a cross-key regex. | ||
| const obj = src.match(/\{[^{}]*id: "secrets"[^{}]*\}/)?.[0] ?? ""; | ||
| expect(obj).not.toBe(""); | ||
| expect(obj).toContain('flag: "secrets-panel"'); | ||
| }); | ||
|
|
||
| it("SettingsSurface routes every section list through the pure gate", () => { | ||
| // The component must call the SAME visibleSections this test exercises — and the | ||
| // agent group (where secrets lives) must go through shown(). | ||
| expect(src).toContain('import { visibleSections } from "./sectionGate"'); | ||
| expect(src).toMatch(/const shown = \(list: Section\[\]\) => visibleSections\(list, flagOn\)/); | ||
| expect(src).toMatch(/shown\(AGENT_SECTIONS\)/); | ||
| }); | ||
|
|
||
| it("the flag ships at tier dev", () => { | ||
| expect(flags).toMatch(/id="secrets-panel"[\s\S]*?tier="dev"/); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| // Pure half of the settings flag gate (ADR 0068): drop sections whose `flag` resolves | ||
| // off. Extracted from SettingsSurface so the gating is unit-testable without importing | ||
| // the whole settings tree (secretsGate.test.ts exercises it with the flag both ways) — | ||
| // the component wires `flagOn` to useFlagPredicate(). | ||
| export type GatedSection = { id: string; flag?: string }; | ||
|
|
||
| export function visibleSections<T extends GatedSection>(list: T[], flagOn: (id: string) => boolean): T[] { | ||
| return list.filter((s) => !s.flag || flagOn(s.flag)); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.