box-ui-elements 23.4.0-beta.30 → 23.4.0-beta.32
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.
- package/dist/explorer.css +1 -1
- package/dist/explorer.js +1 -1
- package/dist/openwith.js +1 -1
- package/dist/picker.js +1 -1
- package/dist/preview.css +1 -1
- package/dist/preview.js +1 -1
- package/dist/sharing.js +1 -1
- package/dist/sidebar.css +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/uploader.js +1 -1
- package/es/common/types/metadata.js.flow +6 -0
- package/es/common/types/metadata.js.map +1 -1
- package/es/elements/content-sidebar/SidebarNav.js +14 -3
- package/es/elements/content-sidebar/SidebarNav.js.flow +23 -3
- package/es/elements/content-sidebar/SidebarNav.js.map +1 -1
- package/es/elements/content-sidebar/SidebarNavTablist.js +58 -17
- package/es/elements/content-sidebar/SidebarNavTablist.js.flow +80 -21
- package/es/elements/content-sidebar/SidebarNavTablist.js.map +1 -1
- package/es/features/metadata-instance-editor/CascadePolicy.js +53 -23
- package/es/features/metadata-instance-editor/CascadePolicy.js.flow +69 -27
- package/es/features/metadata-instance-editor/CascadePolicy.js.map +1 -1
- package/es/features/metadata-instance-editor/Instance.js +26 -4
- package/es/features/metadata-instance-editor/Instance.js.flow +33 -4
- package/es/features/metadata-instance-editor/Instance.js.map +1 -1
- package/es/features/metadata-instance-editor/constants.js +4 -1
- package/es/features/metadata-instance-editor/constants.js.flow +10 -1
- package/es/features/metadata-instance-editor/constants.js.map +1 -1
- package/es/features/metadata-instance-editor/messages.js +16 -0
- package/es/features/metadata-instance-editor/messages.js.flow +21 -0
- package/es/features/metadata-instance-editor/messages.js.map +1 -1
- package/es/features/metadata-instance-editor/stories/tests/CascadePolicy-visual.stories.js +32 -0
- package/es/features/metadata-instance-editor/stories/tests/CascadePolicy-visual.stories.js.flow +36 -0
- package/es/features/metadata-instance-editor/stories/tests/CascadePolicy-visual.stories.js.map +1 -0
- package/i18n/bn-IN.js +4 -0
- package/i18n/da-DK.js +4 -0
- package/i18n/de-DE.js +4 -0
- package/i18n/en-AU.js +4 -0
- package/i18n/en-CA.js +4 -0
- package/i18n/en-GB.js +4 -0
- package/i18n/en-US.js +4 -0
- package/i18n/en-US.properties +8 -0
- package/i18n/en-x-pseudo.js +4 -0
- package/i18n/es-419.js +4 -0
- package/i18n/es-ES.js +4 -0
- package/i18n/fi-FI.js +4 -0
- package/i18n/fr-CA.js +4 -0
- package/i18n/fr-FR.js +4 -0
- package/i18n/hi-IN.js +4 -0
- package/i18n/it-IT.js +4 -0
- package/i18n/ja-JP.js +4 -0
- package/i18n/ko-KR.js +4 -0
- package/i18n/nb-NO.js +4 -0
- package/i18n/nl-NL.js +4 -0
- package/i18n/pl-PL.js +4 -0
- package/i18n/pt-BR.js +4 -0
- package/i18n/ru-RU.js +4 -0
- package/i18n/sv-SE.js +4 -0
- package/i18n/tr-TR.js +4 -0
- package/i18n/zh-CN.js +4 -0
- package/i18n/zh-TW.js +4 -0
- package/package.json +7 -7
- package/src/common/types/metadata.js +6 -0
- package/src/elements/content-sidebar/SidebarNav.js +23 -3
- package/src/elements/content-sidebar/SidebarNavTablist.js +80 -21
- package/src/elements/content-sidebar/__tests__/SidebarNav.test.js +99 -147
- package/src/elements/content-sidebar/__tests__/SidebarNavTablist.test.js +189 -42
- package/src/features/metadata-instance-editor/CascadePolicy.js +69 -27
- package/src/features/metadata-instance-editor/Instance.js +33 -4
- package/src/features/metadata-instance-editor/__tests__/CascadePolicy.test.js +70 -63
- package/src/features/metadata-instance-editor/__tests__/Instance.test.js +34 -19
- package/src/features/metadata-instance-editor/__tests__/Instances.test.js +15 -10
- package/src/features/metadata-instance-editor/__tests__/MetadataInstanceEditor.test.js +53 -10
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/Instance.test.js.snap +2 -1
- package/src/features/metadata-instance-editor/constants.js +10 -1
- package/src/features/metadata-instance-editor/messages.js +21 -0
- package/src/features/metadata-instance-editor/stories/tests/CascadePolicy-visual.stories.js +36 -0
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/CascadePolicy.test.js.snap +0 -108
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { MemoryRouter } from 'react-router-dom';
|
|
3
|
-
import userEvent from '@testing-library/user-event';
|
|
4
|
-
import { mount } from 'enzyme';
|
|
5
|
-
import { BoxAiLogo } from '@box/blueprint-web-assets/icons/Logo';
|
|
6
3
|
import { usePromptFocus } from '@box/box-ai-content-answers';
|
|
7
|
-
|
|
8
|
-
import AdditionalTabs from '../additional-tabs';
|
|
9
|
-
import AdditionalTabsLoading from '../additional-tabs/AdditionalTabsLoading';
|
|
4
|
+
|
|
10
5
|
import FeatureProvider from '../../common/feature-checking/FeatureProvider';
|
|
11
|
-
import DocGenIcon from '../../../icon/fill/DocGenIcon';
|
|
12
|
-
import IconChatRound from '../../../icons/general/IconChatRound';
|
|
13
|
-
import IconDocInfo from '../../../icons/general/IconDocInfo';
|
|
14
|
-
import IconMagicWand from '../../../icons/general/IconMagicWand';
|
|
15
|
-
import IconMetadataThick from '../../../icons/general/IconMetadataThick';
|
|
16
6
|
import SidebarNav from '../SidebarNav';
|
|
17
|
-
|
|
18
|
-
import
|
|
19
|
-
import { render, screen } from '../../../test-utils/testing-library';
|
|
7
|
+
|
|
8
|
+
import { render, screen, userEvent } from '../../../test-utils/testing-library';
|
|
20
9
|
|
|
21
10
|
jest.mock('@box/box-ai-content-answers');
|
|
22
11
|
|
|
@@ -24,88 +13,52 @@ describe('elements/content-sidebar/SidebarNav', () => {
|
|
|
24
13
|
const focusBoxAISidebarPromptMock = jest.fn();
|
|
25
14
|
|
|
26
15
|
beforeEach(() => {
|
|
16
|
+
jest.clearAllMocks();
|
|
27
17
|
usePromptFocus.mockReturnValue({
|
|
28
18
|
focusPrompt: focusBoxAISidebarPromptMock,
|
|
29
19
|
});
|
|
30
20
|
});
|
|
31
21
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
<MemoryRouter initialEntries={[
|
|
22
|
+
const renderSidebarNav = ({ path = '/', props = {}, features = {} } = {}) => {
|
|
23
|
+
return render(
|
|
24
|
+
<MemoryRouter initialEntries={[path]}>
|
|
35
25
|
<FeatureProvider features={features}>
|
|
36
26
|
<SidebarNav {...props} />
|
|
37
27
|
</FeatureProvider>
|
|
38
28
|
</MemoryRouter>,
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
test('should render skills tab', () => {
|
|
52
|
-
const props = {
|
|
53
|
-
hasSkills: true,
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
describe('individual tab rendering', () => {
|
|
33
|
+
const TABS_CONFIG = {
|
|
34
|
+
skills: { testId: 'sidebarskills', propName: 'hasSkills' },
|
|
35
|
+
details: { testId: 'sidebardetails', propName: 'hasDetails' },
|
|
36
|
+
activity: { testId: 'sidebaractivity', propName: 'hasActivity' },
|
|
37
|
+
metadata: { testId: 'sidebarmetadata', propName: 'hasMetadata' },
|
|
38
|
+
boxai: { testId: 'sidebarboxai', propName: 'hasBoxAI' },
|
|
39
|
+
docgen: { testId: 'sidebardocgen', propName: 'hasDocGen' },
|
|
54
40
|
};
|
|
55
|
-
const wrapper = getWrapper(props);
|
|
56
|
-
expect(wrapper.find(BoxAiLogo)).toHaveLength(0);
|
|
57
|
-
expect(wrapper.find(IconMagicWand)).toHaveLength(1);
|
|
58
|
-
expect(wrapper.find(IconMetadataThick)).toHaveLength(0);
|
|
59
|
-
expect(wrapper.find(IconDocInfo)).toHaveLength(0);
|
|
60
|
-
expect(wrapper.find(IconChatRound)).toHaveLength(0);
|
|
61
|
-
});
|
|
62
41
|
|
|
63
|
-
|
|
64
|
-
const props = {
|
|
65
|
-
hasDetails: true,
|
|
66
|
-
};
|
|
67
|
-
const wrapper = getWrapper(props);
|
|
68
|
-
expect(wrapper.find(BoxAiLogo)).toHaveLength(0);
|
|
69
|
-
expect(wrapper.find(IconMagicWand)).toHaveLength(0);
|
|
70
|
-
expect(wrapper.find(IconMetadataThick)).toHaveLength(0);
|
|
71
|
-
expect(wrapper.find(IconDocInfo)).toHaveLength(1);
|
|
72
|
-
expect(wrapper.find(IconChatRound)).toHaveLength(0);
|
|
73
|
-
});
|
|
42
|
+
const tabNames = Object.keys(TABS_CONFIG);
|
|
74
43
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
hasActivity: true,
|
|
78
|
-
};
|
|
79
|
-
const wrapper = getWrapper(props);
|
|
80
|
-
expect(wrapper.find(BoxAiLogo)).toHaveLength(0);
|
|
81
|
-
expect(wrapper.find(IconMagicWand)).toHaveLength(0);
|
|
82
|
-
expect(wrapper.find(IconMetadataThick)).toHaveLength(0);
|
|
83
|
-
expect(wrapper.find(IconDocInfo)).toHaveLength(0);
|
|
84
|
-
expect(wrapper.find(IconChatRound)).toHaveLength(1);
|
|
85
|
-
});
|
|
44
|
+
test.each(tabNames)('should render %s tab', tabName => {
|
|
45
|
+
const { testId, propName } = TABS_CONFIG[tabName];
|
|
86
46
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
expect(wrapper.find(BoxAiLogo)).toHaveLength(0);
|
|
93
|
-
expect(wrapper.find(IconMagicWand)).toHaveLength(0);
|
|
94
|
-
expect(wrapper.find(IconMetadataThick)).toHaveLength(1);
|
|
95
|
-
expect(wrapper.find(IconDocInfo)).toHaveLength(0);
|
|
96
|
-
expect(wrapper.find(IconChatRound)).toHaveLength(0);
|
|
97
|
-
});
|
|
47
|
+
renderSidebarNav({
|
|
48
|
+
props: {
|
|
49
|
+
[propName]: true,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
98
52
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
expect(wrapper.find(IconChatRound)).toHaveLength(0);
|
|
53
|
+
expect(screen.getByTestId(testId)).toBeInTheDocument();
|
|
54
|
+
|
|
55
|
+
tabNames
|
|
56
|
+
.filter(name => name !== tabName)
|
|
57
|
+
.forEach(otherTabName => {
|
|
58
|
+
const otherTab = TABS_CONFIG[otherTabName];
|
|
59
|
+
expect(screen.queryByTestId(otherTab.testId)).not.toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
109
62
|
});
|
|
110
63
|
|
|
111
64
|
describe('should render box ai tab with correct disabled state and tooltip', () => {
|
|
@@ -116,16 +69,16 @@ describe('elements/content-sidebar/SidebarNav', () => {
|
|
|
116
69
|
`(
|
|
117
70
|
'given feature boxai.sidebar.showOnlyNavButton = true and boxai.sidebar.disabledTooltip = $disabledTooltip, should render box ai tab with disabled state and tooltip = $expectedTooltip',
|
|
118
71
|
async ({ disabledTooltip, expectedTooltip }) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
);
|
|
72
|
+
const user = userEvent();
|
|
73
|
+
|
|
74
|
+
renderSidebarNav({
|
|
75
|
+
features: { boxai: { sidebar: { disabledTooltip, showOnlyNavButton: true } } },
|
|
76
|
+
props: { hasBoxAI: true },
|
|
77
|
+
});
|
|
125
78
|
|
|
126
79
|
const button = screen.getByTestId('sidebarboxai');
|
|
127
80
|
|
|
128
|
-
await
|
|
81
|
+
await user.hover(button);
|
|
129
82
|
|
|
130
83
|
expect(button).toHaveAttribute('aria-disabled', 'true');
|
|
131
84
|
expect(screen.getByText(expectedTooltip)).toBeInTheDocument();
|
|
@@ -133,16 +86,16 @@ describe('elements/content-sidebar/SidebarNav', () => {
|
|
|
133
86
|
);
|
|
134
87
|
|
|
135
88
|
test('given feature boxai.sidebar.showOnlyNavButton = false, should render box ai tab with default tooltip', async () => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
);
|
|
89
|
+
const user = userEvent();
|
|
90
|
+
|
|
91
|
+
renderSidebarNav({
|
|
92
|
+
features: { boxai: { sidebar: { showOnlyNavButton: false } } },
|
|
93
|
+
props: { hasBoxAI: true },
|
|
94
|
+
});
|
|
142
95
|
|
|
143
96
|
const button = screen.getByTestId('sidebarboxai');
|
|
144
97
|
|
|
145
|
-
await
|
|
98
|
+
await user.hover(button);
|
|
146
99
|
|
|
147
100
|
expect(button).not.toHaveAttribute('aria-disabled');
|
|
148
101
|
expect(screen.getByText('Box AI')).toBeInTheDocument();
|
|
@@ -150,22 +103,22 @@ describe('elements/content-sidebar/SidebarNav', () => {
|
|
|
150
103
|
});
|
|
151
104
|
|
|
152
105
|
test('should call focusBoxAISidebarPrompt when clicked on Box AI Tab', async () => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
106
|
+
const user = userEvent();
|
|
107
|
+
|
|
108
|
+
renderSidebarNav({
|
|
109
|
+
features: {
|
|
110
|
+
boxai: {
|
|
111
|
+
sidebar: {
|
|
112
|
+
showOnlyNavButton: false,
|
|
160
113
|
},
|
|
161
114
|
},
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
);
|
|
115
|
+
},
|
|
116
|
+
props: { hasBoxAI: true },
|
|
117
|
+
});
|
|
165
118
|
|
|
166
119
|
const button = screen.getByTestId('sidebarboxai');
|
|
167
120
|
|
|
168
|
-
await
|
|
121
|
+
await user.click(button);
|
|
169
122
|
|
|
170
123
|
expect(usePromptFocus).toHaveBeenCalledTimes(1);
|
|
171
124
|
expect(usePromptFocus).toHaveBeenCalledWith('.be.bcs');
|
|
@@ -175,53 +128,52 @@ describe('elements/content-sidebar/SidebarNav', () => {
|
|
|
175
128
|
});
|
|
176
129
|
|
|
177
130
|
test('should have multiple tabs', () => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
expect(
|
|
189
|
-
expect(
|
|
190
|
-
expect(
|
|
131
|
+
renderSidebarNav({
|
|
132
|
+
path: '/activity',
|
|
133
|
+
props: {
|
|
134
|
+
hasActivity: true,
|
|
135
|
+
hasBoxAI: true,
|
|
136
|
+
hasMetadata: true,
|
|
137
|
+
hasSkills: true,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
expect(screen.getByTestId('sidebaractivity')).toBeInTheDocument();
|
|
142
|
+
expect(screen.getByTestId('sidebarboxai')).toBeInTheDocument();
|
|
143
|
+
expect(screen.getByTestId('sidebarmetadata')).toBeInTheDocument();
|
|
144
|
+
expect(screen.getByTestId('sidebarskills')).toBeInTheDocument();
|
|
145
|
+
|
|
146
|
+
expect(screen.queryByTestId('sidebardetails')).not.toBeInTheDocument();
|
|
147
|
+
|
|
148
|
+
const navButtons = screen.getAllByRole('tab');
|
|
149
|
+
expect(navButtons).toHaveLength(4);
|
|
191
150
|
});
|
|
192
151
|
|
|
193
152
|
test('should render the additional tabs loading state', () => {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
expect(
|
|
153
|
+
renderSidebarNav({
|
|
154
|
+
props: {
|
|
155
|
+
additionalTabs: [],
|
|
156
|
+
hasAdditionalTabs: true,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
expect(screen.getByTestId('additional-tabs-overflow')).toBeInTheDocument();
|
|
161
|
+
|
|
162
|
+
const placeholders = screen.getAllByTestId('additionaltabplaceholder');
|
|
163
|
+
expect(placeholders).toHaveLength(5);
|
|
202
164
|
});
|
|
203
165
|
|
|
204
166
|
test('should render the Box Sign entry point if its feature is enabled', () => {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
167
|
+
renderSidebarNav({
|
|
168
|
+
props: {
|
|
169
|
+
signSidebarProps: {
|
|
170
|
+
enabled: true,
|
|
171
|
+
onClick: () => {},
|
|
172
|
+
},
|
|
209
173
|
},
|
|
210
|
-
};
|
|
211
|
-
const wrapper = getWrapper(props);
|
|
174
|
+
});
|
|
212
175
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
test('should render docgen tab', () => {
|
|
216
|
-
const props = {
|
|
217
|
-
hasDocGen: true,
|
|
218
|
-
};
|
|
219
|
-
const wrapper = getWrapper(props);
|
|
220
|
-
expect(wrapper.find(IconMagicWand)).toHaveLength(0);
|
|
221
|
-
expect(wrapper.find(IconMetadataThick)).toHaveLength(0);
|
|
222
|
-
expect(wrapper.find(IconDocInfo)).toHaveLength(0);
|
|
223
|
-
expect(wrapper.find(IconChatRound)).toHaveLength(0);
|
|
224
|
-
expect(wrapper.find(BoxAiLogo)).toHaveLength(0);
|
|
225
|
-
expect(wrapper.find(DocGenIcon)).toHaveLength(1);
|
|
176
|
+
const boxSignSection = screen.getByRole('button', { name: /sign/i });
|
|
177
|
+
expect(boxSignSection).toBeInTheDocument();
|
|
226
178
|
});
|
|
227
179
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { MemoryRouter, useHistory } from 'react-router-dom';
|
|
3
|
+
import { render, screen, userEvent } from '../../../test-utils/testing-library';
|
|
3
4
|
import SidebarNavTablist from '../SidebarNavTablist';
|
|
4
5
|
import {
|
|
5
6
|
SIDEBAR_VIEW_SKILLS,
|
|
@@ -9,59 +10,205 @@ import {
|
|
|
9
10
|
KEYS,
|
|
10
11
|
} from '../../../constants';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const MockTabComponent = React.forwardRef(
|
|
14
|
+
(
|
|
15
|
+
{
|
|
16
|
+
sidebarView,
|
|
17
|
+
elementId,
|
|
18
|
+
internalSidebarNavigation,
|
|
19
|
+
internalSidebarNavigationHandler,
|
|
20
|
+
isOpen,
|
|
21
|
+
onNavigate,
|
|
22
|
+
routerDisabled,
|
|
23
|
+
...otherProps
|
|
24
|
+
},
|
|
25
|
+
ref,
|
|
26
|
+
) => (
|
|
27
|
+
<button ref={ref} data-testid={`tab-${sidebarView}`} {...otherProps}>
|
|
28
|
+
{sidebarView}
|
|
29
|
+
</button>
|
|
30
|
+
),
|
|
31
|
+
);
|
|
16
32
|
|
|
17
33
|
describe('elements/content-sidebar/SidebarNavTablist', () => {
|
|
18
|
-
|
|
19
|
-
|
|
34
|
+
const viewList = [SIDEBAR_VIEW_ACTIVITY, SIDEBAR_VIEW_DETAILS, SIDEBAR_VIEW_SKILLS, SIDEBAR_VIEW_METADATA];
|
|
35
|
+
let testHistory;
|
|
36
|
+
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
jest.clearAllMocks();
|
|
39
|
+
});
|
|
20
40
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
const renderSidebarNavTablist = ({
|
|
42
|
+
path = '/',
|
|
43
|
+
props = {},
|
|
44
|
+
children = [<MockTabComponent key="test" sidebarView="test" />],
|
|
45
|
+
} = {}) => {
|
|
46
|
+
let historyRef;
|
|
47
|
+
|
|
48
|
+
const HistoryCapture = () => {
|
|
49
|
+
const history = useHistory();
|
|
50
|
+
historyRef = history;
|
|
51
|
+
return null;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const result = render(
|
|
55
|
+
<MemoryRouter initialEntries={[path]}>
|
|
56
|
+
<HistoryCapture />
|
|
57
|
+
<SidebarNavTablist {...props}>{children}</SidebarNavTablist>
|
|
58
|
+
</MemoryRouter>,
|
|
25
59
|
);
|
|
26
60
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
61
|
+
testHistory = historyRef;
|
|
62
|
+
return result;
|
|
63
|
+
};
|
|
31
64
|
|
|
32
|
-
|
|
33
|
-
|
|
65
|
+
test('should correctly render children', () => {
|
|
66
|
+
renderSidebarNavTablist({
|
|
67
|
+
props: { routerDisabled: false },
|
|
68
|
+
children: [<MockTabComponent key="test" sidebarView="test" />],
|
|
69
|
+
});
|
|
34
70
|
|
|
71
|
+
expect(screen.getByRole('tablist')).toBeInTheDocument();
|
|
72
|
+
expect(screen.getByTestId('tab-test')).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('handleKeyDown with router', () => {
|
|
35
76
|
test.each`
|
|
36
|
-
key
|
|
37
|
-
${KEYS.arrowUp}
|
|
38
|
-
${KEYS.arrowDown}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
77
|
+
key | expectedPath
|
|
78
|
+
${KEYS.arrowUp} | ${`/${SIDEBAR_VIEW_ACTIVITY}`}
|
|
79
|
+
${KEYS.arrowDown} | ${`/${SIDEBAR_VIEW_SKILLS}`}
|
|
80
|
+
`('should navigate to $expectedPath when user presses $key', async ({ key, expectedPath }) => {
|
|
81
|
+
const user = userEvent();
|
|
82
|
+
const children = viewList.map(view => <MockTabComponent sidebarView={view} key={view} />);
|
|
83
|
+
|
|
84
|
+
renderSidebarNavTablist({
|
|
85
|
+
path: `/${SIDEBAR_VIEW_DETAILS}`,
|
|
86
|
+
props: { routerDisabled: false },
|
|
87
|
+
children,
|
|
43
88
|
});
|
|
44
89
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
const tablist = screen.getByRole('tablist');
|
|
91
|
+
|
|
92
|
+
await user.click(tablist);
|
|
93
|
+
await user.keyboard(`{${key}}`);
|
|
94
|
+
|
|
95
|
+
expect(testHistory.location.pathname).toBe(expectedPath);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('should not navigate when user presses arrow right', async () => {
|
|
99
|
+
const user = userEvent();
|
|
100
|
+
const children = viewList.map(view => <MockTabComponent sidebarView={view} key={view} />);
|
|
101
|
+
|
|
102
|
+
renderSidebarNavTablist({
|
|
103
|
+
path: `/${SIDEBAR_VIEW_DETAILS}`,
|
|
104
|
+
props: { routerDisabled: false },
|
|
105
|
+
children,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const tablist = screen.getByRole('tablist');
|
|
109
|
+
|
|
110
|
+
await user.click(tablist);
|
|
111
|
+
await user.keyboard(`{${KEYS.arrowRight}}`);
|
|
112
|
+
|
|
113
|
+
expect(testHistory.location.pathname).toBe(`/${SIDEBAR_VIEW_DETAILS}`);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('handleKeyDown with routerDisabled', () => {
|
|
118
|
+
test.each`
|
|
119
|
+
key | expectedView
|
|
120
|
+
${KEYS.arrowUp} | ${SIDEBAR_VIEW_ACTIVITY}
|
|
121
|
+
${KEYS.arrowDown} | ${SIDEBAR_VIEW_SKILLS}
|
|
122
|
+
`(
|
|
123
|
+
'should use internal navigation when routerDisabled=true and user presses $key',
|
|
124
|
+
async ({ key, expectedView }) => {
|
|
125
|
+
const user = userEvent();
|
|
126
|
+
const mockInternalSidebarNavigationHandler = jest.fn();
|
|
127
|
+
const internalSidebarNavigation = {
|
|
128
|
+
sidebar: SIDEBAR_VIEW_DETAILS,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const children = viewList.map(view => <MockTabComponent sidebarView={view} key={view} />);
|
|
132
|
+
|
|
133
|
+
renderSidebarNavTablist({
|
|
134
|
+
props: {
|
|
135
|
+
routerDisabled: true,
|
|
136
|
+
internalSidebarNavigation,
|
|
137
|
+
internalSidebarNavigationHandler: mockInternalSidebarNavigationHandler,
|
|
138
|
+
},
|
|
139
|
+
children,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const tablist = screen.getByRole('tablist');
|
|
143
|
+
|
|
144
|
+
await user.click(tablist);
|
|
145
|
+
await user.keyboard(`{${key}}`);
|
|
146
|
+
|
|
147
|
+
expect(mockInternalSidebarNavigationHandler).toHaveBeenCalledWith({
|
|
148
|
+
sidebar: expectedView,
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
test.each`
|
|
154
|
+
currentView | key | expectedView
|
|
155
|
+
${SIDEBAR_VIEW_ACTIVITY} | ${KEYS.arrowUp} | ${SIDEBAR_VIEW_METADATA}
|
|
156
|
+
${SIDEBAR_VIEW_METADATA} | ${KEYS.arrowDown} | ${SIDEBAR_VIEW_ACTIVITY}
|
|
157
|
+
`(
|
|
158
|
+
'should wrap around when navigating beyond tabs range: from $currentView with $key goes to $expectedView',
|
|
159
|
+
async ({ currentView, key, expectedView }) => {
|
|
160
|
+
const user = userEvent();
|
|
161
|
+
const mockInternalSidebarNavigationHandler = jest.fn();
|
|
162
|
+
const internalSidebarNavigation = {
|
|
163
|
+
sidebar: currentView,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const children = viewList.map(view => <MockTabComponent sidebarView={view} key={view} />);
|
|
167
|
+
|
|
168
|
+
renderSidebarNavTablist({
|
|
169
|
+
props: {
|
|
170
|
+
routerDisabled: true,
|
|
171
|
+
internalSidebarNavigation,
|
|
172
|
+
internalSidebarNavigationHandler: mockInternalSidebarNavigationHandler,
|
|
173
|
+
},
|
|
174
|
+
children,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const tablist = screen.getByRole('tablist');
|
|
178
|
+
|
|
179
|
+
await user.click(tablist);
|
|
180
|
+
await user.keyboard(`{${key}}`);
|
|
181
|
+
|
|
182
|
+
expect(mockInternalSidebarNavigationHandler).toHaveBeenCalledWith({
|
|
183
|
+
sidebar: expectedView,
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
test('should not call internal navigation handler when user presses arrow right', async () => {
|
|
189
|
+
const user = userEvent();
|
|
190
|
+
const mockInternalSidebarNavigationHandler = jest.fn();
|
|
191
|
+
const internalSidebarNavigation = {
|
|
192
|
+
sidebar: SIDEBAR_VIEW_DETAILS,
|
|
57
193
|
};
|
|
58
|
-
wrapper.props().onKeyDown(event);
|
|
59
194
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
195
|
+
const children = viewList.map(view => <MockTabComponent sidebarView={view} key={view} />);
|
|
196
|
+
|
|
197
|
+
renderSidebarNavTablist({
|
|
198
|
+
props: {
|
|
199
|
+
routerDisabled: true,
|
|
200
|
+
internalSidebarNavigation,
|
|
201
|
+
internalSidebarNavigationHandler: mockInternalSidebarNavigationHandler,
|
|
202
|
+
},
|
|
203
|
+
children,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const tablist = screen.getByRole('tablist');
|
|
207
|
+
|
|
208
|
+
await user.click(tablist);
|
|
209
|
+
await user.keyboard(`{${KEYS.arrowRight}}`);
|
|
210
|
+
|
|
211
|
+
expect(mockInternalSidebarNavigationHandler).not.toHaveBeenCalled();
|
|
65
212
|
});
|
|
66
213
|
});
|
|
67
214
|
});
|