From ed826bb247d0427fb9e7074c86927886ead79c8a Mon Sep 17 00:00:00 2001
From: kibagateaux <kibagateaux@gmail.com>
Date: Sat, 9 Dec 2023 18:44:45 -0600
Subject: [PATCH] finalize initial android health tests

---
 __mocks__/react-native-health-connect.js      |  4 +-
 package.json                                  |  3 +
 setupTest.js => setupTests.js                 |  0
 .../__tests__/android-health-connect.test.ts  | 83 ++++++++++---------
 src/utils/inventory/android-health-connect.ts | 21 ++---
 5 files changed, 57 insertions(+), 54 deletions(-)
 rename setupTest.js => setupTests.js (100%)

diff --git a/__mocks__/react-native-health-connect.js b/__mocks__/react-native-health-connect.js
index 5264045..1d62660 100644
--- a/__mocks__/react-native-health-connect.js
+++ b/__mocks__/react-native-health-connect.js
@@ -1,8 +1,8 @@
 module.exports = {
     openHealthConnectSettings: jest.fn(),
     // assume installed for testing purposes. not worth getting into weeds
-    initialize: () => true,
-    getSdkStatus: () => 3,
+    initialize: jest.fn(),
+    getSdkStatus: jest.fn(),
     requestPermission: jest.fn(),
     readRecords: jest.fn(),
     revokeAllPermissions: jest.fn(),
diff --git a/package.json b/package.json
index c2e099e..3534acb 100644
--- a/package.json
+++ b/package.json
@@ -96,6 +96,9 @@
   },
   "jest": {
     "preset": "jest-expo",
+    "setupFiles": [
+      "<rootDir>/setupTests.js"
+    ],
     "transformIgnorePatterns": [
       "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
     ]
diff --git a/setupTest.js b/setupTests.js
similarity index 100%
rename from setupTest.js
rename to setupTests.js
diff --git a/src/utils/inventory/__tests__/android-health-connect.test.ts b/src/utils/inventory/__tests__/android-health-connect.test.ts
index 4dec5d1..61e8ad4 100644
--- a/src/utils/inventory/__tests__/android-health-connect.test.ts
+++ b/src/utils/inventory/__tests__/android-health-connect.test.ts
@@ -1,13 +1,11 @@
 import item from '../android-health-connect';
 import mockHealth from 'react-native-health-connect';
-import Permission from 'react-native-health-connect/types';
 
 jest.mock('react-native-health-connect');
 
 beforeEach(() => {
-    // assume app installed for simplicity of testing.
-    // manually override when needed
-    item.checkEligibility = async () => true;
+    mockHealth.initialize.mockResolvedValue(true);
+    mockHealth.getSdkStatus.mockResolvedValue(3);
 });
 
 describe('InventoryItem', () => {
@@ -46,73 +44,82 @@ describe('checkEligibility', () => {
     //         getSdkStatus: () => 1,
     //     expect(await item.checkEligibility()).toBe(true);
     // });
-    // it('should return false if SDK is not available', async () => {
-    //         getSdkStatus: () => 1,
-    //     expect(await item.checkEligibility()).toBe(false);
-    // });
-    // it('should throw error if SDK fails to initialize', async () => {
-    //         getSdkStatus: () => 3,
-    //         initialize: () => false,
-    //     expect(await item.checkEligibility()).rejects.toThrow('Unable to initialize Android Health');
-    // });
+
+    it('should return false if SDK is not available', async () => {
+        mockHealth.getSdkStatus.mockResolvedValue(1);
+        expect(await item.checkEligibility()).toBe(false);
+    });
+
+    it('should throw error if SDK fails to initialize', async () => {
+        mockHealth.initialize.mockResolvedValue(false);
+        // await on outside so error is caught by expect instead of run in program
+        await expect(item.checkEligibility()).rejects.toThrow(
+            'Unable to initialize Android Health',
+        );
+    });
 });
 
 describe('initPermissions', () => {
-    it('should return false if checkEligibility returns false', async () => {
-        item.checkEligibility = async () => false;
-        // mockHealth.requestPermission = async (perms) => perms;
-        expect(await item.initPermissions()).toBe(false);
-    });
+    // TODO figure out how to mock our own func for testing uninstalled items
+    // it('should return false if checkEligibility returns false', async () => {
+    //     item.checkEligibility = async () => false;
+    //     // mockHealth.requestPermission.mockImplementation(mockResolvedValue(item.permissions);
+    //     expect(await item.initPermissions()).toBe(false);
+    // });
 
     it('should return true if permissions are granted', async () => {
         item.checkEligibility = async () => true;
-        // mockHealth.requestPermission = async (perms) => perms;
-        mockHealth.getGrantedPermissions = async () => item.permissions as Permission[];
+        mockHealth.requestPermission.mockResolvedValue(['Steps']);
+        mockHealth.getGrantedPermissions.mockResolvedValue(['Steps']);
         expect(await item.initPermissions()).toBe(true);
     });
 
     it('should return false if permissions are not granted', async () => {
-        mockHealth.requestPermission = async () => [];
-        mockHealth.getGrantedPermissions = async () => [];
+        mockHealth.requestPermission.mockResolvedValue([]);
+        mockHealth.getGrantedPermissions.mockResolvedValue([]);
         expect(await item.initPermissions()).toBe(false);
     });
 });
 
 describe('getPermissions', () => {
-    it('should return false if checkEligibility returns false', async () => {
-        item.checkEligibility = async () => false;
-        // mockHealth.requestPermission = async (perms) => perms;
-        mockHealth.getGrantedPermissions = async () => item.permissions as Permission[];
-        expect(await item.getPermissions()).toBe(false);
-    });
+    // TODO figure out how to mock our own func for testing uninstalled items
+    // it('should return false if checkEligibility returns false', async () => {
+    //     item.checkEligibility = async () => false;
+    //     // mockHealth.requestPermission.mockImplementation(mockResolvedValue(item.permissions);
+    //     mockHealth.getGrantedPermissions.mockImplementation(async () => mockResolvedValue.item.permissions);
+    //     expect(await item.getPermissions()).toBe(false);
+    // });
 
     it('should return false if no permissions are granted', async () => {
-        // mockHealth.requestPermission = async (perms) => perms;
-        mockHealth.getGrantedPermissions = async () => [];
+        // mockHealth.requestPermission.mockImplementation(mockResolvedValue(item.permissions);
+        mockHealth.getGrantedPermissions.mockResolvedValue([]);
         expect(await item.getPermissions()).toBe(false);
     });
 
     it('should return true if permissions are granted', async () => {
-        // mockHealth.requestPermission = async (perms) => perms;
-        mockHealth.getGrantedPermissions = async () => item.permissions as Permission[];
+        // mockHealth.requestPermission.mockImplementation(mockResolvedValue(item.permissions);
+        mockHealth.getGrantedPermissions.mockResolvedValue(item.permissions);
         expect(await item.getPermissions()).toBe(true);
     });
 });
 
 describe('equip', () => {
-    it('should return false if checkEligibility returns false', async () => {
-        item.checkEligibility = async () => false;
-        console.log('equip eligible', await item.checkEligibility());
-        expect(await item.equip()).toBe(false);
-    });
+    // TODO figure out how to mock our own func for testing uninstalled items
+    // it('should return false if checkEligibility returns false', async () => {
+    //     item.checkEligibility = async () => false;
+    //     console.log('equip eligible', await item.checkEligibility());
+    //     expect(await item.equip()).toBe(false);
+    // });
 
     it('should return true if permissions are initialized', async () => {
+        mockHealth.requestPermission.mockResolvedValue(['Steps']);
         item.initPermissions = async () => true;
         expect(await item.equip()).toBe(true);
     });
 
     it('should return false if permissions are not initialized', async () => {
-        (item.initPermissions = async () => false), expect(await item.equip()).toBe(false);
+        mockHealth.requestPermission.mockResolvedValue([]);
+        expect(await item.equip()).toBe(false);
     });
 });
 
diff --git a/src/utils/inventory/android-health-connect.ts b/src/utils/inventory/android-health-connect.ts
index 2886251..d75aca7 100644
--- a/src/utils/inventory/android-health-connect.ts
+++ b/src/utils/inventory/android-health-connect.ts
@@ -29,6 +29,7 @@ import {
     GetHealthDataProps,
     QueryAndroidHealthDataProps,
 } from 'types/HealthData';
+import { JsonMap } from '@segment/analytics-react-native';
 
 const ITEM_ID = 'AndroidHealthConnect';
 const PERMISSIONS = [
@@ -76,16 +77,7 @@ const checkEligibility = async (): Promise<boolean> => {
 };
 
 const getPermissions = async () => {
-    try {
-        if (!(await checkEligibility())) {
-            console.log('Android Health is not available on this device');
-            return false;
-        }
-    } catch (e: unknown) {
-        console.log('Inv:AndroidHealthConnect:checkElig: ', e);
-        debug(e);
-        return false;
-    }
+    if (!(await checkEligibility())) return false;
 
     try {
         const grantedPerms = await getGrantedPermissions();
@@ -108,8 +100,10 @@ const getPermissions = async () => {
 const initPermissions = async () => {
     if (!(await checkEligibility())) return false;
     try {
-        console.log('Inv:andoird-health-connect:Init');
-        const permissions = await requestPermission(PERMISSIONS);
+        const permissions = (await requestPermission(PERMISSIONS)) as object[] as JsonMap[];
+        console.log('Inv:andoird-health-connect:Init', permissions);
+        if (!permissions?.length) return false;
+
         track(TRACK_PERMS_REQUESTED, { itemId: ITEM_ID, permissions });
         console.log('Inv:AndroidHealthConnect:Init: Permissions Granted!', permissions);
         return true;
@@ -129,9 +123,8 @@ const equip: HoF = async () => {
     if (!(await checkEligibility())) return false;
 
     try {
-        await initPermissions();
+        return await initPermissions();
         // TODO return array of string for permissions granted
-        return true;
     } catch (e: unknown) {
         console.log('Error requesting permissions: ', e);
         debug(e);