@availity/mui-spaces 0.1.0

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.
@@ -0,0 +1,265 @@
1
+ import '@testing-library/jest-dom';
2
+ import { useState } from 'react';
3
+ import { render, waitFor, fireEvent } from '@testing-library/react';
4
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
+ import { Spaces, useSpaces, useSpacesContext } from '..';
6
+
7
+ // eslint-disable-next-line @nx/enforce-module-boundaries
8
+ import { server } from '../../../mock/src/lib/server';
9
+ import { NormalizedSpace } from './spaces-types';
10
+
11
+ beforeAll(() => {
12
+ // Start the interception.
13
+ server.listen();
14
+ });
15
+
16
+ afterEach(() => {
17
+ // Remove any handlers you may have added
18
+ // in individual tests (runtime handlers).
19
+ server.resetHandlers();
20
+ });
21
+
22
+ afterAll(() => {
23
+ // Disable request interception and clean up.
24
+ server.close();
25
+ });
26
+
27
+ describe('Spaces', () => {
28
+ it('provides correct spaces from props and from avWebQL', async () => {
29
+ const queryClient = new QueryClient();
30
+ // Create a space component that renders "Space <id-here> is in provider" if the space is in the provider and "Space <id-here> is not in provider" if it is not the provider
31
+ const SpaceComponent = ({ spaceId }: { spaceId: string }) => {
32
+ const space = useSpaces(spaceId);
33
+ return (
34
+ <div>
35
+ <span id={`space-for-${spaceId}`}>
36
+ {space && space.length > 0 ? `Space ${spaceId} is in provider` : `Space ${spaceId} is not in provider`}
37
+ </span>
38
+ </div>
39
+ );
40
+ };
41
+ // Create component that renders a SpaceComponent for ids 1, 2, and 3
42
+ const MyComponent = () => {
43
+ const [spaceIds, setSpaceIds] = useState(['1', '3']);
44
+ return (
45
+ <QueryClientProvider client={queryClient}>
46
+ <Spaces
47
+ spaceIds={spaceIds}
48
+ spaces={[{ id: '3', configurationId: '3', type: 'space', name: 'Space 3' }]}
49
+ clientId="my-client-id"
50
+ >
51
+ <SpaceComponent spaceId="1" />
52
+ <SpaceComponent spaceId="2" />
53
+ <SpaceComponent spaceId="3" />
54
+ <button type="button" id="add-spaceid-btn" onClick={() => setSpaceIds(['1', '2', '3'])}>
55
+ Add
56
+ </button>
57
+ </Spaces>
58
+ </QueryClientProvider>
59
+ );
60
+ };
61
+ const { container, getByText } = render(<MyComponent />);
62
+ // Check that space 1 (fetched from avWebQL) is accessible by spaces provider
63
+ await waitFor(() => getByText('Space 1 is in provider'));
64
+ expect(getByText('Space 1 is in provider')).toBeDefined();
65
+ // Check that space 2 (not provided) is not accessible by spaces provider
66
+ await waitFor(() => getByText('Space 2 is not in provider'));
67
+ expect(getByText('Space 2 is not in provider')).toBeDefined();
68
+ // Check that space 3 (provided by props) is accessible by spaces provider
69
+ await waitFor(() => getByText('Space 3 is in provider'));
70
+ expect(getByText('Space 3 is in provider')).toBeDefined();
71
+ // Check that avWebQL was only queried for space 1 because space 3 was provided by props
72
+ // Click button that adds another space id, "2", to the provider
73
+ const button = container.querySelector('#add-spaceid-btn');
74
+ if (button) fireEvent.click(button);
75
+ // // Check that space 1 (fetched from avWebQL) is still accessible by spaces provider
76
+ await waitFor(() => getByText('Space 1 is in provider'));
77
+ expect(getByText('Space 1 is in provider')).toBeDefined();
78
+ // // Check that space 2 (now fetched from avWebQL) is now accessible by spaces provider
79
+ await waitFor(() => getByText('Space 2 is in provider'));
80
+ expect(getByText('Space 2 is in provider')).toBeDefined();
81
+ // // Check that space 3 (provided by props) is still accessible by spaces provider
82
+ await waitFor(() => getByText('Space 3 is in provider'));
83
+ expect(getByText('Space 3 is in provider')).toBeDefined();
84
+ });
85
+ });
86
+
87
+ it('toggles whether the spaces provider is loading', async () => {
88
+ const queryClient = new QueryClient();
89
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
90
+ const fn = jest.fn();
91
+ // Create component to call mock function
92
+ const SpaceComponent = ({ spaceId }: { spaceId: string }) => {
93
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
94
+
95
+ const space = useSpaces(spaceId);
96
+ const { loading } = useSpacesContext();
97
+
98
+ if (loading) fn();
99
+
100
+ // Should be called when we fetch spaces from avWebQL gets executed
101
+ return loading ? null : (
102
+ <span id={`space-for-${spaceId}`}>{space?.[0] ? `Space ${space[0].id}` : 'No Space '}</span>
103
+ );
104
+ };
105
+
106
+ // Create component that renders a SpaceComponent for the current space id
107
+ const MyComponent = () => {
108
+ const [spaceId, setSpaceId] = useState(['1']);
109
+
110
+ return (
111
+ <QueryClientProvider client={queryClient}>
112
+ <Spaces spaceIds={spaceId} clientId="my-client-id">
113
+ <SpaceComponent spaceId={spaceId[0]} />
114
+
115
+ <button type="button" id="add-spaceid-btn" onClick={() => setSpaceId(['2'])}>
116
+ Add
117
+ </button>
118
+ </Spaces>
119
+ </QueryClientProvider>
120
+ );
121
+ };
122
+
123
+ const { container, getByText } = render(<MyComponent />);
124
+
125
+ expect(fn).toHaveBeenCalled();
126
+
127
+ await waitFor(() => getByText('Space 1'));
128
+
129
+ // Add a space id
130
+ const button = container.querySelector('#add-spaceid-btn');
131
+ if (button) fireEvent.click(button);
132
+
133
+ expect(fn).toHaveBeenCalled();
134
+
135
+ await waitFor(() => getByText('Space 2'));
136
+ });
137
+
138
+ describe('useSpaces', () => {
139
+ // Create a spaces component that renders ids passed in
140
+ const SpacesComponent = ({ ids = [] }: { ids?: string[] }) => {
141
+ const spaces = useSpaces(...ids) || [];
142
+
143
+ const dataTestIdSuffix = ids && ids.length > 0 ? ids.join('-') : 'all-spaces';
144
+ return (
145
+ <div>
146
+ <span id={`spaces-for-${dataTestIdSuffix}`}>{spaces.map((spc) => `Id: ${spc.id} `)}</span>
147
+ </div>
148
+ );
149
+ };
150
+
151
+ it('returns spaces by id', async () => {
152
+ const queryClient = new QueryClient();
153
+ const { container } = render(
154
+ <QueryClientProvider client={queryClient}>
155
+ <Spaces spaceIds={['1', '2', '3']} clientId="test-client-id">
156
+ <SpacesComponent />
157
+ <SpacesComponent ids={['2', '3']} />
158
+ </Spaces>
159
+ </QueryClientProvider>
160
+ );
161
+
162
+ // Check that all spaces get returned when no ids get passed to useSpaces hook
163
+ const allSpaces = await waitFor(() => container.querySelector('#spaces-for-all-spaces'));
164
+ await waitFor(() => expect(allSpaces?.textContent).toBe('Id: 1 Id: 2 Id: 3 '));
165
+
166
+ // Check that spaces for ids get returned when ids passed to useSpaces hook
167
+ const specificSpaces = await waitFor(() => container.querySelector('#spaces-for-2-3'));
168
+ expect(specificSpaces?.textContent).toBe('Id: 2 Id: 3 ');
169
+ });
170
+
171
+ it('returns spaces by configurationId', async () => {
172
+ const queryClient = new QueryClient();
173
+ const { getByText } = render(
174
+ <QueryClientProvider client={queryClient}>
175
+ <Spaces spaceIds={['11', '22', '33']} clientId="test-client-id">
176
+ <SpacesComponent />
177
+ <SpacesComponent ids={['22', '33']} />
178
+ </Spaces>
179
+ </QueryClientProvider>
180
+ );
181
+
182
+ // Check that all spaces get returned when no configurationIds get passed to useSpaces hook
183
+ await waitFor(() => getByText('Id: 1 Id: 2 Id: 3'));
184
+
185
+ // Check that spaces for configurationIds get returned when configurationIds passed to useSpaces hook
186
+ await waitFor(() => getByText('Id: 2 Id: 3'));
187
+ });
188
+
189
+ it('returns all matching spaces when searching by payerId', async () => {
190
+ const queryClient = new QueryClient();
191
+ const { getByText } = render(
192
+ <QueryClientProvider client={queryClient}>
193
+ <Spaces payerIds={['a', 'b', 'c']} clientId="test-client-id">
194
+ <SpacesComponent ids={['b']} />
195
+ <SpacesComponent ids={['c']} />
196
+ </Spaces>
197
+ </QueryClientProvider>
198
+ );
199
+
200
+ // Check that spaces for payer ids get returned when ids passed to useSpaces hook
201
+ await waitFor(() => getByText('Id: 1 Id: 2'));
202
+ await waitFor(() => getByText('Id: 1 Id: 2 Id: 3'));
203
+ });
204
+
205
+ it('renders with warning when returning all spaces because no ids were passed in', async () => {
206
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
207
+ const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation(() => {});
208
+ const SpacesComponent = ({ ids = [] }) => {
209
+ const spaces = useSpaces(...ids) || [];
210
+
211
+ const dataTestIdSuffix = ids && ids.length > 0 ? ids.join('-') : 'all-spaces';
212
+ return (
213
+ <div>
214
+ <span id={`spaces-for-${dataTestIdSuffix}`}>{spaces.map((spc) => `Id: ${spc && spc.id} `)}</span>
215
+ </div>
216
+ );
217
+ };
218
+
219
+ const queryClient = new QueryClient();
220
+
221
+ const { container } = render(
222
+ <QueryClientProvider client={queryClient}>
223
+ <Spaces spaceIds={['1', '2']} clientId="test-client-id">
224
+ <SpacesComponent />
225
+ </Spaces>
226
+ </QueryClientProvider>
227
+ );
228
+
229
+ await waitFor(() => container.querySelector('#spaces-for-all-spaces'));
230
+
231
+ expect(consoleWarnMock).toHaveBeenCalled();
232
+ expect(consoleWarnMock.mock.calls[0][0]).toBe('You did not pass in an ID to find a space, returning all spaces.');
233
+
234
+ consoleWarnMock.mockRestore();
235
+ });
236
+ });
237
+
238
+ it('returns first payer space with when no spaceId passed', async () => {
239
+ // Create component that renders a SpaceComponent for the current space id
240
+ const SpaceComponent = () => {
241
+ const spaces = useSpaces() || [];
242
+
243
+ return (
244
+ <div id={`space-${spaces[0]?.id}`}>
245
+ <span>{spaces[0]?.name}</span>
246
+ </div>
247
+ );
248
+ };
249
+
250
+ const queryClient = new QueryClient();
251
+
252
+ const { container, getByText } = render(
253
+ <QueryClientProvider client={queryClient}>
254
+ <Spaces spaceIds={['1']} clientId="my-client-id">
255
+ <SpaceComponent />
256
+ </Spaces>
257
+ </QueryClientProvider>
258
+ );
259
+
260
+ const spc1 = await waitFor(() => container.querySelector('#space-1'));
261
+ const spc2 = await waitFor(() => getByText('Space 1'));
262
+
263
+ expect(spc1).toBeDefined();
264
+ expect(spc2).toBeDefined();
265
+ });
@@ -0,0 +1,202 @@
1
+ import { createContext, useContext, useReducer, useEffect } from 'react';
2
+ import { useQueries } from '@tanstack/react-query';
3
+ import { normalizeSpaces, spacesReducer, fetchAllSpaces } from './spaces-data';
4
+ import { Space, SpacesProps, SpacesContextType } from './spaces-types';
5
+ import configurationFindMany from './configurationFindMany';
6
+
7
+ export const INITIAL_STATE = {
8
+ loading: true,
9
+ };
10
+
11
+ export const SpacesContext = createContext<SpacesContextType>(INITIAL_STATE);
12
+
13
+ export const useSpacesContext = () => useContext(SpacesContext);
14
+
15
+ export const Spaces = ({
16
+ query = configurationFindMany,
17
+ variables = { types: ['PAYERSPACE'] },
18
+ clientId,
19
+ children,
20
+ payerIds,
21
+ spaceIds,
22
+ spaces: spacesFromProps,
23
+ }: SpacesProps): JSX.Element => {
24
+ const [{ previousSpacesMap, previousSpacesByConfigMap, previousSpacesByPayerMap, loading, error }, dispatch] =
25
+ useReducer(spacesReducer, INITIAL_STATE);
26
+
27
+ const spacesMap: Map<string, Space> = new Map(previousSpacesMap);
28
+ const configIdsMap: Map<string, Space> = new Map(previousSpacesByConfigMap);
29
+ const payerIdsMap: Map<string, Space[]> = new Map(previousSpacesByPayerMap);
30
+ const spaceIdsToQuery: Set<string> = new Set();
31
+ const payerIdsToQuery: Set<string> = new Set();
32
+
33
+ if (spacesFromProps && spacesFromProps.length > 0) {
34
+ for (const space of spacesFromProps) {
35
+ if (space.id && !spacesMap.has(space.id)) {
36
+ spacesMap.set(space.id, space);
37
+ }
38
+
39
+ if (space.configurationId && !configIdsMap.has(space.configurationId)) {
40
+ configIdsMap.set(space.configurationId, space);
41
+ }
42
+
43
+ if (space.payerIDs) {
44
+ for (const pId of space.payerIDs) {
45
+ const currentSpacesForPayerId = payerIdsMap.get(pId);
46
+ if (currentSpacesForPayerId) {
47
+ payerIdsMap.set(pId, [...currentSpacesForPayerId, space]);
48
+ } else {
49
+ payerIdsMap.set(pId, [space]);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ if (spaceIds && spaceIds.length > 0) {
57
+ for (const id of spaceIds) {
58
+ if (!(spacesMap.has(id) || configIdsMap.has(id))) {
59
+ spaceIdsToQuery.add(id);
60
+ }
61
+ }
62
+ }
63
+
64
+ if (payerIds && payerIds.length > 0) {
65
+ for (const pid of payerIds) {
66
+ if (!payerIdsMap.has(pid)) {
67
+ payerIdsToQuery.add(pid);
68
+ }
69
+ }
70
+ }
71
+
72
+ const spaceIdVars = { ...variables, ids: [...spaceIdsToQuery.keys()] };
73
+
74
+ const payerIdVars = { ...variables, payerIds: [...payerIdsToQuery.keys()] };
75
+
76
+ const [
77
+ { data: spacesBySpaceIds, isFetching: isLoadingBySpaceIds, error: errorBySpaceIds },
78
+ { data: spacesByPayerIds, isFetching: isLoadingByPayerIds, error: errorByPayerIds },
79
+ ] = useQueries({
80
+ queries: [
81
+ {
82
+ queryKey: ['id', spaceIdVars],
83
+ queryFn: () => fetchAllSpaces({ query, clientId, variables: spaceIdVars }),
84
+ enabled: spaceIdsToQuery.size > 0,
85
+ },
86
+ {
87
+ queryKey: ['id', payerIdVars],
88
+ queryFn: () => fetchAllSpaces({ query, clientId, variables: payerIdVars }),
89
+ enabled: payerIdsToQuery.size > 0,
90
+ },
91
+ ],
92
+ });
93
+
94
+ useEffect(() => {
95
+ if (errorByPayerIds || errorBySpaceIds) {
96
+ dispatch({
97
+ type: 'ERROR',
98
+ error: errorByPayerIds?.message || errorBySpaceIds?.message,
99
+ loading: false,
100
+ });
101
+ }
102
+ }, [errorByPayerIds, errorBySpaceIds]);
103
+
104
+ useEffect(() => {
105
+ dispatch({
106
+ type: 'LOADING',
107
+ loading: true,
108
+ });
109
+ if (spaceIdsToQuery.size === 0 && payerIdsToQuery.size === 0) {
110
+ dispatch({
111
+ type: 'LOADING',
112
+ loading: false,
113
+ });
114
+ return;
115
+ }
116
+ if (spacesBySpaceIds) {
117
+ for (const space of spacesBySpaceIds) {
118
+ if (!spacesMap.has(space.id)) {
119
+ spacesMap.set(space.id, space);
120
+ }
121
+
122
+ if (!configIdsMap.has(space.configurationId)) {
123
+ configIdsMap.set(space.configurationId, space);
124
+ }
125
+
126
+ if (space.payerIDs) {
127
+ for (const pId of space.payerIDs) {
128
+ const currentSpacesForPayerId = payerIdsMap.get(pId);
129
+ if (currentSpacesForPayerId) {
130
+ payerIdsMap.set(pId, [...currentSpacesForPayerId, space]);
131
+ } else {
132
+ payerIdsMap.set(pId, [space]);
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ if (payerIdsToQuery.size > 0) {
139
+ if (spacesByPayerIds) {
140
+ for (const space of spacesByPayerIds) {
141
+ if (!spacesMap.has(space.id)) {
142
+ spacesMap.set(space.id, space);
143
+ }
144
+
145
+ if (!configIdsMap.has(space.configurationId)) {
146
+ configIdsMap.set(space.configurationId, space);
147
+ }
148
+
149
+ if (space.payerIDs) {
150
+ for (const pId of space.payerIDs) {
151
+ const currentSpacesForPayerId = payerIdsMap.get(pId);
152
+ if (currentSpacesForPayerId) {
153
+ payerIdsMap.set(pId, [...currentSpacesForPayerId, space]);
154
+ } else {
155
+ payerIdsMap.set(pId, [space]);
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+ }
162
+ dispatch({
163
+ type: 'SPACES',
164
+ spaces: spacesMap,
165
+ spacesByConfig: configIdsMap,
166
+ spacesByPayer: payerIdsMap,
167
+ loading: false,
168
+ });
169
+ }, [spacesBySpaceIds, spacesByPayerIds, payerIds, spaceIds]);
170
+
171
+ // const hasParentModalProvider = useModal() !== undefined;
172
+ return (
173
+ <SpacesContext.Provider
174
+ children={children}
175
+ value={{
176
+ spaces: spacesMap,
177
+ spacesByConfig: configIdsMap,
178
+ spacesByPayer: payerIdsMap,
179
+ loading: loading || isLoadingByPayerIds || isLoadingBySpaceIds,
180
+ error,
181
+ }}
182
+ />
183
+ );
184
+ };
185
+
186
+ export const useSpaces = (...ids: string[]) => {
187
+ const { spaces, spacesByConfig, spacesByPayer } = useSpacesContext();
188
+
189
+ const idsIsEmpty = !ids || ids.length === 0;
190
+ const callerIsExpectingFirstSpace = ids?.length === 1 && ids[0] === undefined;
191
+ const shouldReturnAllSpaces = idsIsEmpty || callerIsExpectingFirstSpace;
192
+
193
+ if (shouldReturnAllSpaces) {
194
+ console.warn(`You did not pass in an ID to find a space, returning all spaces.`);
195
+ return spaces && normalizeSpaces([...spaces.values()]);
196
+ }
197
+
198
+ const matchedSpaces = ids.map((id) => spaces?.get(id) || spacesByConfig?.get(id) || spacesByPayer?.get(id));
199
+ const normalized = normalizeSpaces(matchedSpaces);
200
+
201
+ return normalized;
202
+ };
@@ -0,0 +1,105 @@
1
+ export default `query configurationFindMany($ids: [String!], $payerIDs: [ID!], $types: [TypeEnum!]) {
2
+ configurationPagination(filter: { ids: $ids, payerIds: $payerIDs, types: $types }) {
3
+ pageInfo {
4
+ hasNextPage
5
+ currentPage
6
+ }
7
+ items {
8
+ ... on Configuration {
9
+ configurationId
10
+ name
11
+ shortName
12
+ type
13
+ activeDate
14
+ isNew
15
+ description
16
+ payerIDs
17
+ parentIDs
18
+ metadataPairs {
19
+ name
20
+ value
21
+ }
22
+ }
23
+
24
+ ... on Node {
25
+ id
26
+ }
27
+
28
+ ... on Alert {
29
+ link {
30
+ text
31
+ target
32
+ url
33
+ }
34
+ }
35
+
36
+ ... on Container {
37
+ link {
38
+ text
39
+ target
40
+ url
41
+ }
42
+ images {
43
+ tile
44
+ promotional
45
+ logo
46
+ billboard
47
+ }
48
+ }
49
+
50
+ ... on PayerSpace {
51
+ link {
52
+ text
53
+ target
54
+ url
55
+ }
56
+ images {
57
+ tile
58
+ logo
59
+ billboard
60
+ }
61
+ url
62
+ }
63
+
64
+ ... on Application {
65
+ link {
66
+ text
67
+ target
68
+ url
69
+ }
70
+ }
71
+
72
+ ... on Resource {
73
+ link {
74
+ text
75
+ target
76
+ url
77
+ }
78
+ }
79
+
80
+ ... on Navigation {
81
+ icons {
82
+ dashboard
83
+ navigation
84
+ }
85
+ images {
86
+ promotional
87
+ }
88
+ }
89
+
90
+ ... on Learning {
91
+ images {
92
+ promotional
93
+ }
94
+ }
95
+
96
+ ... on Proxy {
97
+ url
98
+ }
99
+
100
+ ... on File {
101
+ url
102
+ }
103
+ }
104
+ }
105
+ }`;
@@ -0,0 +1,26 @@
1
+ import { updateUrl, getUrl } from './helpers';
2
+
3
+ describe('updateUrl', () => {
4
+ it('should parse the given url return the existing and new params in alphabetical order', () => {
5
+ let updatedUrl = updateUrl('http://www.example.com?foo=bar#hashme', 'fakeKey', 'fakeValue');
6
+ expect(updatedUrl).toBe('http://www.example.com?fakeKey=fakeValue&foo=bar%23hashme');
7
+
8
+ updatedUrl = updateUrl('http://www.example.com', 'fakeKey', 'fakeValue');
9
+ expect(updatedUrl).toBe('http://www.example.com?fakeKey=fakeValue');
10
+
11
+ updatedUrl = updateUrl('http://www.example.com?foo=bar', 'fakeKey', 'fakeValue');
12
+ expect(updatedUrl).toBe('http://www.example.com?fakeKey=fakeValue&foo=bar');
13
+ });
14
+ });
15
+
16
+ describe('getUrl', () => {
17
+ it('should return an absolute url', () => {
18
+ const url = getUrl('http://www.availity.com', false, true);
19
+ expect(url).toBe('http://www.availity.com');
20
+ });
21
+
22
+ it('should return a relative url', () => {
23
+ const url = getUrl('/path/to/my/app', true, false);
24
+ expect(url).toBe('/public/apps/home/#!/loadApp?appUrl=%2Fpath%2Fto%2Fmy%2Fapp');
25
+ });
26
+ });
@@ -0,0 +1,15 @@
1
+ import qs from 'qs';
2
+
3
+ export const updateUrl = (url: string, key: string, value: string) => {
4
+ const [uri, queryString] = url.split('?');
5
+ const currentParams = qs.parse(queryString);
6
+ const newParams = qs.stringify({ ...currentParams, [key]: value }, { sort: (a, b) => a.localeCompare(b) });
7
+
8
+ return `${uri}?${newParams}`;
9
+ };
10
+
11
+ export const getUrl = (url = '', loadApp: boolean, absolute: boolean) => {
12
+ if (absolute || !loadApp) return url;
13
+
14
+ return `/public/apps/home/#!/loadApp?appUrl=${encodeURIComponent(url)}`;
15
+ };
@@ -0,0 +1,57 @@
1
+ import { normalizeSpaces, fetchAllSpaces } from './spaces-data';
2
+ import configurationFindMany from './configurationFindMany';
3
+ // eslint-disable-next-line @nx/enforce-module-boundaries
4
+ import { server } from '../../../mock/src/lib/server';
5
+
6
+ beforeAll(() => {
7
+ // Start the interception.
8
+ server.listen();
9
+ });
10
+
11
+ afterEach(() => {
12
+ // Remove any handlers you may have added
13
+ // in individual tests (runtime handlers).
14
+ server.resetHandlers();
15
+ });
16
+
17
+ afterAll(() => {
18
+ // Disable request interception and clean up.
19
+ server.close();
20
+ });
21
+
22
+ describe('getAllSpaces', () => {
23
+ it('gets all spaces', async () => {
24
+ const spaces = await fetchAllSpaces({
25
+ query: configurationFindMany,
26
+ clientId: 'clientId',
27
+ variables: {
28
+ types: ['space'],
29
+ },
30
+ });
31
+ // Check correct spaces get returned
32
+ expect(spaces.length).toBe(10);
33
+ expect(spaces[0].id).toBe('1');
34
+ expect(spaces[spaces.length - 1].id).toBe('10');
35
+ });
36
+ });
37
+
38
+ describe('normalizeSpaces', () => {
39
+ it('normalizes space pairs', async () => {
40
+ const spaces = [
41
+ {
42
+ id: '1',
43
+ configurationId: '1',
44
+ type: 'space',
45
+ name: 'Space 1',
46
+ metadata: [
47
+ { name: 'a', value: '1' },
48
+ { name: 'b', value: '2' },
49
+ ],
50
+ },
51
+ ];
52
+
53
+ const sanitized = normalizeSpaces(spaces);
54
+
55
+ expect(sanitized[0].metadata).toEqual({ a: '1', b: '2' });
56
+ });
57
+ });