From 598a0dc1b84e2a2c80302e58f524832dd350273a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 1 Jul 2026 16:00:00 +0900 Subject: [PATCH] [ci] Reward Config minting and dry run scheme render as drop-downs Signed-off-by: Tim Emiola --- .../forms/set-amulet-rules-form.test.tsx | 47 ++++++++++++++ .../buildAmuletRulesConfigFromChanges.test.ts | 6 +- .../form-components/ConfigField.tsx | 63 +++++++++++++++---- .../src/utils/buildAmuletConfigChanges.ts | 25 +++++++- apps/sv/frontend/src/utils/types.ts | 8 +++ 5 files changed, 130 insertions(+), 19 deletions(-) diff --git a/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx index 728ca1538c..c34f095ad5 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx @@ -241,6 +241,53 @@ describe('Set Amulet Config Rules Form', () => { expect(changes.length).toBe(2); }); + test('reward config minting scheme renders as a dropdown', async () => { + const user = userEvent.setup(); + + render( + + + + ); + + // Minting scheme should render as a Select, not a TextField + const mintingField = screen.getByTestId('config-field-rewardConfigMintingVersion'); + expect(mintingField).toBeInTheDocument(); + const selectInput = mintingField.querySelector('[role="combobox"]') as HTMLElement; + expect(selectInput).toBeInTheDocument(); + + // Open dropdown and verify options + await user.click(selectInput); + expect(screen.getByText('Featured App Markers (pre CIP-104)')).toBeInTheDocument(); + expect(screen.getByText('Traffic-Based App Rewards (CIP-104)')).toBeInTheDocument(); + + // Select an option + await user.click(screen.getByText('Traffic-Based App Rewards (CIP-104)')); + + // Verify current value is shown after change + const currentValue = screen.getByTestId('config-current-value-rewardConfigMintingVersion'); + expect(currentValue).toBeInTheDocument(); + }); + + test('reward config dry-run scheme includes None option', async () => { + const user = userEvent.setup(); + + render( + + + + ); + + const dryRunField = screen.getByTestId('config-field-rewardConfigDryRunVersion'); + expect(dryRunField).toBeInTheDocument(); + const selectInput = dryRunField.querySelector('[role="combobox"]') as HTMLElement; + expect(selectInput).toBeInTheDocument(); + + // Open dropdown and verify None option exists + await user.click(selectInput); + expect(screen.getByText('None (disabled)')).toBeInTheDocument(); + }); + test('should show proposal review page after form completion', async () => { const user = userEvent.setup(); diff --git a/apps/sv/frontend/src/__tests__/utils/buildAmuletRulesConfigFromChanges.test.ts b/apps/sv/frontend/src/__tests__/utils/buildAmuletRulesConfigFromChanges.test.ts index a0bea6e3d9..1035962057 100644 --- a/apps/sv/frontend/src/__tests__/utils/buildAmuletRulesConfigFromChanges.test.ts +++ b/apps/sv/frontend/src/__tests__/utils/buildAmuletRulesConfigFromChanges.test.ts @@ -220,19 +220,19 @@ describe('buildAmuletRulesConfigFromChanges', () => { }, { fieldName: 'rewardConfigMintingVersion', - label: 'Reward config: Minting version', + label: 'Reward config: Minting scheme', currentValue: 'RewardVersion_FeaturedAppMarkers', newValue: 'RewardVersion_TrafficBasedAppRewards', }, { fieldName: 'rewardConfigDryRunVersion', - label: 'Reward config: Dry-run version', + label: 'Reward config: Dry-run minting scheme', currentValue: '', newValue: 'RewardVersion_TrafficBasedAppRewards', }, { fieldName: 'rewardConfigBatchSize', - label: 'Reward config: Batch size', + label: 'Reward config: Merkle tree batch size', currentValue: '100', newValue: '200', }, diff --git a/apps/sv/frontend/src/components/form-components/ConfigField.tsx b/apps/sv/frontend/src/components/form-components/ConfigField.tsx index 61a0216eaa..2ad76fe163 100644 --- a/apps/sv/frontend/src/components/form-components/ConfigField.tsx +++ b/apps/sv/frontend/src/components/form-components/ConfigField.tsx @@ -2,7 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 import { Link as RouterLink } from 'react-router'; -import { Box, Divider, TextField as MuiTextField, Typography } from '@mui/material'; +import { + Box, + Divider, + FormControl, + MenuItem, + Select, + TextField as MuiTextField, + Typography, +} from '@mui/material'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import { useFieldContext } from '../../hooks/formContext'; @@ -90,18 +98,47 @@ export const ConfigField: React.FC = props => { - - field.handleChange({ - fieldName: configChange.fieldName, - value: e.target.value, - }) - } - /> + {configChange.options ? ( + + + + ) : ( + + field.handleChange({ + fieldName: configChange.fieldName, + value: e.target.value, + }) + } + /> + )} + + {configChange.description && ( + + {configChange.description} + + )} {!field.state.meta.isDefaultValue && (