diff --git a/packages/frontend/editor-ui/src/features/settings/security/DataRedactionSection.vue b/packages/frontend/editor-ui/src/features/settings/security/DataRedactionSection.vue
index 6404e1d045d..caa2f7ad927 100644
--- a/packages/frontend/editor-ui/src/features/settings/security/DataRedactionSection.vue
+++ b/packages/frontend/editor-ui/src/features/settings/security/DataRedactionSection.vue
@@ -202,27 +202,54 @@ function goToUpgrade() {
- {{
- i18n.baseText('settings.security.dataRedaction.scope.title')
- }}
+ {{ i18n.baseText('settings.security.dataRedaction.scope.title') }}
+ {{
+ i18n.baseText('generic.upgrade')
+ }}
+
{{
i18n.baseText('settings.security.dataRedaction.scope.description')
}}
diff --git a/packages/frontend/editor-ui/src/features/settings/security/SecuritySettings.test.ts b/packages/frontend/editor-ui/src/features/settings/security/SecuritySettings.test.ts
index 3f0c09f7c15..5da80f3d898 100644
--- a/packages/frontend/editor-ui/src/features/settings/security/SecuritySettings.test.ts
+++ b/packages/frontend/editor-ui/src/features/settings/security/SecuritySettings.test.ts
@@ -661,7 +661,7 @@ describe('SecuritySettings', () => {
expect(getByTestId('enable-redaction-enforcement')).toHaveClass('is-disabled');
});
- it('should not render scope dropdown when unlicensed even if enforced=true', async () => {
+ it('should render disabled scope dropdown when unlicensed even if enforced=true', async () => {
enableRedactionEnforcementFlag(true);
settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.DataRedaction] = false;
getSecuritySettings.mockResolvedValue({
@@ -669,13 +669,91 @@ describe('SecuritySettings', () => {
redactionEnforcement: { floor: 'production' },
});
- const { getByTestId, queryByTestId } = renderView();
+ const { getByTestId } = renderView();
await waitFor(() => {
expect(getByTestId('enable-redaction-enforcement')).toBeInTheDocument();
});
- expect(queryByTestId('redaction-enforcement-scope-row')).not.toBeInTheDocument();
+ expect(getByTestId('redaction-enforcement-scope-row')).toBeInTheDocument();
+ expect(getByTestId('redaction-enforcement-scope-select')).toHaveAttribute('data-disabled');
+ });
+
+ it('should render scope dropdown with Upgrade badge when unlicensed and not enforced', async () => {
+ enableRedactionEnforcementFlag(true);
+ settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.DataRedaction] = false;
+
+ const { getAllByText, getByTestId } = renderView();
+
+ await waitFor(() => {
+ expect(getByTestId('enable-redaction-enforcement')).toBeInTheDocument();
+ });
+
+ expect(getByTestId('redaction-enforcement-scope-row')).toBeInTheDocument();
+ expect(getByTestId('redaction-enforcement-scope-select')).toHaveAttribute('data-disabled');
+ // One badge on the toggle row, one on the scope row.
+ expect(getAllByText('Upgrade').length).toBeGreaterThanOrEqual(2);
+ // Summary reflects stored floor='off' while the disabled dropdown previews 'production'.
+ expect(getByTestId('redaction-enforcement-summary')).toHaveTextContent('No executions');
+ });
+
+ it('should not call updateSecuritySettings when clicking disabled scope dropdown', async () => {
+ enableRedactionEnforcementFlag(true);
+ settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.DataRedaction] = false;
+ getSecuritySettings.mockResolvedValue({
+ ...defaultSettings,
+ redactionEnforcement: { floor: 'production' },
+ });
+
+ const { getByTestId } = renderView();
+
+ await waitFor(() => {
+ expect(getByTestId('redaction-enforcement-scope-select')).toBeInTheDocument();
+ });
+
+ await userEvent.click(getByTestId('redaction-enforcement-scope-select'));
+
+ expect(updateSecuritySettings).not.toHaveBeenCalled();
+ });
+
+ it('should show stored scope value when unlicensed with floor=production (downgrade)', async () => {
+ enableRedactionEnforcementFlag(true);
+ settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.DataRedaction] = false;
+ getSecuritySettings.mockResolvedValue({
+ ...defaultSettings,
+ redactionEnforcement: { floor: 'production' },
+ });
+
+ const { getByTestId } = renderView();
+
+ await waitFor(() => {
+ expect(getByTestId('redaction-enforcement-scope-row')).toBeInTheDocument();
+ });
+
+ expect(getByTestId('redaction-enforcement-scope-select')).toHaveAttribute('data-disabled');
+ expect(getByTestId('redaction-enforcement-summary')).toHaveTextContent(
+ 'Production executions',
+ );
+ });
+
+ it('should show stored scope value when unlicensed with floor=all (downgrade)', async () => {
+ enableRedactionEnforcementFlag(true);
+ settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.DataRedaction] = false;
+ getSecuritySettings.mockResolvedValue({
+ ...defaultSettings,
+ redactionEnforcement: { floor: 'all' },
+ });
+
+ const { getByTestId } = renderView();
+
+ await waitFor(() => {
+ expect(getByTestId('redaction-enforcement-scope-row')).toBeInTheDocument();
+ });
+
+ expect(getByTestId('redaction-enforcement-scope-select')).toHaveAttribute('data-disabled');
+ expect(getByTestId('redaction-enforcement-summary')).toHaveTextContent(
+ 'Manual and production executions',
+ );
});
it('should disable toggle when managed by env', async () => {