Skip to content

Commit 442dbf9

Browse files
Fix: Reset submit error on YAML editor changes
1 parent 33844cb commit 442dbf9

File tree

2 files changed

+110
-2
lines changed

2 files changed

+110
-2
lines changed

src/components/pipeline-builder/CodeEditorField.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const CodeEditorField: React.FC<CodeEditorFieldProps> = ({
5454
language,
5555
}) => {
5656
const [field] = useField(name);
57-
const { setFieldValue } = useFormikContext<FormikValues>();
57+
const { setFieldValue, setStatus } = useFormikContext<FormikValues>();
5858
const { t } = useTranslation('plugin__pipelines-console-plugin');
5959
const editorRef = React.useRef();
6060

@@ -91,6 +91,11 @@ const CodeEditorField: React.FC<CodeEditorFieldProps> = ({
9191
[templateExtensions],
9292
);
9393

94+
const handleOnChange = (newYAML: string) => {
95+
setFieldValue(name, newYAML);
96+
setStatus({ submitError: '' });
97+
};
98+
9499
return (
95100
<div className="osc-yaml-editor odc-p-has-sidebar" data-test="yaml-editor">
96101
<div
@@ -104,7 +109,7 @@ const CodeEditorField: React.FC<CodeEditorFieldProps> = ({
104109
ref={editorRef}
105110
value={field.value}
106111
minHeight={minHeight ?? '200px'}
107-
onChange={(yaml: string) => setFieldValue(name, yaml)}
112+
onChange={handleOnChange}
108113
onSave={onSave}
109114
showShortcuts={showShortcuts}
110115
showMiniMap={showMiniMap}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import * as React from 'react';
2+
import { render } from '@testing-library/react';
3+
import CodeEditorField from '../CodeEditorField';
4+
5+
const mockSetFieldValue = jest.fn();
6+
const mockSetStatus = jest.fn();
7+
let mockOnChange: (yaml: string) => void = jest.fn();
8+
9+
jest.mock('formik', () => ({
10+
useField: jest.fn(() => [
11+
{ value: 'apiVersion: v1\nkind: Pipeline' },
12+
{},
13+
{},
14+
]),
15+
useFormikContext: jest.fn(() => ({
16+
setFieldValue: mockSetFieldValue,
17+
setStatus: mockSetStatus,
18+
})),
19+
}));
20+
21+
jest.mock('@openshift-console/dynamic-plugin-sdk', () => {
22+
// eslint-disable-next-line @typescript-eslint/no-var-requires
23+
const React = require('react');
24+
return {
25+
CodeEditor: React.forwardRef(({ onChange }: any, ref: any) => {
26+
mockOnChange = onChange;
27+
return <div data-testid="code-editor" ref={ref} />;
28+
}),
29+
useK8sWatchResource: jest.fn(() => [[], true, null]),
30+
useResolvedExtensions: jest.fn(() => [[]]),
31+
isYAMLTemplate: jest.fn(),
32+
};
33+
});
34+
35+
jest.mock('react-i18next', () => ({
36+
useTranslation: () => ({ t: (key: string) => key }),
37+
}));
38+
39+
jest.mock('../utils', () => ({
40+
getResourceSidebarSamples: jest.fn(() => ({ samples: [], snippets: [] })),
41+
}));
42+
43+
jest.mock('../swagger', () => ({
44+
definitionFor: jest.fn(() => ({ properties: [] })),
45+
}));
46+
47+
jest.mock('../CodeEditorSidebar', () => ({
48+
__esModule: true,
49+
default: () => null,
50+
}));
51+
52+
describe('CodeEditorField', () => {
53+
beforeEach(() => {
54+
jest.clearAllMocks();
55+
});
56+
57+
it('should reset submitError when YAML content changes', () => {
58+
render(<CodeEditorField name="yamlData" showSamples={false} />);
59+
60+
mockOnChange('apiVersion: v1\nkind: Pipeline\nmetadata:\n name: test');
61+
62+
expect(mockSetFieldValue).toHaveBeenCalledWith(
63+
'yamlData',
64+
'apiVersion: v1\nkind: Pipeline\nmetadata:\n name: test',
65+
);
66+
expect(mockSetStatus).toHaveBeenCalledWith({ submitError: '' });
67+
});
68+
69+
it('should reset submitError on every YAML edit', () => {
70+
render(<CodeEditorField name="yamlData" showSamples={false} />);
71+
72+
mockOnChange('edit 1');
73+
expect(mockSetStatus).toHaveBeenCalledWith({ submitError: '' });
74+
75+
jest.clearAllMocks();
76+
77+
mockOnChange('edit 2');
78+
expect(mockSetStatus).toHaveBeenCalledWith({ submitError: '' });
79+
});
80+
81+
it('should consistently reset submitError after re-renders (simulating editor toggle)', () => {
82+
const { rerender } = render(
83+
<CodeEditorField name="yamlData" showSamples={false} />,
84+
);
85+
86+
// First edit - simulate user making invalid YAML
87+
mockOnChange('invalid yaml');
88+
expect(mockSetStatus).toHaveBeenCalledWith({ submitError: '' });
89+
90+
jest.clearAllMocks();
91+
92+
// Simulate re-render that would occur during view toggle
93+
rerender(<CodeEditorField name="yamlData" showSamples={false} />);
94+
95+
// Edit after "returning" to YAML view - should still reset error
96+
mockOnChange('apiVersion: v1\nkind: Pipeline');
97+
expect(mockSetFieldValue).toHaveBeenCalledWith(
98+
'yamlData',
99+
'apiVersion: v1\nkind: Pipeline',
100+
);
101+
expect(mockSetStatus).toHaveBeenCalledWith({ submitError: '' });
102+
});
103+
});

0 commit comments

Comments
 (0)