eletrotupi / tcc/ frontend/tests/setup.ts9cd93e6ab48e317d51b0bdf9066dc5852cda738f
2.8 KB | 86 lines Raw
1
// The single global shade over the native/Expo boundary, applied to every test
2
// file. Mirrors the API's rule: fake only what leaves the process. Individual
3
// tests never re-stub the device.
4

5
// Expo secure store -> in-memory map. Prefixed with `mock` so jest's hoisting
6
// lets the mock factories below close over it.
7
const mockSecureStore = new Map<string, string>();
8

9
jest.mock('expo-secure-store', () => ({
10
  getItemAsync: jest.fn(
11
    async (key: string) => mockSecureStore.get(key) ?? null,
12
  ),
13
  setItemAsync: jest.fn(async (key: string, value: string) => {
14
    mockSecureStore.set(key, value);
15
  }),
16
  deleteItemAsync: jest.fn(async (key: string) => {
17
    mockSecureStore.delete(key);
18
  }),
19
}));
20

21
// MMKV (the query cache's KV store) -> in-memory map.
22
type MockMmkvValue = boolean | string | number | ArrayBuffer;
23

24
const mockKv = new Map<string, MockMmkvValue>();
25

26
jest.mock('react-native-mmkv', () => ({
27
  createMMKV: jest.fn(() => ({
28
    set: (key: string, value: MockMmkvValue) => {
29
      mockKv.set(key, value);
30
    },
31
    getString: (key: string) => {
32
      const value = mockKv.get(key);
33
      return typeof value === 'string' ? value : undefined;
34
    },
35
    getNumber: (key: string) => {
36
      const value = mockKv.get(key);
37
      return typeof value === 'number' ? value : undefined;
38
    },
39
    getBoolean: (key: string) => {
40
      const value = mockKv.get(key);
41
      return typeof value === 'boolean' ? value : undefined;
42
    },
43
    getBuffer: (key: string) => {
44
      const value = mockKv.get(key);
45
      return value instanceof ArrayBuffer ? value : undefined;
46
    },
47
    contains: (key: string) => mockKv.has(key),
48
    remove: (key: string) => mockKv.delete(key),
49
    getAllKeys: () => Array.from(mockKv.keys()),
50
    clearAll: () => {
51
      mockKv.clear();
52
    },
53
  })),
54
}));
55

56
// Expo constants -> a stable dev-like stub, so the client's base-url fallback
57
// resolves without a real manifest.
58
jest.mock('expo-constants', () => ({
59
  __esModule: true,
60
  default: {
61
    expoConfig: {
62
      hostUri: 'localhost:8081',
63
      extra: { eas: { projectId: 'test-project-id' } },
64
    },
65
  },
66
}));
67

68
// Expo notifications -> stubs for the calls the app makes at module and hook
69
// time.
70
jest.mock('expo-notifications', () => ({
71
  setNotificationHandler: jest.fn(),
72
  getPermissionsAsync: jest.fn(async () => ({ status: 'granted' })),
73
  requestPermissionsAsync: jest.fn(async () => ({ status: 'granted' })),
74
  setNotificationChannelAsync: jest.fn(async () => null),
75
  getExpoPushTokenAsync: jest.fn(async () => ({ data: 'expo-push-token' })),
76
  getLastNotificationResponseAsync: jest.fn(async () => null),
77
  addNotificationResponseReceivedListener: jest.fn(() => ({
78
    remove: jest.fn(),
79
  })),
80
  AndroidImportance: { MAX: 5 },
81
}));
82

83
// Expo device -> claim to be a device, so push registration proceeds.
84
jest.mock('expo-device', () => ({
85
  isDevice: true,
86
}));