Skip to content

Commit 86c7245

Browse files
authored
Merge pull request #2570 from pie-framework/feat/PD-4040
Feat/pd 4040
2 parents f3fda5c + 2c9d279 commit 86c7245

9 files changed

Lines changed: 620 additions & 922 deletions

File tree

packages/passage/configure/src/__tests__/__snapshots__/main.test.js.snap

Lines changed: 0 additions & 592 deletions
This file was deleted.
Lines changed: 95 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -1,225 +1,133 @@
11
import React from 'react';
22
import { shallow } from 'enzyme';
33
import { Main } from '../design';
4-
import defaults from '../defaults';
5-
import { InputContainer } from '@pie-lib/pie-toolbox/config-ui';
64

75
jest.mock('@pie-lib/pie-toolbox/config-ui', () => ({
86
layout: {
9-
ConfigLayout: (props) => <div>{props.children}</div>,
7+
ConfigLayout: (props) => <div className="mockConfigLayout">{props.children}</div>,
108
},
119
settings: {
12-
Panel: (props) => <div onChange={props.onChange} />,
13-
toggle: jest.fn(),
10+
Panel: (props) => <div className="mockPanel" onClick={props.onChange} />,
11+
toggle: (label, defaultVal = false) => true,
1412
dropdown: jest.fn(),
1513
},
16-
InputContainer: (props) => <div {...props}>{props.children}</div>,
1714
}));
1815

