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}