Skip to content

Commit 31559df

Browse files
committed
Create SignalRContext.test.tsx
1 parent 3dc5390 commit 31559df

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { renderHook, waitFor } from '@testing-library/react-native';
2+
import React from 'react';
3+
4+
import { SignalRProvider, useSignalR } from '@/context/SignalRContext';
5+
6+
const mockUseAuth = jest.fn();
7+
const mockIsEnabled = jest.fn();
8+
const mockGetAccessTokenAsync = jest.fn();
9+
const mockConfigServiceGet = jest.fn();
10+
11+
jest.mock('@/context/AuthContext', () => ({
12+
useAuth: () => mockUseAuth(),
13+
}));
14+
15+
jest.mock('@/hooks/useFeatureFlags', () => ({
16+
useFeatureFlags: () => ({ isEnabled: mockIsEnabled }),
17+
}));
18+
19+
jest.mock('@/lib/tokenProvider', () => ({
20+
getAccessTokenAsync: () => mockGetAccessTokenAsync(),
21+
}));
22+
23+
jest.mock('@/config/env.config', () => ({
24+
configService: {
25+
get: (key: string) => mockConfigServiceGet(key),
26+
},
27+
}));
28+
29+
jest.mock('@/services/loggerService', () => ({
30+
logger: {
31+
info: jest.fn(),
32+
warn: jest.fn(),
33+
error: jest.fn(),
34+
trace: jest.fn(),
35+
},
36+
}));
37+
38+
const createWrapper = () => {
39+
return ({ children }: { children: React.ReactNode }) => (
40+
<SignalRProvider>{children}</SignalRProvider>
41+
);
42+
};
43+
44+
describe('SignalRContext', () => {
45+
beforeEach(() => {
46+
jest.clearAllMocks();
47+
mockUseAuth.mockReturnValue({ status: 'unauthenticated' });
48+
mockIsEnabled.mockReturnValue(false);
49+
mockConfigServiceGet.mockReturnValue('https://api.example.com');
50+
mockGetAccessTokenAsync.mockResolvedValue('mock-token');
51+
});
52+
53+
it('throws error when useSignalR is used outside provider', () => {
54+
expect(() => {
55+
renderHook(() => useSignalR());
56+
}).toThrow('useSignalR must be used within SignalRProvider');
57+
});
58+
59+
it('provides context value with subscribe, unsubscribe, and addMessageListener', () => {
60+
const { result } = renderHook(() => useSignalR(), {
61+
wrapper: createWrapper(),
62+
});
63+
64+
expect(result.current).toHaveProperty('subscribe');
65+
expect(result.current).toHaveProperty('unsubscribe');
66+
expect(result.current).toHaveProperty('addMessageListener');
67+
expect(result.current).toHaveProperty('isConnected');
68+
expect(result.current).toHaveProperty('connectionState');
69+
});
70+
71+
it('initializes with disconnected state', () => {
72+
const { result } = renderHook(() => useSignalR(), {
73+
wrapper: createWrapper(),
74+
});
75+
76+
expect(result.current.isConnected).toBe(false);
77+
expect(result.current.connectionState).toBe('Disconnected');
78+
});
79+
80+
it('does not initialize connection when feature flag is disabled', async () => {
81+
mockIsEnabled.mockReturnValue(false);
82+
mockUseAuth.mockReturnValue({ status: 'authenticated' });
83+
84+
const { result } = renderHook(() => useSignalR(), {
85+
wrapper: createWrapper(),
86+
});
87+
88+
await waitFor(() => {
89+
expect(result.current.isConnected).toBe(false);
90+
});
91+
});
92+
93+
it('does not initialize connection when unauthenticated', async () => {
94+
mockIsEnabled.mockReturnValue(true);
95+
mockUseAuth.mockReturnValue({ status: 'unauthenticated' });
96+
97+
const { result } = renderHook(() => useSignalR(), {
98+
wrapper: createWrapper(),
99+
});
100+
101+
await waitFor(() => {
102+
expect(result.current.isConnected).toBe(false);
103+
});
104+
});
105+
106+
it('addMessageListener returns cleanup function', () => {
107+
const { result } = renderHook(() => useSignalR(), {
108+
wrapper: createWrapper(),
109+
});
110+
111+
const mockListener = jest.fn();
112+
const cleanup = result.current.addMessageListener(mockListener);
113+
114+
expect(typeof cleanup).toBe('function');
115+
cleanup();
116+
});
117+
});

0 commit comments

Comments
 (0)