Skip to content

Commit

Permalink
Feature/improved location tracking and time intersection algorithms (#…
Browse files Browse the repository at this point in the history
…195)

- move localization to server based data (fallback to local data).
- missing some typing fixes.
- moved also notifications and external links to texts.
- algorithm done.
- moved logic to service.
- moved params to config.
- initiate config in background services.
- fixed change language title issue.
- added scroll to change language.
- fixed missing short language text for added language.
- fixed google-services mismatch.
- removed unnecessary code.
- fixed failed tests.
- fixed eslint configuration.
- added close option for 'not forced' version update.
- replaced to animated hamagen logo in main screen.
- fixed 'no data' screen not showing although GPS is off.
- fixed logout from google if getting timeline data fails.
- added auto retry to avoid failed timeline fetch on first try in iOS.
- fix force update to not show if app version > server version.
- add scheme to run ios script.
- mock native modules
- removed firebase analytics.
- fixed exposure to show the latest between sick startTime and user startTime.
- exposures flow screen UI refactor.
- fixed foreground timer interval.
- add WifiMacAddressDatabase, UserLocationsDatabase, IntersectionSickDatabase mockImplementation to setup file
- tracker test pass again
- fix for HV points overriding the last point in DB.
- fix for unignored sample locations.
- move firebase mock from setup to __mocks__
- fixed transistor SDK ignore params.
- fixed wrong velocity calculations.
- MC-95.
- MC-94.
- MC-7.
- MC-33.
- MC-36.
- MC-93.
- updateDBAccordingToSampleVelocity UT
- extened Database mock
- add check for onError functon to not call
- accessibility fixes.
- fixed #159.
- fixed #155.
- fixed #177.
- fixed #150, #160.
- updated texts file.
- check with v2 force updates params from server.
- crash fix.
- disabled hermes.
- added headless task to background geolocation.
- move error check to afterAll function and add with multiple points from db test
- Add test to SampleService (#186)
- add scheme to run ios script
- mock native modules
- linting, removing unnecessary code.
- move redux-mock-store to dev dependencies
- fixed google timeline logout.
- clear cookies after flow completed (whatever the result is).
- add locale action test
- fix for failed tests.
- fix for BG geolocation headless callback.
- improved BG geolocation config.
- bumped versions.
- another fix to BG geolocation config.
- add axios simple mock
- updated texts.
- add axios mock
- ignore locations with timestamp earlier then the last location saved.
- add moment mock
- add LocationHistoryService test start
- insertToSampleDB tests
- add sha256 mock
- change store dispatch to return value only in tracker test
- LocationHistoryService test and new mocks
- fix updateDBAccordingToSampleVelocity failing tests
- updated config.

Co-authored-by: YossiGreen <>
Co-authored-by: Sagiv Stekolshik <[email protected]>
Co-authored-by: sagivStekolshik <[email protected]>
Co-authored-by: SagivOnoApps <[email protected]>
  • Loading branch information
4 people authored Apr 19, 2020
1 parent b72fbcc commit 09293b8
Show file tree
Hide file tree
Showing 82 changed files with 2,445 additions and 1,147 deletions.
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@
"plugins": [
"react-hooks"
],
"globals": { "fetch": false }
"globals": { "fetch": false },
"env": {
"jest": true
}
}
12 changes: 12 additions & 0 deletions __mocks__/axios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// import mockAxios from 'jest-mock-axios';
const axios = {
get: jest.fn(),
post: jest.fn()
}

axios.mockClear = function() {
for(const key in axios) {
axios[key]?.mockClear?.()
}
}
export default axios;
7 changes: 7 additions & 0 deletions __mocks__/latlon-geohash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const encode = jest.fn()

const geohash = {
encode
}

export default geohash
21 changes: 21 additions & 0 deletions __mocks__/moment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const subtract = jest.fn()
export const date = jest.fn()
export const month = jest.fn()
export const year = jest.fn()
export const valueOf = jest.fn()

const moment = jest.fn().mockImplementation(() => ({
subtract,
date,
month,
year,
valueOf,
}))

