Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Adds SDK unit tests and CI task #105

Merged
merged 19 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .github/workflows/sdk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,28 @@ jobs:
- name: Run npm Install
run: npm install

# TODO: Check Lint
- name: Unit Tests
run: npm run test
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved

# Checks code formatting, fails if there are changes after applying prettier.
# Based on this example here:
# https://github.com/creyD/prettier_action?tab=readme-ov-file#example-4-dry-run
prettier:
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Make sure the actual branch is checked out when running on pull requests
ref: ${{ github.head_ref }}
# Make sure the value of GITHUB_TOKEN will not be persisted in repo's config
persist-credentials: false

- name: Prettify code
uses: creyD/[email protected]
with:
# "dry" causes that if any file is modified, the job fails
dry: True
# "write" performs changes in place
prettier_options: --write sdk/**/*.js sdk/**/*.ts sdk/**/*.tsx
github_token: ${{ secrets.PERSONAL_GITHUB_TOKEN }}
17 changes: 17 additions & 0 deletions sdk/__mocks__/@react-native-async-storage/async-storage.js
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export * from '@react-native-async-storage/async-storage/jest/async-storage-mock';

var storage = {};

export default {
getItem: (item, value = null) => {
return new Promise((resolve, reject) => {
storage[item] ? resolve(storage[item]) : resolve(value);
});
},
setItem: (item, value) => {
return new Promise((resolve, reject) => {
storage[item] = value;
resolve(value);
});
}
};
5 changes: 5 additions & 0 deletions sdk/__mocks__/RaygunNativeBridge.js
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { NativeModules } from 'react-native';

NativeModules.RaygunNativeBridge = {
DEVICE_ID: '1234567890'
};
60 changes: 60 additions & 0 deletions sdk/__tests__/RaygunClient.test.tsx
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { init, sendError } from '../src/RaygunClient';
import { RaygunClientOptions } from '../src/Types';

describe('RaygunClient', () => {
beforeAll(() => {
const options: RaygunClientOptions = {
apiKey: 'ABCD',
version: '1.2.3',
logLevel: 'off',
enableCrashReporting: true,
enableRealUserMonitoring: false,
disableNativeCrashReporting: true
};
init(options);

global.fetch = jest.fn(() =>
Promise.resolve({
status: 200
})
);
});

beforeEach(() => {
fetch.mockClear();
});

it('should send error correctly', async () => {
const error = new Error('Test error');
await sendError(error);

// fetch should be called once
expect(fetch).toHaveBeenCalledTimes(1);

// Check url correct
expect(fetch.mock.calls[0][0]).toBe('https://api.raygun.com/entries?apiKey=ABCD');

// Capture body from fetch and check if correct
const body = JSON.parse(fetch.mock.calls[0][1].body);
expect(body.Details.Error.Message).toBe('Test error');

// Check if the version is correct
expect(body.Details.Version).toBe('1.2.3');
});

it('should fail to send error', async () => {
fetch.mockImplementationOnce(() => Promise.reject('API is down'));
const error = new Error('Failed error');
await sendError(error);

expect(fetch).toHaveBeenCalledTimes(1);

// failed to send error should be stored in AsyncStorage
const storedErrors = await AsyncStorage.getItem('raygun4reactnative_local_storage');
expect(storedErrors).not.toBeNull();

const errors = JSON.parse(storedErrors);
expect(errors[0].Details.Error.Message).toBe('Failed error');
});
});
4 changes: 4 additions & 0 deletions sdk/babel.config.js
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['babel-plugin-syntax-hermes-parser']
};
12 changes: 6 additions & 6 deletions sdk/jest.config.js
TheRealAgentK marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/src'],
preset: 'react-native',
transform: {
'^.+\\.tsx?$': 'ts-jest'
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { rootMode: 'upward' }]
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
clearMocks: true
transformIgnorePatterns: [
'node_modules/(?!(react-native|@react-native|react-navigation|@react-navigation|@react-native-community|@react-native-firebase|@react-navigation/stack|@react-navigation/bottom-tabs|@react-navigation/drawer|@react-navigation/native|@react-navigation/material-bottom-tabs|@react-navigation/material-top-tabs|@react-navigation/stack|@react-navigation/web))'
],
setupFiles: ['./__mocks__/RaygunNativeBridge.js']
};
6 changes: 5 additions & 1 deletion sdk/package.json
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding dev dependencies for running tests, as well as fixed the prettier command to include tests and mocks

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"run_demo_3:windows": "cd ../demo && npx react-native run-android",
"run_demo_3:macos": "cd ../demo && cd ios && pod install && cd ../ && npx react-native run-ios",
"run_demo_3:linux": "cd ../demo && gnome-terminal -x bash -c \"npx react-native start\" && npx react-native run-android",
"prettier": "npx prettier --write src"
"prettier": "npx prettier --write **/*.js __mocks__/**/*.js **/*.ts **/*.tsx",
"test": "jest"
},
"repository": {
"type": "git",
Expand All @@ -54,6 +55,8 @@
"@types/react-native": "^0.72.8",
"@typescript-eslint/eslint-plugin": "^8.13.0",
"@typescript-eslint/parser": "^8.13.0",
"babel-plugin-syntax-hermes-parser": "^0.25.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"copyfiles": "^2.4.1",
"eslint": "^9.14.0",
"eslint-config-google": "^0.14.0",
Expand All @@ -66,6 +69,7 @@
"glob": "^11.0.0",
"jest": "^29.7.0",
"jest-fetch-mock": "^3.0.3",
"metro-react-native-babel-preset": "^0.77.0",
"mockdate": "^3.0.2",
"react": "^18.3.1",
"react-native": "^0.76.1",
Expand Down
2 changes: 1 addition & 1 deletion sdk/react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
platforms: {
ios: {},
android: {
packageInstance: "new RaygunNativeBridgePackage()"
packageInstance: 'new RaygunNativeBridgePackage()'
}
}
}
Expand Down
Loading
Loading