Skip to content

Commit 4655783

Browse files
committed
added tests for the typescript functions and the plugin, added jest configs
1 parent 817f75c commit 4655783

6 files changed

Lines changed: 160 additions & 5 deletions

File tree

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ jobs:
2828

2929
- name: Run typecheck
3030
run: npm run typecheck
31+
32+
- name: Run tests
33+
run: npm test

jest.config.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
transform: {
5+
'^.+\\.tsx?$': 'ts-jest',
6+
},
7+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
8+
testMatch: ['**/tests/**/*.test.ts', '**/tests/**/*.test.tsx'],
9+
transformIgnorePatterns: ['<rootDir>/node_modules/'],
10+
globals: {
11+
'ts-jest': {
12+
tsconfig: 'tsconfig.json',
13+
},
14+
},
15+
};
16+

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const MotionActivityTracker = require('../src/MotionActivityTrackerModule');
2+
3+
4+
jest.mock('../src/MotionActivityTrackerModule.ts', () => ({
5+
startTracking: jest.fn(() => Promise.resolve('tracking started')),
6+
stopTracking: jest.fn(() => 'tracking stopped'),
7+
getHistoricalDataIos: jest.fn((startDate, endDate) =>
8+
Promise.resolve([
9+
{ walking: true, running: false, timestamp: 123456789, confidence: 'high' },
10+
]),
11+
),
12+
addMotionStateChangeListener: jest.fn((callback) => {
13+
callback({ state: 'walking' });
14+
return { remove: jest.fn() };
15+
}),
16+
}));
17+
18+
describe('MotionActivityTracker', () => {
19+
test('should start tracking', async () => {
20+
const result = await MotionActivityTracker.startTracking();
21+
expect(result).toBe('tracking started');
22+
});
23+
24+
test('should stop tracking', () => {
25+
const result = MotionActivityTracker.stopTracking();
26+
expect(result).toBe('tracking stopped');
27+
});
28+
29+
test('should fetch historical data', async () => {
30+
const startDate = new Date(Date.now() - 1000 * 60 * 60); // 1 hour ago
31+
const endDate = new Date();
32+
const data = await MotionActivityTracker.getHistoricalDataIos(startDate, endDate);
33+
expect(data).toHaveLength(1);
34+
expect(data[0]).toHaveProperty('walking', true);
35+
});
36+
37+
test('should call listener on state change', () => {
38+
const mockListener = jest.fn();
39+
const subscription = MotionActivityTracker.addMotionStateChangeListener(mockListener);
40+
expect(mockListener).toHaveBeenCalledWith({ state: 'walking' });
41+
subscription.remove();
42+
});
43+
});
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { withInfoPlist, withAndroidManifest } from "@expo/config-plugins";
2+
import withMotionActivityPermissions from "../config-plugin/withMotionActivityPermissions";
3+
import type { ExpoConfig } from "@expo/config-types";
4+
5+
interface ExpoConfigWithModResults extends ExpoConfig {
6+
modResults?: {
7+
// For iOS
8+
NSMotionUsageDescription?: string;
9+
// For Android
10+
manifest?: {
11+
"uses-permission"?: Array<{ $: { "android:name": string } }>;
12+
};
13+
};
14+
}
15+
16+
jest.mock("@expo/config-plugins", () => ({
17+
withInfoPlist: jest.fn((config, callback) => {
18+
const updatedConfig = {
19+
...config,
20+
modResults: {
21+
...config.modResults,
22+
NSMotionUsageDescription: undefined,
23+
},
24+
};
25+
const modifiedConfig = callback(updatedConfig);
26+
return {
27+
...config,
28+
modResults: { ...updatedConfig.modResults, ...modifiedConfig.modResults },
29+
};
30+
}),
31+
withAndroidManifest: jest.fn((config, callback) => {
32+
const updatedConfig = {
33+
...config,
34+
modResults: {
35+
...config.modResults,
36+
manifest: {
37+
...config.modResults?.manifest,
38+
"uses-permission": [],
39+
},
40+
},
41+
};
42+
const modifiedConfig = callback(updatedConfig);
43+
return {
44+
...config,
45+
modResults: { ...updatedConfig.modResults, ...modifiedConfig.modResults },
46+
};
47+
}),
48+
}));
49+
50+
describe("withMotionActivityPermissions", () => {
51+
it("should add iOS motion activity permissions", () => {
52+
const config: ExpoConfigWithModResults = {
53+
name: "mock-app",
54+
slug: "mock-app",
55+
modResults: {
56+
NSMotionUsageDescription: undefined,
57+
},
58+
};
59+
60+
const updatedConfig: ExpoConfigWithModResults =
61+
withMotionActivityPermissions(config);
62+
63+
expect(updatedConfig.modResults?.NSMotionUsageDescription).toBe(
64+
"This app uses motion activity tracking."
65+
);
66+
67+
expect(withInfoPlist).toHaveBeenCalled();
68+
});
69+
70+
it("should add Android motion activity recognition permission", () => {
71+
const config: ExpoConfigWithModResults = {
72+
name: "mock-app",
73+
slug: "mock-app",
74+
modResults: {
75+
manifest: {
76+
"uses-permission": [],
77+
},
78+
},
79+
};
80+
81+
const updatedConfig: ExpoConfigWithModResults =
82+
withMotionActivityPermissions(config);
83+
84+
const permissions = updatedConfig.modResults?.manifest?.["uses-permission"];
85+
expect(permissions).toEqual(
86+
expect.arrayContaining([
87+
{ $: { "android:name": "android.permission.ACTIVITY_RECOGNITION" } },
88+
])
89+
);
90+
91+
expect(withAndroidManifest).toHaveBeenCalled();
92+
});
93+
});

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"compilerOptions": {
55
"outDir": "./build"
66
},
7-
"include": ["./src"],
7+
"include": ["./src", "./tests"],
88
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
99
}

0 commit comments

Comments
 (0)