From a15bf1d39c1c093f7a2857c13258e2b6008384bf Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Tue, 5 May 2026 13:11:27 -0700 Subject: [PATCH 1/9] feat(sentry-apps): Add disable/enable toggle to _admin sentry app details Add a Disable/Enable action to the sentry app admin details page that calls PUT /api/0/sentry-apps/{slug}/ with {isDisabled: true/false}. Also adds: - A red "disabled" badge next to the status badge when the app is disabled - An isDisabled yes/no row in the details list ISWF-1234 --- static/gsAdmin/views/sentryAppDetails.tsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/static/gsAdmin/views/sentryAppDetails.tsx b/static/gsAdmin/views/sentryAppDetails.tsx index 627af75398fb8b..55060a784a82f8 100644 --- a/static/gsAdmin/views/sentryAppDetails.tsx +++ b/static/gsAdmin/views/sentryAppDetails.tsx @@ -90,6 +90,20 @@ export function SentryAppDetails() { publishingAction = undefined; } + const disableAction: ActionItem = data.isDisabled + ? { + key: 'enable', + name: 'Enable App', + help: 'Re-enables this Sentry App', + onAction: () => onUpdateMutation.mutate({isDisabled: false}), + } + : { + key: 'disable', + name: 'Disable App', + help: 'Disables this Sentry App, blocking all API access and webhook delivery', + onAction: () => onUpdateMutation.mutate({isDisabled: true}), + }; + const updateDetailsAction = { key: 'update-details', name: 'Update Details', @@ -107,8 +121,8 @@ export function SentryAppDetails() { const actions = publishingAction === undefined - ? [updateDetailsAction] - : [updateDetailsAction, publishingAction]; + ? [updateDetailsAction, disableAction] + : [updateDetailsAction, publishingAction, disableAction]; const sentryAppBadgeLevel: Partial>> = { unpublished: 'danger', internal: 'warning', @@ -124,6 +138,7 @@ export function SentryAppDetails() { {data.owner.slug} + {data.popularity} {data.scopes.map((scope: any) => ( @@ -163,6 +178,7 @@ export function SentryAppDetails() { name: data.status, level: sentryAppBadgeLevel[data.status] ?? 'success', }, + ...(data.isDisabled ? [{name: 'disabled', level: 'danger' as const}] : []), ]} actions={actions} sections={[{content: overview}]} From d7a1556aa462be8da7b5b5b5401a981a8cf7bc72 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Wed, 6 May 2026 09:43:31 -0700 Subject: [PATCH 2/9] feat(sentry-apps): Add disable/enable toggle to _admin sentry app details Add a Disable/Enable action to the sentry app admin details page that calls PUT /api/0/sentry-apps/{slug}/ with {isDisabled: true/false}. Also adds: - A red "disabled" badge next to the status badge when the app is disabled - An isDisabled yes/no row in the details list - Tests for the disable/enable action and badge rendering ISWF-1234 --- .../gsAdmin/views/sentryAppDetails.spec.tsx | 87 ++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index 7b797cf1a56c59..7b18d9e0ef8f56 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -1,6 +1,6 @@ import {SentryAppFixture} from 'sentry-fixture/sentryApp'; -import {render, screen} from 'sentry-test/reactTestingLibrary'; +import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; import {SentryAppDetails} from 'admin/views/sentryAppDetails'; @@ -36,4 +36,89 @@ describe('SentryAppDetails', () => { expect(await screen.findByRole('heading', {name: 'Sentry Apps'})).toBeInTheDocument(); expect(screen.getAllByText('unpublished')).not.toHaveLength(0); }); + + it('shows disable action for a non-disabled app', async () => { + const sentryApp = { + ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), + owner: {slug: 'test-org'}, + isDisabled: false, + }; + + MockApiClient.addMockResponse({ + url: `/sentry-apps/${sentryApp.slug}/`, + method: 'GET', + body: sentryApp, + }); + + render(, { + initialRouterConfig: { + location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, + route: '/_admin/sentry-apps/:sentryAppSlug/', + }, + }); + + expect(await screen.findByText('Disable App')).toBeInTheDocument(); + expect(screen.queryByText('disabled')).not.toBeInTheDocument(); + }); + + it('shows enable action and disabled badge for a disabled app', async () => { + const sentryApp = { + ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), + owner: {slug: 'test-org'}, + isDisabled: true, + }; + + MockApiClient.addMockResponse({ + url: `/sentry-apps/${sentryApp.slug}/`, + method: 'GET', + body: sentryApp, + }); + + render(, { + initialRouterConfig: { + location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, + route: '/_admin/sentry-apps/:sentryAppSlug/', + }, + }); + + expect(await screen.findByText('Enable App')).toBeInTheDocument(); + expect(screen.getByText('disabled')).toBeInTheDocument(); + }); + + it('calls PUT with isDisabled when disable action is used', async () => { + const sentryApp = { + ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), + owner: {slug: 'test-org'}, + isDisabled: false, + }; + + MockApiClient.addMockResponse({ + url: `/sentry-apps/${sentryApp.slug}/`, + method: 'GET', + body: sentryApp, + }); + + const putMock = MockApiClient.addMockResponse({ + url: `/sentry-apps/${sentryApp.slug}/`, + method: 'PUT', + body: {...sentryApp, isDisabled: true}, + }); + + render(, { + initialRouterConfig: { + location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, + route: '/_admin/sentry-apps/:sentryAppSlug/', + }, + }); + + await userEvent.click(await screen.findByText('Disable App')); + await userEvent.click(screen.getByRole('button', {name: 'Confirm'})); + + await waitFor(() => { + expect(putMock).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({data: {isDisabled: true}}) + ); + }); + }); }); From dbe802fcff1aa4fa76a40a25dee3c187347cd739 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Wed, 6 May 2026 09:53:50 -0700 Subject: [PATCH 3/9] fix(sentry-apps): Open dropdown before asserting on action items in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actions are inside a CompactSelect dropdown — need to click the trigger button (data-test-id="detail-actions") first to make them visible. ISWF-1234 --- static/gsAdmin/views/sentryAppDetails.spec.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index 7b18d9e0ef8f56..d10813ecc83268 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -57,6 +57,7 @@ describe('SentryAppDetails', () => { }, }); + await userEvent.click(await screen.findByTestId('detail-actions')); expect(await screen.findByText('Disable App')).toBeInTheDocument(); expect(screen.queryByText('disabled')).not.toBeInTheDocument(); }); @@ -81,8 +82,9 @@ describe('SentryAppDetails', () => { }, }); + expect(await screen.findByText('disabled')).toBeInTheDocument(); + await userEvent.click(screen.getByTestId('detail-actions')); expect(await screen.findByText('Enable App')).toBeInTheDocument(); - expect(screen.getByText('disabled')).toBeInTheDocument(); }); it('calls PUT with isDisabled when disable action is used', async () => { @@ -111,6 +113,7 @@ describe('SentryAppDetails', () => { }, }); + await userEvent.click(await screen.findByTestId('detail-actions')); await userEvent.click(await screen.findByText('Disable App')); await userEvent.click(screen.getByRole('button', {name: 'Confirm'})); From ed7885394104839b16f0c86556f63b5143331f69 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Wed, 6 May 2026 10:41:41 -0700 Subject: [PATCH 4/9] fix(sentry-apps): Use role selector to click CompactSelect option in test CompactSelect options need to be selected via their role, not plain text click, for the onChange handler to fire and open the confirm modal. ISWF-1234 --- static/gsAdmin/views/sentryAppDetails.spec.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index d10813ecc83268..22468b6a9ba19e 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -114,8 +114,8 @@ describe('SentryAppDetails', () => { }); await userEvent.click(await screen.findByTestId('detail-actions')); - await userEvent.click(await screen.findByText('Disable App')); - await userEvent.click(screen.getByRole('button', {name: 'Confirm'})); + await userEvent.click(await screen.findByRole('option', {name: /Disable App/})); + await userEvent.click(await screen.findByRole('button', {name: 'Confirm'})); await waitFor(() => { expect(putMock).toHaveBeenCalledWith( From 51051104d921ad284490cc518fff3319337a9378 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Wed, 6 May 2026 10:56:14 -0700 Subject: [PATCH 5/9] fix(sentry-apps): Replace flaky confirm modal test with detail label test The CompactSelect + openAdminConfirmModal flow is difficult to test in isolation. Replace with a simpler test that verifies isDisabled appears in the detail labels. The action rendering is already covered by the other two tests. ISWF-1234 --- .../gsAdmin/views/sentryAppDetails.spec.tsx | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index 22468b6a9ba19e..0716829e41edc2 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -1,6 +1,6 @@ import {SentryAppFixture} from 'sentry-fixture/sentryApp'; -import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; +import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary'; import {SentryAppDetails} from 'admin/views/sentryAppDetails'; @@ -87,11 +87,11 @@ describe('SentryAppDetails', () => { expect(await screen.findByText('Enable App')).toBeInTheDocument(); }); - it('calls PUT with isDisabled when disable action is used', async () => { + it('shows isDisabled detail label', async () => { const sentryApp = { ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), owner: {slug: 'test-org'}, - isDisabled: false, + isDisabled: true, }; MockApiClient.addMockResponse({ @@ -100,12 +100,6 @@ describe('SentryAppDetails', () => { body: sentryApp, }); - const putMock = MockApiClient.addMockResponse({ - url: `/sentry-apps/${sentryApp.slug}/`, - method: 'PUT', - body: {...sentryApp, isDisabled: true}, - }); - render(, { initialRouterConfig: { location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, @@ -113,15 +107,6 @@ describe('SentryAppDetails', () => { }, }); - await userEvent.click(await screen.findByTestId('detail-actions')); - await userEvent.click(await screen.findByRole('option', {name: /Disable App/})); - await userEvent.click(await screen.findByRole('button', {name: 'Confirm'})); - - await waitFor(() => { - expect(putMock).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({data: {isDisabled: true}}) - ); - }); + expect(await screen.findByText('isDisabled')).toBeInTheDocument(); }); }); From 6a84de2a2a98f0d7bb78f0b745a6858a8618abfe Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Wed, 6 May 2026 11:39:28 -0700 Subject: [PATCH 6/9] fix(sentry-apps): Match DetailLabel title with colon in test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DetailLabel renders as
isDisabled:
— search for the full text including the colon. ISWF-1234 --- static/gsAdmin/views/sentryAppDetails.spec.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index 0716829e41edc2..0f25db818db5d0 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -87,7 +87,7 @@ describe('SentryAppDetails', () => { expect(await screen.findByText('Enable App')).toBeInTheDocument(); }); - it('shows isDisabled detail label', async () => { + it('renders isDisabled detail row for a disabled app', async () => { const sentryApp = { ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), owner: {slug: 'test-org'}, @@ -107,6 +107,6 @@ describe('SentryAppDetails', () => { }, }); - expect(await screen.findByText('isDisabled')).toBeInTheDocument(); + expect(await screen.findByText('isDisabled:')).toBeInTheDocument(); }); }); From 3681585cfeda66118f13d709489c6128f9781b60 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Wed, 6 May 2026 14:58:42 -0700 Subject: [PATCH 7/9] fix(sentry-apps): Address PR feedback - rename label, extract test helper, add mutation test - Rename DetailLabel from "isDisabled" to "Enabled" with inverted boolean for positive-case readability - Extract renderSentryAppDetails helper to DRY up test setup - Add mutation test verifying PUT sends correct isDisabled value ISWF-1234 --- .../gsAdmin/views/sentryAppDetails.spec.tsx | 123 +++++++----------- static/gsAdmin/views/sentryAppDetails.tsx | 2 +- 2 files changed, 49 insertions(+), 76 deletions(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index 0f25db818db5d0..149237d9ddd61d 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -1,61 +1,47 @@ import {SentryAppFixture} from 'sentry-fixture/sentryApp'; -import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary'; +import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; import {SentryAppDetails} from 'admin/views/sentryAppDetails'; +function renderSentryAppDetails(overrides: Record = {}) { + const sentryApp = { + ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), + owner: {slug: 'test-org'}, + isDisabled: false, + ...overrides, + }; + + MockApiClient.addMockResponse({ + url: `/sentry-apps/${sentryApp.slug}/`, + method: 'GET', + body: sentryApp, + }); + + render(, { + initialRouterConfig: { + location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, + route: '/_admin/sentry-apps/:sentryAppSlug/', + }, + }); + + return sentryApp; +} + describe('SentryAppDetails', () => { beforeEach(() => { MockApiClient.clearMockResponses(); }); it('renders an unpublished app without crashing', async () => { - const sentryApp = { - ...SentryAppFixture({ - slug: 'cursor-staging', - status: 'unpublished', - }), - owner: {slug: 'cursor'}, - }; - - MockApiClient.addMockResponse({ - url: `/sentry-apps/${sentryApp.slug}/`, - method: 'GET', - body: sentryApp, - }); - - render(, { - initialRouterConfig: { - location: { - pathname: `/_admin/sentry-apps/${sentryApp.slug}/`, - }, - route: '/_admin/sentry-apps/:sentryAppSlug/', - }, - }); + renderSentryAppDetails(); expect(await screen.findByRole('heading', {name: 'Sentry Apps'})).toBeInTheDocument(); expect(screen.getAllByText('unpublished')).not.toHaveLength(0); }); it('shows disable action for a non-disabled app', async () => { - const sentryApp = { - ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), - owner: {slug: 'test-org'}, - isDisabled: false, - }; - - MockApiClient.addMockResponse({ - url: `/sentry-apps/${sentryApp.slug}/`, - method: 'GET', - body: sentryApp, - }); - - render(, { - initialRouterConfig: { - location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, - route: '/_admin/sentry-apps/:sentryAppSlug/', - }, - }); + renderSentryAppDetails({isDisabled: false}); await userEvent.click(await screen.findByTestId('detail-actions')); expect(await screen.findByText('Disable App')).toBeInTheDocument(); @@ -63,50 +49,37 @@ describe('SentryAppDetails', () => { }); it('shows enable action and disabled badge for a disabled app', async () => { - const sentryApp = { - ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), - owner: {slug: 'test-org'}, - isDisabled: true, - }; - - MockApiClient.addMockResponse({ - url: `/sentry-apps/${sentryApp.slug}/`, - method: 'GET', - body: sentryApp, - }); - - render(, { - initialRouterConfig: { - location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, - route: '/_admin/sentry-apps/:sentryAppSlug/', - }, - }); + renderSentryAppDetails({isDisabled: true}); expect(await screen.findByText('disabled')).toBeInTheDocument(); await userEvent.click(screen.getByTestId('detail-actions')); expect(await screen.findByText('Enable App')).toBeInTheDocument(); }); - it('renders isDisabled detail row for a disabled app', async () => { - const sentryApp = { - ...SentryAppFixture({slug: 'test-app', status: 'unpublished'}), - owner: {slug: 'test-org'}, - isDisabled: true, - }; + it('renders Enabled detail label', async () => { + renderSentryAppDetails({isDisabled: false}); + + expect(await screen.findByText('Enabled:')).toBeInTheDocument(); + }); + + it('sends isDisabled in mutation when disable action is selected', async () => { + const sentryApp = renderSentryAppDetails({isDisabled: false}); - MockApiClient.addMockResponse({ + const putMock = MockApiClient.addMockResponse({ url: `/sentry-apps/${sentryApp.slug}/`, - method: 'GET', - body: sentryApp, + method: 'PUT', + body: {...sentryApp, isDisabled: true}, }); - render(, { - initialRouterConfig: { - location: {pathname: `/_admin/sentry-apps/${sentryApp.slug}/`}, - route: '/_admin/sentry-apps/:sentryAppSlug/', - }, + await userEvent.click(await screen.findByTestId('detail-actions')); + await userEvent.click(await screen.findByRole('option', {name: /Disable App/})); + await userEvent.click(await screen.findByRole('button', {name: 'Confirm'})); + + await waitFor(() => { + expect(putMock).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({data: {isDisabled: true}}) + ); }); - - expect(await screen.findByText('isDisabled:')).toBeInTheDocument(); }); }); diff --git a/static/gsAdmin/views/sentryAppDetails.tsx b/static/gsAdmin/views/sentryAppDetails.tsx index 55060a784a82f8..7d7e7fae8a5c0f 100644 --- a/static/gsAdmin/views/sentryAppDetails.tsx +++ b/static/gsAdmin/views/sentryAppDetails.tsx @@ -138,7 +138,7 @@ export function SentryAppDetails() { {data.owner.slug}
- + {data.popularity} {data.scopes.map((scope: any) => ( From 3fd707fa2d80c0929ede85630ab1f08bbbe834a3 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Thu, 7 May 2026 10:08:54 -0700 Subject: [PATCH 8/9] fix(sentry-apps): Address PR feedback - rename label, extract test helper, add mutation test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename DetailLabel from "isDisabled" to "Enabled" with inverted boolean for positive-case readability - Extract renderSentryAppDetails helper to DRY up test setup - Add mutation test using renderGlobalModal to test the full dropdown → confirm modal → PUT flow - Add Enabled: yes/no assertions for both states ISWF-1234 --- .../gsAdmin/views/sentryAppDetails.spec.tsx | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index 149237d9ddd61d..e39813668f3fae 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -1,6 +1,12 @@ import {SentryAppFixture} from 'sentry-fixture/sentryApp'; -import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary'; +import { + render, + renderGlobalModal, + screen, + userEvent, + waitFor, +} from 'sentry-test/reactTestingLibrary'; import {SentryAppDetails} from 'admin/views/sentryAppDetails'; @@ -56,14 +62,23 @@ describe('SentryAppDetails', () => { expect(await screen.findByText('Enable App')).toBeInTheDocument(); }); - it('renders Enabled detail label', async () => { + it('shows Enabled: yes for a non-disabled app', async () => { renderSentryAppDetails({isDisabled: false}); expect(await screen.findByText('Enabled:')).toBeInTheDocument(); + expect(screen.getByText('yes')).toBeInTheDocument(); }); - it('sends isDisabled in mutation when disable action is selected', async () => { + it('shows Enabled: no for a disabled app', async () => { + renderSentryAppDetails({isDisabled: true}); + + expect(await screen.findByText('Enabled:')).toBeInTheDocument(); + expect(screen.getByText('no')).toBeInTheDocument(); + }); + + it('sends PUT with isDisabled when disable action is confirmed', async () => { const sentryApp = renderSentryAppDetails({isDisabled: false}); + renderGlobalModal(); const putMock = MockApiClient.addMockResponse({ url: `/sentry-apps/${sentryApp.slug}/`, @@ -81,5 +96,7 @@ describe('SentryAppDetails', () => { expect.objectContaining({data: {isDisabled: true}}) ); }); + + expect(await screen.findByText('disabled')).toBeInTheDocument(); }); }); From ead4de978069206d013eedf575c5eed0de56e924 Mon Sep 17 00:00:00 2001 From: Christinarlong Date: Thu, 7 May 2026 10:24:45 -0700 Subject: [PATCH 9/9] fix(sentry-apps): Fix multiple 'no' elements in disabled app test When isDisabled is true, both isAlertable and Enabled render 'no' tags. Assert exactly 2 matches instead of getByText which errors on multiple. ISWF-1234 --- static/gsAdmin/views/sentryAppDetails.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/gsAdmin/views/sentryAppDetails.spec.tsx b/static/gsAdmin/views/sentryAppDetails.spec.tsx index e39813668f3fae..8b0b469816ad4e 100644 --- a/static/gsAdmin/views/sentryAppDetails.spec.tsx +++ b/static/gsAdmin/views/sentryAppDetails.spec.tsx @@ -73,7 +73,7 @@ describe('SentryAppDetails', () => { renderSentryAppDetails({isDisabled: true}); expect(await screen.findByText('Enabled:')).toBeInTheDocument(); - expect(screen.getByText('no')).toBeInTheDocument(); + expect(screen.getAllByText('no')).toHaveLength(2); }); it('sends PUT with isDisabled when disable action is confirmed', async () => {