moment.mockClear = function(){
for(const element in moment){
moment[element]?.mockClear?.()
}
}

export default moment
10 changes: 10 additions & 0 deletions __mocks__/react-native-background-geolocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const onLocation = jest.fn().mockImplementation(() => ({}));

const ready = jest.fn().mockImplementation(() => {
return jest.fn().mockResolvedValue(true);
});

export default {
onLocation,
ready
};
34 changes: 34 additions & 0 deletions __mocks__/react-native-firebase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const logEvent = jest.fn();

const firebase = {
messaging: jest.fn(() => {
return {
hasPermission: jest.fn(() => Promise.resolve(true)),
subscribeToTopic: jest.fn(),
unsubscribeFromTopic: jest.fn(),
requestPermission: jest.fn(() => Promise.resolve(true)),
getToken: jest.fn(() => Promise.resolve('myMockToken'))
};
}),
notifications: jest.fn(() => {
return {
onNotification: jest.fn(),
onNotificationDisplayed: jest.fn()
};
})
};

firebase.notifications.Android = {
Channel: jest.fn(() => ({
setDescription: jest.fn(),
setSound: jest.fn(),
enableVibration: jest.fn(),
setVibrationPattern: jest.fn()
})),
Importance: {
Max: {}
}
};


export default firebase;
20 changes: 20 additions & 0 deletions __mocks__/react-native-permissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Permission } from 'react-native-permissions';

export const PERMISSIONS = {
IOS: {
LOCATION_ALWAYS: 'LOCATION_ALWAYS'
}
};

export const RESULTS = {
GRANTED: 'GRANTED'
};

// mock out any functions you want in this style...
export const check = async (permission: Permission) => {
return jest.fn().mockResolvedValue(true);
};

export const request = async (permission: Permission) => {
return jest.fn().mockResolvedValue(true);
};
10 changes: 10 additions & 0 deletions __mocks__/react-native-sqlite-storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const echoTest = jest.fn().mockResolvedValue()
const openDatabase = jest.fn()

const sqlite = {
enablePromise: jest.fn(),
echoTest,
openDatabase
}

export default sqlite
138 changes: 89 additions & 49 deletions __mocks__/setupFile.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';
import { NativeModules } from 'react-native';
import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';

global.fetch = require('jest-fetch-mock');