19-
describe('Render Main Component', () => {
20-
let wrapper, instance, onChange;
21-
let model = defaults.model;
22-
let configuration = defaults.configuration;
23-
24-
beforeEach(() => {
25-
onChange = jest.fn();
26-
const classes = {
27-
inputContainer: 'mockInputContainer',
28-
errorText: 'mockErrorText',
29-
};
16+
jest.mock('../common', () => ({
17+
ConfimationDialog: (props) => <div className="mockDialog" {...props} />,
18+
PassageButton: (props) => (
19+
<button className="mockPassageButton" onClick={props.onClick}>
20+
{props.label}
21+
</button>
22+
),
23+
}));
3024

31-
wrapper = shallow(
32-
<Main
33-
classes={classes}
34-
model={model}
35-
configuration={configuration}
36-
onModelChanged={onChange}
37-
imageSupport={{}}
38-
uploadSoundSupport={{}}
39-
/>,
40-
);
25+
jest.mock('../passage', () => (props) => <div className="mockPassage" {...props} />);
26+
27+
describe('Main Component - Unit Method Tests', () => {
28+
let wrapper, instance, onModelChanged;
29+
30+
const basePassage = {
31+
teacherInstructions: '',
32+
title: '',
33+
subtitle: '',
34+
author: '',
35+
text: '',
36+
};
37+
38+
const baseModel = {
39+
passages: [basePassage],
40+
language: 'en',
41+
};
42+
43+
const configuration = {
44+
additionalPassage: { label: 'Additional Passage', settings: true, enabled: true },
45+
teacherInstructions: { label: 'Teacher Instructions', settings: true },
46+
title: { label: 'Title', settings: true },
47+
subtitle: { label: 'Subtitle', settings: true },
48+
author: { label: 'Author', settings: true },
49+
text: { label: 'Text', settings: true },
50+
};
51+
52+
const props = {
53+
model: baseModel,
54+
configuration,
55+
imageSupport: {},
56+
uploadSoundSupport: {},
57+
classes: { additionalPassageHeading: 'heading' },
58+
onModelChanged: jest.fn(),
59+
onConfigurationChanged: jest.fn(),
60+
};
4161

62+
beforeEach(() => {
63+
onModelChanged = jest.fn();
64+
wrapper = shallow(<Main {...props} onModelChanged={onModelChanged} />);
4265
instance = wrapper.instance();
4366
});
4467

45-
it('Match Snapshot', () => {
46-
expect(wrapper).toMatchSnapshot();
68+
it('getInnerText removes HTML tags', () => {
69+
expect(instance.getInnerText('<p>Test <strong>123</strong></p>')).toBe('Test 123');
70+
expect(instance.getInnerText('')).toBe('');
71+
expect(instance.getInnerText(null)).toBe('');
72+
expect(instance.getInnerText('<img src="x" />')).toBe('');
4773
});
4874

49-
describe('logic', () => {
50-
it('changeTeacherInstructions calls onModelChanged', () => {
51-
const updatedModel = {
52-
...model,
53-
passages: [{ ...model.passages[0], teacherInstructions: 'Teacher Instructions' }],
54-
};
55-
instance.handleChange('teacherInstructions', 'Teacher Instructions', 0);
56-
expect(onChange).toBeCalledWith(updatedModel);
57-
});
75+
it('addAdditionalPassage adds an empty passage and calls onModelChanged', () => {
76+
instance.addAdditionalPassage();
5877

59-
it('changeTitle calls onModelChanged', () => {
60-
const updatedModel = {
61-
...model,
62-
passages: [{ ...model.passages[0], title: 'New Title' }],
63-
};
64-
instance.handleChange('title', 'New Title', 0);
65-
expect(onChange).toBeCalledWith(updatedModel);
66-
});
67-
68-
it('changeSubtitle calls onModelChanged', () => {
69-
const updatedModel = {
70-
...model,
71-
passages: [{ ...model.passages[0], subtitle: 'New Subtitle' }],
72-
};
73-
instance.handleChange('subtitle', 'New Subtitle', 0);
74-
expect(onChange).toBeCalledWith(updatedModel);
78+
expect(onModelChanged).toHaveBeenCalledWith({
79+
...baseModel,
80+
passages: [...baseModel.passages, { teacherInstructions: '', title: '', subtitle: '', author: '', text: '' }],
7581
});
82+
});
7683

77-
it('changeAuthor calls onModelChanged', () => {
78-
const updatedModel = {
79-
...model,
80-
passages: [{ ...model.passages[0], author: 'New Author' }],
81-
};
82-
instance.handleChange('author', 'New Author', 0);
83-
expect(onChange).toBeCalledWith(updatedModel);
84-
});
84+
it('removeAdditionalPassage calls onDelete directly for empty passage', () => {
85+
const modelWithTwo = {
86+
...baseModel,
87+
passages: [basePassage, basePassage],
88+
};
8589

86-
it('changeText calls onModelChanged', () => {
87-
const updatedModel = {
88-
...model,
89-
passages: [{ ...model.passages[0], text: 'New Text' }],
90-
};
91-
instance.handleChange('text', 'New Text', 0);
92-
expect(onChange).toBeCalledWith(updatedModel);
93-
});
94-
});
90+
wrapper.setProps({ model: modelWithTwo });
91+
instance = wrapper.instance();
9592

96-
describe('UI Rendering', () => {
97-
it('renders teacher instructions input when enabled', () => {
98-
wrapper.setProps({
99-
model: { ...model, teacherInstructionsEnabled: true },
100-
configuration: {
101-
...configuration,
102-
teacherInstructions: { label: 'Teacher Instructions' },
103-
},
104-
});
105-
expect(wrapper.find(InputContainer).at(0).prop('label')).toEqual('Teacher Instructions');
106-
});
93+
const onDeleteSpy = jest.spyOn(instance, 'onDelete');
94+
instance.removeAdditionalPassage(1);
10795

108-
it('renders title input when enabled', () => {
109-
wrapper.setProps({
110-
model: { ...model, titleEnabled: true },
111-
configuration: { ...configuration, title: { label: 'Title' } },
112-
});
113-
expect(wrapper.find(InputContainer).at(1).prop('label')).toEqual('Title');
114-
});
96+
expect(onDeleteSpy).toHaveBeenCalledWith(modelWithTwo, 1, onModelChanged);
97+
});
11598

116-
it('renders subtitle input when enabled', () => {
117-
wrapper.setProps({
118-
model: { ...model, subtitleEnabled: true },
119-
configuration: { ...configuration, subtitle: { label: 'Subtitle' } },
120-
});
121-
expect(wrapper.find(InputContainer).at(2).prop('label')).toEqual('Subtitle');
122-
});
99+
it('removeAdditionalPassage sets dialog state if passage has content', () => {
100+
const modelWithContent = {
101+
...baseModel,
102+
passages: [basePassage, { ...basePassage, teacherInstructions: '<p>Filled</p>' }],
103+
};
123104

124-
it('renders author input when enabled', () => {
125-
wrapper.setProps({
126-
model: { ...model, authorEnabled: true },
127-
configuration: { ...configuration, author: { label: 'Author' } },
128-
});
129-
expect(wrapper.find(InputContainer).at(3).prop('label')).toEqual('Author');
130-
});
105+
wrapper.setProps({ model: modelWithContent });
106+
instance.removeAdditionalPassage(1);
131107

132-
it('renders text input when enabled', () => {
133-
wrapper.setProps({
134-
model: { ...model, textEnabled: true },
135-
configuration: { ...configuration, text: { label: 'Text' } },
136-
});
137-
expect(wrapper.find(InputContainer).at(4).prop('label')).toEqual('Text');
108+
expect(wrapper.state()).toEqual({
109+
showConfirmationDialog: true,
110+
indexToRemove: 1,
138111
});
139112
});
140113

141-
describe('Error Handling', () => {
142-
it('displays teacher instructions error when provided', () => {
143-
wrapper.setProps({
144-
model: {
145-
...model,
146-
errors: {
147-
passages: {
148-
0: { teacherInstructions: 'Teacher Instructions is required' },
149-
},
150-
},
151-
teacherInstructionsEnabled: true,
152-
},
153-
configuration: {
154-
...configuration,
155-
teacherInstructions: { label: 'Teacher Instructions' },
156-
},
157-
});
158-
expect(wrapper.find('.mockErrorText').text()).toEqual('Teacher Instructions is required');
159-
});
160-
161-
it('displays title error when provided', () => {
162-
wrapper.setProps({
163-
model: {
164-
...model,
165-
errors: {
166-
passages: {
167-
0: { title: 'Title is required' },
168-
},
169-
},
170-
titleEnabled: true,
171-
},
172-
configuration: { ...configuration, title: { label: 'Title' } },
173-
});
174-
expect(wrapper.find('.mockErrorText').text()).toEqual('Title is required');
175-
});
114+
it('onDelete removes passage at index and resets confirmation state', () => {
115+
const modelWithTwo = {
116+
...baseModel,
117+
passages: [{ teacherInstructions: 'Keep' }, { teacherInstructions: 'Remove' }],
118+
};
176119

177-
it('displays subtitle error when provided', () => {
178-
wrapper.setProps({
179-
model: {
180-
...model,
181-
errors: {
182-
passages: {
183-
0: { subtitle: 'Subtitle is required' },
184-
},
185-
},
186-
subtitleEnabled: true,
187-
},
188-
configuration: { ...configuration, subtitle: { label: 'Subtitle' } },
189-
});
190-
expect(wrapper.find('.mockErrorText').text()).toEqual('Subtitle is required');
191-
});
120+
wrapper.setProps({ model: modelWithTwo });
121+
instance.onDelete(modelWithTwo, 1, onModelChanged);
192122

193-
it('displays author error when provided', () => {
194-
wrapper.setProps({
195-
model: {
196-
...model,
197-
errors: {
198-
passages: {
199-
0: { author: 'Author is required' },
200-
},
201-
},
202-
authorEnabled: true,
203-
},
204-
configuration: { ...configuration, author: { label: 'Author' } },
205-
});
206-
expect(wrapper.find('.mockErrorText').text()).toEqual('Author is required');
123+
expect(onModelChanged).toHaveBeenCalledWith({
124+
...modelWithTwo,
125+
passages: [{ teacherInstructions: 'Keep' }],
207126
});
208127

209-
it('displays text error when provided', () => {
210-
wrapper.setProps({
211-
model: {
212-
...model,
213-
errors: {
214-
passages: {
215-
0: { text: 'Text is required' },
216-
},
217-
},
218-
textEnabled: true,
219-
},
220-
configuration: { ...configuration, text: { label: 'Text' } },
221-
});
222-
expect(wrapper.find('.mockErrorText').at(0).text()).toEqual('Text is required');
128+
expect(wrapper.state()).toEqual({
129+
showConfirmationDialog: false,
130+
indexToRemove: -1,
223131
});
224132
});
225133
});

0 commit comments

Comments
 (0)