@pie-lib/config-ui 13.1.0-beta.8 → 13.1.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,141 +0,0 @@
1
- import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import userEvent from '@testing-library/user-event';
4
- import { buildDefaults, FeedbackConfig } from '../index';
5
-
6
- // Mock FeedbackSelector to simplify testing
7
- jest.mock('../feedback-selector', () => {
8
- return function FeedbackSelector({ label, feedback, onChange }) {
9
- return (
10
- <div data-testid="feedback-selector">
11
- <label>{label}</label>
12
- <select
13
- aria-label={label}
14
- value={feedback.type}
15
- onChange={(e) => onChange({ ...feedback, type: e.target.value })}
16
- >
17
- <option value="default">Default</option>
18
- <option value="custom">Custom</option>
19
- <option value="none">None</option>
20
- </select>
21
- </div>
22
- );
23
- };
24
- });
25
-
26
- describe('FeedbackConfig', () => {
27
- const onChange = jest.fn();
28
-
29
- beforeEach(() => {
30
- onChange.mockClear();
31
- });
32
-
33
- describe('rendering', () => {
34
- it('renders with default feedback types', () => {
35
- const feedback = buildDefaults();
36
-
37
- render(<FeedbackConfig feedback={feedback} onChange={onChange} />);
38
-
39
- expect(screen.getByText('Feedback')).toBeInTheDocument();
40
- expect(screen.getByText('If correct, show')).toBeInTheDocument();
41
- expect(screen.getByText('If partially correct, show')).toBeInTheDocument();
42
- expect(screen.getByText('If incorrect, show')).toBeInTheDocument();
43
- });
44
-
45
- it('renders all three feedback selectors by default', () => {
46
- const feedback = buildDefaults();
47
-
48
- render(<FeedbackConfig feedback={feedback} onChange={onChange} />);
49
-
50
- const selectors = screen.getAllByTestId('feedback-selector');
51
- expect(selectors).toHaveLength(3);
52
- });
53
-
54
- it('does not render partial feedback selector when allowPartial is false', () => {
55
- const feedback = buildDefaults();
56
-
57
- render(<FeedbackConfig allowPartial={false} feedback={feedback} onChange={onChange} />);
58
-
59
- expect(screen.getByText('If correct, show')).toBeInTheDocument();
60
- expect(screen.queryByText('If partially correct, show')).not.toBeInTheDocument();
61
- expect(screen.getByText('If incorrect, show')).toBeInTheDocument();
62
-
63
- const selectors = screen.getAllByTestId('feedback-selector');
64
- expect(selectors).toHaveLength(2);
65
- });
66
- });
67
-
68
- describe('user interactions', () => {
69
- it('calls onChange when correct feedback type changes', async () => {
70
- const user = userEvent.setup();
71
- const feedback = buildDefaults();
72
-
73
- render(<FeedbackConfig feedback={feedback} onChange={onChange} />);
74
-
75
- const correctSelect = screen.getByLabelText('If correct, show');
76
- await user.selectOptions(correctSelect, 'custom');
77
-
78
- expect(onChange).toHaveBeenCalledWith(
79
- expect.objectContaining({
80
- correct: expect.objectContaining({ type: 'custom' }),
81
- }),
82
- );
83
- });
84
-
85
- it('calls onChange when incorrect feedback type changes', async () => {
86
- const user = userEvent.setup();
87
- const feedback = buildDefaults();
88
-
89
- render(<FeedbackConfig feedback={feedback} onChange={onChange} />);
90
-
91
- const incorrectSelect = screen.getByLabelText('If incorrect, show');
92
- await user.selectOptions(incorrectSelect, 'none');
93
-
94
- expect(onChange).toHaveBeenCalledWith(
95
- expect.objectContaining({
96
- incorrect: expect.objectContaining({ type: 'none' }),
97
- }),
98
- );
99
- });
100
-
101
- it('calls onChange when partial feedback type changes', async () => {
102
- const user = userEvent.setup();
103
- const feedback = buildDefaults();
104
-
105
- render(<FeedbackConfig feedback={feedback} onChange={onChange} />);
106
-
107
- const partialSelect = screen.getByLabelText('If partially correct, show');
108
- await user.selectOptions(partialSelect, 'custom');
109
-
110
- expect(onChange).toHaveBeenCalledWith(
111
- expect.objectContaining({
112
- partial: expect.objectContaining({ type: 'custom' }),
113
- }),
114
- );
115
- });
116
- });
117
-
118
- describe('buildDefaults helper', () => {
119
- it('returns default feedback configuration', () => {
120
- const defaults = buildDefaults();
121
-
122
- expect(defaults).toEqual({
123
- correct: { type: 'default', default: 'Correct' },
124
- incorrect: { type: 'default', default: 'Incorrect' },
125
- partial: { type: 'default', default: 'Nearly' },
126
- });
127
- });
128
-
129
- it('merges custom values with defaults', () => {
130
- const defaults = buildDefaults({
131
- correct: { type: 'custom', custom: 'Great job!' },
132
- });
133
-
134
- expect(defaults).toEqual({
135
- correct: { type: 'custom', default: 'Correct', custom: 'Great job!' },
136
- incorrect: { type: 'default', default: 'Incorrect' },
137
- partial: { type: 'default', default: 'Nearly' },
138
- });
139
- });
140
- });
141
- });
@@ -1,97 +0,0 @@
1
- import { render, screen } from '@testing-library/react';
2
- import userEvent from '@testing-library/user-event';
3
- import React from 'react';
4
- import { FeedbackSelector } from '../feedback-selector';
5
-
6
- // Mock the editable-html component to avoid window dependencies in tests
7
- jest.mock('@pie-lib/editable-html-tip-tap', () => {
8
- return {
9
- __esModule: true,
10
- default: ({ markup, onChange }) => (
11
- <textarea data-testid="editable-html" defaultValue={markup || ''} onChange={(e) => onChange(e.target.value)} />
12
- ),
13
- };
14
- });
15
-
16
- describe('feedback-selector', () => {
17
- let onChange;
18
-
19
- const renderComponent = (feedback = { type: 'default', default: 'hi' }) => {
20
- return render(<FeedbackSelector label={'Feedback'} onChange={onChange} feedback={feedback} />);
21
- };
22
-
23
- beforeEach(() => {
24
- onChange = jest.fn();
25
- });
26
-
27
- describe('rendering', () => {
28
- it('renders feedback type selector', () => {
29
- renderComponent();
30
- expect(screen.getByText('Simple Feedback')).toBeInTheDocument();
31
- expect(screen.getByText('No Feedback')).toBeInTheDocument();
32
- expect(screen.getByText('Customized Feedback')).toBeInTheDocument();
33
- });
34
-
35
- it('shows default feedback text when type is default', () => {
36
- renderComponent({ type: 'default', default: 'hi' });
37
- expect(screen.getByText('hi')).toBeInTheDocument();
38
- });
39
-
40
- it('shows editable html when type is custom', () => {
41
- renderComponent({ type: 'custom', default: 'hi', custom: 'custom text' });
42
- expect(screen.getByTestId('editable-html')).toBeInTheDocument();
43
- expect(screen.getByTestId('editable-html')).toHaveValue('custom text');
44
- });
45
-
46
- it('does not show default feedback when type is none', () => {
47
- renderComponent({ type: 'none', default: 'hi' });
48
- expect(screen.queryByText('hi')).not.toBeInTheDocument();
49
- });
50
- });
51
-
52
- describe('user interactions', () => {
53
- it('calls onChange when switching to default feedback', async () => {
54
- const user = userEvent.setup();
55
- renderComponent({ type: 'custom', default: 'hi' });
56
-
57
- await user.click(screen.getByLabelText('Simple Feedback'));
58
-
59
- expect(onChange).toHaveBeenCalledWith({ type: 'default', default: 'hi' });
60
- });
61
-
62
- it('calls onChange when switching to custom feedback', async () => {
63
- const user = userEvent.setup();
64
- renderComponent({ type: 'default', default: 'hi' });
65
-
66
- await user.click(screen.getByLabelText('Customized Feedback'));
67
-
68
- expect(onChange).toHaveBeenCalledWith({ type: 'custom', default: 'hi' });
69
- });
70
-
71
- it('calls onChange when switching to no feedback', async () => {
72
- const user = userEvent.setup();
73
- renderComponent({ type: 'default', default: 'hi' });
74
-
75
- await user.click(screen.getByLabelText('No Feedback'));
76
-
77
- expect(onChange).toHaveBeenCalledWith({ type: 'none', default: 'hi' });
78
- });
79
-
80
- it('calls onChange with custom text when editing custom feedback', async () => {
81
- const user = userEvent.setup();
82
- renderComponent({ type: 'custom', default: 'hi', custom: '' });
83
-
84
- const editor = screen.getByTestId('editable-html');
85
- await user.clear(editor);
86
- await user.type(editor, 'text');
87
-
88
- // user.type triggers onChange for each character, so check that onChange was called
89
- // and that the last call has 'text' in custom field
90
- expect(onChange).toHaveBeenCalled();
91
- const lastCall = onChange.mock.calls[onChange.mock.calls.length - 1][0];
92
- expect(lastCall.type).toBe('custom');
93
- expect(lastCall.custom).toBe('text');
94
- expect(lastCall.default).toBe('hi');
95
- });
96
- });
97
- });
@@ -1,59 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, waitFor } from '@testing-library/react';
3
- import ConfigLayout from '../config-layout';
4
-
5
- describe('ConfigLayout', () => {
6
- const settingsPanel = (
7
- <div data-testid="settings-panel">
8
- <div key={0}>Foo</div>
9
- <div key={1}>Bar</div>
10
- </div>
11
- );
12
-
13
- const children = (
14
- <div data-testid="main-content">
15
- <div>Foo</div>
16
- <div>Bar</div>
17
- </div>
18
- );
19
-
20
- describe('rendering', () => {
21
- it('renders correctly with settings panel', async () => {
22
- render(<ConfigLayout settings={settingsPanel}>{children}</ConfigLayout>);
23
-
24
- // Main content should render immediately
25
- expect(screen.getByTestId('main-content')).toBeInTheDocument();
26
-
27
- // Settings panel may render after layout calculation
28
- // In test environment, react-measure may not provide dimensions,
29
- // so we check if it exists but don't require it
30
- await waitFor(() => {
31
- expect(screen.getByText('Foo')).toBeInTheDocument();
32
- });
33
- });
34
-
35
- it('renders main content when provided', () => {
36
- render(<ConfigLayout settings={settingsPanel}>{children}</ConfigLayout>);
37
-
38
- expect(screen.getByTestId('main-content')).toBeInTheDocument();
39
- expect(screen.getByText('Foo')).toBeInTheDocument();
40
- // Only check that Bar appears at least once (in main content)
41
- expect(screen.getAllByText('Bar').length).toBeGreaterThanOrEqual(1);
42
- });
43
-
44
- it('renders settings panel content', () => {
45
- render(<ConfigLayout settings={settingsPanel}>{children}</ConfigLayout>);
46
-
47
- // Settings panel might not render in test environment due to react-measure
48
- // Just verify the component renders without crashing
49
- expect(screen.getByTestId('main-content')).toBeInTheDocument();
50
- });
51
-
52
- it('renders without settings panel when not provided', () => {
53
- render(<ConfigLayout>{children}</ConfigLayout>);
54
-
55
- expect(screen.queryByTestId('settings-panel')).not.toBeInTheDocument();
56
- expect(screen.getByTestId('main-content')).toBeInTheDocument();
57
- });
58
- });
59
- });
@@ -1,3 +0,0 @@
1
- describe('layout-content', () => {
2
- it.todo('add tests!');
3
- });
@@ -1,113 +0,0 @@
1
- import { TagsInput } from '../index';
2
- import { Keys, pressKey, render, screen, userEvent } from '@pie-lib/test-utils';
3
- import React from 'react';
4
-
5
- describe('TagsInput', () => {
6
- describe('rendering', () => {
7
- it('renders existing tags as chips', () => {
8
- render(<TagsInput tags={['foo', 'bar']} onChange={jest.fn()} />);
9
-
10
- expect(screen.getByText('foo')).toBeInTheDocument();
11
- expect(screen.getByText('bar')).toBeInTheDocument();
12
- });
13
-
14
- it('renders input field', () => {
15
- render(<TagsInput tags={['foo']} onChange={jest.fn()} />);
16
-
17
- const input = screen.getByRole('textbox');
18
- expect(input).toBeInTheDocument();
19
- });
20
- });
21
-
22
- describe('user interactions', () => {
23
- let onChange;
24
- const renderComponent = (tags = ['foo']) => {
25
- onChange = jest.fn();
26
- return render(<TagsInput onChange={onChange} tags={tags} />);
27
- };
28
-
29
- describe('focus behavior', () => {
30
- it('allows user to focus the input', async () => {
31
- const user = userEvent.setup();
32
- renderComponent();
33
-
34
- const input = screen.getByRole('textbox');
35
- await user.click(input);
36
-
37
- expect(input).toHaveFocus();
38
- });
39
-
40
- it('allows user to blur the input', async () => {
41
- const user = userEvent.setup();
42
- renderComponent();
43
-
44
- const input = screen.getByRole('textbox');
45
- await user.click(input);
46
- expect(input).toHaveFocus();
47
-
48
- await user.tab();
49
- expect(input).not.toHaveFocus();
50
- });
51
- });
52
-
53
- describe('typing in input', () => {
54
- it('updates input value when user types', async () => {
55
- const user = userEvent.setup();
56
- renderComponent();
57
-
58
- const input = screen.getByRole('textbox');
59
- await user.type(input, 'boo');
60
-
61
- expect(input).toHaveValue('boo');
62
- });
63
- });
64
-
65
- describe('adding tags', () => {
66
- it('adds new tag when user presses Enter', async () => {
67
- const user = userEvent.setup();
68
- renderComponent();
69
-
70
- const input = screen.getByRole('textbox');
71
- await user.type(input, 'banana');
72
- pressKey(input, Keys.ENTER);
73
-
74
- expect(onChange).toHaveBeenCalledWith(['foo', 'banana']);
75
- });
76
-
77
- it('does not add duplicate tags', async () => {
78
- const user = userEvent.setup();
79
- renderComponent();
80
-
81
- const input = screen.getByRole('textbox');
82
- await user.type(input, 'foo');
83
- pressKey(input, Keys.ENTER);
84
-
85
- expect(onChange).not.toHaveBeenCalled();
86
- });
87
-
88
- it('clears input after adding tag', async () => {
89
- const user = userEvent.setup();
90
- renderComponent();
91
-
92
- const input = screen.getByRole('textbox');
93
- await user.type(input, 'banana');
94
- pressKey(input, Keys.ENTER);
95
-
96
- expect(input).toHaveValue('');
97
- });
98
- });
99
-
100
- describe('deleting tags', () => {
101
- it('removes tag when user clicks delete button', async () => {
102
- const user = userEvent.setup();
103
- renderComponent(['foo', 'bar']);
104
-
105
- // Find the delete button for 'foo' tag
106
- const deleteButtons = screen.getAllByTestId('CancelIcon');
107
- await user.click(deleteButtons[0]);
108
-
109
- expect(onChange).toHaveBeenCalledWith(['bar']);
110
- });
111
- });
112
- });
113
- });