Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLNP-4657] Provider migration - P0 items #1269

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
67105ee
[CLNP-5043] Migrate MessageSearchProvider (#1216)
AhyoungRyu Sep 27, 2024
77f5395
refactor: ChannelSettingsProvider migration (#1229)
HoonBaek Oct 11, 2024
4689d79
[CLNP-5043] Add unit tests for improved MessageSearch module (#1228)
AhyoungRyu Oct 14, 2024
1e980b8
refactor: GroupChannelList migration (#1231)
git-babel Oct 17, 2024
3bd9b40
refactor: Add tests for ChannelSettings migration (#1234)
HoonBaek Oct 22, 2024
0cc69d5
refactor: Add unit tests for new GroupChannelListProvider (#1233)
git-babel Oct 23, 2024
2720797
[CLNP-5047] Migrate GroupChannelProvider to new state management patt…
AhyoungRyu Nov 19, 2024
6a88cc9
[CLNP-5045] CreateChannelProvider Migration (#1243)
git-babel Nov 28, 2024
9931db0
[CLNP-5046] Migrate ThreadProvider to the new state management patter…
git-babel Nov 28, 2024
1abf238
refactor: SendbirdProvider Migration (#1260)
HoonBaek Nov 29, 2024
3a5c833
[CLNP-5907] fix: update group channel list state properly (#1261)
AhyoungRyu Nov 29, 2024
bfd8141
[CLNP-5817][CLNP-5918] fix: scroll & search message issues in GroupCh…
AhyoungRyu Dec 2, 2024
a689dd3
[CLNP-5914] Fix unit tests and UI error (#1267)
git-babel Dec 2, 2024
99a765f
Used useDeepCompareEffect for the updateState of SendbirdProvider (#1…
HoonBaek Dec 2, 2024
9d6558f
Resolve conflict after rebase from main
AhyoungRyu Dec 3, 2024
c92fd25
[CLNP-5974] Add more GroupChannel module custom hook unit tests (#1271)
AhyoungRyu Dec 5, 2024
6e4a14a
Use useEffect instead of useDeepCompareEffect in GroupChannelListProv…
AhyoungRyu Dec 6, 2024
37f0f25
[CLNP-5981] fix blinking GroupChannel on switching to another (#1277)
AhyoungRyu Dec 6, 2024
db30b62
chore: Add tests for SendbirdProvider migration (#1275)
HoonBaek Dec 6, 2024
6f0e194
Add basic test cases for the new `ThreadProvider` (#1274)
git-babel Dec 9, 2024
dc48275
[CLNP-6010] Add more unit tests for existing message search custom ho…
AhyoungRyu Dec 9, 2024
4101889
[CLNP-6022] fix scroll position issue when switching GroupChannel (#1…
AhyoungRyu Dec 10, 2024
21a625d
Resolve conflicts
AhyoungRyu Dec 11, 2024
5890933
used useSendbird for mocking instead of useSendbirdStateContext
HoonBaek Dec 11, 2024
9c9f520
Fix migration test failure (#1285)
git-babel Dec 12, 2024
38ff25b
[CLNP-6003] test: Add tests for hooks in `src/hooks` (#1283)
git-babel Dec 13, 2024
9c2f8b3
Merge branch 'main' into feat/state-mgmt-migration-1
git-babel Dec 13, 2024
7d4b638
Fix merge error
git-babel Dec 13, 2024
8ca7861
Fix lint error
git-babel Dec 13, 2024
2c0387f
[CLNP-6022] Memoize useGroupChannel actions to prevent unnecessary re…
AhyoungRyu Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 3 additions & 3 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type { Preview } from '@storybook/react';
import { SendbirdSdkContext } from '../src/lib/SendbirdSdkContext';
import { SendbirdContext } from '../src/lib/Sendbird/context/SendbirdContext';

import '../src/lib/index.scss';
import './index.css';
Expand Down Expand Up @@ -28,9 +28,9 @@ const preview: Preview = {
decorators: [
(Story) => (
<div className="sendbird-theme--light">
<SendbirdSdkContext.Provider value={{} as any}>
<SendbirdContext.Provider value={{} as any}>
{Story()}
</SendbirdSdkContext.Provider>
</SendbirdContext.Provider>
</div>
),
],
Expand Down
2 changes: 1 addition & 1 deletion apps/testing/src/utils/paramsBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UIKitOptions } from '../../../../src/lib/types.ts';
import { UIKitOptions } from '../../../../src/lib/Sendbird/types';
import { useSearchParams } from 'react-router-dom';

export interface InitialParams {
Expand Down
5 changes: 5 additions & 0 deletions apps/testing/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import postcssRtlOptions from '../../postcssRtlOptions.mjs';
export default defineConfig({
plugins: [react(), vitePluginSvgr({ include: '**/*.svg' })],
css: {
preprocessorOptions: {
scss: {
silenceDeprecations: ['legacy-js-api'],
},
},
postcss: {
plugins: [postcssRtl(postcssRtlOptions)],
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
"ts-pattern": "^4.2.2",
"typedoc": "^0.25.13",
"typescript": "^5.4.5",
"use-sync-external-store": "^1.2.2",
"vite": "^5.1.5",
"vite-plugin-svgr": "^4.2.0"
},
Expand Down
9 changes: 5 additions & 4 deletions rollup.module-exports.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ export default {
App: 'src/modules/App/index.tsx',

// SendbirdProvider
SendbirdProvider: 'src/lib/Sendbird.tsx',
SendbirdProvider: 'src/lib/Sendbird/index.tsx',
sendbirdSelectors: 'src/lib/selectors.ts',
useSendbirdStateContext: 'src/hooks/useSendbirdStateContext.tsx',
withSendbird: 'src/lib/SendbirdSdkContext.tsx',
// TODO: Support below legacy exports
// useSendbirdStateContext: 'src/hooks/useSendbirdStateContext.tsx',
// withSendbird: 'src/lib/SendbirdSdkContext.tsx',

// Voice message
'VoiceRecorder/context': 'src/hooks/VoiceRecorder/index.tsx',
Expand Down Expand Up @@ -57,7 +58,7 @@ export default {

// ChannelSettings
ChannelSettings: 'src/modules/ChannelSettings/index.tsx',
'ChannelSettings/context': 'src/modules/ChannelSettings/context/ChannelSettingsProvider.tsx',
'ChannelSettings/context': 'src/modules/ChannelSettings/context/index.tsx',
'ChannelSettings/hooks/useMenuList': 'src/modules/ChannelSettings/components/ChannelSettingsUI/hooks/useMenuItems.tsx',
'ChannelSettings/components/ChannelProfile': 'src/modules/ChannelSettings/components/ChannelProfile/index.tsx',
'ChannelSettings/components/ChannelSettingsUI': 'src/modules/ChannelSettings/components/ChannelSettingsUI/index.tsx',
Expand Down
5 changes: 3 additions & 2 deletions src/hooks/VoicePlayer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import {
VOICE_PLAYER_AUDIO_ID,
VOICE_PLAYER_ROOT_ID,
} from '../../utils/consts';
import useSendbirdStateContext from '../useSendbirdStateContext';
import { getParsedVoiceAudioFileInfo } from './utils';
import useSendbird from '../../lib/Sendbird/context/hooks/useSendbird';

// VoicePlayerProvider interface
export interface VoicePlayerProps {
Expand Down Expand Up @@ -64,7 +64,8 @@ export const VoicePlayerProvider = ({
currentPlayer,
audioStorage,
} = voicePlayerStore;
const { config } = useSendbirdStateContext();
const { state } = useSendbird();
const { config } = state;
const { logger } = config;

const stop = (text = '') => {
Expand Down
5 changes: 3 additions & 2 deletions src/hooks/VoiceRecorder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
VOICE_MESSAGE_MIME_TYPE,
VOICE_RECORDER_AUDIO_BIT_RATE,
} from '../../utils/consts';
import useSendbirdStateContext from '../useSendbirdStateContext';
import { type WebAudioUtils } from './WebAudioUtils';
import { noop } from '../../utils/utils';
import useSendbird from '../../lib/Sendbird/context/hooks/useSendbird';

// Input props of VoiceRecorder
export interface VoiceRecorderProps {
Expand All @@ -37,7 +37,8 @@ const Context = createContext<VoiceRecorderContext>({

export const VoiceRecorderProvider = (props: VoiceRecorderProps): React.ReactElement => {
const { children } = props;
const { config } = useSendbirdStateContext();
const { state } = useSendbird();
const { config } = state;
const { logger, groupChannel } = config;
const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
const [isRecordable, setIsRecordable] = useState<boolean>(false);
Expand Down
5 changes: 3 additions & 2 deletions src/hooks/VoiceRecorder/useVoiceRecorder.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { VoiceRecorderEventHandler, useVoiceRecorderContext } from '.';
import useSendbirdStateContext from '../useSendbirdStateContext';
import { noop } from '../../utils/utils';
import useSendbird from '../../lib/Sendbird/context/hooks/useSendbird';

// export interface UseVoiceRecorderProps extends VoiceRecorderEventHandler {
// /**
Expand Down Expand Up @@ -31,7 +31,8 @@ export const useVoiceRecorder = ({
onRecordingStarted = noop,
onRecordingEnded = noop,
}: VoiceRecorderEventHandler): UseVoiceRecorderContext => {
const { config } = useSendbirdStateContext();
const { state } = useSendbird();
const { config } = state;
const { voiceRecord } = config;
const maxRecordingTime = voiceRecord.maxRecordingTime;
const voiceRecorder = useVoiceRecorderContext();
Expand Down
44 changes: 44 additions & 0 deletions src/hooks/__tests__/useAsyncRequest.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { renderHook } from '@testing-library/react-hooks';
import { useAsyncRequest } from '../useAsyncRequest';

describe('useAsyncRequest', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('handle request with no response correctly', async () => {
const mockPromise = Promise.resolve();
const mockRequest = jest.fn().mockReturnValue(mockPromise);

const { result } = renderHook(() => useAsyncRequest(mockRequest));

await mockPromise;

expect(result.current.loading).toBe(false);
});

it('handle request with response correctly', async () => {
const mockResponse = { code: 'ok' };
const mockPromise = Promise.resolve(mockResponse);
const mockRequest = jest.fn().mockReturnValue(mockPromise);

const { result } = renderHook(() => useAsyncRequest(mockRequest));

await mockPromise;

expect(result.current.response).toBe(mockResponse);
expect(result.current.loading).toBe(false);
});

it('cancel request correctly', async () => {
const mockCancel = jest.fn();
const mockRequest = { cancel: mockCancel };

const { unmount } = renderHook(() => useAsyncRequest(mockRequest));

unmount();

expect(mockCancel).toBeCalled();
});

});
28 changes: 28 additions & 0 deletions src/hooks/__tests__/useDebounce.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { renderHook } from '@testing-library/react-hooks';
import { useDebounce } from '../useDebounce';

describe('useAsyncRequest', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('handle useDebounce correctly', async () => {
const mockFunction = jest.fn();
const { result } = renderHook(() => useDebounce(mockFunction, 1000));

const debounceFunction = result.current;

debounceFunction();
debounceFunction();
debounceFunction();
debounceFunction();
debounceFunction();

await new Promise(resolve => {
setTimeout(resolve, 1000);
});

expect(mockFunction).toBeCalledTimes(1);
});

});
63 changes: 63 additions & 0 deletions src/hooks/__tests__/useLongPress.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
import useLongPress from '../useLongPress';
import { screen, fireEvent, render, waitFor } from '@testing-library/react';

describe('useLongPress', () => {

beforeEach(() => {
jest.clearAllMocks();
});

it('handle long press correctly', async () => {
const mockOnLongPress = jest.fn();
const mockOnClick = jest.fn();

const { result } = renderHook(() => useLongPress({
onLongPress: mockOnLongPress,
onClick: mockOnClick,
}));
const { onTouchStart, onTouchEnd } = result.current;

const targetComponent = <div id="target" onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>touch this</div>;
render(targetComponent);

const element = screen.getByText('touch this');
fireEvent.touchStart(element);
await new Promise(resolve => {
setTimeout(resolve, 1000);
});
fireEvent.touchEnd(element);

await waitFor(() => {
expect(mockOnLongPress).toHaveBeenCalled();
});
});

it('cancel long press if touch is too short', async () => {
const mockOnLongPress = jest.fn();
const mockOnClick = jest.fn();

const { result } = renderHook(() => useLongPress({
onLongPress: mockOnLongPress,
onClick: mockOnClick,
}));
const { onTouchStart, onTouchEnd } = result.current;

const targetComponent = <div id="target" onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>touch this</div>;
render(targetComponent);

const element = screen.getByText('touch this');
fireEvent.touchStart(element);
await new Promise(resolve => {
setTimeout(resolve, 100);
});
fireEvent.touchEnd(element);

await waitFor(() => {
expect(mockOnClick).toHaveBeenCalled();
expect(mockOnLongPress).not.toHaveBeenCalled();
});
});

});
38 changes: 38 additions & 0 deletions src/hooks/__tests__/useMouseHover.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
import { screen, fireEvent, render, waitFor } from '@testing-library/react';
import useMouseHover from '../useMouseHover';

describe('useMouseHover', () => {

beforeEach(() => {
jest.clearAllMocks();
});

it('handle mouse over and out correctly', async () => {
const mockSetHover = jest.fn();

const targetComponent = <div id="target">hover</div>;
render(targetComponent);

const hoverElement = screen.getByText('hover');
const ref = {
current: hoverElement,
};

renderHook(() => useMouseHover({
ref,
setHover: mockSetHover,
}));

fireEvent.mouseEnter(hoverElement);
fireEvent.mouseLeave(hoverElement);

await waitFor(() => {
expect(mockSetHover).toHaveBeenCalledTimes(2);
expect(mockSetHover).toHaveBeenCalledWith(true);
expect(mockSetHover).toHaveBeenCalledWith(false);
});
});

});
35 changes: 35 additions & 0 deletions src/hooks/__tests__/useOutsideAlerter.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
import { screen, fireEvent, render, waitFor } from '@testing-library/react';
import useOutsideAlerter from '../useOutsideAlerter';

describe('useOutsideAlerter', () => {

beforeEach(() => {
jest.clearAllMocks();
});

it('handle click outside correctly', async () => {
const mockClickOutside = jest.fn();

const targetComponent = <div id="target">inside</div>;
render(targetComponent);

const insideElement = screen.getByText('inside');
const ref = {
current: insideElement,
};

renderHook(() => useOutsideAlerter({
ref,
callback: mockClickOutside,
}));

fireEvent.mouseDown(insideElement);

await waitFor(() => {
expect(mockClickOutside).toHaveBeenCalledTimes(1);
});
});

});
Loading