diff --git a/static/app/views/settings/projectSeer/index.spec.tsx b/static/app/views/settings/projectSeer/index.spec.tsx index 2c0615becd38b8..69317698be1db8 100644 --- a/static/app/views/settings/projectSeer/index.spec.tsx +++ b/static/app/views/settings/projectSeer/index.spec.tsx @@ -545,15 +545,17 @@ describe('ProjectSeer', () => { } }); - it('hides Scan Issues toggle when triage-signals-v0 feature flag is enabled', async () => { - const projectWithFeatureFlag = ProjectFixture({ - features: ['triage-signals-v0'], + it('hides Scan Issues toggle when triage-signals-v0-org feature flag is enabled', async () => { + const orgWithFeatureFlag = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); + const projectWithAutomation = ProjectFixture({ autofixAutomationTuning: 'medium', // Already enabled, so no auto-enable PUT }); render(, { - organization, - outletContext: {project: projectWithFeatureFlag}, + organization: orgWithFeatureFlag, + outletContext: {project: projectWithAutomation}, }); // Wait for the page to load @@ -567,7 +569,7 @@ describe('ProjectSeer', () => { ).not.toBeInTheDocument(); }); - it('shows Scan Issues toggle when triage-signals-v0 feature flag is disabled', async () => { + it('shows Scan Issues toggle when triage-signals-v0-org feature flag is disabled', async () => { render(, { organization, outletContext: {project}, @@ -580,16 +582,18 @@ describe('ProjectSeer', () => { expect(toggle).toBeInTheDocument(); }); - describe('Auto-Trigger Fixes with triage-signals-v0', () => { + describe('Auto-Trigger Fixes with triage-signals-v0-org', () => { it('shows as toggle when flag enabled, dropdown when disabled', async () => { + const orgWithFlag = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); const projectWithFlag = ProjectFixture({ - features: ['triage-signals-v0'], seerScannerAutomation: true, autofixAutomationTuning: 'medium', // Already enabled, so no auto-enable PUT }); const {unmount} = render(, { - organization, + organization: orgWithFlag, outletContext: {project: projectWithFlag}, }); @@ -622,14 +626,16 @@ describe('ProjectSeer', () => { ).not.toBeInTheDocument(); }); - it('toggle is always checked when triage-signals-v0 flag is enabled', async () => { + it('toggle is always checked when triage-signals-v0-org flag is enabled', async () => { // When flag is on, the toggle is always checked regardless of stored value // because we default to ON for triage signals users + const orgWithFlag = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); render(, { - organization, + organization: orgWithFlag, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], seerScannerAutomation: true, autofixAutomationTuning: 'medium', }), @@ -642,17 +648,19 @@ describe('ProjectSeer', () => { }); it('saves "medium" when toggled ON, "off" when toggled OFF', async () => { + const orgWithFlag = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); const projectPutRequest = MockApiClient.addMockResponse({ - url: `/projects/${organization.slug}/${project.slug}/`, + url: `/projects/${orgWithFlag.slug}/${project.slug}/`, method: 'PUT', body: {}, }); render(, { - organization, + organization: orgWithFlag, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], seerScannerAutomation: true, autofixAutomationTuning: 'medium', // Start with enabled so no auto-enable }), @@ -684,11 +692,13 @@ describe('ProjectSeer', () => { }); it('respects existing off setting for orgs with flag enabled', async () => { + const orgWithFlag = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); render(, { - organization, + organization: orgWithFlag, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], seerScannerAutomation: true, autofixAutomationTuning: 'off', // Existing org with it disabled }), @@ -702,11 +712,13 @@ describe('ProjectSeer', () => { }); it('defaults to ON for new orgs (undefined value)', async () => { + const orgWithFlag = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); render(, { - organization, + organization: orgWithFlag, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], seerScannerAutomation: true, autofixAutomationTuning: undefined, // New org }), @@ -1228,11 +1240,14 @@ describe('ProjectSeer', () => { describe('Auto-open PR and Cursor Handoff toggles with triage-signals-v0', () => { it('shows Auto-open PR toggle when Auto-Trigger is ON', async () => { + const orgWithTriageSignals = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); + render(, { - organization, + organization: orgWithTriageSignals, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1243,11 +1258,14 @@ describe('ProjectSeer', () => { }); it('hides Auto-open PR toggle when Auto-Trigger is OFF', async () => { + const orgWithTriageSignals = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); + render(, { - organization, + organization: orgWithTriageSignals, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'off', }), }, @@ -1261,7 +1279,11 @@ describe('ProjectSeer', () => { it('shows Cursor handoff toggle when Auto-Trigger is ON and Cursor integration exists', async () => { const orgWithCursor = OrganizationFixture({ - features: ['autofix-seer-preferences', 'integrations-cursor'], + features: [ + 'autofix-seer-preferences', + 'integrations-cursor', + 'triage-signals-v0-org', + ], }); MockApiClient.addMockResponse({ @@ -1298,7 +1320,6 @@ describe('ProjectSeer', () => { organization: orgWithCursor, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1311,11 +1332,14 @@ describe('ProjectSeer', () => { }); it('hides Cursor handoff toggle when no Cursor integration', async () => { + const orgWithTriageSignals = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); + render(, { - organization, + organization: orgWithTriageSignals, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1328,22 +1352,25 @@ describe('ProjectSeer', () => { }); it('updates preferences when Auto-open PR toggle is changed', async () => { + const orgWithTriageSignals = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); + MockApiClient.addMockResponse({ - url: `/projects/${organization.slug}/${project.slug}/`, + url: `/projects/${orgWithTriageSignals.slug}/${project.slug}/`, method: 'PUT', body: {}, }); const seerPreferencesPostRequest = MockApiClient.addMockResponse({ - url: `/projects/${organization.slug}/${project.slug}/seer/preferences/`, + url: `/projects/${orgWithTriageSignals.slug}/${project.slug}/seer/preferences/`, method: 'POST', }); render(, { - organization, + organization: orgWithTriageSignals, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1367,7 +1394,11 @@ describe('ProjectSeer', () => { it('updates preferences when Cursor handoff toggle is changed', async () => { const orgWithCursor = OrganizationFixture({ - features: ['autofix-seer-preferences', 'integrations-cursor'], + features: [ + 'autofix-seer-preferences', + 'integrations-cursor', + 'triage-signals-v0-org', + ], }); MockApiClient.addMockResponse({ @@ -1415,7 +1446,6 @@ describe('ProjectSeer', () => { organization: orgWithCursor, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1444,7 +1474,11 @@ describe('ProjectSeer', () => { it('shows error when Cursor handoff fails due to missing integration', async () => { const orgWithCursor = OrganizationFixture({ - features: ['autofix-seer-preferences', 'integrations-cursor'], + features: [ + 'autofix-seer-preferences', + 'integrations-cursor', + 'triage-signals-v0-org', + ], }); MockApiClient.addMockResponse({ @@ -1480,7 +1514,6 @@ describe('ProjectSeer', () => { organization: orgWithCursor, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1497,24 +1530,27 @@ describe('ProjectSeer', () => { it('shows error message when Auto-open PR toggle fails', async () => { jest.spyOn(indicators, 'addErrorMessage'); + const orgWithTriageSignals = OrganizationFixture({ + features: ['autofix-seer-preferences', 'triage-signals-v0-org'], + }); + MockApiClient.addMockResponse({ - url: `/projects/${organization.slug}/${project.slug}/`, + url: `/projects/${orgWithTriageSignals.slug}/${project.slug}/`, method: 'PUT', body: {}, }); const seerPreferencesPostRequest = MockApiClient.addMockResponse({ - url: `/projects/${organization.slug}/${project.slug}/seer/preferences/`, + url: `/projects/${orgWithTriageSignals.slug}/${project.slug}/seer/preferences/`, method: 'POST', statusCode: 500, body: {detail: 'Internal Server Error'}, }); render(, { - organization, + organization: orgWithTriageSignals, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, @@ -1537,7 +1573,11 @@ describe('ProjectSeer', () => { jest.spyOn(indicators, 'addErrorMessage'); const orgWithCursor = OrganizationFixture({ - features: ['autofix-seer-preferences', 'integrations-cursor'], + features: [ + 'autofix-seer-preferences', + 'integrations-cursor', + 'triage-signals-v0-org', + ], }); MockApiClient.addMockResponse({ @@ -1587,7 +1627,6 @@ describe('ProjectSeer', () => { organization: orgWithCursor, outletContext: { project: ProjectFixture({ - features: ['triage-signals-v0'], autofixAutomationTuning: 'medium', }), }, diff --git a/static/app/views/settings/projectSeer/index.tsx b/static/app/views/settings/projectSeer/index.tsx index a57b023ef5efcf..98625edbcc9db5 100644 --- a/static/app/views/settings/projectSeer/index.tsx +++ b/static/app/views/settings/projectSeer/index.tsx @@ -201,7 +201,9 @@ function ProjectSeerGeneralForm({project}: {project: Project}) { const {mutate: updateProjectSeerPreferences} = useUpdateProjectSeerPreferences(project); const {data: codingAgentIntegrations} = useCodingAgentIntegrations(); - const isTriageSignalsFeatureOn = project.features.includes('triage-signals-v0'); + const isTriageSignalsFeatureOn = organization.features.includes( + 'triage-signals-v0-org' + ); const canWriteProject = hasEveryAccess(['project:read'], {organization, project}); const cursorIntegrations =