test(deploy): contract test — ConfigTabs disabled gates all inputs
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user