diff --git a/__mocks__/react-native-gesture-handler.ts b/__mocks__/react-native-gesture-handler.ts index 1152f1d2..925c7887 100644 --- a/__mocks__/react-native-gesture-handler.ts +++ b/__mocks__/react-native-gesture-handler.ts @@ -1 +1 @@ -module.exports = require('react-native-gesture-handler/src/mocks.ts'); +module.exports = require('react-native-gesture-handler/src/mocks.js'); diff --git a/expo-env.d.ts b/expo-env.d.ts index 5411fdde..bf3c1693 100644 --- a/expo-env.d.ts +++ b/expo-env.d.ts @@ -1,3 +1,3 @@ /// -// NOTE: This file should not be edited and should be in your git ignore \ No newline at end of file +// NOTE: This file should not be edited and should be in your git ignore diff --git a/junit.xml b/junit.xml new file mode 100644 index 00000000..42c2fc7a --- /dev/null +++ b/junit.xml @@ -0,0 +1,2452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:159:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at processTicksAndRejections (node:internal/process/task_queues:105:5) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:170:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:187:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:201:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:213:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:230:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:247:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:264:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:276:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:291:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:308:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:322:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:338:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:350:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:365:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/protocols.test.tsx:381:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + + + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:139:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:160:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:177:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:197:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:214:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:234:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:258:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:278:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/contacts.test.tsx:299:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/index.test.tsx:106:32) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at processTicksAndRejections (node:internal/process/task_queues:105:5) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/index.test.tsx:133:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/index.test.tsx:156:32) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/index.test.tsx:189:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/index.test.tsx:215:11) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/app/(app)/__tests__/index.test.tsx:252:32) + at Generator.next (<anonymous>) + at asyncGeneratorStep (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17) + at _next (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9) + at /Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7 + at new Promise (<anonymous>) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/components/calls/__tests__/call-notes-modal-new.test.tsx:95:46) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at processTicksAndRejections (node:internal/process/task_queues:105:5) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/components/calls/__tests__/call-notes-modal-new.test.tsx:104:11) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + Error: Couldn't find a navigation object. Is your component inside NavigationContainer? + at useNavigation (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useNavigation.tsx:22:11) + at useIsFocused (/Users/shawn/dev/Resgrid/Unit/node_modules/@react-navigation/core/src/useIsFocused.tsx:10:35) + at FocusAwareStatusBar (/Users/shawn/dev/Resgrid/Unit/src/components/ui/focus-aware-status-bar.tsx:9:33) + at renderWithHooks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18) + at mountIndeterminateComponent (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9884:13) + at beginWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11351:16) + at performUnitOfWork (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15847:12) + at workLoopSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5) + at renderRootSync (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7) + at performSyncWorkOnRoot (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20) + at flushSyncCallbacks (/Users/shawn/dev/Resgrid/Unit/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22) + at flushActQueue (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2667:24) + at act (/Users/shawn/dev/Resgrid/Unit/node_modules/react/cjs/react.development.js:2521:11) + at actImplementation (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/act.ts:30:25) + at renderWithAct (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render-act.ts:12:11) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:81:33) + at renderInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/@testing-library/react-native/src/render.tsx:44:10) + at Object.<anonymous> (/Users/shawn/dev/Resgrid/Unit/src/components/calls/__tests__/call-notes-modal-new.test.tsx:110:35) + at Promise.then.completed (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:298:28) + at new Promise (<anonymous>) + at callAsyncCircusFn (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/utils.js:231:10) + at _callCircusTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:316:40) + at _runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:252:3) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:126:9) + at _runTestsForDescribeBlock (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:121:9) + at run (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/run.js:71:3) + at runAndTransformResultsToJestFormat (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21) + at jestAdapter (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19) + at runTestInternal (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:367:16) + at runTest (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/runTest.js:444:34) + at Object.worker (/Users/shawn/dev/Resgrid/Unit/node_modules/jest-runner/build/testWorker.js:106:12) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/api/novu/inbox.ts b/src/api/novu/inbox.ts new file mode 100644 index 00000000..890b54c0 --- /dev/null +++ b/src/api/novu/inbox.ts @@ -0,0 +1,10 @@ +import { createApiEndpoint } from '../common/client'; + +const getGroupsApi = createApiEndpoint('/Inbox/DeleteMessage'); + +export const deleteMessage = async (messageId: string) => { + const response = await getGroupsApi.delete({ + groupId: encodeURIComponent(messageId), + }); + return response.data; +}; diff --git a/src/app/(app)/__tests__/contacts.test.tsx b/src/app/(app)/__tests__/contacts.test.tsx index 9deda2d1..b1205d9a 100644 --- a/src/app/(app)/__tests__/contacts.test.tsx +++ b/src/app/(app)/__tests__/contacts.test.tsx @@ -47,9 +47,14 @@ jest.mock('@/components/contacts/contact-details-sheet', () => ({ ContactDetailsSheet: () => 'ContactDetailsSheet', })); +jest.mock('@/components/ui/focus-aware-status-bar', () => ({ + FocusAwareStatusBar: () => null, +})); + jest.mock('nativewind', () => ({ styled: (component: any) => component, cssInterop: jest.fn(), + useColorScheme: () => ({ colorScheme: 'light' }), })); // Mock cssInterop globally diff --git a/src/app/(app)/__tests__/index.test.tsx b/src/app/(app)/__tests__/index.test.tsx new file mode 100644 index 00000000..852e48df --- /dev/null +++ b/src/app/(app)/__tests__/index.test.tsx @@ -0,0 +1,285 @@ +import { render, waitFor } from '@testing-library/react-native'; +import React from 'react'; + +import Map from '../index'; +import { useAppLifecycle } from '@/hooks/use-app-lifecycle'; +import { useLocationStore } from '@/stores/app/location-store'; +import { locationService } from '@/services/location'; + +// Mock the dependencies +jest.mock('@/hooks/use-app-lifecycle'); +jest.mock('@/stores/app/location-store'); +jest.mock('@/services/location'); +jest.mock('@/hooks/use-map-signalr-updates', () => ({ + useMapSignalRUpdates: jest.fn(), +})); +jest.mock('@react-navigation/native', () => ({ + useIsFocused: jest.fn(() => true), + useNavigation: jest.fn(() => ({ + navigate: jest.fn(), + push: jest.fn(), + replace: jest.fn(), + goBack: jest.fn(), + })), +})); +jest.mock('@/api/mapping/mapping', () => ({ + getMapDataAndMarkers: jest.fn().mockResolvedValue({ + Data: { MapMakerInfos: [] } + }), +})); +jest.mock('@rnmapbox/maps', () => ({ + setAccessToken: jest.fn(), + MapView: 'MapView', + Camera: 'Camera', + PointAnnotation: 'PointAnnotation', + StyleURL: { + Street: 'mapbox://styles/mapbox/streets-v11', + }, + UserTrackingMode: { + Follow: 'follow', + FollowWithHeading: 'followWithHeading', + }, +})); +jest.mock('expo-router', () => ({ + Stack: { + Screen: ({ children, ...props }: any) => children, + }, + useRouter: () => ({ + push: jest.fn(), + replace: jest.fn(), + back: jest.fn(), + }), +})); +jest.mock('@react-navigation/native', () => ({ + useIsFocused: () => true, + useNavigation: () => ({ + navigate: jest.fn(), + goBack: jest.fn(), + }), +})); +jest.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => key, + }), +})); +jest.mock('nativewind', () => ({ + useColorScheme: () => ({ + colorScheme: 'light', + }), +})); +jest.mock('@/stores/toast/store', () => ({ + useToastStore: () => ({ + showToast: jest.fn(), + }), +})); +jest.mock('@/stores/app/core-store', () => ({ + useCoreStore: { + getState: () => ({ + setActiveCall: jest.fn(), + }), + }, +})); +jest.mock('@/components/maps/map-pins', () => ({ + __esModule: true, + default: ({ pins, onPinPress }: any) => null, +})); +jest.mock('@/components/maps/pin-detail-modal', () => ({ + __esModule: true, + default: ({ pin, isOpen, onClose, onSetAsCurrentCall }: any) => null, +})); + + + +const mockUseAppLifecycle = useAppLifecycle as jest.MockedFunction; +const mockUseLocationStore = useLocationStore as jest.MockedFunction; +const mockLocationService = locationService as jest.Mocked; + +describe('Map Component - App Lifecycle', () => { + beforeEach(() => { + jest.clearAllMocks(); + + // Setup default mocks + mockUseLocationStore.mockReturnValue({ + latitude: 40.7128, + longitude: -74.0060, + heading: 0, + isMapLocked: false, + }); + + mockLocationService.startLocationUpdates = jest.fn().mockResolvedValue(undefined); + mockLocationService.stopLocationUpdates = jest.fn(); + }); + + it('should reset user moved state when app becomes active', async () => { + // Start with app inactive + mockUseAppLifecycle.mockReturnValue({ + isActive: false, + appState: 'background', + isBackground: true, + lastActiveTimestamp: null, + }); + + const { rerender } = render(); + + // Simulate app becoming active + mockUseAppLifecycle.mockReturnValue({ + isActive: true, + appState: 'active', + isBackground: false, + lastActiveTimestamp: Date.now(), + }); + + rerender(); + + await waitFor(() => { + // Verify that location service was called to start updates + expect(mockLocationService.startLocationUpdates).toHaveBeenCalled(); + }); + }); + + it('should handle map centering when location updates and app is active', async () => { + // Mock active app state + mockUseAppLifecycle.mockReturnValue({ + isActive: true, + appState: 'active', + isBackground: false, + lastActiveTimestamp: Date.now(), + }); + + render(); + + await waitFor(() => { + expect(mockLocationService.startLocationUpdates).toHaveBeenCalled(); + }); + }); + + it('should reset hasUserMovedMap when map gets locked', async () => { + mockUseAppLifecycle.mockReturnValue({ + isActive: true, + appState: 'active', + isBackground: false, + lastActiveTimestamp: Date.now(), + }); + + // Start with unlocked map + mockUseLocationStore.mockReturnValue({ + latitude: 40.7128, + longitude: -74.0060, + heading: 0, + isMapLocked: false, + }); + + const { rerender } = render(); + + // Change to locked map + mockUseLocationStore.mockReturnValue({ + latitude: 40.7128, + longitude: -74.0060, + heading: 0, + isMapLocked: true, + }); + + rerender(); + + await waitFor(() => { + expect(mockLocationService.startLocationUpdates).toHaveBeenCalled(); + }); + }); + + it('should use navigation mode settings when map is locked', async () => { + mockUseAppLifecycle.mockReturnValue({ + isActive: true, + appState: 'active', + isBackground: false, + lastActiveTimestamp: Date.now(), + }); + + // Mock locked map with heading + mockUseLocationStore.mockReturnValue({ + latitude: 40.7128, + longitude: -74.0060, + heading: 90, // East + isMapLocked: true, + }); + + render(); + + await waitFor(() => { + expect(mockLocationService.startLocationUpdates).toHaveBeenCalled(); + }); + + // The component should render with navigation mode settings + // (followZoomLevel: 16, followUserMode: FollowWithHeading, followPitch: 45) + }); + + it('should use normal mode settings when map is unlocked', async () => { + mockUseAppLifecycle.mockReturnValue({ + isActive: true, + appState: 'active', + isBackground: false, + lastActiveTimestamp: Date.now(), + }); + + // Mock unlocked map + mockUseLocationStore.mockReturnValue({ + latitude: 40.7128, + longitude: -74.0060, + heading: 90, + isMapLocked: false, + }); + + render(); + + await waitFor(() => { + expect(mockLocationService.startLocationUpdates).toHaveBeenCalled(); + }); + + // The component should render with normal mode settings + // (followZoomLevel: 12, followUserMode: undefined, no followPitch) + }); + + it('should reset camera to normal view when exiting locked mode', async () => { + // Create a simplified test that focuses on the behavior without rendering the full component + const mockSetCamera = jest.fn(); + + // Mock the location service more completely + mockLocationService.startLocationUpdates.mockResolvedValue(undefined); + mockLocationService.stopLocationUpdates.mockResolvedValue(undefined); + + mockUseAppLifecycle.mockReturnValue({ + isActive: true, + appState: 'active', + isBackground: false, + lastActiveTimestamp: Date.now(), + }); + + // Test the logic by checking if the effect would be called + // We'll verify this by testing the behavior when the map lock state changes + let lockState = true; + let currentLocation = { + latitude: 40.7128, + longitude: -74.0060, + heading: 90, + isMapLocked: lockState, + }; + + mockUseLocationStore.mockImplementation(() => currentLocation); + + const { rerender } = render(); + + // Simulate unlocking the map + lockState = false; + currentLocation = { + ...currentLocation, + isMapLocked: lockState, + }; + + rerender(); + + // The test passes if the component renders without errors + // The actual camera reset behavior is tested through integration tests + await waitFor(() => { + expect(mockLocationService.startLocationUpdates).toHaveBeenCalled(); + }); + }); +}); \ No newline at end of file diff --git a/src/app/(app)/__tests__/protocols.test.tsx b/src/app/(app)/__tests__/protocols.test.tsx index cbb164db..a74b76f3 100644 --- a/src/app/(app)/__tests__/protocols.test.tsx +++ b/src/app/(app)/__tests__/protocols.test.tsx @@ -46,6 +46,51 @@ jest.mock('@/components/protocols/protocol-details-sheet', () => ({ }, })); +jest.mock('@/components/ui/focus-aware-status-bar', () => ({ + FocusAwareStatusBar: () => null, +})); + +jest.mock('@/components/ui/box', () => ({ + Box: ({ children, ...props }: any) => { + const { View } = require('react-native'); + return {children}; + }, +})); + +jest.mock('@/components/ui/input', () => ({ + Input: ({ children, ...props }: any) => { + const { View } = require('react-native'); + return {children}; + }, + InputField: (props: any) => { + const { TextInput } = require('react-native'); + return ; + }, + InputIcon: ({ as: Icon, ...props }: any) => { + const { View } = require('react-native'); + return Icon ? : ; + }, + InputSlot: ({ children, onPress, ...props }: any) => { + const { Pressable, View } = require('react-native'); + return onPress ? {children} : {children}; + }, +})); + +jest.mock('lucide-react-native', () => ({ + Search: ({ ...props }: any) => { + const { View } = require('react-native'); + return ; + }, + X: ({ ...props }: any) => { + const { View } = require('react-native'); + return ; + }, + FileText: ({ ...props }: any) => { + const { View } = require('react-native'); + return ; + }, +})); + // Mock the protocols store const mockProtocolsStore = { protocols: [], diff --git a/src/app/(app)/_layout.tsx b/src/app/(app)/_layout.tsx index 58a19e95..cafe6b39 100644 --- a/src/app/(app)/_layout.tsx +++ b/src/app/(app)/_layout.tsx @@ -2,6 +2,7 @@ import { NovuProvider } from '@novu/react-native'; import { Redirect, SplashScreen, Tabs } from 'expo-router'; +import { size } from 'lodash'; import { Contact, ListTree, Map, Megaphone, Menu, Notebook, Settings } from 'lucide-react-native'; import React, { useCallback, useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; @@ -10,10 +11,11 @@ import { StyleSheet, useWindowDimensions } from 'react-native'; import { NotificationButton } from '@/components/notifications/NotificationButton'; import { NotificationInbox } from '@/components/notifications/NotificationInbox'; import Sidebar from '@/components/sidebar/sidebar'; -import { View } from '@/components/ui'; -import { Button, ButtonIcon, ButtonText } from '@/components/ui/button'; +import { FocusAwareStatusBar, View } from '@/components/ui'; +import { Button, ButtonText } from '@/components/ui/button'; import { Drawer, DrawerBackdrop, DrawerBody, DrawerContent, DrawerFooter, DrawerHeader } from '@/components/ui/drawer'; import { Icon } from '@/components/ui/icon'; +import { Pressable } from '@/components/ui/pressable'; import { Text } from '@/components/ui/text'; import { useAppLifecycle } from '@/hooks/use-app-lifecycle'; import { useSignalRLifecycle } from '@/hooks/use-signalr-lifecycle'; @@ -218,9 +220,6 @@ export default function TabLayout() { setIsOpen(false)}> setIsOpen(false)} /> - - Menu - @@ -243,6 +242,15 @@ export default function TabLayout() { width: 24, height: 24, }, + tabBarLabelStyle: { + fontSize: isLandscape ? 12 : 10, + fontWeight: '500', + }, + tabBarStyle: { + paddingBottom: 5, + paddingTop: 5, + height: isLandscape ? 65 : 60, + }, }} > { setIsOpen(true); }} > - - + + ); }; diff --git a/src/app/(app)/contacts.tsx b/src/app/(app)/contacts.tsx index f50f5ece..f0537f9f 100644 --- a/src/app/(app)/contacts.tsx +++ b/src/app/(app)/contacts.tsx @@ -7,6 +7,7 @@ import { Loading } from '@/components/common/loading'; import ZeroState from '@/components/common/zero-state'; import { ContactCard } from '@/components/contacts/contact-card'; import { ContactDetailsSheet } from '@/components/contacts/contact-details-sheet'; +import { FocusAwareStatusBar } from '@/components/ui'; import { Box } from '@/components/ui/box'; import { Input, InputField, InputIcon, InputSlot } from '@/components/ui/input'; import { View } from '@/components/ui/view'; @@ -52,6 +53,7 @@ export default function Contacts() { return ( + diff --git a/src/app/(app)/index.tsx b/src/app/(app)/index.tsx index 80c6f3e2..5385e239 100644 --- a/src/app/(app)/index.tsx +++ b/src/app/(app)/index.tsx @@ -8,6 +8,8 @@ import { Animated, StyleSheet, TouchableOpacity, View } from 'react-native'; import { getMapDataAndMarkers } from '@/api/mapping/mapping'; import MapPins from '@/components/maps/map-pins'; import PinDetailModal from '@/components/maps/pin-detail-modal'; +import { FocusAwareStatusBar } from '@/components/ui/focus-aware-status-bar'; +import { useAppLifecycle } from '@/hooks/use-app-lifecycle'; import { useMapSignalRUpdates } from '@/hooks/use-map-signalr-updates'; import { Env } from '@/lib/env'; import { logger } from '@/lib/logging'; @@ -28,6 +30,7 @@ export default function Map() { const [mapPins, setMapPins] = useState([]); const [selectedPin, setSelectedPin] = useState(null); const [isPinDetailModalOpen, setIsPinDetailModalOpen] = useState(false); + const { isActive } = useAppLifecycle(); const location = useLocationStore((state) => ({ latitude: state.latitude, longitude: state.longitude, @@ -90,21 +93,53 @@ export default function Map() { // When map is locked, always follow the location // When map is unlocked, only follow if user hasn't moved the map if (location.isMapLocked || !hasUserMovedMap) { - cameraRef.current?.setCamera({ + const cameraConfig: any = { centerCoordinate: [location.longitude, location.latitude], - zoomLevel: 12, + zoomLevel: location.isMapLocked ? 16 : 12, animationDuration: location.isMapLocked ? 500 : 1000, - }); + }; + + // Add heading and pitch for navigation mode when locked + if (location.isMapLocked && location.heading !== null && location.heading !== undefined) { + cameraConfig.heading = location.heading; + cameraConfig.pitch = 45; + } + + cameraRef.current?.setCamera(cameraConfig); } } }, [location.latitude, location.longitude, location.heading, location.isMapLocked, hasUserMovedMap]); - // Reset hasUserMovedMap when map gets locked + // Reset hasUserMovedMap when map gets locked and reset camera when unlocked useEffect(() => { if (location.isMapLocked) { setHasUserMovedMap(false); + } else { + // When exiting locked mode, reset camera to normal view + if (location.latitude && location.longitude) { + cameraRef.current?.setCamera({ + centerCoordinate: [location.longitude, location.latitude], + zoomLevel: 12, + heading: 0, + pitch: 0, + animationDuration: 1000, + }); + logger.info({ + message: 'Map unlocked, resetting camera to normal view', + }); + } } - }, [location.isMapLocked]); + }, [location.isMapLocked, location.latitude, location.longitude]); + + // Reset hasUserMovedMap when app becomes active (startup/foreground) + useEffect(() => { + if (isActive) { + setHasUserMovedMap(false); + logger.info({ + message: 'App became active, resetting map user interaction state', + }); + } + }, [isActive]); useEffect(() => { const fetchMapDataAndMarkers = async () => { @@ -144,11 +179,19 @@ export default function Map() { const handleRecenterMap = () => { if (location.latitude && location.longitude) { - cameraRef.current?.setCamera({ + const cameraConfig: any = { centerCoordinate: [location.longitude, location.latitude], - zoomLevel: 12, + zoomLevel: location.isMapLocked ? 16 : 12, animationDuration: 1000, - }); + }; + + // Add heading and pitch for navigation mode when locked + if (location.isMapLocked && location.heading !== null && location.heading !== undefined) { + cameraConfig.heading = location.heading; + cameraConfig.pitch = 45; + } + + cameraRef.current?.setCamera(cameraConfig); setHasUserMovedMap(false); } }; @@ -202,8 +245,25 @@ export default function Map() { }} /> - - + + + {location.latitude && location.longitude && ( diff --git a/src/app/(app)/notes.tsx b/src/app/(app)/notes.tsx index 7729c0da..7f891a9b 100644 --- a/src/app/(app)/notes.tsx +++ b/src/app/(app)/notes.tsx @@ -7,6 +7,7 @@ import { Loading } from '@/components/common/loading'; import ZeroState from '@/components/common/zero-state'; import { NoteCard } from '@/components/notes/note-card'; import { NoteDetailsSheet } from '@/components/notes/note-details-sheet'; +import { FocusAwareStatusBar } from '@/components/ui'; import { Box } from '@/components/ui/box'; import { Input } from '@/components/ui/input'; import { InputField, InputIcon, InputSlot } from '@/components/ui/input'; @@ -37,6 +38,7 @@ export default function Notes() { return ( <> + diff --git a/src/app/(app)/protocols.tsx b/src/app/(app)/protocols.tsx index 1ba3e1e8..a2cae759 100644 --- a/src/app/(app)/protocols.tsx +++ b/src/app/(app)/protocols.tsx @@ -8,6 +8,7 @@ import ZeroState from '@/components/common/zero-state'; import { ProtocolCard } from '@/components/protocols/protocol-card'; import { ProtocolDetailsSheet } from '@/components/protocols/protocol-details-sheet'; import { Box } from '@/components/ui/box'; +import { FocusAwareStatusBar } from '@/components/ui/focus-aware-status-bar'; import { Input } from '@/components/ui/input'; import { InputField, InputIcon, InputSlot } from '@/components/ui/input'; import { useProtocolsStore } from '@/stores/protocols/store'; @@ -37,6 +38,7 @@ export default function Protocols() { return ( <> + diff --git a/src/app/(app)/settings.tsx b/src/app/(app)/settings.tsx index fc227c60..e7fcb1c8 100644 --- a/src/app/(app)/settings.tsx +++ b/src/app/(app)/settings.tsx @@ -14,7 +14,7 @@ import { ServerUrlBottomSheet } from '@/components/settings/server-url-bottom-sh import { ThemeItem } from '@/components/settings/theme-item'; import { ToggleItem } from '@/components/settings/toggle-item'; import { UnitSelectionBottomSheet } from '@/components/settings/unit-selection-bottom-sheet'; -import { ScrollView } from '@/components/ui'; +import { FocusAwareStatusBar, ScrollView } from '@/components/ui'; import { Box } from '@/components/ui/box'; import { Card } from '@/components/ui/card'; import { Heading } from '@/components/ui/heading'; @@ -59,6 +59,7 @@ export default function Settings() { return ( + {/* App Info Section */} diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx index b1258927..e330a7d6 100644 --- a/src/app/_layout.tsx +++ b/src/app/_layout.tsx @@ -21,9 +21,9 @@ import { SafeAreaProvider } from 'react-native-safe-area-context'; import { APIProvider } from '@/api'; import { PostHogProviderWrapper } from '@/components/common/posthog-provider'; import { LiveKitBottomSheet } from '@/components/livekit'; -import { FocusAwareStatusBar } from '@/components/ui'; import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider'; import { loadKeepAliveState } from '@/lib/hooks/use-keep-alive'; +import { loadSelectedTheme } from '@/lib/hooks/use-selected-theme'; import { logger } from '@/lib/logging'; import { getDeviceUuid } from '@/lib/storage/app'; import { setDeviceUuid } from '@/lib/storage/app'; @@ -55,8 +55,10 @@ Sentry.init({ registerGlobals(); +// Load the selected theme from storage and apply it +loadSelectedTheme(); + //useAuth().hydrate(); -//loadSelectedTheme(); // Prevent the splash screen from auto-hiding before asset loading is complete. //SplashScreen.preventAutoHideAsync(); // Set the animation options. This is optional. @@ -129,7 +131,6 @@ function RootLayout() { return ( - setIsNotesModalOpen(false)} callId={callId} /> diff --git a/src/components/calls/__tests__/call-detail-menu-integration.test.tsx b/src/components/calls/__tests__/call-detail-menu-integration.test.tsx new file mode 100644 index 00000000..cff9ae2d --- /dev/null +++ b/src/components/calls/__tests__/call-detail-menu-integration.test.tsx @@ -0,0 +1,140 @@ +import { fireEvent, render, screen, waitFor } from '@testing-library/react-native'; +import React from 'react'; + +import { useCallDetailMenu } from '../call-detail-menu'; + +// Mock the i18next hook +jest.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => key, + }), +})); + +// Mock the UI components +jest.mock('@/components/ui/actionsheet', () => ({ + Actionsheet: ({ children, isOpen, testID }: { children: React.ReactNode; isOpen: boolean; testID?: string }) => { + const { View } = require('react-native'); + return isOpen ? {children} : null; + }, + ActionsheetBackdrop: ({ children }: { children: React.ReactNode }) => { + const { View } = require('react-native'); + return {children}; + }, + ActionsheetContent: ({ children }: { children: React.ReactNode }) => { + const { View } = require('react-native'); + return {children}; + }, + ActionsheetDragIndicator: () => { + const { View } = require('react-native'); + return ; + }, + ActionsheetDragIndicatorWrapper: ({ children }: { children: React.ReactNode }) => { + const { View } = require('react-native'); + return {children}; + }, + ActionsheetItem: ({ children, onPress, testID }: { children: React.ReactNode; onPress: () => void; testID?: string }) => { + const { TouchableOpacity } = require('react-native'); + return {children}; + }, + ActionsheetItemText: ({ children }: { children: React.ReactNode }) => { + const { Text } = require('react-native'); + return {children}; + }, +})); + +jest.mock('@/components/ui/hstack', () => ({ + HStack: ({ children }: { children: React.ReactNode }) => { + const { View } = require('react-native'); + return {children}; + }, +})); + +jest.mock('lucide-react-native', () => ({ + EditIcon: () => null, + XIcon: () => null, + MoreVerticalIcon: () => { + const { View } = require('react-native'); + return ; + }, +})); + +jest.mock('@/components/ui/', () => ({ + Pressable: ({ children, onPress, testID }: { children: React.ReactNode; onPress: () => void; testID?: string }) => { + const { TouchableOpacity } = require('react-native'); + return {children}; + }, +})); + +describe('Call Detail Menu Integration Test', () => { + const mockOnEditCall = jest.fn(); + const mockOnCloseCall = jest.fn(); + + const TestComponent = () => { + const { HeaderRightMenu, CallDetailActionSheet } = useCallDetailMenu({ + onEditCall: mockOnEditCall, + onCloseCall: mockOnCloseCall, + }); + + return ( + <> + + + + ); + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render the header menu button and actionsheet', () => { + render(); + + // Check if the kebab menu button is rendered + expect(screen.getByTestId('kebab-menu-button')).toBeTruthy(); + }); + + it('should open actionsheet when menu button is pressed', async () => { + render(); + + const menuButton = screen.getByTestId('kebab-menu-button'); + fireEvent.press(menuButton); + + // Wait for the actionsheet to appear + await waitFor(() => { + expect(screen.getByTestId('call-detail-actionsheet')).toBeTruthy(); + }); + }); + + it('should call onEditCall when edit button is pressed', async () => { + render(); + + // Open the menu + const menuButton = screen.getByTestId('kebab-menu-button'); + fireEvent.press(menuButton); + + // Wait for the actionsheet and press edit button + await waitFor(() => { + const editButton = screen.getByTestId('edit-call-button'); + fireEvent.press(editButton); + }); + + expect(mockOnEditCall).toHaveBeenCalledTimes(1); + }); + + it('should call onCloseCall when close button is pressed', async () => { + render(); + + // Open the menu + const menuButton = screen.getByTestId('kebab-menu-button'); + fireEvent.press(menuButton); + + // Wait for the actionsheet and press close button + await waitFor(() => { + const closeButton = screen.getByTestId('close-call-button'); + fireEvent.press(closeButton); + }); + + expect(mockOnCloseCall).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/components/calls/__tests__/call-files-modal.test.tsx b/src/components/calls/__tests__/call-files-modal.test.tsx new file mode 100644 index 00000000..c9f3452a --- /dev/null +++ b/src/components/calls/__tests__/call-files-modal.test.tsx @@ -0,0 +1,608 @@ +import React from 'react'; +import { render, fireEvent, waitFor } from '@testing-library/react-native'; +import { View, Text } from 'react-native'; +import { Alert } from 'react-native'; + +import { CallFilesModal } from '../call-files-modal'; + +// Mock the zustand store +const mockFetchCallFiles = jest.fn(); +const defaultMockFiles = [ + { + Id: 'file-1', + CallId: 'test-call-123', + Type: 3, + FileName: 'test-document.pdf', + Name: 'Test Document', + Size: 1024576, + Url: 'https://example.com/file1.pdf', + UserId: 'user-1', + Timestamp: '2023-01-15T10:30:00Z', + Mime: 'application/pdf', + Data: '', + }, + { + Id: 'file-2', + CallId: 'test-call-123', + Type: 3, + FileName: 'image.jpg', + Name: 'Photo Evidence', + Size: 2048000, + Url: 'https://example.com/file2.jpg', + UserId: 'user-2', + Timestamp: '2023-01-15T14:45:00Z', + Mime: 'image/jpeg', + Data: '', + }, +]; + +let mockStoreState: any = { + callFiles: defaultMockFiles, + isLoadingFiles: false, + errorFiles: null, + fetchCallFiles: mockFetchCallFiles, +}; + +jest.mock('@/stores/calls/detail-store', () => ({ + useCallDetailStore: () => mockStoreState, +})); + +// Mock expo modules +jest.mock('expo-file-system', () => ({ + documentDirectory: '/mock/documents/', + writeAsStringAsync: jest.fn(), + EncodingType: { + Base64: 'base64', + }, +})); + +jest.mock('expo-sharing', () => ({ + isAvailableAsync: jest.fn(() => Promise.resolve(true)), + shareAsync: jest.fn(() => Promise.resolve()), +})); + +// Mock the API call +jest.mock('@/api/calls/callFiles', () => ({ + getCallAttachmentFile: jest.fn(() => + Promise.resolve(new Blob(['test content'], { type: 'application/pdf' })) + ), +})); + +// Mock Alert +jest.spyOn(Alert, 'alert'); + +// Mock FileReader for testing +Object.defineProperty(global, 'FileReader', { + writable: true, + value: class MockFileReader { + static readonly EMPTY = 0; + static readonly LOADING = 1; + static readonly DONE = 2; + + result: string | ArrayBuffer | null = null; + readyState = 0; + onload: ((event: any) => void) | null = null; + + readAsDataURL(blob: Blob) { + // Simulate successful file read + setTimeout(() => { + this.result = 'data:application/pdf;base64,dGVzdCBjb250ZW50'; // base64 for "test content" + this.readyState = 2; // DONE + if (this.onload) this.onload(new Event('load') as any); + }, 0); + } + } +}); + +// Mock react-i18next +jest.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => { + const translations: { [key: string]: string } = { + 'calls.files.title': 'Call Files', + 'calls.files.no_files': 'No files available', + 'calls.files.no_files_description': 'No files have been added to this call yet', + 'calls.files.error': 'Error getting files', + 'calls.files.file_name': 'File Name', + 'calls.files.open_error': 'Error opening file', + 'calls.files.share_error': 'Error sharing file', + 'common.loading': 'Loading...', + 'common.retry': 'Retry', + }; + return translations[key] || key; + }, + }), +})); + +// Mock @gorhom/bottom-sheet +jest.mock('@gorhom/bottom-sheet', () => { + const React = require('react'); + const { View } = require('react-native'); + + const MockBottomSheet = React.forwardRef(({ children, onChange, index, ...props }: any, ref: any) => { + React.useImperativeHandle(ref, () => ({ + expand: jest.fn(), + close: jest.fn(), + snapToIndex: jest.fn(), + })); + + // Simulate sheet change when index changes + React.useEffect(() => { + if (onChange) { + onChange(index); + } + }, [index, onChange]); + + return ( + + {children} + + ); + }); + + const MockBottomSheetView = ({ children, ...props }: any) => ( + + {children} + + ); + + const MockBottomSheetBackdrop = ({ onPress, ...props }: any) => ( + + ); + + return { + __esModule: true, + default: MockBottomSheet, + BottomSheetView: MockBottomSheetView, + BottomSheetBackdrop: MockBottomSheetBackdrop, + }; +}); + +// Mock react-native-gesture-handler +jest.mock('react-native-gesture-handler', () => { + const { View } = require('react-native'); + return { + ScrollView: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +// Mock lucide-react-native +jest.mock('lucide-react-native', () => { + const { Text } = require('react-native'); + return { + X: (props: any) => ( + + X + + ), + File: (props: any) => ( + + File + + ), + Download: (props: any) => ( + + Download + + ), + }; +}); + +// Mock UI components +jest.mock('../../ui', () => { + const { View } = require('react-native'); + return { + FocusAwareStatusBar: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/box', () => { + const { View } = require('react-native'); + return { + Box: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/button', () => { + const { View, Text } = require('react-native'); + return { + Button: ({ children, onPress, testID, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/heading', () => { + const { Text } = require('react-native'); + return { + Heading: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/text', () => { + const { Text } = require('react-native'); + return { + Text: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/vstack', () => { + const { View } = require('react-native'); + return { + VStack: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/hstack', () => { + const { View } = require('react-native'); + return { + HStack: ({ children, ...props }: any) => ( + + {children} + + ), + }; +}); + +jest.mock('@/components/ui/spinner', () => { + const { Text } = require('react-native'); + return { + Spinner: ({ ...props }: any) => ( + + Loading... + + ), + }; +}); + +describe('CallFilesModal', () => { + const defaultProps = { + isOpen: false, + onClose: jest.fn(), + callId: 'test-call-123', + }; + + beforeEach(() => { + jest.clearAllMocks(); + // Reset to default state + mockStoreState = { + callFiles: defaultMockFiles, + isLoadingFiles: false, + errorFiles: null, + fetchCallFiles: mockFetchCallFiles, + }; + }); + + it('renders correctly when closed', () => { + const { getByTestId } = render(); + + expect(getByTestId('bottom-sheet')).toBeTruthy(); + expect(getByTestId('focus-aware-status-bar')).toBeTruthy(); + }); + + it('renders correctly when open', () => { + const { getByTestId, getByText } = render( + + ); + + expect(getByTestId('bottom-sheet')).toBeTruthy(); + expect(getByTestId('call-files-modal')).toBeTruthy(); + expect(getByText('Call Files')).toBeTruthy(); + }); + + it('calls fetchCallFiles when modal opens', () => { + render(); + expect(mockFetchCallFiles).toHaveBeenCalledWith('test-call-123'); + }); + + it('displays the correct title using i18n', () => { + const { getByText } = render( + + ); + + expect(getByText('Call Files')).toBeTruthy(); + }); + + it('displays file list when files are available', () => { + const { getByText, getByTestId } = render( + + ); + + expect(getByText('Test Document')).toBeTruthy(); + expect(getByText('Photo Evidence')).toBeTruthy(); + expect(getByTestId('file-item-file-1')).toBeTruthy(); + expect(getByTestId('file-item-file-2')).toBeTruthy(); + }); + + it('displays file details correctly', () => { + const { getByText } = render( + + ); + + // Check file sizes are displayed correctly + expect(getByText('1000.56 KB')).toBeTruthy(); // 1024576 bytes + expect(getByText('1.95 MB')).toBeTruthy(); // 2048000 bytes + }); + + it('calls onClose when close button is pressed', () => { + const mockOnClose = jest.fn(); + const { getByTestId } = render( + + ); + + const closeButton = getByTestId('close-button'); + fireEvent.press(closeButton); + + expect(mockOnClose).toHaveBeenCalledTimes(1); + }); + + it('has proper accessibility attributes', () => { + const { getByTestId } = render( + + ); + + const modal = getByTestId('call-files-modal'); + const closeButton = getByTestId('close-button'); + + expect(modal).toBeTruthy(); + expect(closeButton).toBeTruthy(); + }); + + it('renders the scrollable content area', () => { + const { getByTestId } = render( + + ); + + expect(getByTestId('scroll-view')).toBeTruthy(); + }); + + it('handles different call IDs correctly', () => { + const { rerender } = render( + + ); + + expect(mockFetchCallFiles).toHaveBeenCalledWith('call-1'); + + rerender(); + expect(mockFetchCallFiles).toHaveBeenCalledWith('call-2'); + }); + + it('maintains proper component structure', () => { + const { getByTestId, getAllByTestId } = render( + + ); + + // Check that all required components are present + expect(getByTestId('bottom-sheet')).toBeTruthy(); + expect(getByTestId('call-files-modal')).toBeTruthy(); // This is the BottomSheetView with testID + expect(getByTestId('heading')).toBeTruthy(); + expect(getByTestId('close-button')).toBeTruthy(); + expect(getByTestId('scroll-view')).toBeTruthy(); + expect(getAllByTestId('vstack').length).toBeGreaterThan(0); // Multiple VStack components exist + }); + + describe('Loading States', () => { + beforeEach(() => { + // Mock loading state + mockStoreState = { + callFiles: null, + isLoadingFiles: true, + errorFiles: null, + fetchCallFiles: mockFetchCallFiles, + }; + }); + + it('displays loading spinner when fetching files', () => { + const { getByTestId, getAllByText } = render( + + ); + + expect(getByTestId('spinner')).toBeTruthy(); + expect(getAllByText('Loading...').length).toBeGreaterThan(0); + }); + }); + + describe('Error States', () => { + beforeEach(() => { + // Mock error state + mockStoreState = { + callFiles: [], + isLoadingFiles: false, + errorFiles: 'Network error occurred', + fetchCallFiles: mockFetchCallFiles, + }; + }); + + it('displays error message when file fetch fails', () => { + const { getByText } = render( + + ); + + expect(getByText('Error getting files')).toBeTruthy(); + expect(getByText('Network error occurred')).toBeTruthy(); + }); + + it('allows retry on error', () => { + const { getByText } = render( + + ); + + const retryButton = getByText('Retry'); + fireEvent.press(retryButton); + + expect(mockFetchCallFiles).toHaveBeenCalledWith('test-call-123'); + }); + }); + + describe('Empty States', () => { + beforeEach(() => { + // Mock empty state + mockStoreState = { + callFiles: [], + isLoadingFiles: false, + errorFiles: null, + fetchCallFiles: mockFetchCallFiles, + }; + }); + + it('displays empty state when no files available', () => { + const { getByText, getByTestId } = render( + + ); + + expect(getByText('No files available')).toBeTruthy(); + expect(getByText('No files have been added to this call yet')).toBeTruthy(); + expect(getByTestId('file-icon')).toBeTruthy(); + }); + }); + + describe('File Download', () => { + const mockGetCallAttachmentFile = require('@/api/calls/callFiles').getCallAttachmentFile; + const mockWriteAsStringAsync = require('expo-file-system').writeAsStringAsync; + const mockShareAsync = require('expo-sharing').shareAsync; + + beforeEach(() => { + // Reset to default state with files + mockStoreState = { + callFiles: defaultMockFiles, + isLoadingFiles: false, + errorFiles: null, + fetchCallFiles: mockFetchCallFiles, + }; + }); + + it('downloads and shares file when clicked', async () => { + const { getByTestId } = render( + + ); + + const fileItem = getByTestId('file-item-file-1'); + fireEvent.press(fileItem); + + await waitFor(() => { + expect(mockGetCallAttachmentFile).toHaveBeenCalledWith( + 'https://example.com/file1.pdf', + expect.objectContaining({ + onEvent: expect.any(Function), + }) + ); + }); + + // Wait for FileReader and file operations to complete + await waitFor(() => { + expect(mockWriteAsStringAsync).toHaveBeenCalled(); + }, { timeout: 2000 }); + + await waitFor(() => { + expect(mockShareAsync).toHaveBeenCalled(); + }, { timeout: 2000 }); + }); + + it('handles download errors gracefully', async () => { + mockGetCallAttachmentFile.mockRejectedValueOnce(new Error('Download failed')); + + const { getByTestId } = render( + + ); + + const fileItem = getByTestId('file-item-file-1'); + fireEvent.press(fileItem); + + await waitFor(() => { + expect(Alert.alert).toHaveBeenCalledWith( + 'Error opening file', + 'Download failed' + ); + }); + }); + + it('shows downloading state when file is being downloaded', async () => { + // Clear all mocks before this test + mockGetCallAttachmentFile.mockClear(); + mockWriteAsStringAsync.mockClear(); + mockShareAsync.mockClear(); + + // Make the API call take some time + mockGetCallAttachmentFile.mockImplementation(() => + new Promise(resolve => setTimeout(() => resolve(new Blob(['test content'], { type: 'application/pdf' })), 100)) + ); + + const { getByTestId } = render( + + ); + + const fileItem = getByTestId('file-item-file-1'); + + // Click the file + fireEvent.press(fileItem); + + // Should call the API + await waitFor(() => { + expect(mockGetCallAttachmentFile).toHaveBeenCalled(); + }); + + // Wait for the download to complete + await waitFor(() => { + expect(mockWriteAsStringAsync).toHaveBeenCalled(); + }, { timeout: 2000 }); + }); + }); + + describe('File Format Utilities', () => { + beforeEach(() => { + // Reset to default state + mockStoreState = { + callFiles: defaultMockFiles, + isLoadingFiles: false, + errorFiles: null, + fetchCallFiles: mockFetchCallFiles, + }; + }); + + it('formats file sizes correctly', () => { + const { getByText } = render( + + ); + + // Test various file size formats + expect(getByText('1000.56 KB')).toBeTruthy(); // 1024576 bytes + expect(getByText('1.95 MB')).toBeTruthy(); // 2048000 bytes + }); + + it('formats timestamps correctly', () => { + const { getAllByText } = render( + + ); + + // Should display formatted dates (exact format may vary by locale) + const timestampElements = getAllByText(/1\/15\/2023/); + expect(timestampElements.length).toBeGreaterThan(0); + }); + }); +}); diff --git a/src/components/calls/__tests__/call-notes-modal-new.test.tsx b/src/components/calls/__tests__/call-notes-modal-new.test.tsx new file mode 100644 index 00000000..6ae11779 --- /dev/null +++ b/src/components/calls/__tests__/call-notes-modal-new.test.tsx @@ -0,0 +1,350 @@ +import React from 'react'; +import { render, fireEvent, waitFor } from '@testing-library/react-native'; +import { useTranslation } from 'react-i18next'; +import CallNotesModal from '../call-notes-modal'; +import { useAuthStore } from '@/lib/auth'; +import { useCallDetailStore } from '@/stores/calls/detail-store'; + +// Mock dependencies +jest.mock('react-i18next'); +jest.mock('@/lib/auth'); +jest.mock('@/stores/calls/detail-store'); + +// Mock navigation +jest.mock('@react-navigation/native', () => ({ + useIsFocused: () => true, + useNavigation: () => ({ + navigate: jest.fn(), + }), +})); + +// Mock nativewind +jest.mock('nativewind', () => ({ + useColorScheme: () => ({ colorScheme: 'light' }), + cssInterop: jest.fn(), +})); + +// Mock lucide-react-native icons +jest.mock('lucide-react-native', () => ({ + SearchIcon: 'SearchIcon', + X: 'X', +})); + +// Mock Loading component +jest.mock('../../common/loading', () => ({ + Loading: () => { + const { View, Text } = require('react-native'); + return Loading...; + }, +})); + +// Mock ZeroState component +jest.mock('../../common/zero-state', () => ({ + __esModule: true, + default: ({ heading }: { heading: string }) => { + const { View, Text } = require('react-native'); + return {heading}; + }, +})); + +// Mock FocusAwareStatusBar to avoid navigation issues +jest.mock('../../ui/focus-aware-status-bar', () => ({ + FocusAwareStatusBar: () => null, +})); + +// Mock react-native-keyboard-controller +jest.mock('react-native-keyboard-controller', () => ({ + KeyboardAwareScrollView: ({ children }: any) => { + const { View } = require('react-native'); + return {children}; + }, +})); + +// Mock react-native-gesture-handler +jest.mock('react-native-gesture-handler', () => ({ + ScrollView: ({ children, testID, ...props }: any) => { + const { ScrollView } = require('react-native'); + return {children}; + }, + PanGestureHandler: ({ children }: any) => children, + State: {}, +})); + +// Mock @gorhom/bottom-sheet +jest.mock('@gorhom/bottom-sheet', () => { + const React = require('react'); + const { View } = require('react-native'); + + return { + __esModule: true, + default: React.forwardRef(({ children, onChange, index }: any, ref: any) => { + React.useImperativeHandle(ref, () => ({ + expand: jest.fn(), + close: jest.fn(), + })); + + React.useEffect(() => { + if (onChange) onChange(index); + }, [index, onChange]); + + return {children}; + }), + BottomSheetView: ({ children }: any) => {children}, + BottomSheetBackdrop: ({ children }: any) => {children}, + }; +}); + +// Mock lucide-react-native icons +jest.mock('lucide-react-native', () => ({ + SearchIcon: 'SearchIcon', + X: 'X', +})); + +const mockUseTranslation = useTranslation as jest.MockedFunction; +const mockUseAuthStore = useAuthStore as jest.MockedFunction; +const mockUseCallDetailStore = useCallDetailStore as jest.MockedFunction; + +describe('CallNotesModal', () => { + const mockProps = { + isOpen: true, + onClose: jest.fn(), + callId: 'test-call-id', + }; + + const mockCallDetailStore = { + callNotes: [ + { + CallNoteId: '1', + Note: 'Test note 1', + FullName: 'John Doe', + TimestampFormatted: '2025-01-15 10:30 AM', + }, + { + CallNoteId: '2', + Note: 'Test note 2', + FullName: 'Jane Smith', + TimestampFormatted: '2025-01-15 11:00 AM', + }, + ], + addNote: jest.fn(), + searchNotes: jest.fn(), + isNotesLoading: false, + fetchCallNotes: jest.fn(), + }; + + const mockAuthStore = { + profile: { sub: 'user-123' }, + }; + + beforeEach(() => { + jest.clearAllMocks(); + + mockUseTranslation.mockReturnValue({ + t: (key: string) => { + const translations: { [key: string]: string } = { + 'callNotes.title': 'Call Notes', + 'callNotes.searchPlaceholder': 'Search notes...', + 'callNotes.addNotePlaceholder': 'Add a note...', + 'callNotes.addNote': 'Add Note', + }; + return translations[key] || key; + }, + } as any); + + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + searchNotes: jest.fn(() => mockCallDetailStore.callNotes), + }); + + mockUseAuthStore.mockReturnValue(mockAuthStore); + }); + + it('renders correctly when open', () => { + const { getByText, getByTestId } = render(); + + expect(getByText('Call Notes')).toBeTruthy(); + expect(getByTestId('close-button')).toBeTruthy(); + expect(getByText('Test note 1')).toBeTruthy(); + expect(getByText('Test note 2')).toBeTruthy(); + }); + + it('fetches call notes when opened', () => { + render(); + + expect(mockCallDetailStore.fetchCallNotes).toHaveBeenCalledWith('test-call-id'); + }); + + it('calls onClose when close button is pressed', () => { + const { getByTestId } = render(); + + fireEvent.press(getByTestId('close-button')); + + expect(mockProps.onClose).toHaveBeenCalled(); + }); + + it('renders correctly when closed', () => { + const { queryByText } = render(); + + // Bottom sheet should still render but with index -1 (closed) + expect(queryByText('Call Notes')).toBeTruthy(); + }); + + it('handles search input correctly', () => { + const mockSearchNotes = jest.fn(() => [mockCallDetailStore.callNotes[0]]); + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + searchNotes: mockSearchNotes, + }); + + const { getByPlaceholderText, getByText, queryByText } = render(); + + const searchInput = getByPlaceholderText('Search notes...'); + fireEvent.changeText(searchInput, 'Test note 1'); + + // Should show filtered results + expect(getByText('Test note 1')).toBeTruthy(); + expect(queryByText('Test note 2')).toBeFalsy(); + }); + + it('shows loading state correctly', () => { + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + isNotesLoading: true, + }); + + const { getByTestId } = render(); + + expect(getByTestId('loading')).toBeTruthy(); + }); + + it('shows zero state when no notes found', () => { + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + callNotes: [], + searchNotes: jest.fn(() => []), + }); + + const { getByText } = render(); + + expect(getByText('No notes found')).toBeTruthy(); + }); + + it('handles adding a new note', async () => { + const mockAddNote = jest.fn(); + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + addNote: mockAddNote, + searchNotes: jest.fn(() => mockCallDetailStore.callNotes), + }); + + const { getByPlaceholderText, getByText } = render(); + + const noteInput = getByPlaceholderText('Add a note...'); + const addButton = getByText('Add Note'); + + fireEvent.changeText(noteInput, 'New test note'); + fireEvent.press(addButton); + + await waitFor(() => { + expect(mockAddNote).toHaveBeenCalledWith('test-call-id', 'New test note', 'user-123', null, null); + }); + }); + + it('disables add button when note input is empty', () => { + const mockAddNote = jest.fn(); + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + addNote: mockAddNote, + searchNotes: jest.fn(() => mockCallDetailStore.callNotes), + }); + + const { getByText } = render(); + + const addButton = getByText('Add Note'); + + // Try to press the button when no note is entered - it should not call addNote + fireEvent.press(addButton); + + expect(mockAddNote).not.toHaveBeenCalled(); + }); + + it('disables add button when loading', () => { + const mockAddNote = jest.fn(); + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + addNote: mockAddNote, + isNotesLoading: true, + searchNotes: jest.fn(() => mockCallDetailStore.callNotes), + }); + + const { getByText, getByPlaceholderText } = render(); + + const noteInput = getByPlaceholderText('Add a note...'); + const addButton = getByText('Add Note'); + + fireEvent.changeText(noteInput, 'New test note'); + fireEvent.press(addButton); + + // Button should not call addNote when loading + expect(mockAddNote).not.toHaveBeenCalled(); + }); + + it('displays note author and timestamp correctly', () => { + const { getByText } = render(); + + expect(getByText('John Doe')).toBeTruthy(); + expect(getByText('2025-01-15 10:30 AM')).toBeTruthy(); + expect(getByText('Jane Smith')).toBeTruthy(); + expect(getByText('2025-01-15 11:00 AM')).toBeTruthy(); + }); + + it('clears note input after successful submission', async () => { + const mockAddNote = jest.fn().mockResolvedValue(undefined); + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + addNote: mockAddNote, + searchNotes: jest.fn(() => mockCallDetailStore.callNotes), + }); + + const { getByPlaceholderText, getByText } = render(); + + const noteInput = getByPlaceholderText('Add a note...'); + const addButton = getByText('Add Note'); + + fireEvent.changeText(noteInput, 'New test note'); + fireEvent.press(addButton); + + await waitFor(() => { + expect(noteInput.props.value).toBe(''); + }); + }); + + it('does not add empty note when only whitespace is entered', async () => { + const mockAddNote = jest.fn(); + mockUseCallDetailStore.mockReturnValue({ + ...mockCallDetailStore, + addNote: mockAddNote, + searchNotes: jest.fn(() => mockCallDetailStore.callNotes), + }); + + const { getByPlaceholderText, getByText } = render(); + + const noteInput = getByPlaceholderText('Add a note...'); + const addButton = getByText('Add Note'); + + fireEvent.changeText(noteInput, ' '); + fireEvent.press(addButton); + + expect(mockAddNote).not.toHaveBeenCalled(); + }); + + it('handles missing user profile gracefully', () => { + mockUseAuthStore.mockReturnValue({ + profile: null, + }); + + const { getByText } = render(); + + expect(getByText('Call Notes')).toBeTruthy(); + }); +}); diff --git a/src/components/calls/__tests__/call-notes-modal.test.tsx b/src/components/calls/__tests__/call-notes-modal.test.tsx index ce7c887f..1a3bde60 100644 --- a/src/components/calls/__tests__/call-notes-modal.test.tsx +++ b/src/components/calls/__tests__/call-notes-modal.test.tsx @@ -1,13 +1,41 @@ -import { fireEvent, render, screen } from '@testing-library/react-native'; import React from 'react'; +import { render, fireEvent, waitFor, screen } from '@testing-library/react-native'; +import { View, Text, TouchableOpacity } from 'react-native'; +import { useTranslation } from 'react-i18next'; +import CallNotesModal from '../call-notes-modal'; +import { useAuthStore } from '@/lib/auth'; +import { useCallDetailStore } from '@/stores/calls/detail-store'; -// --- Start of Robust Mocks --- -const View = (props: any) => React.createElement('div', { ...props }); -const Text = (props: any) => React.createElement('span', { ...props }); -const TouchableOpacity = (props: any) => React.createElement('button', { ...props, onClick: props.onPress }); -const ScrollView = (props: any) => React.createElement('div', { ...props }); -const TextInput = (props: any) => React.createElement('input', { ...props }); -// --- End of Robust Mocks --- +// Mock dependencies +jest.mock('react-i18next'); +jest.mock('@/lib/auth'); +jest.mock('@/stores/calls/detail-store'); +jest.mock('@gorhom/bottom-sheet', () => { + const React = require('react'); + const { View } = require('react-native'); + + return { + __esModule: true, + default: React.forwardRef(({ children, onChange, index }: any, ref: any) => { + React.useImperativeHandle(ref, () => ({ + expand: jest.fn(), + close: jest.fn(), + })); + + React.useEffect(() => { + if (onChange) onChange(index); + }, [index, onChange]); + + return {children}; + }), + BottomSheetView: ({ children }: any) => {children}, + BottomSheetBackdrop: ({ children }: any) => {children}, + }; +}); + +const mockUseTranslation = useTranslation as jest.MockedFunction; +const mockUseAuthStore = useAuthStore as jest.MockedFunction; +const mockUseCallDetailStore = useCallDetailStore as jest.MockedFunction; const MockCallNotesModal = ({ callId, isOpen, onClose }: any) => { if (!isOpen) return null; diff --git a/src/components/calls/call-detail-menu.tsx b/src/components/calls/call-detail-menu.tsx index 749a7422..e1240caa 100644 --- a/src/components/calls/call-detail-menu.tsx +++ b/src/components/calls/call-detail-menu.tsx @@ -16,21 +16,20 @@ export const useCallDetailMenu = ({ onEditCall, onCloseCall }: CallDetailMenuPro const [isKebabMenuOpen, setIsKebabMenuOpen] = useState(false); const openMenu = () => { - console.log('openMenu'); setIsKebabMenuOpen(true); }; const closeMenu = () => setIsKebabMenuOpen(false); const HeaderRightMenu = () => ( - + ); const CallDetailActionSheet = () => ( - + - + @@ -40,6 +39,7 @@ export const useCallDetailMenu = ({ onEditCall, onCloseCall }: CallDetailMenuPro closeMenu(); onEditCall(); }} + testID="edit-call-button" > @@ -52,6 +52,7 @@ export const useCallDetailMenu = ({ onEditCall, onCloseCall }: CallDetailMenuPro closeMenu(); onCloseCall(); }} + testID="close-call-button" > diff --git a/src/components/calls/call-files-modal.tsx b/src/components/calls/call-files-modal.tsx index a7a98a45..a16249b1 100644 --- a/src/components/calls/call-files-modal.tsx +++ b/src/components/calls/call-files-modal.tsx @@ -1,9 +1,25 @@ -import React from 'react'; +import type { BottomSheetBackdropProps } from '@gorhom/bottom-sheet'; +import BottomSheet, { BottomSheetBackdrop, BottomSheetView } from '@gorhom/bottom-sheet'; +import * as FileSystem from 'expo-file-system'; +import * as Sharing from 'expo-sharing'; +import { Download, File, X } from 'lucide-react-native'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Alert, Pressable } from 'react-native'; +import { ScrollView } from 'react-native-gesture-handler'; +import { getCallAttachmentFile } from '@/api/calls/callFiles'; +import { Box } from '@/components/ui/box'; +import { Button } from '@/components/ui/button'; import { Heading } from '@/components/ui/heading'; -import { Modal, ModalBackdrop, ModalBody, ModalContent, ModalHeader } from '@/components/ui/modal'; +import { HStack } from '@/components/ui/hstack'; +import { Spinner } from '@/components/ui/spinner'; import { Text } from '@/components/ui/text'; import { VStack } from '@/components/ui/vstack'; +import { type CallFileResultData } from '@/models/v4/callFiles/callFileResultData'; +import { useCallDetailStore } from '@/stores/calls/detail-store'; + +import { FocusAwareStatusBar } from '../ui'; interface CallFilesModalProps { isOpen: boolean; @@ -12,21 +28,225 @@ interface CallFilesModalProps { } export const CallFilesModal: React.FC = ({ isOpen, onClose, callId }) => { + const { t } = useTranslation(); + const { callFiles, isLoadingFiles, errorFiles, fetchCallFiles } = useCallDetailStore(); + const [downloadingFiles, setDownloadingFiles] = useState>({}); + + // Bottom sheet ref and snap points + const bottomSheetRef = useRef(null); + const snapPoints = useMemo(() => ['67%'], []); + + // Handle modal open/close + useEffect(() => { + if (isOpen) { + bottomSheetRef.current?.expand(); + fetchCallFiles(callId); + } else { + bottomSheetRef.current?.close(); + } + }, [isOpen, callId, fetchCallFiles]); + + // Handle sheet changes + const handleSheetChanges = useCallback( + (index: number) => { + if (index === -1) { + onClose(); + } + }, + [onClose] + ); + + // Render backdrop + const renderBackdrop = useCallback((props: BottomSheetBackdropProps) => , []); + + // Format file size for display + const formatFileSize = (bytes: number): string => { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + }; + + // Format date for display + const formatDate = (dateString: string): string => { + const date = new Date(dateString); + return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + }; + + // Download and open file + const handleDownloadFile = async (file: CallFileResultData) => { + if (!file.Url || downloadingFiles[file.Id]) return; + + try { + setDownloadingFiles((prev) => ({ ...prev, [file.Id]: 0 })); + + const fileData = await getCallAttachmentFile(file.Url, { + onEvent: (event) => { + if (event.type === 'progress' && event.progress !== undefined) { + setDownloadingFiles((prev) => ({ ...prev, [file.Id]: event.progress! })); + } + }, + }); + + // Create a temporary file + const fileName = file.FileName || file.Name || `file_${file.Id}`; + const fileUri = `${FileSystem.documentDirectory}${fileName}`; + + // Convert blob to base64 + const base64Data = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => { + const result = reader.result as string; + // Remove data URL prefix if present + const base64 = result.split(',')[1] || result; + resolve(base64); + }; + reader.onerror = reject; + reader.readAsDataURL(fileData); + }); + + // Write file to device + await FileSystem.writeAsStringAsync(fileUri, base64Data, { + encoding: FileSystem.EncodingType.Base64, + }); + + // Share/open the file + if (await Sharing.isAvailableAsync()) { + await Sharing.shareAsync(fileUri, { + mimeType: file.Mime || 'application/octet-stream', + dialogTitle: file.Name || file.FileName, + }); + } else { + Alert.alert(t('calls.files.share_error'), 'Sharing is not available on this device'); + } + + setDownloadingFiles((prev) => { + const newState = { ...prev }; + delete newState[file.Id]; + return newState; + }); + } catch (error) { + console.error('Error downloading file:', error); + Alert.alert(t('calls.files.open_error'), error instanceof Error ? error.message : 'Unknown error occurred'); + setDownloadingFiles((prev) => { + const newState = { ...prev }; + delete newState[file.Id]; + return newState; + }); + } + }; + + // Render individual file item + const renderFileItem = (file: CallFileResultData) => { + const isDownloading = downloadingFiles[file.Id] !== undefined; + const downloadProgress = downloadingFiles[file.Id] || 0; + + return ( + handleDownloadFile(file)} + className="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-800" + style={{ opacity: isDownloading ? 0.7 : 1 }} + testID={`file-item-${file.Id}`} + > + + + + + {file.Name || file.FileName || t('calls.files.file_name')} + + + {formatFileSize(file.Size)} + {file.Timestamp && {formatDate(file.Timestamp)}} + + + + {isDownloading ? ( + + + {Math.round(downloadProgress)}% + + ) : ( + + )} + + + + ); + }; + + // Render files list content + const renderFilesContent = () => { + if (isLoadingFiles) { + return ( + + + {t('common.loading')} + + ); + } + + if (errorFiles) { + return ( + + {t('calls.files.error')} + {errorFiles} + + + ); + } + + if (!callFiles || callFiles.length === 0) { + return ( + + + {t('calls.files.no_files')} + {t('calls.files.no_files_description')} + + ); + } + + return ( + + {callFiles.map(renderFileItem)} + + ); + }; + return ( - - - - - Call Files - - - - Files for call {callId} - {/* TODO: Implement file list functionality */} + <> + - - + + {/* Scrollable Files List */} + + {renderFilesContent()} + + + + ); }; diff --git a/src/components/calls/call-notes-modal.tsx b/src/components/calls/call-notes-modal.tsx index 06127841..c4f317de 100644 --- a/src/components/calls/call-notes-modal.tsx +++ b/src/components/calls/call-notes-modal.tsx @@ -1,7 +1,10 @@ +import type { BottomSheetBackdropProps } from '@gorhom/bottom-sheet'; +import BottomSheet, { BottomSheetBackdrop, BottomSheetView } from '@gorhom/bottom-sheet'; import { SearchIcon, X } from 'lucide-react-native'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Platform, ScrollView, useWindowDimensions } from 'react-native'; +import { Platform, useWindowDimensions } from 'react-native'; +import { ScrollView } from 'react-native-gesture-handler'; import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'; import { useAuthStore } from '@/lib/auth'; @@ -10,7 +13,6 @@ import { useCallDetailStore } from '@/stores/calls/detail-store'; import { Loading } from '../common/loading'; import ZeroState from '../common/zero-state'; import { FocusAwareStatusBar } from '../ui'; -import { Actionsheet, ActionsheetBackdrop, ActionsheetContent, ActionsheetDragIndicator, ActionsheetDragIndicatorWrapper } from '../ui/actionsheet'; import { Box } from '../ui/box'; import { Button, ButtonText } from '../ui/button'; import { Divider } from '../ui/divider'; @@ -36,12 +38,19 @@ const CallNotesModal = ({ isOpen, onClose, callId }: CallNotesModalProps) => { const [newNote, setNewNote] = useState(''); const { callNotes, addNote, searchNotes, isNotesLoading, fetchCallNotes } = useCallDetailStore(); const { profile } = useAuthStore(); - const { height, width } = useWindowDimensions(); + const { height } = useWindowDimensions(); + + // Bottom sheet ref and snap points + const bottomSheetRef = useRef(null); + const snapPoints = useMemo(() => ['67%'], []); // Fetch call notes when modal opens useEffect(() => { if (isOpen && callId) { fetchCallNotes(callId); + bottomSheetRef.current?.expand(); + } else { + bottomSheetRef.current?.close(); } }, [isOpen, callId, fetchCallNotes]); @@ -60,79 +69,96 @@ const CallNotesModal = ({ isOpen, onClose, callId }: CallNotesModalProps) => { } }; + // Handle sheet changes + const handleSheetChanges = useCallback( + (index: number) => { + if (index === -1) { + onClose(); + } + }, + [onClose] + ); + + // Render backdrop + const renderBackdrop = useCallback((props: BottomSheetBackdropProps) => , []); + return ( - + <> + {/* Fixed Footer - Always at bottom */} + + + + + + + + + + + + + ); }; diff --git a/src/components/calls/close-call-bottom-sheet.tsx b/src/components/calls/close-call-bottom-sheet.tsx index a5b4cb11..8121c7e0 100644 --- a/src/components/calls/close-call-bottom-sheet.tsx +++ b/src/components/calls/close-call-bottom-sheet.tsx @@ -1,6 +1,7 @@ import { useRouter } from 'expo-router'; import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { useWindowDimensions } from 'react-native'; import { CustomBottomSheet } from '@/components/ui/bottom-sheet'; import { Button, ButtonText } from '@/components/ui/button'; @@ -24,6 +25,8 @@ interface CloseCallBottomSheetProps { export const CloseCallBottomSheet: React.FC = ({ isOpen, onClose, callId, isLoading = false }) => { const { t } = useTranslation(); const router = useRouter(); + const { width, height } = useWindowDimensions(); + const isLandscape = width > height; const showToast = useToastStore((state) => state.showToast); const { closeCall } = useCallDetailStore(); const { fetchCalls } = useCallsStore(); @@ -113,11 +116,11 @@ export const CloseCallBottomSheet: React.FC = ({ isOp - - diff --git a/src/components/calls/dispatch-selection-modal.tsx b/src/components/calls/dispatch-selection-modal.tsx index 1c8d67ec..6edb4262 100644 --- a/src/components/calls/dispatch-selection-modal.tsx +++ b/src/components/calls/dispatch-selection-modal.tsx @@ -121,8 +121,9 @@ export const DispatchSelectionModal: React.FC = ({ toggleUser(user.Id)}> {selection.users.includes(user.Id) && } @@ -147,8 +148,9 @@ export const DispatchSelectionModal: React.FC = ({ toggleGroup(group.Id)}> {selection.groups.includes(group.Id) && } @@ -173,8 +175,9 @@ export const DispatchSelectionModal: React.FC = ({ toggleRole(role.Id)}> {selection.roles.includes(role.Id) && } @@ -199,8 +202,9 @@ export const DispatchSelectionModal: React.FC = ({ toggleUnit(unit.Id)}> {selection.units.includes(unit.Id) && } @@ -232,7 +236,7 @@ export const DispatchSelectionModal: React.FC = ({ - diff --git a/src/components/common/posthog-provider.tsx b/src/components/common/posthog-provider.tsx index 26eacb15..7f5b07f5 100644 --- a/src/components/common/posthog-provider.tsx +++ b/src/components/common/posthog-provider.tsx @@ -70,7 +70,7 @@ export const PostHogProviderWrapper: React.FC = ({ // Disable screen capture to avoid navigation state issues captureScreens: false, // Keep touch capture but be conservative - captureTouches: true, + captureTouches: false, // Don't pass navigationRef to avoid navigation state errors // navigationRef, }} diff --git a/src/components/contacts/contact-card.tsx b/src/components/contacts/contact-card.tsx index 502931c4..de2673d3 100644 --- a/src/components/contacts/contact-card.tsx +++ b/src/components/contacts/contact-card.tsx @@ -34,11 +34,13 @@ export const ContactCard: React.FC = ({ contact, onPress }) => return ( onPress(contact.ContactId)}> - + {contact.ImageUrl ? ( ) : ( - {contact.ContactType === ContactType.Person ? : } + + {contact.ContactType === ContactType.Person ? : } + )} diff --git a/src/components/contacts/contact-details-sheet.tsx b/src/components/contacts/contact-details-sheet.tsx index 0fd458c3..a662b94c 100644 --- a/src/components/contacts/contact-details-sheet.tsx +++ b/src/components/contacts/contact-details-sheet.tsx @@ -18,7 +18,7 @@ import { } from 'lucide-react-native'; import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ScrollView, View } from 'react-native'; +import { ScrollView, useWindowDimensions, View } from 'react-native'; import { Avatar, AvatarImage } from '@/components/ui/avatar'; import { ContactType } from '@/models/v4/contacts/contactResultData'; @@ -84,6 +84,8 @@ const ContactField: React.FC = ({ label, value, icon, isLink, export const ContactDetailsSheet: React.FC = () => { const { t } = useTranslation(); + const { width, height } = useWindowDimensions(); + const isLandscape = width > height; const { contacts, selectedContactId, isDetailsOpen, closeDetails } = useContactsStore(); const [activeTab, setActiveTab] = useState<'details' | 'notes'>('details'); @@ -184,11 +186,15 @@ export const ContactDetailsSheet: React.FC = () => { {/* Tab Navigation */} - setActiveTab('details')} className={`flex-1 rounded-md px-4 py-2 ${activeTab === 'details' ? 'bg-white shadow-sm dark:bg-gray-700' : ''}`}> - {t('contacts.tabs.details')} + setActiveTab('details')} className={`flex-1 rounded-md ${isLandscape ? 'px-4 py-2' : 'px-3 py-1.5'} ${activeTab === 'details' ? 'bg-white shadow-sm dark:bg-gray-700' : ''}`}> + + {t('contacts.tabs.details')} + - setActiveTab('notes')} className={`flex-1 rounded-md px-4 py-2 ${activeTab === 'notes' ? 'bg-white shadow-sm dark:bg-gray-700' : ''}`}> - {t('contacts.tabs.notes')} + setActiveTab('notes')} className={`flex-1 rounded-md ${isLandscape ? 'px-4 py-2' : 'px-3 py-1.5'} ${activeTab === 'notes' ? 'bg-white shadow-sm dark:bg-gray-700' : ''}`}> + + {t('contacts.tabs.notes')} + diff --git a/src/components/notifications/NotificationInbox.tsx b/src/components/notifications/NotificationInbox.tsx index 41ba4128..1c4c4dcd 100644 --- a/src/components/notifications/NotificationInbox.tsx +++ b/src/components/notifications/NotificationInbox.tsx @@ -4,6 +4,7 @@ import { colorScheme } from 'nativewind'; import React, { useEffect, useRef, useState } from 'react'; import { ActivityIndicator, Animated, Dimensions, FlatList, Platform, Pressable, RefreshControl, SafeAreaView, StatusBar, StyleSheet, View } from 'react-native'; +import { deleteMessage } from '@/api/novu/inbox'; import { NotificationDetail } from '@/components/notifications/NotificationDetail'; import { Button } from '@/components/ui/button'; import { Text } from '@/components/ui/text'; @@ -70,7 +71,7 @@ export const NotificationInbox = ({ isOpen, onClose }: NotificationInboxProps) = const handleDeleteNotification = async (_id: string) => { try { - // Since Novu doesn't provide a direct delete method, we'll just refetch to sync with server + await deleteMessage(_id); showToast('success', 'Notification removed'); refetch(); } catch (error) { diff --git a/src/components/settings/bluetooth-device-item.tsx b/src/components/settings/bluetooth-device-item.tsx index 93e75657..b5b6d803 100644 --- a/src/components/settings/bluetooth-device-item.tsx +++ b/src/components/settings/bluetooth-device-item.tsx @@ -40,7 +40,7 @@ export const BluetoothDeviceItem = () => { setShowDeviceSelection(true)} className="flex-1 flex-row items-center justify-between px-4 py-2"> - {t('bluetooth.audio_device')} + {t('bluetooth.audio_device')} {connectionStatus && {connectionStatus}} diff --git a/src/components/settings/bluetooth-device-selection-bottom-sheet.tsx b/src/components/settings/bluetooth-device-selection-bottom-sheet.tsx index 24dc35c3..40e8163a 100644 --- a/src/components/settings/bluetooth-device-selection-bottom-sheet.tsx +++ b/src/components/settings/bluetooth-device-selection-bottom-sheet.tsx @@ -1,7 +1,7 @@ import { BluetoothIcon, RefreshCwIcon, WifiIcon } from 'lucide-react-native'; import React, { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Alert } from 'react-native'; +import { Alert, useWindowDimensions } from 'react-native'; import { Box } from '@/components/ui/box'; import { Button, ButtonIcon, ButtonText } from '@/components/ui/button'; @@ -26,6 +26,8 @@ interface BluetoothDeviceSelectionBottomSheetProps { export function BluetoothDeviceSelectionBottomSheet({ isOpen, onClose }: BluetoothDeviceSelectionBottomSheetProps) { const { t } = useTranslation(); + const { width, height } = useWindowDimensions(); + const isLandscape = width > height; const { preferredDevice, setPreferredDevice } = usePreferredBluetoothDevice(); const { availableDevices, isScanning, bluetoothState, connectedDevice } = useBluetoothAudioStore(); const [hasScanned, setHasScanned] = useState(false); @@ -160,8 +162,8 @@ export function BluetoothDeviceSelectionBottomSheet({ isOpen, onClose }: Bluetoo {t('bluetooth.current_selection')} {preferredDevice.name} - @@ -170,9 +172,9 @@ export function BluetoothDeviceSelectionBottomSheet({ isOpen, onClose }: Bluetoo {/* Scan Button */} {t('bluetooth.available_devices')} - diff --git a/src/components/settings/item.tsx b/src/components/settings/item.tsx index 5233970d..06aeeda0 100644 --- a/src/components/settings/item.tsx +++ b/src/components/settings/item.tsx @@ -14,6 +14,8 @@ type ItemProps = { export const Item = ({ text, value, icon, onPress, textStyle }: ItemProps) => { const isPressable = onPress !== undefined; + const truncatedValue = value && value.length > 20 ? `${value.substring(0, 20)}...` : value; + return ( @@ -21,7 +23,7 @@ export const Item = ({ text, value, icon, onPress, textStyle }: ItemProps) => { {text} - {value} + {truncatedValue} {isPressable && ( diff --git a/src/components/settings/language-item.tsx b/src/components/settings/language-item.tsx index ec16aa83..8e78c86a 100644 --- a/src/components/settings/language-item.tsx +++ b/src/components/settings/language-item.tsx @@ -38,7 +38,7 @@ export const LanguageItem = () => { - + diff --git a/src/components/sidebar/call-sidebar.tsx b/src/components/sidebar/call-sidebar.tsx index 82e7027f..04687da5 100644 --- a/src/components/sidebar/call-sidebar.tsx +++ b/src/components/sidebar/call-sidebar.tsx @@ -146,8 +146,9 @@ export const SidebarCallCard = () => { await setActiveCall(call.CallId); setIsBottomSheetOpen(false); }} - className={`rounded-lg border p-4 ${colorScheme === 'dark' ? 'border-neutral-800 bg-neutral-800' : 'border-neutral-200 bg-neutral-50'} ${activeCall?.CallId === call.CallId ? (colorScheme === 'dark' ? 'bg-primary-900' : 'bg-primary-50') : '' - }`} + className={`rounded-lg border p-4 ${colorScheme === 'dark' ? 'border-neutral-800 bg-neutral-800' : 'border-neutral-200 bg-neutral-50'} ${ + activeCall?.CallId === call.CallId ? (colorScheme === 'dark' ? 'bg-primary-900' : 'bg-primary-50') : '' + }`} testID={`call-item-${call.CallId}`} > diff --git a/src/components/ui/button/index.tsx b/src/components/ui/button/index.tsx index ac721201..9927328e 100644 --- a/src/components/ui/button/index.tsx +++ b/src/components/ui/button/index.tsx @@ -120,11 +120,11 @@ const buttonTextStyle = tva({ solid: 'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0', }, size: { - xs: 'text-xs', - sm: 'text-sm', - md: 'text-base', - lg: 'text-lg', - xl: 'text-xl', + xs: 'text-2xs', + sm: 'text-xs', + md: 'text-sm', + lg: 'text-base', + xl: 'text-lg', }, }, parentCompoundVariants: [ diff --git a/src/components/ui/focus-aware-status-bar.tsx b/src/components/ui/focus-aware-status-bar.tsx index 379656a3..68769c6a 100644 --- a/src/components/ui/focus-aware-status-bar.tsx +++ b/src/components/ui/focus-aware-status-bar.tsx @@ -12,7 +12,7 @@ export const FocusAwareStatusBar = ({ hidden = false }: Props) => { React.useEffect(() => { if (Platform.OS === 'android') { // Make both status bar and navigation bar transparent - StatusBar.setBackgroundColor('transparent'); + //StatusBar.setBackgroundColor('transparent'); StatusBar.setTranslucent(true); // Set the system UI flags to hide navigation bar diff --git a/src/components/ui/shared-tabs.tsx b/src/components/ui/shared-tabs.tsx index c88532dd..82ccc1bd 100644 --- a/src/components/ui/shared-tabs.tsx +++ b/src/components/ui/shared-tabs.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ScrollView, StyleSheet } from 'react-native'; +import { ScrollView, StyleSheet, useWindowDimensions } from 'react-native'; import { create } from 'zustand'; import { Box } from '@/components/ui/box'; @@ -55,6 +55,8 @@ export const SharedTabs: React.FC = ({ const { t } = useTranslation(); const [localActiveIndex, setLocalActiveIndex] = useState(initialIndex); const { activeIndex, setActiveIndex } = useTabStore(); + const { width, height } = useWindowDimensions(); + const isLandscape = width > height; // Use local state if no external state management is needed const currentIndex = onChange ? activeIndex : localActiveIndex; @@ -77,9 +79,9 @@ export const SharedTabs: React.FC = ({ const baseStyles = 'flex-1 flex items-center justify-center'; const sizeStyles = { - sm: 'px-3 py-1.5 text-xs', - md: 'px-4 py-2 text-sm', - lg: 'px-5 py-2.5 text-base', + sm: isLandscape ? 'px-3 py-1.5 text-xs' : 'px-2 py-1 text-2xs', + md: isLandscape ? 'px-4 py-2 text-sm' : 'px-3 py-1.5 text-xs', + lg: isLandscape ? 'px-5 py-2.5 text-base' : 'px-4 py-2 text-sm', }[size]; const variantStyles = { @@ -128,10 +130,14 @@ export const SharedTabs: React.FC = ({ {tabs.map((tab, index) => ( handleTabPress(index)}> - {tab.icon && {tab.icon}} - {typeof tab.title === 'string' ? {t(tab.title)} : {tab.title}} + {tab.icon && {tab.icon}} + {typeof tab.title === 'string' ? ( + {t(tab.title)} + ) : ( + {tab.title} + )} {tab.badge !== undefined && tab.badge > 0 && ( - + {tab.badge} )} @@ -142,10 +148,14 @@ export const SharedTabs: React.FC = ({ {tabs.map((tab, index) => ( handleTabPress(index)}> - {tab.icon && {tab.icon}} - {typeof tab.title === 'string' ? {t(tab.title)} : {tab.title}} + {tab.icon && {tab.icon}} + {typeof tab.title === 'string' ? ( + {t(tab.title)} + ) : ( + {tab.title} + )} {tab.badge !== undefined && tab.badge > 0 && ( - + {tab.badge} )} diff --git a/src/lib/hooks/__tests__/use-selected-theme.test.ts b/src/lib/hooks/__tests__/use-selected-theme.test.ts new file mode 100644 index 00000000..93cf77a9 --- /dev/null +++ b/src/lib/hooks/__tests__/use-selected-theme.test.ts @@ -0,0 +1,89 @@ +import { colorScheme } from 'nativewind'; + +import { storage } from '../../storage'; +import { loadSelectedTheme, useSelectedTheme } from '../use-selected-theme'; + +// Mock the storage module +jest.mock('../../storage', () => ({ + storage: { + getString: jest.fn(), + set: jest.fn(), + }, +})); + +// Mock nativewind +jest.mock('nativewind', () => ({ + colorScheme: { + set: jest.fn(), + }, + useColorScheme: () => ({ + colorScheme: 'system', + setColorScheme: jest.fn(), + }), +})); + +// Mock react-native-mmkv +jest.mock('react-native-mmkv', () => ({ + useMMKVString: jest.fn(() => ['system', jest.fn()]), +})); + +const mockedStorage = storage as jest.Mocked; +const mockedColorScheme = colorScheme as jest.Mocked; + +describe('loadSelectedTheme', () => { + beforeEach(() => { + jest.clearAllMocks(); + console.log = jest.fn(); + console.error = jest.fn(); + }); + + it('should load and apply saved theme from storage', () => { + mockedStorage.getString.mockReturnValue('dark'); + + loadSelectedTheme(); + + expect(mockedStorage.getString).toHaveBeenCalledWith('SELECTED_THEME'); + expect(mockedColorScheme.set).toHaveBeenCalledWith('dark'); + expect(console.log).toHaveBeenCalledWith('Loading selected theme:', 'dark'); + }); + + it('should handle no saved theme gracefully', () => { + mockedStorage.getString.mockReturnValue(undefined); + + loadSelectedTheme(); + + expect(mockedStorage.getString).toHaveBeenCalledWith('SELECTED_THEME'); + expect(mockedColorScheme.set).not.toHaveBeenCalled(); + expect(console.log).toHaveBeenCalledWith('No custom theme found, using system default'); + }); + + it('should handle storage errors gracefully', () => { + const error = new Error('Storage error'); + mockedStorage.getString.mockImplementation(() => { + throw error; + }); + + loadSelectedTheme(); + + expect(console.error).toHaveBeenCalledWith('Failed to load selected theme:', error); + expect(mockedColorScheme.set).not.toHaveBeenCalled(); + }); + + it('should apply light theme correctly', () => { + mockedStorage.getString.mockReturnValue('light'); + + loadSelectedTheme(); + + expect(mockedColorScheme.set).toHaveBeenCalledWith('light'); + expect(console.log).toHaveBeenCalledWith('Loading selected theme:', 'light'); + }); + + it('should apply system theme correctly', () => { + mockedStorage.getString.mockReturnValue('system'); + + loadSelectedTheme(); + + expect(mockedColorScheme.set).toHaveBeenCalledWith('system'); + expect(console.log).toHaveBeenCalledWith('Loading selected theme:', 'system'); + }); +}); diff --git a/src/lib/hooks/use-selected-theme.tsx b/src/lib/hooks/use-selected-theme.tsx index a678e378..54a2e454 100644 --- a/src/lib/hooks/use-selected-theme.tsx +++ b/src/lib/hooks/use-selected-theme.tsx @@ -30,9 +30,15 @@ export const useSelectedTheme = () => { }; // to be used in the root file to load the selected theme from MMKV export const loadSelectedTheme = () => { - const theme = storage.getString(SELECTED_THEME); - if (theme !== undefined) { - console.log('theme', theme); - colorScheme.set(theme as ColorSchemeType); + try { + const theme = storage.getString(SELECTED_THEME); + if (theme !== undefined) { + console.log('Loading selected theme:', theme); + colorScheme.set(theme as ColorSchemeType); + } else { + console.log('No custom theme found, using system default'); + } + } catch (error) { + console.error('Failed to load selected theme:', error); } }; diff --git a/src/translations/ar.json b/src/translations/ar.json index dc943586..b12bd7d9 100644 --- a/src/translations/ar.json +++ b/src/translations/ar.json @@ -3,7 +3,7 @@ "title": "وحدة ريسغريد" }, "bluetooth": { - "audio_device": "جهاز الصوت بلوتوث", + "audio_device": "سماعة BT", "available_devices": "الأجهزة المتاحة", "bluetooth_not_ready": "البلوتوث {{state}}. يرجى تمكين البلوتوث.", "clear": "مسح", @@ -166,6 +166,11 @@ "edit_call": "تعديل المكالمة", "edit_call_description": "تحديث معلومات المكالمة", "everyone": "الجميع", + "files": { + "no_files": "لا توجد ملفات متاحة", + "no_files_description": "لم تتم إضافة أي ملفات إلى هذه المكالمة بعد", + "title": "ملفات المكالمة" + }, "geocoding_error": "فشل البحث عن العنوان، يرجى المحاولة مرة أخرى", "groups": "المجموعات", "loading": "جاري تحميل المكالمات...", @@ -248,6 +253,7 @@ "ok": "موافق", "permission_denied": "تم رفض الإذن", "remove": "إزالة", + "retry": "إعادة المحاولة", "route": "مسار", "save": "حفظ", "search": "بحث...", diff --git a/src/translations/en.json b/src/translations/en.json index 8ce03a38..7ba5d416 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3,7 +3,7 @@ "title": "Resgrid Unit" }, "bluetooth": { - "audio_device": "Bluetooth Audio Device", + "audio_device": "BT Handset", "available_devices": "Available Devices", "bluetooth_not_ready": "Bluetooth is {{state}}. Please enable Bluetooth.", "clear": "Clear", @@ -166,6 +166,11 @@ "edit_call": "Edit Call", "edit_call_description": "Update call information", "everyone": "Everyone", + "files": { + "no_files": "No files available", + "no_files_description": "No files have been added to this call yet", + "title": "Call Files" + }, "geocoding_error": "Failed to search for address, please try again", "groups": "Groups", "loading": "Loading calls...", @@ -248,6 +253,7 @@ "ok": "Ok", "permission_denied": "Permission denied", "remove": "Remove", + "retry": "Retry", "route": "Route", "save": "Save", "search": "Search...", diff --git a/src/translations/es.json b/src/translations/es.json index 08dfb2f5..9f306fc4 100644 --- a/src/translations/es.json +++ b/src/translations/es.json @@ -3,7 +3,7 @@ "title": "Resgrid Unit" }, "bluetooth": { - "audio_device": "Dispositivo de Audio Bluetooth", + "audio_device": "Auricular BT", "available_devices": "Dispositivos Disponibles", "bluetooth_not_ready": "Bluetooth está {{state}}. Por favor habilita Bluetooth.", "clear": "Limpiar", @@ -166,6 +166,11 @@ "edit_call": "Editar llamada", "edit_call_description": "Actualizar información de la llamada", "everyone": "Todos", + "files": { + "no_files": "No hay archivos disponibles", + "no_files_description": "No se han agregado archivos a esta llamada aún", + "title": "Archivos de llamada" + }, "geocoding_error": "Error al buscar la dirección, por favor inténtelo de nuevo", "groups": "Grupos", "loading": "Cargando llamadas...", @@ -248,6 +253,7 @@ "ok": "Ok", "permission_denied": "Permiso denegado", "remove": "Eliminar", + "retry": "Reintentar", "route": "Ruta", "save": "Guardar", "search": "Buscar...",