MM-59740 + others - Add tests for various files in hooks/ (#8448)
* Add tests for hooks/android_back_handler * Add tests for hooks/gallery * Add tests for hooks/files * Add tests for hooks/emoji_category_bar * Add tests for hooks/markdown * Increase more coverage for hooks/gallery.ts --------- Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
This commit is contained in:
parent
2e027d2d98
commit
e8ed761d30
6 changed files with 726 additions and 2 deletions
60
app/hooks/android_back_handler.test.ts
Normal file
60
app/hooks/android_back_handler.test.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {renderHook} from '@testing-library/react-hooks';
|
||||
import {BackHandler} from 'react-native';
|
||||
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
|
||||
import useAndroidHardwareBackHandler from './android_back_handler';
|
||||
|
||||
jest.mock('react-native', () => ({
|
||||
BackHandler: {
|
||||
addEventListener: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('@store/navigation_store', () => ({
|
||||
getVisibleScreen: jest.fn(),
|
||||
}));
|
||||
|
||||
test('useAndroidHardwareBackHandler - calls callback when visible screen matches componentId', () => {
|
||||
const componentId = 'About';
|
||||
const callback = jest.fn();
|
||||
|
||||
(NavigationStore.getVisibleScreen as jest.Mock).mockReturnValue(componentId);
|
||||
|
||||
renderHook(() => useAndroidHardwareBackHandler(componentId, callback));
|
||||
|
||||
const hardwareBackPressHandler = (BackHandler.addEventListener as jest.Mock).mock.calls[0][1];
|
||||
hardwareBackPressHandler();
|
||||
|
||||
expect(callback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('useAndroidHardwareBackHandler - does not call callback when visible screen does not match componentId', () => {
|
||||
const componentId = 'About';
|
||||
const callback = jest.fn();
|
||||
|
||||
(NavigationStore.getVisibleScreen as jest.Mock).mockReturnValue('otherScreen');
|
||||
|
||||
renderHook(() => useAndroidHardwareBackHandler(componentId, callback));
|
||||
|
||||
const hardwareBackPressHandler = (BackHandler.addEventListener as jest.Mock).mock.calls[0][1];
|
||||
hardwareBackPressHandler();
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('useAndroidHardwareBackHandler - removes event listener on unmount', () => {
|
||||
const componentId = 'About';
|
||||
const callback = jest.fn();
|
||||
const remove = jest.fn();
|
||||
(BackHandler.addEventListener as jest.Mock).mockReturnValue({remove});
|
||||
|
||||
const {unmount} = renderHook(() => useAndroidHardwareBackHandler(componentId, callback));
|
||||
|
||||
unmount();
|
||||
|
||||
expect(remove).toHaveBeenCalled();
|
||||
});
|
||||
128
app/hooks/emoji_category_bar.test.ts
Normal file
128
app/hooks/emoji_category_bar.test.ts
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {renderHook, act} from '@testing-library/react-hooks';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
|
||||
import {
|
||||
selectEmojiCategoryBarSection,
|
||||
setEmojiCategoryBarSection,
|
||||
setEmojiCategoryBarIcons,
|
||||
setEmojiSkinTone,
|
||||
useEmojiCategoryBar,
|
||||
useEmojiSkinTone,
|
||||
} from './emoji_category_bar';
|
||||
|
||||
describe('EmojiCategoryBar', () => {
|
||||
const mockSubject = {
|
||||
next: jest.fn(),
|
||||
value: {
|
||||
icons: undefined,
|
||||
currentIndex: 0,
|
||||
selectedIndex: undefined,
|
||||
skinTone: 'default',
|
||||
},
|
||||
subscribe: jest.fn().mockImplementation((callback) => {
|
||||
callback(mockSubject.value);
|
||||
return {unsubscribe: jest.fn()};
|
||||
}),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(BehaviorSubject.prototype, 'next').mockImplementation(mockSubject.next);
|
||||
jest.spyOn(BehaviorSubject.prototype, 'subscribe').mockImplementation(mockSubject.subscribe);
|
||||
jest.spyOn(BehaviorSubject.prototype, 'value', 'get').mockReturnValue(mockSubject.value);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('setEmojiSkinTone', () => {
|
||||
it('should update the skin tone in the state', () => {
|
||||
setEmojiSkinTone('light');
|
||||
|
||||
expect(mockSubject.next).toHaveBeenCalledWith({
|
||||
...mockSubject.value,
|
||||
skinTone: 'light',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useEmojiSkinTone', () => {
|
||||
it('should return the current skin tone', () => {
|
||||
const {result} = renderHook(() => useEmojiSkinTone());
|
||||
|
||||
expect(result.current).toBe('default');
|
||||
});
|
||||
|
||||
it('should update the skin tone when it changes', () => {
|
||||
const {result} = renderHook(() => useEmojiSkinTone());
|
||||
|
||||
act(() => {
|
||||
mockSubject.subscribe.mock.calls[0][0]({skinTone: 'dark'});
|
||||
});
|
||||
|
||||
expect(result.current).toBe('dark');
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectEmojiCategoryBarSection', () => {
|
||||
it('should update the selected index in the state', () => {
|
||||
selectEmojiCategoryBarSection(1);
|
||||
|
||||
expect(mockSubject.next).toHaveBeenCalledWith({
|
||||
...mockSubject.value,
|
||||
selectedIndex: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setEmojiCategoryBarSection', () => {
|
||||
it('should update the current index in the state', () => {
|
||||
setEmojiCategoryBarSection(1);
|
||||
|
||||
expect(mockSubject.next).toHaveBeenCalledWith({
|
||||
...mockSubject.value,
|
||||
currentIndex: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setEmojiCategoryBarIcons', () => {
|
||||
it('should update the icons in the state', () => {
|
||||
const icons = [{key: 'smile', name: 'smile', icon: 'smile'}];
|
||||
setEmojiCategoryBarIcons(icons);
|
||||
|
||||
expect(mockSubject.next).toHaveBeenCalledWith({
|
||||
...mockSubject.value,
|
||||
icons,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useEmojiCategoryBar', () => {
|
||||
it('should return the current state', () => {
|
||||
const {result} = renderHook(() => useEmojiCategoryBar());
|
||||
|
||||
expect(result.current).toEqual(mockSubject.value);
|
||||
});
|
||||
|
||||
it('should update the state when it changes', () => {
|
||||
const {result} = renderHook(() => useEmojiCategoryBar());
|
||||
|
||||
const newState = {
|
||||
icons: [{name: 'smile', icon: 'smile'}],
|
||||
currentIndex: 1,
|
||||
selectedIndex: 2,
|
||||
skinTone: 'dark',
|
||||
};
|
||||
|
||||
act(() => {
|
||||
mockSubject.subscribe.mock.calls[0][0](newState);
|
||||
});
|
||||
|
||||
expect(result.current).toEqual(newState);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -3,12 +3,16 @@
|
|||
|
||||
import {renderHook} from '@testing-library/react-hooks';
|
||||
|
||||
import {getLocalFileInfo} from '@actions/local/file';
|
||||
import {buildFilePreviewUrl, buildFileUrl} from '@actions/remote/file';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {mockFileInfo} from '@test/api_mocks/file';
|
||||
import {isGif, isImage, isVideo} from '@utils/file';
|
||||
import {getImageSize} from '@utils/gallery';
|
||||
|
||||
import {useImageAttachments} from './files';
|
||||
import {useChannelBookmarkFiles, useImageAttachments} from './files';
|
||||
|
||||
import type ChannelBookmarkModel from '@typings/database/models/servers/channel_bookmark';
|
||||
|
||||
jest.mock('@actions/remote/file', () => ({
|
||||
buildFilePreviewUrl: jest.fn(),
|
||||
|
|
@ -25,6 +29,9 @@ jest.mock('@context/server', () => ({
|
|||
useServerUrl: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@utils/gallery');
|
||||
jest.mock('@actions/local/file');
|
||||
|
||||
describe('useImageAttachments', () => {
|
||||
const serverUrl = 'https://example.com';
|
||||
|
||||
|
|
@ -143,3 +150,42 @@ describe('useImageAttachments', () => {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useChannelBookmarkFiles', () => {
|
||||
it('should fetch and set file info correctly', async () => {
|
||||
const serverUrl = 'https://example.com';
|
||||
(useServerUrl as jest.Mock).mockReturnValue(serverUrl);
|
||||
|
||||
const bookmarks = [
|
||||
{fileId: '1', ownerId: 'user1'},
|
||||
{fileId: '2', ownerId: 'user2'},
|
||||
] as ChannelBookmarkModel[];
|
||||
|
||||
const file1 = {id: '1', localPath: 'path/to/image1', has_preview_image: true, toFileInfo: jest.fn().mockReturnValue({id: '1'})};
|
||||
const file2 = {id: '2', localPath: 'path/to/video1', has_preview_image: false, toFileInfo: jest.fn().mockReturnValue({id: '2'})};
|
||||
|
||||
(getLocalFileInfo as jest.Mock).mockImplementation((url, id) => {
|
||||
if (id === '1') {
|
||||
return {file: file1};
|
||||
} else if (id === '2') {
|
||||
return {file: file2};
|
||||
}
|
||||
return {file: null};
|
||||
});
|
||||
|
||||
(isImage as jest.Mock).mockImplementation((file) => file.id === '1');
|
||||
(isVideo as jest.Mock).mockImplementation((file) => file.id === '2');
|
||||
(isGif as jest.Mock).mockImplementation(() => false);
|
||||
(buildFileUrl as jest.Mock).mockImplementation((url, id) => `${url}/files/${id}`);
|
||||
(buildFilePreviewUrl as jest.Mock).mockImplementation((url, id) => `${url}/files/${id}/preview`);
|
||||
(getImageSize as jest.Mock).mockImplementation(() => ({width: 100, height: 100}));
|
||||
|
||||
const {result, waitForNextUpdate} = renderHook(() => useChannelBookmarkFiles(bookmarks, true));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current).toHaveLength(2);
|
||||
expect(result.current[0].id).toBe('1');
|
||||
expect(result.current[1].id).toBe('2');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
398
app/hooks/gallery.test.ts
Normal file
398
app/hooks/gallery.test.ts
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {renderHook, act} from '@testing-library/react-hooks';
|
||||
import {useSharedValue} from 'react-native-reanimated';
|
||||
|
||||
import {useGallery} from '@context/gallery';
|
||||
|
||||
import {useGalleryControls, useGalleryItem, diff, useCreateAnimatedGestureHandler} from './gallery';
|
||||
|
||||
jest.mock('react-native-reanimated', () => ({
|
||||
Easing: {
|
||||
bezier: jest.fn(),
|
||||
},
|
||||
runOnJS: jest.fn((fn) => fn),
|
||||
useAnimatedRef: jest.fn(() => ({})),
|
||||
useAnimatedStyle: jest.fn((fn) => fn()),
|
||||
useEvent: jest.fn(),
|
||||
useSharedValue: jest.fn(),
|
||||
withTiming: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@context/gallery', () => ({
|
||||
useGallery: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('react-native', () => ({
|
||||
Platform: {
|
||||
OS: 'ios',
|
||||
},
|
||||
}));
|
||||
|
||||
describe('gallery hooks', () => {
|
||||
test('diff', () => {
|
||||
const context = {} as {___diffs?: any};
|
||||
const name = 'test';
|
||||
const value = 10;
|
||||
|
||||
const result = diff(context, name, value);
|
||||
|
||||
expect(result).toBe(0);
|
||||
expect(context.___diffs[name].stash).toBe(0);
|
||||
expect(context.___diffs[name].prev).toBe(value);
|
||||
});
|
||||
|
||||
test('diff should return 0 for the same value', () => {
|
||||
const context = {} as {___diffs?: any};
|
||||
const name = 'test';
|
||||
const value = 10;
|
||||
|
||||
diff(context, name, value);
|
||||
const result = diff(context, name, value);
|
||||
|
||||
expect(result).toBe(0);
|
||||
expect(context.___diffs[name].stash).toBe(0);
|
||||
expect(context.___diffs[name].prev).toBe(value);
|
||||
});
|
||||
|
||||
describe('useCreateAnimatedGestureHandler', () => {
|
||||
const handlers = {
|
||||
onInit: jest.fn(),
|
||||
onGesture: jest.fn(),
|
||||
shouldHandleEvent: jest.fn(),
|
||||
onEvent: jest.fn(),
|
||||
shouldCancel: jest.fn(),
|
||||
onEnd: jest.fn(),
|
||||
onStart: jest.fn(),
|
||||
onActive: jest.fn(),
|
||||
onFail: jest.fn(),
|
||||
onCancel: jest.fn(),
|
||||
onFinish: jest.fn(),
|
||||
beforeEach: jest.fn(),
|
||||
afterEach: jest.fn(),
|
||||
};
|
||||
|
||||
test('iOS and state is active', () => {
|
||||
const context = {__initialized: false, _shouldSkip: false} as any;
|
||||
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
expect(handler).toBeInstanceOf(Function);
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 4,
|
||||
oldState: 1,
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.onInit).toHaveBeenCalled();
|
||||
expect(handlers.onGesture).toHaveBeenCalled();
|
||||
expect(handlers.shouldHandleEvent).not.toHaveBeenCalled();
|
||||
expect(handlers.onEvent).toHaveBeenCalled();
|
||||
expect(handlers.shouldCancel).toHaveBeenCalled();
|
||||
expect(handlers.onEnd).not.toHaveBeenCalled();
|
||||
expect(handlers.onStart).not.toHaveBeenCalled();
|
||||
expect(handlers.onActive).toHaveBeenCalled();
|
||||
expect(handlers.onFail).not.toHaveBeenCalled();
|
||||
expect(handlers.onCancel).not.toHaveBeenCalled();
|
||||
expect(handlers.onFinish).not.toHaveBeenCalled();
|
||||
expect(handlers.beforeEach).toHaveBeenCalled();
|
||||
expect(handlers.afterEach).toHaveBeenCalled();
|
||||
|
||||
// Check the expected values of context
|
||||
expect(context.__initialized).toBe(true);
|
||||
expect(context._shouldSkip).toBe(false);
|
||||
});
|
||||
|
||||
test('State is end, oldState is active', () => {
|
||||
const context = {__initialized: false, _shouldSkip: false} as any;
|
||||
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
expect(handler).toBeInstanceOf(Function);
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 5,
|
||||
oldState: 4,
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.onEnd).toHaveBeenCalled();
|
||||
|
||||
// Check the expected values of context
|
||||
expect(context.__initialized).toBe(true);
|
||||
expect(context._shouldCancel).toBeUndefined();
|
||||
expect(context._shouldSkip).toBeUndefined();
|
||||
});
|
||||
|
||||
test('State is began, oldState is active, velocity non-zero', () => {
|
||||
const context = {__initialized: false, _shouldSkip: false} as any;
|
||||
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
expect(handler).toBeInstanceOf(Function);
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 2,
|
||||
oldState: 4,
|
||||
velocityX: 1,
|
||||
velocityY: 1,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.shouldHandleEvent).toHaveBeenCalled();
|
||||
|
||||
// Check the expected values of context
|
||||
expect(context.__initialized).toBe(true);
|
||||
expect(context._shouldCancel).toBeUndefined();
|
||||
expect(context._shouldSkip).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should skip handling event if shouldHandleEvent returns false', () => {
|
||||
const context = {__initialized: false, _shouldSkip: undefined} as any;
|
||||
|
||||
handlers.shouldHandleEvent.mockReturnValueOnce(false);
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
expect(handler).toBeInstanceOf(Function);
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 2,
|
||||
velocityX: 1,
|
||||
velocityY: 1,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.shouldHandleEvent).toHaveBeenCalled();
|
||||
expect(context._shouldSkip).toBe(true);
|
||||
});
|
||||
|
||||
test('handles shouldCancel returning true', () => {
|
||||
const context = {__initialized: true, _shouldSkip: false} as any;
|
||||
handlers.shouldCancel.mockReturnValueOnce(true);
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 4, // ACTIVE
|
||||
oldState: 2, // BEGAN
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.shouldCancel).toHaveBeenCalled();
|
||||
expect(handlers.onEnd).toHaveBeenCalledWith(
|
||||
event.nativeEvent,
|
||||
context,
|
||||
true, // cancelled = true
|
||||
);
|
||||
expect(handlers.onActive).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('skips event handling when context._shouldSkip is undefined', () => {
|
||||
const context = {__initialized: true} as any;
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 4, // ACTIVE
|
||||
oldState: 3, // CANCELLED
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.onEvent).not.toHaveBeenCalled();
|
||||
expect(handlers.onActive).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('handles CANCELLED state when oldState is ACTIVE', () => {
|
||||
const context = {__initialized: true, _shouldSkip: false} as any;
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 3, // CANCELLED
|
||||
oldState: 4, // ACTIVE
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.onCancel).toHaveBeenCalled();
|
||||
expect(handlers.onFinish).toHaveBeenCalledWith(
|
||||
event.nativeEvent,
|
||||
context,
|
||||
true, // cancelled = true
|
||||
);
|
||||
});
|
||||
|
||||
test('handles FAILED state when oldState is ACTIVE', () => {
|
||||
const context = {__initialized: true, _shouldSkip: false} as any;
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: context}));
|
||||
|
||||
const {result} = renderHook(() => useCreateAnimatedGestureHandler(handlers));
|
||||
const handler = result.current;
|
||||
|
||||
const event = {
|
||||
nativeEvent: {
|
||||
state: 1, // FAILED
|
||||
oldState: 4, // ACTIVE
|
||||
velocityX: 0,
|
||||
velocityY: 0,
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
handler(event.nativeEvent as any);
|
||||
});
|
||||
|
||||
expect(handlers.onFail).toHaveBeenCalled();
|
||||
expect(handlers.onFinish).toHaveBeenCalledWith(
|
||||
event.nativeEvent,
|
||||
context,
|
||||
true, // failed = true
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('useGalleryControls', () => {
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: false}));
|
||||
const {result} = renderHook(() => useGalleryControls());
|
||||
|
||||
act(() => {
|
||||
result.current.setControlsHidden(true);
|
||||
});
|
||||
|
||||
expect(result.current.controlsHidden.value).toBe(true);
|
||||
|
||||
act(() => {
|
||||
result.current.setControlsHidden(false);
|
||||
});
|
||||
|
||||
expect(result.current.controlsHidden.value).toBe(false);
|
||||
});
|
||||
|
||||
test('useGalleryControls does not update controlsHidden when same value is set', () => {
|
||||
const mockWithTiming = jest.fn();
|
||||
(useSharedValue as jest.Mock).mockImplementationOnce(() => ({value: true}));
|
||||
|
||||
const {result} = renderHook(() => useGalleryControls());
|
||||
|
||||
act(() => {
|
||||
result.current.setControlsHidden(true);
|
||||
});
|
||||
|
||||
expect(mockWithTiming).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('useGalleryItem', () => {
|
||||
const identifier = 'test';
|
||||
const index = 0;
|
||||
const onPress = jest.fn();
|
||||
const gallery = {
|
||||
sharedValues: {
|
||||
opacity: {value: 1},
|
||||
activeIndex: {value: 0},
|
||||
},
|
||||
registerItem: jest.fn(),
|
||||
};
|
||||
(useGallery as jest.Mock).mockReturnValue(gallery);
|
||||
|
||||
const {result} = renderHook(() => useGalleryItem(identifier, index, onPress));
|
||||
|
||||
expect(result.current.ref).toBeDefined();
|
||||
expect(result.current.styles).toBeDefined();
|
||||
expect(result.current.onGestureEvent).toBeInstanceOf(Function);
|
||||
|
||||
act(() => {
|
||||
result.current.onGestureEvent();
|
||||
});
|
||||
|
||||
expect(gallery.sharedValues.activeIndex.value).toBe(index);
|
||||
expect(onPress).toHaveBeenCalledWith(identifier, index);
|
||||
});
|
||||
|
||||
test('useGalleryItem updates activeIndex when onGestureEvent is triggered', () => {
|
||||
const identifier = 'test';
|
||||
const index = 0;
|
||||
const onPress = jest.fn();
|
||||
const gallery = {
|
||||
sharedValues: {
|
||||
opacity: {value: 1},
|
||||
activeIndex: {value: 1}, // Initial value different from index
|
||||
},
|
||||
registerItem: jest.fn(),
|
||||
};
|
||||
(useGallery as jest.Mock).mockReturnValue(gallery);
|
||||
|
||||
const {result} = renderHook(() => useGalleryItem(identifier, index, onPress));
|
||||
|
||||
expect(result.current.styles.opacity).toBe(1);
|
||||
|
||||
act(() => {
|
||||
result.current.onGestureEvent();
|
||||
});
|
||||
|
||||
expect(gallery.sharedValues.activeIndex.value).toBe(index);
|
||||
expect(onPress).toHaveBeenCalledWith(identifier, index);
|
||||
});
|
||||
});
|
||||
|
|
@ -14,7 +14,7 @@ import {useGallery} from '@context/gallery';
|
|||
import type {Context, GestureHandlers, OnGestureEvent} from '@typings/screens/gallery';
|
||||
import type {GestureHandlerGestureEvent} from 'react-native-gesture-handler';
|
||||
|
||||
function diff(context: any, name: string, value: any) {
|
||||
export function diff(context: any, name: string, value: any) {
|
||||
'worklet';
|
||||
|
||||
if (!context.___diffs) {
|
||||
|
|
|
|||
92
app/hooks/markdown.test.ts
Normal file
92
app/hooks/markdown.test.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {renderHook} from '@testing-library/react-hooks';
|
||||
|
||||
import {getUsersByUsername} from '@utils/user';
|
||||
|
||||
import {useMemoMentionedUser, useMemoMentionedGroup} from './markdown';
|
||||
|
||||
import type {GroupModel, UserModel} from '@database/models/server';
|
||||
|
||||
jest.mock('@utils/user', () => ({
|
||||
getUsersByUsername: jest.fn(),
|
||||
}));
|
||||
|
||||
const mockGetUsersByUsername = jest.mocked(getUsersByUsername);
|
||||
|
||||
describe('useMemoMentionedUser', () => {
|
||||
it('should return the mentioned user if found', () => {
|
||||
const users = [{username: 'john_doe'} as UserModel];
|
||||
const mentionName = 'john_doe';
|
||||
const usersByUsername = {john_doe: users[0]};
|
||||
mockGetUsersByUsername.mockReturnValue(usersByUsername);
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedUser(users, mentionName));
|
||||
|
||||
expect(result.current).toBe(users[0]);
|
||||
});
|
||||
|
||||
it('should return undefined if the mentioned user is not found', () => {
|
||||
const users = [{username: 'john_doe'} as UserModel];
|
||||
const mentionName = 'jane_doe';
|
||||
const usersByUsername = {john_doe: users[0]};
|
||||
mockGetUsersByUsername.mockReturnValue(usersByUsername);
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedUser(users, mentionName));
|
||||
|
||||
expect(result.current).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should trim trailing punctuation from the mention name', () => {
|
||||
const users = [{username: 'john_doe'} as UserModel];
|
||||
const mentionName = 'john_doe.';
|
||||
const usersByUsername = {john_doe: users[0]};
|
||||
mockGetUsersByUsername.mockReturnValue(usersByUsername);
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedUser(users, mentionName));
|
||||
|
||||
expect(result.current).toBe(users[0]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useMemoMentionedGroup', () => {
|
||||
it('should return the mentioned group if found', () => {
|
||||
const groups = [{name: 'developers'} as GroupModel];
|
||||
const user = undefined;
|
||||
const mentionName = 'developers';
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedGroup(groups, user, mentionName));
|
||||
|
||||
expect(result.current).toBe(groups[0]);
|
||||
});
|
||||
|
||||
it('should return undefined if the mentioned group is not found', () => {
|
||||
const groups = [{name: 'developers'} as GroupModel];
|
||||
const user = undefined;
|
||||
const mentionName = 'designers';
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedGroup(groups, user, mentionName));
|
||||
|
||||
expect(result.current).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return undefined if the user is defined', () => {
|
||||
const groups = [{name: 'developers'} as GroupModel];
|
||||
const user = {username: 'john_doe'} as UserModel;
|
||||
const mentionName = 'developers';
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedGroup(groups, user, mentionName));
|
||||
|
||||
expect(result.current).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should trim trailing punctuation from the mention name', () => {
|
||||
const groups = [{name: 'developers'} as GroupModel];
|
||||
const user = undefined;
|
||||
const mentionName = 'developers.';
|
||||
|
||||
const {result} = renderHook(() => useMemoMentionedGroup(groups, user, mentionName));
|
||||
|
||||
expect(result.current).toBe(groups[0]);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue