test(deploy): contract test — ConfigTabs disabled gates all inputs

This commit is contained in:
hsiegeln
2026-04-23 13:10:17 +02:00
parent c3ecff9d45
commit 48217e0034

View File

@@ -0,0 +1,269 @@
import { describe, it, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ThemeProvider } from '@cameleer/design-system';
import type { ReactNode } from 'react';
import { MonitoringTab } from './MonitoringTab';
import { ResourcesTab } from './ResourcesTab';
import { VariablesTab } from './VariablesTab';
import { SensitiveKeysTab } from './SensitiveKeysTab';
import type {
MonitoringFormState,
ResourcesFormState,
VariablesFormState,
SensitiveKeysFormState,
} from '../hooks/useDeploymentPageState';
function wrap(ui: ReactNode) {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
},
});
return render(
<QueryClientProvider client={queryClient}>
<ThemeProvider>{ui}</ThemeProvider>
</QueryClientProvider>,
);
}
const defaultMonitoring: MonitoringFormState = {
engineLevel: 'REGULAR',
payloadCaptureMode: 'BOTH',
payloadSize: '4',
payloadUnit: 'KB',
applicationLogLevel: 'INFO',
agentLogLevel: 'INFO',
metricsEnabled: true,
metricsInterval: '60',
samplingRate: '1.0',
compressSuccess: false,
replayEnabled: true,
routeControlEnabled: true,
};
const defaultResources: ResourcesFormState = {
memoryLimit: '512',
memoryReserve: '',
cpuRequest: '500',
cpuLimit: '',
ports: [],
appPort: '8080',
replicas: '1',
deployStrategy: 'blue-green',
stripPrefix: true,
sslOffloading: true,
runtimeType: 'auto',
customArgs: '',
extraNetworks: [],
};
const defaultVariables: VariablesFormState = {
envVars: [],
};
const defaultSensitiveKeys: SensitiveKeysFormState = {
sensitiveKeys: [],
};
describe('ConfigTabs disabled contract', () => {
describe('MonitoringTab', () => {
it('disables all inputs and selects when disabled=true', () => {
wrap(
<MonitoringTab
value={defaultMonitoring}
onChange={vi.fn()}
disabled={true}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
const comboboxes = screen.queryAllByRole('combobox');
expect(textboxes.length).toBeGreaterThan(0);
expect(comboboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).toBeDisabled();
});
comboboxes.forEach((cb) => {
expect(cb).toBeDisabled();
});
});
it('enables inputs when disabled=false', () => {
wrap(
<MonitoringTab
value={defaultMonitoring}
onChange={vi.fn()}
disabled={false}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
expect(textboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).not.toBeDisabled();
});
});
});
describe('ResourcesTab', () => {
it('disables all inputs and selects when disabled=true', () => {
wrap(
<ResourcesTab
value={defaultResources}
onChange={vi.fn()}
disabled={true}
isProd={true}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
const comboboxes = screen.queryAllByRole('combobox');
expect(textboxes.length).toBeGreaterThan(0);
expect(comboboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).toBeDisabled();
});
comboboxes.forEach((cb) => {
expect(cb).toBeDisabled();
});
});
it('enables inputs when disabled=false', () => {
wrap(
<ResourcesTab
value={defaultResources}
onChange={vi.fn()}
disabled={false}
isProd={true}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
expect(textboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).not.toBeDisabled();
});
});
});
describe('VariablesTab', () => {
it('disables add and import buttons when disabled=true', () => {
wrap(
<VariablesTab
value={defaultVariables}
onChange={vi.fn()}
disabled={true}
/>,
);
const buttons = screen.queryAllByRole('button');
// When disabled, import and clear/add buttons should be disabled
// Copy button is always enabled by design
const importBtn = buttons.find((btn) => btn.title?.includes('Import'));
const clearBtn = buttons.find((btn) => btn.title?.includes('Clear'));
expect(importBtn).toBeDisabled();
expect(clearBtn).toBeDisabled();
});
it('enables inputs when disabled=false', () => {
wrap(
<VariablesTab
value={defaultVariables}
onChange={vi.fn()}
disabled={false}
/>,
);
const buttons = screen.queryAllByRole('button');
const importBtn = buttons.find((btn) => btn.title?.includes('Import'));
const clearBtn = buttons.find((btn) => btn.title?.includes('Clear'));
expect(importBtn).not.toBeDisabled();
expect(clearBtn).not.toBeDisabled();
});
it('with envVars populated, disables textboxes when disabled=true', () => {
const varState: VariablesFormState = {
envVars: [
{ key: 'TEST_VAR', value: 'test-value' },
{ key: 'ANOTHER', value: 'value' },
],
};
wrap(
<VariablesTab
value={varState}
onChange={vi.fn()}
disabled={true}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
expect(textboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).toBeDisabled();
});
});
});
describe('SensitiveKeysTab', () => {
it('disables input and add button when disabled=true', () => {
wrap(
<SensitiveKeysTab
value={defaultSensitiveKeys}
onChange={vi.fn()}
disabled={true}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
expect(textboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).toBeDisabled();
});
const buttons = screen.queryAllByRole('button');
const addButton = buttons.find((btn) => btn.textContent?.includes('Add'));
expect(addButton).toBeDisabled();
});
it('enables input when disabled=false', () => {
wrap(
<SensitiveKeysTab
value={defaultSensitiveKeys}
onChange={vi.fn()}
disabled={false}
/>,
);
const textboxes = screen.queryAllByRole('textbox');
expect(textboxes.length).toBeGreaterThan(0);
textboxes.forEach((box) => {
expect(box).not.toBeDisabled();
});
});
it('with sensitive keys, disables remove tag buttons when disabled=true', () => {
const skState: SensitiveKeysFormState = {
sensitiveKeys: ['Authorization', 'X-API-Key', '*password*'],
};
wrap(
<SensitiveKeysTab
value={skState}
onChange={vi.fn()}
disabled={true}
/>,
);
// Tags have remove buttons that should be disabled
const buttons = screen.queryAllByRole('button');
// Check that at least some buttons exist (the tag removers)
expect(buttons.length).toBeGreaterThan(0);
});
});
});