-
-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ce72c3
commit adecd41
Showing
61 changed files
with
12,502 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
[android] | ||
target = Google Inc.:Google APIs:23 | ||
|
||
[maven_repositories] | ||
central = https://repo1.maven.org/maven2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module.exports = { | ||
root: true, | ||
extends: '@react-native-community', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
[ignore] | ||
; We fork some components by platform | ||
.*/*[.]android.js | ||
|
||
; Ignore "BUCK" generated dirs | ||
<PROJECT_ROOT>/\.buckd/ | ||
|
||
; Ignore polyfills | ||
node_modules/react-native/Libraries/polyfills/.* | ||
|
||
; These should not be required directly | ||
; require from fbjs/lib instead: require('fbjs/lib/warning') | ||
node_modules/warning/.* | ||
|
||
; Flow doesn't support platforms | ||
.*/Libraries/Utilities/LoadingView.js | ||
|
||
[untyped] | ||
.*/node_modules/@react-native-community/cli/.*/.* | ||
|
||
[include] | ||
|
||
[libs] | ||
node_modules/react-native/interface.js | ||
node_modules/react-native/flow/ | ||
|
||
[options] | ||
emoji=true | ||
|
||
esproposal.optional_chaining=enable | ||
esproposal.nullish_coalescing=enable | ||
|
||
module.file_ext=.js | ||
module.file_ext=.json | ||
module.file_ext=.ios.js | ||
|
||
munge_underscores=true | ||
|
||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1' | ||
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub' | ||
|
||
suppress_type=$FlowIssue | ||
suppress_type=$FlowFixMe | ||
suppress_type=$FlowFixMeProps | ||
suppress_type=$FlowFixMeState | ||
|
||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) | ||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ | ||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError | ||
|
||
[lints] | ||
sketchy-null-number=warn | ||
sketchy-null-mixed=warn | ||
sketchy-number=warn | ||
untyped-type-import=warn | ||
nonstrict-import=warn | ||
deprecated-type=warn | ||
unsafe-getters-setters=warn | ||
unnecessary-invariant=warn | ||
signature-verification-failure=warn | ||
deprecated-utility=error | ||
|
||
[strict] | ||
deprecated-type | ||
nonstrict-import | ||
sketchy-null | ||
unclear-type | ||
unsafe-getters-setters | ||
untyped-import | ||
untyped-type-import | ||
|
||
[version] | ||
^0.122.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.pbxproj -text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# OSX | ||
# | ||
.DS_Store | ||
|
||
# Xcode | ||
# | ||
build/ | ||
*.pbxuser | ||
!default.pbxuser | ||
*.mode1v3 | ||
!default.mode1v3 | ||
*.mode2v3 | ||
!default.mode2v3 | ||
*.perspectivev3 | ||
!default.perspectivev3 | ||
xcuserdata | ||
*.xccheckout | ||
*.moved-aside | ||
DerivedData | ||
*.hmap | ||
*.ipa | ||
*.xcuserstate | ||
|
||
# Android/IntelliJ | ||
# | ||
build/ | ||
.idea | ||
.gradle | ||
local.properties | ||
*.iml | ||
|
||
# node.js | ||
# | ||
node_modules/ | ||
npm-debug.log | ||
yarn-error.log | ||
|
||
# BUCK | ||
buck-out/ | ||
\.buckd/ | ||
*.keystore | ||
!debug.keystore | ||
|
||
# fastlane | ||
# | ||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the | ||
# screenshots whenever they are needed. | ||
# For more information about the recommended setup visit: | ||
# https://docs.fastlane.tools/best-practices/source-control/ | ||
|
||
*/fastlane/report.xml | ||
*/fastlane/Preview.html | ||
*/fastlane/screenshots | ||
|
||
# Bundle artifact | ||
*.jsbundle | ||
|
||
# CocoaPods | ||
/ios/Pods/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
bracketSpacing: false, | ||
jsxBracketSameLine: true, | ||
singleQuote: true, | ||
trailingComma: 'all', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react'; | ||
import {SafeAreaView, StyleSheet} from 'react-native'; | ||
|
||
import ReviewApp from './src/screens/reviewApp'; | ||
|
||
const App = () => { | ||
return ( | ||
<SafeAreaView style={styles.MainAppContainer}> | ||
<ReviewApp /> | ||
</SafeAreaView> | ||
); | ||
}; | ||
|
||
const styles = StyleSheet.create({MainAppContainer: {flex: 1}}); | ||
|
||
export default App; |
121 changes: 121 additions & 0 deletions
121
Example/__mocks__/@react-native-async-storage/async-storage.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
const asMock = { | ||
__INTERNAL_MOCK_STORAGE__: {}, | ||
|
||
setItem: jest.fn(async (key, value, callback) => { | ||
const setResult = await asMock.multiSet([[key, value]], undefined); | ||
|
||
callback && callback(setResult); | ||
return setResult; | ||
}), | ||
|
||
getItem: jest.fn(async (key, callback) => { | ||
const getResult = await asMock.multiGet([key], undefined); | ||
|
||
const result = getResult[0] ? getResult[0][1] : null; | ||
|
||
callback && callback(null, result); | ||
return result; | ||
}), | ||
|
||
removeItem: jest.fn((key, callback) => asMock.multiRemove([key], callback)), | ||
mergeItem: jest.fn((key, value, callback) => | ||
asMock.multiMerge([[key, value]], callback), | ||
), | ||
|
||
clear: jest.fn(_clear), | ||
getAllKeys: jest.fn(_getAllKeys), | ||
flushGetRequests: jest.fn(), | ||
|
||
multiGet: jest.fn(_multiGet), | ||
multiSet: jest.fn(_multiSet), | ||
multiRemove: jest.fn(_multiRemove), | ||
multiMerge: jest.fn(_multiMerge), | ||
useAsyncStorage: jest.fn((key) => { | ||
return { | ||
getItem: (...args) => asMock.getItem(key, ...args), | ||
setItem: (...args) => asMock.setItem(key, ...args), | ||
mergeItem: (...args) => asMock.mergeItem(key, ...args), | ||
removeItem: (...args) => asMock.removeItem(key, ...args), | ||
}; | ||
}), | ||
}; | ||
|
||
async function _multiSet(keyValuePairs, callback) { | ||
keyValuePairs.forEach((keyValue) => { | ||
const key = keyValue[0]; | ||
|
||
asMock.__INTERNAL_MOCK_STORAGE__[key] = keyValue[1]; | ||
}); | ||
callback && callback(null); | ||
return null; | ||
} | ||
|
||
async function _multiGet(keys, callback) { | ||
const values = keys.map((key) => [ | ||
key, | ||
asMock.__INTERNAL_MOCK_STORAGE__[key] || null, | ||
]); | ||
callback && callback(null, values); | ||
|
||
return values; | ||
} | ||
|
||
async function _multiRemove(keys, callback) { | ||
keys.forEach((key) => { | ||
if (asMock.__INTERNAL_MOCK_STORAGE__[key]) { | ||
delete asMock.__INTERNAL_MOCK_STORAGE__[key]; | ||
} | ||
}); | ||
|
||
callback && callback(null); | ||
return null; | ||
} | ||
|
||
async function _clear(callback) { | ||
asMock.__INTERNAL_MOCK_STORAGE__ = {}; | ||
|
||
callback && callback(null); | ||
|
||
return null; | ||
} | ||
|
||
async function _getAllKeys() { | ||
return Object.keys(asMock.__INTERNAL_MOCK_STORAGE__); | ||
} | ||
|
||
async function _multiMerge(keyValuePairs, callback) { | ||
keyValuePairs.forEach((keyValue) => { | ||
const key = keyValue[0]; | ||
const value = JSON.parse(keyValue[1]); | ||
|
||
const oldValue = JSON.parse(asMock.__INTERNAL_MOCK_STORAGE__[key]); | ||
|
||
asMock.__INTERNAL_MOCK_STORAGE__[key] = JSON.stringify( | ||
_deepMergeInto(oldValue, value), | ||
); | ||
}); | ||
|
||
callback && callback(null); | ||
return null; | ||
} | ||
|
||
const _isObject = (obj) => typeof obj === 'object' && !Array.isArray(obj); | ||
const _deepMergeInto = (oldObject, newObject) => { | ||
const newKeys = Object.keys(newObject); | ||
const mergedObject = oldObject; | ||
|
||
newKeys.forEach((key) => { | ||
const oldValue = mergedObject[key]; | ||
const newValue = newObject[key]; | ||
|
||
if (_isObject(oldValue) && _isObject(newValue)) { | ||
mergedObject[key] = _deepMergeInto(oldValue, newValue); | ||
} else { | ||
mergedObject[key] = newValue; | ||
} | ||
}); | ||
|
||
return mergedObject; | ||
}; | ||
|
||
module.exports = asMock; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module.exports = { | ||
RequestInAppReview: jest.fn(), | ||
isAvailable: jest.fn(), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import AsyncStorage from '@react-native-async-storage/async-storage'; | ||
import {renderHook, act} from '@testing-library/react-hooks'; | ||
import useAppReview from '../src/screens/reviewApp/useAppReview'; | ||
import InAppReview from 'react-native-in-app-review'; | ||
|
||
describe('App Review Hook Behavoir', () => { | ||
const currentDate = new Date('2021-01-10T11:01:58.135Z'); | ||
global.Date = class extends Date { | ||
constructor(date) { | ||
if (date) { | ||
return super(date); | ||
} | ||
|
||
return currentDate; | ||
} | ||
}; | ||
afterAll(() => { | ||
jest.resetModule(); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should trigger InAppReview in cross platform in first time', async () => { | ||
const expectItemSavedToAsync = ['in_App_Review', new Date().toString()]; | ||
|
||
const {result} = renderHook(() => useAppReview()); | ||
|
||
await act(() => result.current.onReview()); | ||
expect(AsyncStorage.getItem).toBeCalledWith('in_App_Review'); | ||
expect(AsyncStorage.setItem).toHaveBeenCalledWith( | ||
...expectItemSavedToAsync, | ||
); | ||
|
||
expect(InAppReview.RequestInAppReview).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not trigger InAppReview before 15 days user already get InAppReview', async () => { | ||
const expectedItem = '2021-01-05'; | ||
jest | ||
.spyOn(AsyncStorage, 'getItem') | ||
.mockReturnValueOnce(Promise.resolve(expectedItem)); | ||
|
||
const {result} = renderHook(() => useAppReview()); | ||
|
||
await act(() => result.current.onReview()); | ||
expect(AsyncStorage.getItem).toBeCalledWith('in_App_Review'); | ||
|
||
expect(InAppReview.RequestInAppReview).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should trigger InAppReview after 15 days user get InAppReview and save Date to async Storage', async () => { | ||
const expectedItem = '2021-01-26'; | ||
const expectItemSavedToAsync = ['in_App_Review', new Date().toString()]; | ||
|
||
jest | ||
.spyOn(AsyncStorage, 'getItem') | ||
.mockReturnValueOnce(Promise.resolve(expectedItem)); | ||
|
||
jest.spyOn(AsyncStorage, 'setItem'); | ||
|
||
const {result} = renderHook(() => useAppReview()); | ||
|
||
await act(() => result.current.onReview()); | ||
|
||
expect(AsyncStorage.getItem).toBeCalledWith('in_App_Review'); | ||
expect(AsyncStorage.setItem).toHaveBeenCalledWith( | ||
...expectItemSavedToAsync, | ||
); | ||
expect(InAppReview.RequestInAppReview).toHaveBeenCalled(); | ||
}); | ||
}); |
Oops, something went wrong.