Skip to content

Commit 6a88cc9

Browse files
git-babelAhyoungRyu
authored andcommitted
[CLNP-5045] CreateChannelProvider Migration (#1243)
Addresses https://sendbird.atlassian.net/browse/CLNP-5045
1 parent 2720797 commit 6a88cc9

File tree

11 files changed

+476
-76
lines changed

11 files changed

+476
-76
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React from 'react';
2+
import * as useCreateChannelModule from '../../../context/useCreateChannel';
3+
import { CHANNEL_TYPE } from '../../../types';
4+
import { act, render, screen } from '@testing-library/react';
5+
import '@testing-library/jest-dom/extend-expect';
6+
import { LocalizationContext } from '../../../../../lib/LocalizationContext';
7+
import CreateChannelUI from '../index';
8+
9+
jest.mock('../../../../../hooks/useSendbirdStateContext', () => ({
10+
__esModule: true,
11+
default: jest.fn(() => ({
12+
stores: {
13+
userStore: {
14+
user: {
15+
userId: ' test-user-id',
16+
},
17+
},
18+
sdkStore: {
19+
sdk: {
20+
currentUser: {
21+
userId: 'test-user-id',
22+
},
23+
createApplicationUserListQuery: () => ({
24+
next: () => Promise.resolve([{ userId: 'test-user-id' }]),
25+
isLoading: false,
26+
}),
27+
},
28+
initialized: true,
29+
},
30+
},
31+
config: {
32+
logger: console,
33+
userId: 'test-user-id',
34+
groupChannel: {
35+
enableMention: true,
36+
},
37+
isOnline: true,
38+
},
39+
})),
40+
}));
41+
jest.mock('../../../context/useCreateChannel');
42+
43+
const mockStringSet = {
44+
MODAL__CREATE_CHANNEL__TITLE: 'CREATE_CHANNEL',
45+
MODAL__INVITE_MEMBER__SELECTED: 'USERS_SELECTED',
46+
};
47+
48+
const mockLocalizationContext = {
49+
stringSet: mockStringSet,
50+
};
51+
52+
const defaultMockState = {
53+
sdk: undefined,
54+
userListQuery: undefined,
55+
onCreateChannelClick: undefined,
56+
onChannelCreated: undefined,
57+
onBeforeCreateChannel: undefined,
58+
pageStep: 0,
59+
type: CHANNEL_TYPE.GROUP,
60+
onCreateChannel: undefined,
61+
overrideInviteUser: undefined,
62+
};
63+
64+
const defaultMockActions = {
65+
setPageStep: jest.fn(),
66+
setType: jest.fn(),
67+
};
68+
69+
describe('CreateChannelUI Integration Tests', () => {
70+
const mockUseCreateChannel = useCreateChannelModule.default as jest.Mock;
71+
72+
const renderComponent = (mockState = {}, mockActions = {}) => {
73+
mockUseCreateChannel.mockReturnValue({
74+
state: { ...defaultMockState, ...mockState },
75+
actions: { ...defaultMockActions, ...mockActions },
76+
});
77+
78+
return render(
79+
<LocalizationContext.Provider value={mockLocalizationContext as any}>
80+
<CreateChannelUI />
81+
</LocalizationContext.Provider>,
82+
);
83+
};
84+
85+
beforeEach(() => {
86+
jest.clearAllMocks();
87+
document.body.innerHTML = `
88+
<div id='sendbird-modal-root' />
89+
`;
90+
});
91+
92+
it('display initial state correctly', () => {
93+
renderComponent();
94+
95+
expect(screen.getByText('CREATE_CHANNEL')).toBeInTheDocument();
96+
});
97+
98+
it('display SelectChannelType when pageStep is 0', () => {
99+
renderComponent({ pageStep: 0 });
100+
101+
expect(screen.getByText('CREATE_CHANNEL')).toBeInTheDocument();
102+
});
103+
104+
it('display InviteUsers when pageStep is 1', async () => {
105+
await act(async () => {
106+
renderComponent({ pageStep: 1 });
107+
});
108+
109+
expect(screen.getByText('0 USERS_SELECTED')).toBeInTheDocument();
110+
});
111+
112+
});

src/modules/CreateChannel/components/CreateChannelUI/index.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import './create-channel-ui.scss';
22

33
import React from 'react';
44

5-
import { useCreateChannelContext } from '../../context/CreateChannelProvider';
65
import InviteUsers from '../InviteUsers';
76

87
import SelectChannelType from '../SelectChannelType';
8+
import useCreateChannel from '../../context/useCreateChannel';
99

1010
export interface CreateChannelUIProps {
1111
onCancel?(): void;
@@ -16,15 +16,19 @@ const CreateChannel: React.FC<CreateChannelUIProps> = (props: CreateChannelUIPro
1616
const { onCancel, renderStepOne } = props;
1717

1818
const {
19-
step,
20-
setStep,
21-
userListQuery,
22-
} = useCreateChannelContext();
19+
state: {
20+
pageStep,
21+
userListQuery,
22+
},
23+
actions: {
24+
setPageStep,
25+
},
26+
} = useCreateChannel();
2327

2428
return (
2529
<>
2630
{
27-
step === 0 && (
31+
pageStep === 0 && (
2832
renderStepOne?.() || (
2933
<SelectChannelType
3034
onCancel={onCancel}
@@ -33,11 +37,11 @@ const CreateChannel: React.FC<CreateChannelUIProps> = (props: CreateChannelUIPro
3337
)
3438
}
3539
{
36-
step === 1 && (
40+
pageStep === 1 && (
3741
<InviteUsers
3842
userListQuery={userListQuery}
3943
onCancel={() => {
40-
setStep(0);
44+
setPageStep(0);
4145
onCancel?.();
4246
}}
4347
/>

src/modules/CreateChannel/components/InviteUsers/__tests__/index.spec.tsx

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,90 @@
11
import React from 'react';
22
import { render, screen } from '@testing-library/react';
33
import '@testing-library/jest-dom/extend-expect';
4-
import '@testing-library/jest-dom/matchers';
54
import InviteUsers from '../index';
65
import { ApplicationUserListQuery } from '@sendbird/chat';
7-
import { SendbirdSdkContext } from '../../../../../lib/SendbirdSdkContext';
8-
import { SendBirdState } from '../../../../../lib/types';
9-
10-
jest.mock('../../../context/CreateChannelProvider', () => ({
11-
useCreateChannelContext: jest.fn(() => ({
12-
onBeforeCreateChannel: jest.fn(),
13-
onCreateChannel: jest.fn(),
14-
overrideInviteUser: jest.fn(),
15-
createChannel: jest.fn().mockResolvedValue({}),
16-
type: 'group',
6+
import { CHANNEL_TYPE } from '../../../types';
7+
import * as useCreateChannelModule from '../../../context/useCreateChannel';
8+
import { LocalizationContext } from '../../../../../lib/LocalizationContext';
9+
10+
jest.mock('../../../../../hooks/useSendbirdStateContext', () => ({
11+
__esModule: true,
12+
default: jest.fn(() => ({
13+
stores: {
14+
sdkStore: {
15+
sdk: {
16+
currentUser: {
17+
userId: 'test-user-id',
18+
},
19+
},
20+
initialized: true,
21+
},
22+
},
23+
config: { logger: console },
1724
})),
1825
}));
26+
jest.mock('../../../context/useCreateChannel');
1927

2028
// Mock createPortal function to render content directly without portal
2129
jest.mock('react-dom', () => ({
2230
...jest.requireActual('react-dom'),
2331
createPortal: (node) => node,
2432
}));
2533

34+
const mockStringSet = {
35+
MODAL__CREATE_CHANNEL__TITLE: 'CREATE_CHANNEL',
36+
MODAL__INVITE_MEMBER__SELECTED: 'USERS_SELECTED',
37+
BUTTON__CREATE: 'CREATE',
38+
};
39+
40+
const mockLocalizationContext = {
41+
stringSet: mockStringSet,
42+
};
43+
44+
const defaultMockState = {
45+
sdk: undefined,
46+
createChannel: undefined,
47+
userListQuery: undefined,
48+
onCreateChannelClick: undefined,
49+
onChannelCreated: undefined,
50+
onBeforeCreateChannel: undefined,
51+
step: 0,
52+
type: CHANNEL_TYPE.GROUP,
53+
onCreateChannel: undefined,
54+
overrideInviteUser: undefined,
55+
};
56+
57+
const defaultMockActions = {
58+
setStep: jest.fn(),
59+
setType: jest.fn(),
60+
};
61+
62+
const defaultMockInvitUserState = {
63+
user: { userId: 'test-user-id' },
64+
};
65+
2666
describe('InviteUsers', () => {
67+
const mockUseCreateChannel = useCreateChannelModule.default as jest.Mock;
68+
69+
const renderComponent = (mockState = {}, mockActions = {}, mockInviteUsersState = {}) => {
70+
mockUseCreateChannel.mockReturnValue({
71+
state: { ...defaultMockState, ...mockState },
72+
actions: { ...defaultMockActions, ...mockActions },
73+
});
74+
75+
const inviteUserProps = { ...defaultMockInvitUserState, ...mockInviteUsersState };
76+
77+
return render(
78+
<LocalizationContext.Provider value={mockLocalizationContext as any}>
79+
<InviteUsers {...inviteUserProps}/>
80+
</LocalizationContext.Provider>,
81+
);
82+
};
83+
84+
beforeEach(() => {
85+
jest.clearAllMocks();
86+
});
87+
2788
it('should enable the modal submit button when there is only the logged-in user is in the user list', async () => {
2889
const userListQuery = jest.fn(
2990
() => ({
@@ -32,13 +93,9 @@ describe('InviteUsers', () => {
3293
} as unknown as ApplicationUserListQuery),
3394
);
3495

35-
render(
36-
<SendbirdSdkContext.Provider value={{} as SendBirdState}>
37-
<InviteUsers userListQuery={userListQuery} />
38-
</SendbirdSdkContext.Provider>,
39-
);
96+
renderComponent({}, {}, { userListQuery });
4097

41-
expect(await screen.findByText('Create')).toBeEnabled();
98+
expect(await screen.findByText('CREATE')).toBeEnabled();
4299
});
43100

44101
// TODO: add this case too

src/modules/CreateChannel/components/InviteUsers/index.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type { GroupChannelCreateParams } from '@sendbird/chat/groupChannel';
44

55
import './invite-users.scss';
66
import { LocalizationContext } from '../../../../lib/LocalizationContext';
7-
import { useCreateChannelContext } from '../../context/CreateChannelProvider';
87
import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext';
98
import { useMediaQueryContext } from '../../../../lib/MediaQueryContext';
109
import Modal from '../../../../ui/Modal';
@@ -15,6 +14,7 @@ import UserListItem from '../../../../ui/UserListItem';
1514
import { createDefaultUserListQuery, filterUser, setChannelType } from './utils';
1615
import { noop } from '../../../../utils/utils';
1716
import { UserListQuery } from '../../../../types';
17+
import useCreateChannel from '../../context/useCreateChannel';
1818

1919
export interface InviteUsersProps {
2020
onCancel?: () => void;
@@ -28,14 +28,18 @@ const InviteUsers: React.FC<InviteUsersProps> = ({
2828
userListQuery,
2929
}: InviteUsersProps) => {
3030
const {
31-
onCreateChannelClick,
32-
onBeforeCreateChannel,
33-
onChannelCreated,
34-
createChannel,
35-
onCreateChannel,
36-
overrideInviteUser,
37-
type,
38-
} = useCreateChannelContext();
31+
state: {
32+
onCreateChannelClick,
33+
onBeforeCreateChannel,
34+
onChannelCreated,
35+
onCreateChannel,
36+
overrideInviteUser,
37+
type,
38+
},
39+
actions: {
40+
createChannel,
41+
},
42+
} = useCreateChannel();
3943

4044
const globalStore = useSendbirdStateContext();
4145
const userId = globalStore?.config?.userId;

0 commit comments

Comments
 (0)