Expand All @@ -12,29 +12,89 @@ NativeModules.RNCNetInfo = {

NativeModules.SettingsManager = {
settings: {
AppleLocale: 'he'
AppleLocale: 'he',
AppleLanguages: ['he']
}
};

NativeModules.I18nManager = {
localeIdentifier: 'he'
};

jest.mock('@react-native-community/async-storage', () => mockAsyncStorage);
jest.mock('@react-native-community/async-storage', () => ({
...mockAsyncStorage,
mockClear() {
Object.keys(mockAsyncStorage).forEach(key => mockAsyncStorage[key]?.mockClear?.());
mockAsyncStorage.clear();
} }));

jest.mock('../src/database/Database.js', () => {
const listSamples = jest.fn();
jest.mock('@tmcw/togeojson', () => ({
kml: jest.fn()
}))

const UserLocationsDatabase = function () {
return { listSamples };
};
jest.mock('../src/services/ErrorService', () => ({
onError: jest.fn()
// onError: jest.fn(e => console.log(e))
}));

jest.mock('../src/services/sha256', () => ({
sha256: jest.fn().mockImplementation(char => 'a')
}))

jest.mock('../src/database/Database.js', () => {
const containsObjectID = jest.fn();
const addSickRecord = jest.fn();

const IntersectionSickDatabase = function () {
return { containsObjectID, addSickRecord };
const IntersectionSickDatabase = jest.fn().mockImplementation(() => ({
containsObjectID,
addSickRecord
}));

const containsWifiHash = jest.fn();
const addWifiMacAddresses = jest.fn();
const WifiMacAddressDatabase = jest.fn().mockImplementation(() => ({
containsWifiHash,
addWifiMacAddresses
}));

const updateLastSampleEndTime = jest.fn();
const addSample = jest.fn();
const listSamples = jest.fn();
const purgeSamplesTable = jest.fn();
const getLastPointEntered = jest.fn();
const insertBulkSamples = jest.fn();

const UserLocationsDatabase = jest.fn().mockImplementation(() => ({
updateLastSampleEndTime,
addSample,
listSamples,
purgeSamplesTable,
getLastPointEntered,
insertBulkSamples
}));

const db = {
UserLocationsDatabase,
WifiMacAddressDatabase,
IntersectionSickDatabase,
containsObjectID,
addSickRecord,
containsWifiHash,
addWifiMacAddresses,
updateLastSampleEndTime,
addSample,
listSamples,
purgeSamplesTable,
getLastPointEntered,
insertBulkSamples
};

return {
...db,
mockClear() {
Object.keys(db).forEach(key => db[key]?.mockClear?.());
}
};
return { UserLocationsDatabase, IntersectionSickDatabase };
});

jest.mock('react-native-device-info', () => {
Expand All @@ -45,43 +105,6 @@ jest.mock('react-native-device-info', () => {
};
});

jest.mock('react-native-firebase', () => {


const firebase = {
messaging: jest.fn(() => {
return {
hasPermission: jest.fn(() => Promise.resolve(true)),
subscribeToTopic: jest.fn(),
unsubscribeFromTopic: jest.fn(),
requestPermission: jest.fn(() => Promise.resolve(true)),
getToken: jest.fn(() => Promise.resolve('myMockToken'))
};
}),
notifications: jest.fn(() => {
return {
onNotification: jest.fn(),
onNotificationDisplayed: jest.fn()
};
})
}

firebase.notifications.Android = {
Channel: jest.fn(() => ({
setDescription: jest.fn(),
setSound: jest.fn(),
enableVibration: jest.fn(),
setVibrationPattern: jest.fn()
})),
Importance: {
Max: {}
}
};

return firebase;

});


jest.mock('react-native-background-timer', () => {
return {
Expand All @@ -95,6 +118,23 @@ jest.mock('../src/config/config.ts', () => {
return {
__esModule: true,
namedExport: jest.fn(),
default: jest.fn(() => originalModule['com.hamagen.dev']),
locationServiceIgnoreConfidenceThreshold: 80,
locationServiceIgnoreSampleVelocityThreshold: 2.8,
locationHistoryIgnoreList: ['should ignore from test'],
default: jest.fn(() => originalModule['com.hamagen']),
};
});

jest.mock('../src/store.ts', () => {
const dispatch = jest.fn()

const store = jest.fn().mockImplementation(() => ({ dispatch }));

return {
__esModule: true,
namedExport: jest.fn(),
default: store,
dispatch
};
});

20 changes: 10 additions & 10 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ android {
applicationId "com.hamagen"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 27
versionName "1.1.3"
versionCode 32
versionName "1.2.4"
}

dexOptions {
Expand Down Expand Up @@ -177,14 +177,14 @@ android {

buildTypes {
debug {
versionNameSuffix ".dev"
applicationIdSuffix ".dev"
versionNameSuffix ".qa"
applicationIdSuffix ".qa"
signingConfig signingConfigs.debug
}
qa {
initWith release
versionNameSuffix ".dev"
applicationIdSuffix ".dev"
versionNameSuffix ".qa"
applicationIdSuffix ".qa"
signingConfig signingConfigs.release
matchingFallbacks = ["release"]
}
Expand Down Expand Up @@ -223,16 +223,16 @@ android {
}

dependencies {
implementation 'io.radar:sdk:2.1.+'
implementation "com.google.android.gms:play-services-base:17.1.0"
implementation 'com.google.firebase:firebase-core:17.2.3'
implementation "com.google.firebase:firebase-messaging:20.1.2"
implementation "com.google.android.gms:play-services-base:17.2.1"
implementation 'com.google.firebase:firebase-core:17.3.0'
implementation "com.google.firebase:firebase-messaging:20.1.5"
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules

if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
qaImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
Expand Down
Loading

0 comments on commit 09293b8

Please sign in to comment.