From af906d8d0bd0d19643a812abb6dfd5a9192d9335 Mon Sep 17 00:00:00 2001 From: Emma Hoggan Date: Mon, 27 Jul 2026 11:45:15 -0600 Subject: [PATCH] Write the viewer_emails/editor_emails values when initializing studio reports so the values can be carried over/edited from current state on updates. --- CHANGELOG.md | 4 +++ src/commands/studio/reports.test.ts | 44 +++++++++++++++++++++++++++++ src/commands/studio/reports.ts | 6 ++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0981e42..4d561c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- Write the viewer_emails/editor_emails values when initializing studio reports so the values can be carried over/edited from current state on updates. + ## 0.6.0 - 2026-07-21 ### Added diff --git a/src/commands/studio/reports.test.ts b/src/commands/studio/reports.test.ts index 071dcbb..2a72063 100644 --- a/src/commands/studio/reports.test.ts +++ b/src/commands/studio/reports.test.ts @@ -74,7 +74,9 @@ describe("studio reports command", () => { description: "Deployment trends by week", markdown_notes: null, view_access_type: "everyone", + viewer_emails: [], edit_access_type: "specific_users", + editor_emails: ["editor@example.com"], owner: { id: "usr_abc", name: "Alice Example", @@ -546,6 +548,7 @@ describe("studio reports command", () => { expect(yaml).toContain('owner_email: ""'); expect(yaml).toContain("view_access_type: everyone"); expect(yaml).toContain("edit_access_type: specific_users"); + expect(yaml).toContain("editor_emails:\n - editor@example.com"); expect(yaml).toContain("title: Weekly deploys"); expect(yaml).toContain("chart_type: line"); @@ -557,6 +560,47 @@ describe("studio reports command", () => { ); }); + it("--id carries over the report's specific-people viewer list", async () => { + process.env.DX_API_BASE_URL = "https://api.example.com"; + getToken.mockReturnValue("token-123"); + + vi.stubGlobal( + "fetch", + vi.fn().mockResolvedValueOnce( + new Response( + JSON.stringify({ + ok: true, + report: { + ...report, + view_access_type: "specific_users", + viewer_emails: ["viewer@example.com"], + }, + }), + { status: 200 }, + ), + ), + ); + const writeFileSyncSpy = vi + .spyOn(fs, "writeFileSync") + .mockImplementation(() => undefined); + + const { run } = await import("../../cli.js"); + await run([ + "node", + "dx", + "studio", + "reports", + "init", + "./my-report.yaml", + "--id", + "rpt_new", + ]); + + const yaml = writeFileSyncSpy.mock.calls[0]?.[1] as string; + expect(yaml).toContain("view_access_type: specific_users"); + expect(yaml).toContain("viewer_emails:\n - viewer@example.com"); + }); + it("--id omits read-only fields from the written YAML", async () => { process.env.DX_API_BASE_URL = "https://api.example.com"; getToken.mockReturnValue("token-123"); diff --git a/src/commands/studio/reports.ts b/src/commands/studio/reports.ts index 2dfa5f6..4ecfd93 100644 --- a/src/commands/studio/reports.ts +++ b/src/commands/studio/reports.ts @@ -335,7 +335,9 @@ type StudioReport = { description: string | null; markdown_notes: string | null; view_access_type: string; + viewer_emails: string[]; edit_access_type: string; + editor_emails: string[]; owner: StudioReportOwner | null; url: string; tiles: StudioReportTile[]; @@ -641,9 +643,9 @@ function studioReportToYaml(report: StudioReport): string { description: report.description ?? "", markdown_notes: report.markdown_notes ?? "", view_access_type: report.view_access_type, - viewer_emails: [], + viewer_emails: report.viewer_emails ?? [], edit_access_type: report.edit_access_type, - editor_emails: [], + editor_emails: report.editor_emails ?? [], tiles: report.tiles.map((tile) => ({ id: tile.id, title: tile.title,