diff --git a/__test__/components/StreamPreviewImage.spec.tsx b/__test__/components/StreamPreviewImage.spec.tsx new file mode 100644 index 0000000..c3048af --- /dev/null +++ b/__test__/components/StreamPreviewImage.spec.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { fireEvent } from '@testing-library/react-native'; +import StreamPreviewImage from '../../src/components/StreamPreviewImage'; // Adjust the path as necessary +import { customRender } from '../test_utils/customRender'; + +describe('StreamPreviewImage', () => { + const handleAddImageMock = jest.fn(); + const clearImageMock = jest.fn(); + + beforeEach(() => { + handleAddImageMock.mockClear(); + clearImageMock.mockClear(); + }); + + it('customRenders correctly without image', () => { + const { getByTestId, queryByTestId } = customRender( + + ); + + expect(queryByTestId('add-image-button')).toBeTruthy(); + expect(queryByTestId('clear-image-button')).toBeFalsy(); + }); + + it('customRenders correctly with image', () => { + const { getByTestId, queryByTestId } = customRender( + + ); + + expect(queryByTestId('add-image-button')).toBeFalsy(); + expect(queryByTestId('clear-image-button')).toBeTruthy(); + }); + + it('calls handleAddImage when add image button is pressed', () => { + const { getByTestId } = customRender( + + ); + + fireEvent.press(getByTestId('add-image-button')); + expect(handleAddImageMock).toHaveBeenCalledTimes(1); + }); + + it('calls clearImage when clear image button is pressed', () => { + const { getByTestId } = customRender( + + ); + + fireEvent.press(getByTestId('clear-image-button')); + expect(clearImageMock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/__test__/modules/settings/SettingsList.spec.tsx b/__test__/modules/settings/SettingsList.spec.tsx new file mode 100644 index 0000000..9bea480 --- /dev/null +++ b/__test__/modules/settings/SettingsList.spec.tsx @@ -0,0 +1,59 @@ +import { fireEvent } from '@testing-library/react-native'; +import React from 'react'; + +import useAuth from '../../../src/modules/auth/useAuth'; +import SettingsList from '../../../src/modules/settings/SettingsList'; // Adjust the path as necessary +import { settingSectionsMap } from '../../../src/modules/settings/settings'; // Adjust the path as necessary +import { customRender } from '../../test_utils/customRender'; + +// Mock the useAuth hook +jest.mock('@modules/auth/useAuth', () => ({ + __esModule: true, + default: jest.fn(), +})); + +describe('SettingsList', () => { + const mockSignOut = jest.fn(); + const originalConsoleLog = console.log; + + beforeEach(() => { + (useAuth as jest.Mock).mockReturnValue({ signOut: mockSignOut }); + console.log = jest.fn(); // Mock console.log + }); + + afterEach(() => { + jest.clearAllMocks(); + console.log = originalConsoleLog; // Restore console.log + }); + it('renders all settings sections and items correctly', () => { + const { getByTestId } = customRender(); + + Object.entries(settingSectionsMap).forEach(([key, items]) => { + // Check if the section header is rendered + expect(getByTestId(`${key}-header`)).toBeTruthy(); + + // Check if all items in the section are rendered + items.forEach((item) => { + expect(getByTestId(`${item}-button`)).toBeTruthy(); + }); + }); + }); + + it('triggers the correct action on item press', () => { + const { getByTestId } = customRender(); + + Object.entries(settingSectionsMap).forEach(([_, items]) => { + items.forEach((item) => { + // Trigger the onPress event + fireEvent.press(getByTestId(`${item}-button`)); + + // Check console log or signOut action + if (item === 'Logout') { + expect(mockSignOut).toHaveBeenCalled(); + } else { + expect(console.log).toHaveBeenCalled(); + } + }); + }); + }); +}); diff --git a/__test__/modules/settings/settings.spec.ts b/__test__/modules/settings/settings.spec.ts new file mode 100644 index 0000000..920e8c0 --- /dev/null +++ b/__test__/modules/settings/settings.spec.ts @@ -0,0 +1,53 @@ +import { settingSectionsMap } from '../../../src/modules/settings/settings'; + +describe('settingSectionMap', () => { + it('Should have expected Keys', () => { + expect(Object.keys(settingSectionsMap)).toHaveLength(8); + expect(Object.keys(settingSectionsMap)).toEqual([ + 'Account', + 'Livestream Settings', + 'Privacy and Safety', + 'Notifications', + 'Support and Feedback', + 'Legal', + 'About', + 'Logout', + ]); + }); + + it('Key value should have expected length', () => { + const valueLength = [4, 2, 3, 2, 3, 3, 4, 1]; + + Object.keys(settingSectionsMap).forEach((key, index) => { + expect(settingSectionsMap[key]).toHaveLength(valueLength[index]); + }); + }); + + it('Key should have expected value', () => { + expect(settingSectionsMap.Account).toEqual(['Profile', 'Security', 'Shares', 'Permissions']); + expect(settingSectionsMap['Livestream Settings']).toEqual(['Preferences', 'Chat Options']); + expect(settingSectionsMap['Privacy and Safety']).toEqual([ + 'Privacy', + 'Content Moderation', + 'Blocked Users', + ]); + expect(settingSectionsMap.Notifications).toEqual(['General', 'Livestream']); + expect(settingSectionsMap['Support and Feedback']).toEqual([ + 'Help Center', + 'Report a Problem', + 'Rate Us', + ]); + expect(settingSectionsMap.Legal).toEqual([ + 'Terms of Service', + 'Privacy Policy', + 'Community Guidelines', + ]); + expect(settingSectionsMap.About).toEqual([ + 'Version', + 'Developer Info', + 'Release Notes', + 'Join Beta Program', + ]); + expect(settingSectionsMap.Logout).toEqual(['Logout']); + }); +}); diff --git a/src/components/UserFollowerCard.tsx b/src/components/UserFollowerCard.tsx index 63a573b..6ab77fd 100644 --- a/src/components/UserFollowerCard.tsx +++ b/src/components/UserFollowerCard.tsx @@ -23,7 +23,7 @@ const UserFollowerCard: React.FC<{ void; -} - -const SettingButton: React.FC = ({ name, onPress }) => { - return ( - - ); -}; - -export default SettingButton; diff --git a/src/components/settings/SettingStack.tsx b/src/components/settings/SettingStack.tsx deleted file mode 100644 index 16b2a17..0000000 --- a/src/components/settings/SettingStack.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, { ReactNode } from 'react'; -import { YStack } from 'tamagui'; - -interface SettingStackProps { - children: ReactNode; -} - -const SettingStack: React.FC = ({ children }) => { - return ( - - {children} - - ); -}; - -export default SettingStack; diff --git a/src/modules/settings/SettingsList.tsx b/src/modules/settings/SettingsList.tsx index d821221..e150e34 100644 --- a/src/modules/settings/SettingsList.tsx +++ b/src/modules/settings/SettingsList.tsx @@ -1,10 +1,11 @@ import { Feather } from '@expo/vector-icons'; -import { ScrollView } from 'react-native'; +import useAuth from '@modules/auth/useAuth'; import React from 'react'; -import { settingSectionsMap } from './settings'; +import { ScrollView } from 'react-native'; import { H3, ListItem, Separator, YGroup, YStack } from 'tamagui'; + +import { settingSectionsMap } from './settings'; import { SettingTitle } from './types'; -import useAuth from '@modules/auth/useAuth'; const SettingsList: React.FC = () => { const { signOut } = useAuth(); @@ -38,7 +39,7 @@ const SettingsList: React.FC = () => { {Object.entries(settingSectionsMap).map(([key, val]) => { return ( - +

{key}