diff --git a/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.spec.tsx b/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.spec.tsx
index 6c4edbbcdad..22e6b249150 100644
--- a/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.spec.tsx
+++ b/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.spec.tsx
@@ -1,10 +1,20 @@
import { wrapWithReactHookForm } from '__tests__/utils/wrap-with-react-hook-form'
-import { useEditService, useService } from '@qovery/domains/services/feature'
+import * as servicesDomain from '@qovery/domains/services/feature'
import { terraformFactoryMock } from '@qovery/shared/factories'
import { renderWithProviders, screen } from '@qovery/shared/util-tests'
import { PageSettingsTerraformArgumentsFeature } from './page-settings-terraform-arguments-feature'
-jest.mock('@qovery/domains/services/feature')
+const useServiceSpy = jest.spyOn(servicesDomain, 'useService') as jest.Mock
+const useEditServiceSpy = jest.spyOn(servicesDomain, 'useEditService') as jest.Mock
+
+jest.mock('@qovery/domains/variables/feature', () => ({
+ ...jest.requireActual('@qovery/domains/variables/feature'),
+ DropdownVariable: ({ children, onChange }: any) => (
+
onChange('MY_VARIABLE')}>
+ {children}
+
+ ),
+}))
// Mocking the Terraform service
const mockService = terraformFactoryMock(1)[0]
@@ -19,12 +29,12 @@ const mockEditService = jest.fn()
describe('PageSettingsTerraformArgumentsFeature', () => {
beforeEach(() => {
- useService.mockReturnValue({
+ useServiceSpy.mockReturnValue({
data: mockService,
isFetched: true,
isLoading: false,
})
- useEditService.mockReturnValue({
+ useEditServiceSpy.mockReturnValue({
mutate: mockEditService,
isLoading: false,
})
@@ -77,4 +87,93 @@ describe('PageSettingsTerraformArgumentsFeature', () => {
},
})
})
+
+ it('should render variable interpolation wand button for each command', () => {
+ renderWithProviders(wrapWithReactHookForm())
+
+ // Check that the wand button appears for each terraform command
+ const wandButtons = screen.getAllByTestId('dropdown-variable')
+ expect(wandButtons).toHaveLength(5) // init, validate, plan, apply, destroy
+ })
+
+ it('should add variable interpolation to empty input when wand is clicked', async () => {
+ const { userEvent } = renderWithProviders(wrapWithReactHookForm())
+
+ const inputLabelForPlan = screen.getByText('Arguments for plan')
+ const inputForPlan = inputLabelForPlan.closest('div')?.querySelector('input')
+ expect(inputForPlan).toHaveValue('')
+
+ const wandButtons = screen.getAllByTestId('dropdown-variable')
+ const wandButtonForPlan = wandButtons[2]
+
+ // Click the wand button to add a variable
+ await userEvent.click(wandButtonForPlan)
+
+ // Check that the variable was added with correct interpolation syntax
+ expect(inputForPlan).toHaveValue('{{MY_VARIABLE}}')
+ })
+
+ it('should append variable interpolation to existing input when wand is clicked', async () => {
+ const { userEvent } = renderWithProviders(wrapWithReactHookForm())
+
+ // Get the input for init command (which has default value '-auto-approve')
+ const inputLabelForInit = screen.getByText('Arguments for init')
+ const inputForInit = inputLabelForInit.closest('div')?.querySelector('input')
+ expect(inputForInit).toHaveValue('-auto-approve')
+
+ // Find the wand button for the init input (1st command)
+ const wandButtons = screen.getAllByTestId('dropdown-variable')
+ const wandButtonForInit = wandButtons[0]
+
+ // Click the wand button to add a variable
+ await userEvent.click(wandButtonForInit)
+
+ // Check that the variable was appended to existing value with space delimiter
+ expect(inputForInit).toHaveValue('-auto-approve {{MY_VARIABLE}}')
+ })
+
+ it('should correctly submit form with variable interpolation', async () => {
+ const { userEvent } = renderWithProviders(wrapWithReactHookForm())
+
+ // Get the apply input and add a variable using the wand
+ const inputLabelForApply = screen.getByText('Arguments for apply')
+ const inputForApply = inputLabelForApply.closest('div')?.querySelector('input')
+ const wandButtons = screen.getAllByTestId('dropdown-variable')
+ const wandButtonForApply = wandButtons[3] // 0=init, 1=validate, 2=plan, 3=apply
+
+ // Add some text first
+ if (inputForApply) {
+ await userEvent.type(inputForApply, '-auto-approve')
+ }
+
+ // Click the wand button to add a variable
+ await userEvent.click(wandButtonForApply)
+
+ // Submit the form
+ const submitButton = screen.getByText('Save')
+ await userEvent.click(submitButton)
+
+ // Verify that the variable interpolation is correctly submitted
+ expect(mockEditService).toHaveBeenCalledWith({
+ serviceId: mockService.id,
+ payload: {
+ ...mockService,
+ terraform_files_source: {
+ git_repository: {
+ url: mockService.terraform_files_source?.git?.git_repository?.url ?? '',
+ branch: mockService.terraform_files_source?.git?.git_repository?.branch ?? '',
+ git_token_id: mockService.terraform_files_source?.git?.git_repository?.git_token_id ?? '',
+ root_path: mockService.terraform_files_source?.git?.git_repository?.root_path ?? '',
+ },
+ },
+ action_extra_arguments: {
+ init: ['-auto-approve'],
+ validate: [],
+ plan: [],
+ apply: ['-auto-approve', '{{MY_VARIABLE}}'],
+ destroy: ['bye'],
+ },
+ },
+ })
+ })
})
diff --git a/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.tsx b/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.tsx
index 21a089afe3b..a71c90966b7 100644
--- a/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.tsx
+++ b/libs/pages/application/src/lib/feature/page-settings-terraform-arguments-feature/page-settings-terraform-arguments-feature.tsx
@@ -1,8 +1,10 @@
import { Controller, FormProvider, useForm } from 'react-hook-form'
import { useParams } from 'react-router-dom'
import { useEditService, useService } from '@qovery/domains/services/feature'
+import { DropdownVariable } from '@qovery/domains/variables/feature'
import { NeedHelp } from '@qovery/shared/assistant/feature'
-import { Button, Heading, InputText, Section } from '@qovery/shared/ui'
+import { Button, Heading, Icon, InputText, Section } from '@qovery/shared/ui'
+import { twMerge } from '@qovery/shared/util-js'
import { buildEditServicePayload } from '@qovery/shared/util-services'
const DELIMETER = ' '
@@ -138,6 +140,25 @@ export function PageSettingsTerraformArgumentsFeature() {
onChange={(e) => field.onChange(e.target.value.split(DELIMETER).filter((arg) => arg !== ''))}
label={`Arguments for ${command.name}`}
hint={command.hint}
+ rightElement={
+ {
+ const currentValue = field.value?.join(DELIMETER) || ''
+ const newValue = currentValue ? `${currentValue} {{${val}}}` : `{{${val}}}`
+ field.onChange(newValue.split(DELIMETER).filter((arg) => arg !== ''))
+ }}
+ >
+
+
+ }
/>
)}
/>