completion
6
ioneapps-maagapp-ee31119a522d/.buckconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
[android]
|
||||
target = Google Inc.:Google APIs:23
|
||||
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
13
ioneapps-maagapp-ee31119a522d/.dockerignore
Normal file
@@ -0,0 +1,13 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# IGNORE ALL:
|
||||
# ------------------------------------------------------------------------------
|
||||
*
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# EXCEPT THE FOLLOWING:
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# DIRECTORIES
|
||||
|
||||
# FILES
|
||||
!package.json
|
||||
35
ioneapps-maagapp-ee31119a522d/.editorconfig
Normal file
@@ -0,0 +1,35 @@
|
||||
# For more information about the properties used in
|
||||
# this file, please see the EditorConfig documentation:
|
||||
# http://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
# Applied to the following file types:
|
||||
# - js
|
||||
# - coffee
|
||||
# - opts
|
||||
# - Makefile
|
||||
# - md
|
||||
# - Dockerfile
|
||||
# - xml
|
||||
# - opts
|
||||
# - dot files
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[{*.yml,*.yaml,*.java,*.kt,*.kts,*.py,*.sql,*.gradle}]
|
||||
# Applied to the following file types:
|
||||
# - java
|
||||
# - kotlin
|
||||
# - python
|
||||
# - sql
|
||||
# - yaml (http://www.yaml.org/spec/1.2/spec.html#id2777534)
|
||||
indent_style = space
|
||||
5
ioneapps-maagapp-ee31119a522d/.env
Normal file
@@ -0,0 +1,5 @@
|
||||
APP_ID=com.ioneres.maagap
|
||||
BUCKET_PREFIX=maagap-prod-
|
||||
debug=false
|
||||
ENV=prod
|
||||
MOBILE_API_URL=https://87kprj6t9i.execute-api.ap-southeast-1.amazonaws.com/staging
|
||||
5
ioneapps-maagapp-ee31119a522d/.env.alpha
Normal file
@@ -0,0 +1,5 @@
|
||||
APP_ID=com.ioneres.maagap
|
||||
BUCKET_PREFIX=maagap-alpha-
|
||||
debug=true
|
||||
ENV=alpha
|
||||
MOBILE_API_URL=https://87kprj6t9i.execute-api.ap-southeast-1.amazonaws.com/staging
|
||||
5
ioneapps-maagapp-ee31119a522d/.env.beta
Normal file
@@ -0,0 +1,5 @@
|
||||
APP_ID=com.ioneres.maagap
|
||||
BUCKET_PREFIX=maagap-beta-
|
||||
debug=true
|
||||
ENV=beta
|
||||
MOBILE_API_URL=https://87kprj6t9i.execute-api.ap-southeast-1.amazonaws.com/staging
|
||||
5
ioneapps-maagapp-ee31119a522d/.env.dev
Normal file
@@ -0,0 +1,5 @@
|
||||
APP_ID=com.ioneres.maagap
|
||||
BUCKET_PREFIX=maagap-dev-
|
||||
debug=true
|
||||
ENV=dev
|
||||
MOBILE_API_URL=https://87kprj6t9i.execute-api.ap-southeast-1.amazonaws.com/staging
|
||||
5
ioneapps-maagapp-ee31119a522d/.env.qa
Normal file
@@ -0,0 +1,5 @@
|
||||
APP_ID=com.ioneres.maagap
|
||||
BUCKET_PREFIX=maagap-qa-
|
||||
debug=true
|
||||
ENV=qa
|
||||
MOBILE_API_URL=https://87kprj6t9i.execute-api.ap-southeast-1.amazonaws.com/staging
|
||||
5
ioneapps-maagapp-ee31119a522d/.env.rnd
Normal file
@@ -0,0 +1,5 @@
|
||||
APP_ID=com.ioneres.maagap
|
||||
BUCKET_PREFIX=maagap-rnd-
|
||||
debug=true
|
||||
ENV=rnd
|
||||
MOBILE_API_URL=https://87kprj6t9i.execute-api.ap-southeast-1.amazonaws.com/staging
|
||||
10
ioneapps-maagapp-ee31119a522d/.eslintignore
Normal file
@@ -0,0 +1,10 @@
|
||||
.vscode
|
||||
android
|
||||
coverage
|
||||
docker
|
||||
e2e
|
||||
fastlane
|
||||
ios
|
||||
scripts
|
||||
node_modules
|
||||
babel.config.js
|
||||
34
ioneapps-maagapp-ee31119a522d/.eslintrc.js
Normal file
@@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
// extends: '@react-native-community',
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"extends": "airbnb",
|
||||
"globals": {
|
||||
"__DEV__": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaFeatures": { "legacyDecorators": true }
|
||||
},
|
||||
"rules": {
|
||||
"react/jsx-filename-extension": ["error", { extensions: [".js", ".jsx"] }],
|
||||
"indent": [2, "tab", { "SwitchCase": 1, "VariableDeclarator": 1 }],
|
||||
"no-tabs": 0,
|
||||
"max-len": [2, { "code": 120, "tabWidth": 1, "ignoreComments": true, "ignoreTrailingComments": true, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true }],
|
||||
"arrow-parens": 0,
|
||||
"react/jsx-indent": [2, "tab"],
|
||||
"react/jsx-indent-props": [2, "tab"],
|
||||
"react/forbid-prop-types": 0,
|
||||
"react/prefer-stateless-function": 0,
|
||||
"import/prefer-default-export": 0,
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"babel-module": {}
|
||||
}
|
||||
}
|
||||
};
|
||||
75
ioneapps-maagapp-ee31119a522d/.flowconfig
Normal file
@@ -0,0 +1,75 @@
|
||||
[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/Libraries/react-native/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/Libraries/react-native/react-native-implementation'
|
||||
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
|
||||
inexact-spread=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.105.0
|
||||
1
ioneapps-maagapp-ee31119a522d/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.pbxproj -text
|
||||
112
ioneapps-maagapp-ee31119a522d/.gitignore
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
# 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
|
||||
project.xcworkspace
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
build/
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# VS Code
|
||||
#
|
||||
.vscode/
|
||||
.settings
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
\.buckd/
|
||||
*.keystore
|
||||
|
||||
# VS Code
|
||||
#
|
||||
.vscode/
|
||||
.settings
|
||||
|
||||
# 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
|
||||
fastlane/README.md
|
||||
|
||||
coverage/
|
||||
*.mobileprovision
|
||||
*.dSYM.zip
|
||||
ios/Nixplay/main.jsbundle
|
||||
ios/Nixplay/main.jsbundle.meta
|
||||
.vscode/launch.json
|
||||
android/app/src/main/assets/crashlytics-build.properties
|
||||
android/app/src/main/res/values/com_crashlytics_export_strings.xml
|
||||
|
||||
third-party/
|
||||
|
||||
# cocoapods
|
||||
ios/Pods
|
||||
android/app/fabric.properties
|
||||
reactNativeQueue.realm*
|
||||
|
||||
# Google services.json
|
||||
# android/app/google-services.json
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
android/app/build/*
|
||||
android/app/bin
|
||||
android/app/.classpath
|
||||
android/app/.project
|
||||
android/.project
|
||||
|
||||
# Language files
|
||||
language.csv
|
||||
|
||||
|
||||
#Jenkins rvm
|
||||
rvm.env
|
||||
*.cer
|
||||
fastlane/metadata/
|
||||
src/config/revision.json
|
||||
GoogleService-Info.plist
|
||||
device-udid-export.txt
|
||||
firebase-debug.log
|
||||
android/app/.classpath
|
||||
android/app/rnd/release/app-rnd-release.apk
|
||||
|
||||
android/app/beneficiary/*
|
||||
android/app/rnd/*
|
||||
android/app/rndBE/*
|
||||
android/app/rndSW/*
|
||||
android/app/prodSW/*
|
||||
1
ioneapps-maagapp-ee31119a522d/.nvmrc
Normal file
@@ -0,0 +1 @@
|
||||
10
|
||||
1
ioneapps-maagapp-ee31119a522d/.watchmanconfig
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
61
ioneapps-maagapp-ee31119a522d/CHANGELOG.md
Normal file
@@ -0,0 +1,61 @@
|
||||
Changelog 2019-06-05 10:46:50
|
||||
- Customise android transition config
|
||||
- upgrade react-native-webview
|
||||
|
||||
Changelog 2019-05-28 11:24:32
|
||||
- Added svg transform
|
||||
- migrate ios svg library to podfile
|
||||
- added metro config
|
||||
|
||||
Changelog 2019-05-24 15:21:03:
|
||||
- Changed NixShareModule, handle dynamic android content provider uri
|
||||
- Changed react-native-nixplay-core
|
||||
- Changed react-native-creedon-imagepicker
|
||||
- Added shareExtension reducer
|
||||
- Added shareExtension saga
|
||||
- Added shareExtension reducer unit test
|
||||
- Added shareExtension saga unit test
|
||||
- Changed ShareExtPreview ui/ux
|
||||
- Changed ShareExtPlaylist ui/ux
|
||||
- Changed Prompt Natification after upload completed
|
||||
- Show warning messagewhen user selected contents exist max
|
||||
|
||||
Changelog 2019-05-03 18:45:39:
|
||||
- react-natvie async-storage → @react-native-community/async-storage 1.2.4
|
||||
- migration is not support 1.2.x to 1.3.x , we stick to 1.2.x now
|
||||
|
||||
Change logs 2019-04-26 16:50:16:
|
||||
upgrade rn 59
|
||||
- default node verion 10.x
|
||||
- react-native-languages → react-native-localize
|
||||
- react-natvie async-storage → @react-native-community/async-storage
|
||||
- reat-native slider → @react-native-community_slider
|
||||
- react-natvie netinfo → @react-native-community/netinfo
|
||||
- react-native-enhanced-webview → react-native-webview
|
||||
- upgrade babel babel/core": "^7.4.0"
|
||||
- .babelrc → babel.config.js
|
||||
- upgrade jest
|
||||
- toThrow(error.message) → toThrow(error)
|
||||
- .toThrow(error.error.message) → toMatch(error.error.message)
|
||||
- android project.supportLibVersion "27.1.1" → "28.0.0"
|
||||
- upgrade react-navigation
|
||||
- added react-native-gesture-handler
|
||||
- Added export const Root = createAppContainer(RootStack);
|
||||
- headerSetting.navigationOptions → headerSettings.defaultNavigationOptions
|
||||
- upfrade react-native firebase
|
||||
- com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
|
||||
- Android Share Extension
|
||||
- changed Theme.Share.Transparent → default "AppTheme"
|
||||
- CustomMainReactPackage.java
|
||||
- spec.getType() → ("http".equals(NetworkingModule.class) || "https".equals(NetworkingModule.class))
|
||||
- Added CustomNetworkModule.java
|
||||
- gradle-4.6 → gradle-5.1.1
|
||||
- upgrade react-native-intercom
|
||||
- depreceated postinstall.sh
|
||||
- src/components/reduxForm/renderer.js Slider default valude = 0
|
||||
- webViewComponent.js using react-native-webview
|
||||
- src/locale/i18n.js upgrade for RNLocalize
|
||||
- react-native-video 4.3.1 → 4.4.0(customized)
|
||||
- Textinput multi charaters input method fixed
|
||||
- update redux-saga
|
||||
- __tests__ migrate delay to redux-saga/effect
|
||||
8
ioneapps-maagapp-ee31119a522d/Gemfile
Normal file
@@ -0,0 +1,8 @@
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "fastlane"
|
||||
gem "cocoapods"
|
||||
gem 'rb-readline'
|
||||
gem 'pry'
|
||||
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
|
||||
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
||||
227
ioneapps-maagapp-ee31119a522d/Gemfile.lock
Normal file
@@ -0,0 +1,227 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.1)
|
||||
activesupport (4.2.11.1)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
algoliasearch (1.27.1)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
babosa (1.0.3)
|
||||
claide (1.0.3)
|
||||
cocoapods (1.8.3)
|
||||
activesupport (>= 4.0.2, < 5)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.8.3)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.2.2, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-stats (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.6.6)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (~> 1.4)
|
||||
xcodeproj (>= 1.11.1, < 2.0)
|
||||
cocoapods-core (1.8.3)
|
||||
activesupport (>= 4.0.2, < 6)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.4)
|
||||
cocoapods-downloader (1.2.2)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.0)
|
||||
cocoapods-stats (1.1.0)
|
||||
cocoapods-trunk (1.4.1)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.1.0)
|
||||
coderay (1.1.2)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander-fastlane (4.4.6)
|
||||
highline (~> 1.7.2)
|
||||
concurrent-ruby (1.1.5)
|
||||
declarative (0.0.10)
|
||||
declarative-option (0.1.0)
|
||||
digest-crc (0.4.1)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.7.5)
|
||||
emoji_regex (1.0.1)
|
||||
escape (0.0.4)
|
||||
excon (0.67.0)
|
||||
faraday (0.17.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-cookie_jar (0.0.6)
|
||||
faraday (>= 0.7.4)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday_middleware (0.13.1)
|
||||
faraday (>= 0.7.4, < 1.0)
|
||||
fastimage (2.1.7)
|
||||
fastlane (2.134.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
babosa (>= 1.0.2, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored
|
||||
commander-fastlane (>= 4.4.6, < 5.0.0)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 2.0)
|
||||
excon (>= 0.45.0, < 1.0.0)
|
||||
faraday (~> 0.17)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 0.13.1)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-api-client (>= 0.21.2, < 0.24.0)
|
||||
google-cloud-storage (>= 1.15.0, < 2.0.0)
|
||||
highline (>= 1.7.2, < 2.0.0)
|
||||
json (< 3.0.0)
|
||||
jwt (~> 2.1.0)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multi_xml (~> 0.5)
|
||||
multipart-post (~> 2.0.0)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
public_suffix (~> 2.0.0)
|
||||
rubyzip (>= 1.3.0, < 2.0.0)
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
slack-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.8.1, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
fastlane-plugin-firebase_app_distribution (0.1.4)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
google-api-client (0.23.9)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.5, < 0.7.0)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mime-types (~> 3.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.9)
|
||||
google-cloud-core (1.3.2)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-env (1.2.1)
|
||||
faraday (~> 0.11)
|
||||
google-cloud-storage (1.16.0)
|
||||
digest-crc (~> 0.4)
|
||||
google-api-client (~> 0.23)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (>= 0.6.2, < 0.10.0)
|
||||
googleauth (0.6.7)
|
||||
faraday (~> 0.12)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.7)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.2.0)
|
||||
jwt (2.1.0)
|
||||
memoist (0.16.0)
|
||||
method_source (0.9.2)
|
||||
mime-types (3.3)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2019.1009)
|
||||
mini_magick (4.9.5)
|
||||
minitest (5.12.2)
|
||||
molinillo (0.6.6)
|
||||
multi_json (1.14.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
nanaimo (0.2.6)
|
||||
nap (1.1.0)
|
||||
naturally (2.2.0)
|
||||
netrc (0.11.0)
|
||||
os (1.0.1)
|
||||
plist (3.5.0)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
public_suffix (2.0.5)
|
||||
rb-readline (0.5.5)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
declarative-option (< 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rouge (2.0.7)
|
||||
ruby-macho (1.4.0)
|
||||
rubyzip (1.3.0)
|
||||
security (0.1.3)
|
||||
signet (0.12.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (~> 0.9)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.6)
|
||||
CFPropertyList
|
||||
naturally
|
||||
slack-notifier (2.3.2)
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
tty-cursor (0.7.0)
|
||||
tty-screen (0.7.0)
|
||||
tty-spinner (0.9.1)
|
||||
tty-cursor (~> 0.7)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.6)
|
||||
unicode-display_width (1.6.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.13.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.2.6)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.0)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods
|
||||
fastlane
|
||||
fastlane-plugin-firebase_app_distribution
|
||||
pry
|
||||
rb-readline
|
||||
|
||||
BUNDLED WITH
|
||||
2.0.2
|
||||
83
ioneapps-maagapp-ee31119a522d/README-lang.md
Normal file
@@ -0,0 +1,83 @@
|
||||
## Localization Rules
|
||||
|
||||
1. Files is separated by categories. __DO NOT__ just stuff everything in `common`. See below.
|
||||
2. Include punctuations in the json. Duplicates are ok if necessary. For example:
|
||||
```
|
||||
{
|
||||
"Friends": "Friends",
|
||||
"friends": "friends",
|
||||
"signOut?": "Sign out?",
|
||||
"signout": "Sign out"
|
||||
}
|
||||
```
|
||||
3. When creating files in `en`, create the same files in the other language also, even if its an empty object.
|
||||
__DO NOT__ give an empty string, empty string does not fallback to `en`
|
||||
4. __DO NOT__ have more that 1 first level key in the json file, because it is used in the script for importing the texts as filename.
|
||||
5. __DO NOT__ fill other language files with english. Just leave the field blank, so that the translators know which one to translate.
|
||||
6. Check if your text available or not before you add new text.
|
||||
7. The key of your text should be related to the content, not to the component using it. This will help preventing duplicates.
|
||||
8. __BE CAREFUL__ when changing the existing key, check for all occurrence of previous key.
|
||||
|
||||
### IMPORTANT
|
||||
__NEVER__ do something like this:
|
||||
```
|
||||
i18n.t('common.friend').toLowerCase().concat('s')
|
||||
```
|
||||
Firstly, its the wrong category, should be `friends`.
|
||||
Secondly, not all plural ends with `s` or `es`. For example, friend and friends:
|
||||
- German: `Freund` and `Freunde`
|
||||
- Chinese Simplified: `朋友` and `朋友们`
|
||||
Thirdly, `toLowerCase` is tolerable, but better not, because same as the reason above, you cannot guarantee all language follow the same rules.
|
||||
|
||||
|
||||
### Categories:
|
||||
1. Common:
|
||||
anything that you cannot guess the category when you read it
|
||||
|
||||
2. Users:
|
||||
- first / last name
|
||||
- email
|
||||
- username
|
||||
- password
|
||||
- country
|
||||
- accounts
|
||||
- tnc / privacy
|
||||
|
||||
3. Contents:
|
||||
- photo
|
||||
- video
|
||||
- item
|
||||
- caption
|
||||
- upload
|
||||
- download
|
||||
|
||||
4. Albums
|
||||
5. Playlists
|
||||
6. Frames
|
||||
7. Friends
|
||||
|
||||
#### Exception:
|
||||
- Frame Settings
|
||||
|
||||
|
||||
## Updating languages copy
|
||||
`babel-node` is a command that comes with `@babel/node`
|
||||
|
||||
```
|
||||
npm i -g @babel/core @babel/node
|
||||
|
||||
```
|
||||
|
||||
### Exporting
|
||||
Output folder will be the folder where you run the command
|
||||
```
|
||||
babel-node src/locale/export-to-csv.js
|
||||
```
|
||||
|
||||
### Importing
|
||||
```
|
||||
babel-node src/locale/import-from-csv.js ./path/to/csv/lang.csv ./path/to/locale/folder
|
||||
|
||||
# example: babel-node src/locale/import-from-csv.js language.csv src/locale/lang/
|
||||
```
|
||||
|
||||
411
ioneapps-maagapp-ee31119a522d/README.md
Normal file
@@ -0,0 +1,411 @@
|
||||
# MAAGApp Mobile App
|
||||
|
||||
## 1. Setup
|
||||
### 1.1 Compatibility
|
||||
To run this mobile app, we need to have node `8.x.x` installed.
|
||||
To install and manage multiple versions of node, we can use [nvm](https://github.com/creationix/nvm)
|
||||
We also need to have installed Ruby version 2.3.X to use Gem.
|
||||
|
||||
### 1.2 Install
|
||||
|
||||
Install [cocoapod](https://guides.cocoapods.org/using/getting-started.html)
|
||||
|
||||
Clone the repository and then install all dependencies by running the following command
|
||||
```bash
|
||||
nvm use
|
||||
npm install
|
||||
```
|
||||
### 1.3 Run
|
||||
To run on iOS simulator
|
||||
|
||||
pre install pod
|
||||
|
||||
```bash
|
||||
npm run pod
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
cd ios
|
||||
pod install
|
||||
cd ../
|
||||
npm run ios
|
||||
```
|
||||
|
||||
#### Run specific scheme
|
||||
```bash
|
||||
npm run ios -- --scheme "Nixplay" --device "e32c0db8ed7e5ac2be743dcada78b57ac944fd6e"
|
||||
```
|
||||
or
|
||||
|
||||
```bash
|
||||
npm run ios:rnd -- --simulator "iPhone X"
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
npm run ios:rnd -- --device "iPhone X"
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run ios:qa -- --device "iPhone X"
|
||||
```
|
||||
|
||||
To run on Android emulator
|
||||
```bash
|
||||
npm run android
|
||||
```
|
||||
|
||||
To run the unit tests
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
To run the unit tests in watch mode
|
||||
```bash
|
||||
npm run test:watch
|
||||
```
|
||||
## 2. Deploying Alpha build (We will use this until we release to PROD)
|
||||
### 2.1 Increment build number
|
||||
Alpha build is built using the develop branch with only the build number set to `git rev-list --count develop`. To create a new alpha build simply run the following command to update build number and commit it:
|
||||
|
||||
Update package.json version
|
||||
e.g
|
||||
|
||||
"version": "3.0.1"
|
||||
|
||||
1. run `jq -r '.version' package.json` to echo
|
||||
1. `npm run create:release:branch` create release branch with version name
|
||||
1. `npm run prerelease` bumped version code when release to qa
|
||||
2. `git flow release finish` to close release branch
|
||||
|
||||
|
||||
### 2.2 Release an iOS build
|
||||
After running the prerelease script, we can release iOS build by running the following command:
|
||||
```bash
|
||||
npm run ios:release:alpha
|
||||
```
|
||||
|
||||
### 2.3 Release an Android build
|
||||
After running the prerelease script, we can release Android build by running the following command:
|
||||
```bash
|
||||
npm run android:release:alpha
|
||||
```
|
||||
|
||||
## 3. Deploying to QA
|
||||
### 3.1 Before you begin
|
||||
|
||||
#### 3.1.A Setup prpvisioning profile
|
||||
You need to install Fabric app to your mac. You need a account with https://fabric.io/, ask `Kumar` / `James` to send an invite so an account on Fabric can be created. After creating an account you can download and install the Fabric app.
|
||||
|
||||
You need 2 passwords to successfully deploy the app to crashlytics 1) the passcode for decrypting developer certificates to use with match and 2) the password for **mobile@nix-digital.com** apple developer account. Again ask `Kumar` / `James` for these.
|
||||
|
||||
You also need to install Fastlane CLI. Run the following command to do so:
|
||||
```bash
|
||||
gem install fastlane -NV
|
||||
```
|
||||
|
||||
#### 3.1.B sync certificat
|
||||
If certificate is outdate/not be synced run the following commnad to sync up from repo
|
||||
|
||||
|
||||
|
||||
`fastlane ios certificates --env=<env>`
|
||||
|
||||
e.g.
|
||||
```bash
|
||||
fastlane ios certificates --env=rnd
|
||||
```
|
||||
|
||||
for specific type of cert
|
||||
|
||||
`fastlane ios read_dev_cert --env=<env>`
|
||||
`fastlane ios read_adhoc_cert --env=<env>`
|
||||
`fastlane ios read_appstore_cert --env=<env>`
|
||||
|
||||
|
||||
### 3.2 Create release branch
|
||||
You can either use gitflow or simply use git to create a new branch:
|
||||
```bash
|
||||
git flow release start <version>
|
||||
```
|
||||
or
|
||||
|
||||
```bash
|
||||
git checkout -b release/<version>
|
||||
```
|
||||
|
||||
### 3.3 Bump build number
|
||||
Bump build number and run other prerelease scripts like npm install etc
|
||||
```bash
|
||||
npm run prerelease
|
||||
```
|
||||
|
||||
### 3.3.1 Bump version number
|
||||
```bash
|
||||
npm --no-git-tag-version version [major|minor|patch] patch -m "Upgrade to version %s"
|
||||
```
|
||||
|
||||
example output
|
||||
|
||||
``` bash
|
||||
npm --no-git-tag-version version patch -m "Upgrade to version %s"
|
||||
v0.1.2
|
||||
[RNV] Versioning Android...
|
||||
[RNV] Android updated
|
||||
[RNV] Versioning iOS...
|
||||
[RNV] iOS updated
|
||||
[RNV] Amending...
|
||||
[RNV] Adjusting Git tag...
|
||||
[RNV] Done
|
||||
```
|
||||
|
||||
### 3.4 Release to QA
|
||||
Release iOS version to QA:
|
||||
|
||||
```bash
|
||||
npm run ios:release:qa
|
||||
```
|
||||
Release Android version to QA:
|
||||
```bash
|
||||
npm run android:release:qa
|
||||
```
|
||||
|
||||
#### 3.4.1 Extra command
|
||||
Release to Alpha:
|
||||
|
||||
```bash
|
||||
npm run ios:release:alpha
|
||||
npm run android:release:alpha
|
||||
```
|
||||
<!-- ```
|
||||
npm run ios:release:beta
|
||||
npm run android:release:beta
|
||||
|
||||
npm run ios:release:qa
|
||||
npm run android:release:qa
|
||||
``` -->
|
||||
|
||||
### 3.5 Merge the release branch back to Develop and Master
|
||||
|
||||
## 4. Workflow
|
||||
Always create a new git branch to work on a user story. After a user story is completed then commit the code and push your changes. Login to https://git.nixplay.ninja/ and create a **Merge Request**, make sure to assign it to someone. The assignee should review the code and discuss if any issues with the committer and if no issues then merge it back to the develop branch.
|
||||
|
||||
> Note: Please never use **--no-verify** when pushing your changes to any branch including feature branches.
|
||||
|
||||
### 4.1 Create a new branch
|
||||
You can either create a new branch using `git` or use `gitflow` if you have that set up
|
||||
To create and switch to a new branch you can:
|
||||
```bash
|
||||
git checkout -b <branch name>
|
||||
```
|
||||
|
||||
Work on a user story and make sure to add unit tests to cover your changes and to fix any broken unit tests due to the changes made.
|
||||
|
||||
### 4.2 Commit your changes and create merge request
|
||||
Continue to commit changes regularly but make sure all tests and eslint issues is fixed before pushing. If you think a user story is done then go to https://git.nixplay.ninja/ and create a new merge request and assign it to someone to merge.
|
||||
|
||||
> Note: Do not commit directly to master or develop branch unless the changes is minimal. This means changing this README file is okay to commit directly to develop branch or changing the padding of a component. Any changes that requires more changes than that should be committed to feature branch.
|
||||
|
||||
### 4.3 Merge back from develop branch often
|
||||
When we are working on a feature branch we may diverge from the develop branch. To ensure what we are doing is as upto date as possible and also to avoid merge conflicts, we should merge develop branch to our feature branch as often as possible.
|
||||
|
||||
### 5 Update reducerVersion when modifying the index reducer
|
||||
Whenever we modify `src/reducers/index.js` we should also make sure we update the reducerVersion in `src/config/ReduxPersist.js` to prevent the app from crashing.
|
||||
|
||||
## Troubleshooting
|
||||
iOS error `No bundle url present`, can try:
|
||||
- https://www.andrewcbancroft.com/2017/04/22/solving-react-natives-no-bundle-url-present-error/
|
||||
|
||||
|
||||
iOS error related to bundle url, you can also try:
|
||||
- Kill the existing bundler process and then run the bundler
|
||||
```bash
|
||||
watchman watch-del-all
|
||||
yarn cache clean
|
||||
npm start -- --reset-cache
|
||||
```
|
||||
|
||||
iOS error `Entry, :CFBundleIdentifier, Does Not Exist`, can try:
|
||||
- Run
|
||||
```bash
|
||||
npm run build:ios
|
||||
```
|
||||
|
||||
Android stuck on splash screen, can try:
|
||||
- Uninstall the app, then run
|
||||
```bash
|
||||
npm run android
|
||||
```
|
||||
|
||||
If you see a version mismatch error message then try running the following command:
|
||||
```bash
|
||||
npm run ios:reset
|
||||
```
|
||||
|
||||
Android build failed
|
||||
|
||||
```
|
||||
Could not find manifest-merger.jar ...
|
||||
```
|
||||
|
||||
run `rm -rf $HOME/.gradle/caches`
|
||||
run `./android/gradlew cleanBuildCache -p ./android`
|
||||
|
||||
## Update app icon with single command
|
||||
``` bash
|
||||
https://blog.bam.tech/developper-news/change-your-react-native-app-icons-in-a-single-command-line
|
||||
```
|
||||
|
||||
|
||||
# Testing Subscription
|
||||
Library used: [react-native-iap](https://github.com/dooboolab/react-native-iap)
|
||||
|
||||
Subscription flow:
|
||||

|
||||
Reference: https://medium.com/dooboolab/react-native-iap-v3-1259e0b0c017
|
||||
|
||||
### Creating subscription item for iOS
|
||||
`Apple Store Connect` > `My Apps` > Select an App > `Features` > `In-App Purchases` > Create your item
|
||||
|
||||
__IMPORTANT:__ Your item need to be `Ready to Submit` in RND and QA for it to purchasable.
|
||||
|
||||
__IMPORTANT 2:__ Product ID is unique and is for all apps. Even if you delete the item, you still cannot create with the same product ID even in another env.
|
||||
|
||||
### Creating subscription item for Android
|
||||
`Google Play Console` > Select an App > `Store presence` > `In-app products` > `Subscriptions` > Create your item
|
||||
|
||||
__NOTE:__ Once you activate the subscription item, there is no way to deactivate or delete.
|
||||
|
||||
### Setting up sandbox on iOS
|
||||
Create an email address under:
|
||||
`Apple Store Connect` > `Users and Access` > `Testers`
|
||||
|
||||
__Note:__ Cannot create with email that is used for existing appleID, you can create using a non-existing email address.
|
||||
There will be no purchase related email sent for sandbox purchase.
|
||||
|
||||
### Setting up sandbox on Android
|
||||
1. Make sure the email address you register for testing is the primary account in your phone.
|
||||
That means the account is the first ever account you use in your phone.
|
||||
If not, remove all gmail account, then login with that email.
|
||||
Or, create another user profile in your phone (if the function is enabled), and use the email address registered as a user
|
||||
2. Add email address in `Google Play Console > Settings > Account Details > License Testing`
|
||||
3. Add email address in one of the list in `Google Play Console > Manage email lists`
|
||||
4. Open this url with the email account you register:
|
||||
- RND: `https://play.google.com/apps/testing/com.creedon.Nixplay.rnd`
|
||||
- QA: `https://play.google.com/apps/testing/com.creedon.Nixplay.qa`
|
||||
|
||||
__Extra:__ The enabled countries might matters. Go to ` App (RND / QA) > Store presence > Pricing & distribution > Countries`, and enable the country.
|
||||
|
||||
### Subscription renewal timing
|
||||
There is no way to manually unsubscribe in iOS sandbox, need to wait.
|
||||
For Android, can unsubsribe in playstore.
|
||||
Here are the info for the timings:
|
||||
- https://help.apple.com/app-store-connect/#/dev7e89e149d
|
||||
- https://developer.android.com/google/play/billing/billing_testing#testing-renewals
|
||||
|
||||
|
||||
# Trouble Shooting
|
||||
|
||||
## xcrun: error: unable to find utility "instruments", not a developer
|
||||
|
||||
- if you have the following error message
|
||||
``` sh
|
||||
Found Xcode project TestProject.xcodeproj
|
||||
xcrun: error: unable to find utility "instruments", not a developer
|
||||
tool or in PATH
|
||||
|
||||
Command failed: xcrun instruments -s
|
||||
xcrun: error: unable to find utility "instruments", not a developer
|
||||
tool or in PATH
|
||||
```
|
||||
|
||||
```
|
||||
sudo xcode-select -s /Applications/Xcode.app
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
## Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
|
||||
|
||||
- if you have the following error
|
||||
|
||||
``` sh
|
||||
Fetching json 1.8.1
|
||||
Installing json 1.8.1 with native extensions
|
||||
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
|
||||
|
||||
current directory: /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1/ext/json/ext/generator
|
||||
/usr/local/rvm/rubies/ruby-2.3.4/bin/ruby -r ./siteconf20180608-11801-sqv5ra.rb extconf.rb
|
||||
creating Makefile
|
||||
|
||||
current directory: /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1/ext/json/ext/generator
|
||||
make "DESTDIR=" clean
|
||||
|
||||
current directory: /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1/ext/json/ext/generator
|
||||
make "DESTDIR="
|
||||
compiling generator.c
|
||||
In file included from generator.c:1:
|
||||
./../fbuffer/fbuffer.h:175:47: error: too few arguments provided to function-like macro invocation
|
||||
VALUE result = rb_str_new(FBUFFER_PAIR(fb));
|
||||
^
|
||||
/usr/local/rvm/rubies/ruby-2.3.4/include/ruby-2.3.0/ruby/intern.h:798:9: note: macro 'rb_str_new' defined here
|
||||
#define rb_str_new(str, len) __extension__ ( \
|
||||
^
|
||||
In file included from generator.c:1:
|
||||
./../fbuffer/fbuffer.h:175:11: warning: incompatible pointer to integer conversion initializing 'VALUE' (aka 'unsigned
|
||||
long') with an expression of type 'VALUE (const char *, long)' (aka 'unsigned long (const char *, long)')
|
||||
[-Wint-conversion]
|
||||
VALUE result = rb_str_new(FBUFFER_PAIR(fb));
|
||||
^ ~~~~~~~~~~
|
||||
1 warning and 1 error generated.
|
||||
make: *** [generator.o] Error 1
|
||||
|
||||
make failed, exit code 2
|
||||
|
||||
Gem files will remain installed in /usr/local/rvm/gems/ruby-2.3.4/gems/json-1.8.1 for inspection.
|
||||
Results logged to /usr/local/rvm/gems/ruby-2.3.4/extensions/x86_64-darwin-16/2.3.0/json-1.8.1/gem_make.out
|
||||
|
||||
An error occurred while installing json (1.8.1), and Bundler cannot continue.
|
||||
Make sure that `gem install json -v '1.8.1' --source 'https://rubygems.org/'` succeeds before bundling.
|
||||
```
|
||||
|
||||
run the following command to update gem file
|
||||
```
|
||||
https://github.com/flori/json/issues/229
|
||||
```
|
||||
|
||||
## 'config.h' file not found
|
||||
Copy and paste the following commands
|
||||
```
|
||||
cd ./node_modules/react-native
|
||||
./scripts/ios-install-third-party.sh
|
||||
cd third-party/glog-0.3.4
|
||||
./configure
|
||||
cd ../../../..
|
||||
```
|
||||
|
||||
## clean the cache
|
||||
|
||||
```bash
|
||||
npm run clean
|
||||
```
|
||||
|
||||
you can run any one of the command individually
|
||||
|
||||
```
|
||||
watchman watch-del-all
|
||||
rm -rf node_modules
|
||||
npm cache clean
|
||||
rm -rf android/build/
|
||||
rm -rf ./android/app/build/
|
||||
rm -rf ./android/.gradle/
|
||||
rm -rf ./android/.idea/
|
||||
rm -rf ./ios/build
|
||||
rm -rf ~/Library/Developer/Xcode/DerivedData && npm install
|
||||
```
|
||||
|
||||
|
||||
## Android subscription `item not found` in RND and QA
|
||||
Check the `Setting up sandbox on Android` section above
|
||||
@@ -0,0 +1,8 @@
|
||||
/* global jest: true */
|
||||
|
||||
jest.mock('@react-native-community/async-storage', () => ({
|
||||
getItem: () => Promise.resolve(),
|
||||
setItem: () => Promise.resolve(),
|
||||
mergeItem: () => Promise.resolve(),
|
||||
removeItem: () => Promise.resolve(),
|
||||
}));
|
||||
@@ -0,0 +1,11 @@
|
||||
/* global jest: true */
|
||||
|
||||
const geolocation = {
|
||||
setRNConfiguration: jest.fn(() => {}),
|
||||
getCurrentPosition: jest.fn(() => {}),
|
||||
watchPosition: jest.fn(() => {}),
|
||||
clearWatch: jest.fn(() => {}),
|
||||
stopObserving: jest.fn(() => {}),
|
||||
};
|
||||
|
||||
export default geolocation;
|
||||
@@ -0,0 +1,35 @@
|
||||
/* global jest: false */
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
jest.mock('@react-native-community/google-signin', () => {
|
||||
const mockGoogleSignin = require.requireActual('@react-native-community/google-signin');
|
||||
|
||||
mockGoogleSignin.GoogleSignin.hasPlayServices = () => Promise.resolve(true);
|
||||
mockGoogleSignin.GoogleSignin.configure = () => Promise.resolve();
|
||||
mockGoogleSignin.GoogleSignin.currentUserAsync = () => Promise.resolve({
|
||||
name: 'name',
|
||||
email: 'test@example.com',
|
||||
// .... other user data
|
||||
});
|
||||
|
||||
// ... and other functions you want to mock
|
||||
|
||||
return mockGoogleSignin;
|
||||
});
|
||||
|
||||
NativeModules.RNGoogleSignin = {
|
||||
BUTTON_SIZE_ICON: 0,
|
||||
BUTTON_SIZE_STANDARD: 0,
|
||||
BUTTON_SIZE_WIDE: 0,
|
||||
BUTTON_COLOR_AUTO: 0,
|
||||
BUTTON_COLOR_LIGHT: 0,
|
||||
BUTTON_COLOR_DARK: 0,
|
||||
SIGN_IN_CANCELLED: '0',
|
||||
IN_PROGRESS: '1',
|
||||
PLAY_SERVICES_NOT_AVAILABLE: '2',
|
||||
SIGN_IN_REQUIRED: '3',
|
||||
configure: jest.fn(),
|
||||
currentUserAsync: jest.fn(),
|
||||
};
|
||||
|
||||
export { NativeModules };
|
||||
@@ -0,0 +1,7 @@
|
||||
/* global jest: true */
|
||||
|
||||
jest.mock('@react-native-community/netinfo', () => ({
|
||||
getConnectionInfo: () => Promise.resolve(),
|
||||
addEventListener: jest.fn(),
|
||||
isConnected: jest.fn(),
|
||||
}));
|
||||
@@ -0,0 +1,5 @@
|
||||
/* global jest: true */
|
||||
|
||||
jest.mock('@react-native-community/push-notification-ios', () => ({
|
||||
|
||||
}));
|
||||
9
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-config.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// __mocks__/react-native-config.js
|
||||
export default {
|
||||
FOO_BAR: 'baz',
|
||||
FILE_SIZE_LIMIT: 20000000,
|
||||
MAX_WIDTH: 1820,
|
||||
MAX_HEIGHT: 1820,
|
||||
DEFAULT_VIDEO_LENGTH: 15,
|
||||
DEFAULT_MIN_VIDEO_LENGTH: 3,
|
||||
};
|
||||
16
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-creedon-imagepicker.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/* global jest: false */
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
NativeModules.RNCreedonImagepicker = {
|
||||
assets: jest.fn(),
|
||||
launchImageLibrary: jest.fn(),
|
||||
cleanupTempFiles: jest.fn(),
|
||||
addListener: jest.fn(),
|
||||
};
|
||||
|
||||
const mockRNCreedonImagepicker = jest.genMockFromModule('react-native-creedon-imagepicker');
|
||||
mockRNCreedonImagepicker.assets = () => Promise.resolve();
|
||||
mockRNCreedonImagepicker.launchImageLibrary = () => Promise.resolve();
|
||||
mockRNCreedonImagepicker.cleanupTempFiles = () => Promise.resolve();
|
||||
|
||||
module.exports = mockRNCreedonImagepicker;
|
||||
12
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-device-info.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* global jest: true */
|
||||
const deviceInfo = {
|
||||
getVersion: () => '1.0.0',
|
||||
getBuildNumber: () => '100',
|
||||
getUniqueID: () => '0',
|
||||
getDeviceId: () => '0',
|
||||
getModel: () => 'model',
|
||||
getIPAddress: jest.fn(),
|
||||
// add more methods as needed
|
||||
};
|
||||
|
||||
export default deviceInfo;
|
||||
14
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-firebase.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/* global jest: true */
|
||||
|
||||
const firebase = {
|
||||
messaging: jest.fn(() => ({
|
||||
hasPermission: jest.fn(() => new Promise(resolve => resolve(true))),
|
||||
})),
|
||||
analytics: jest.fn(() => ({
|
||||
logEvent: jest.fn(),
|
||||
setUserId: jest.fn(),
|
||||
setUserProperties: jest.fn(),
|
||||
})),
|
||||
};
|
||||
|
||||
export default firebase;
|
||||
44
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-fs.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* global jest: true */
|
||||
jest.mock('react-native-fs', () => Promise.resolve({
|
||||
mkdir: jest.fn(),
|
||||
moveFile: jest.fn(),
|
||||
copyFile: jest.fn(),
|
||||
pathForBundle: jest.fn(),
|
||||
pathForGroup: jest.fn(),
|
||||
getFSInfo: jest.fn(),
|
||||
getAllExternalFilesDirs: jest.fn(),
|
||||
unlink: jest.fn(),
|
||||
exists: jest.fn(),
|
||||
stopDownload: jest.fn(),
|
||||
resumeDownload: jest.fn(),
|
||||
isResumable: jest.fn(),
|
||||
stopUpload: jest.fn(),
|
||||
completeHandlerIOS: jest.fn(),
|
||||
readDir: jest.fn(),
|
||||
readDirAssets: jest.fn(),
|
||||
existsAssets: jest.fn(),
|
||||
readdir: jest.fn(),
|
||||
setReadable: jest.fn(),
|
||||
stat: jest.fn(),
|
||||
readFile: jest.fn(),
|
||||
read: jest.fn(),
|
||||
readFileAssets: jest.fn(),
|
||||
hash: jest.fn(),
|
||||
copyFileAssets: jest.fn(),
|
||||
copyFileAssetsIOS: jest.fn(),
|
||||
copyAssetsVideoIOS: jest.fn(),
|
||||
writeFile: jest.fn(),
|
||||
appendFile: jest.fn(),
|
||||
write: jest.fn(),
|
||||
downloadFile: jest.fn(),
|
||||
uploadFiles: jest.fn(),
|
||||
touch: jest.fn(),
|
||||
MainBundlePath: jest.fn(),
|
||||
CachesDirectoryPath: jest.fn(),
|
||||
DocumentDirectoryPath: jest.fn(),
|
||||
ExternalDirectoryPath: jest.fn(),
|
||||
ExternalStorageDirectoryPath: jest.fn(),
|
||||
TemporaryDirectoryPath: jest.fn(),
|
||||
LibraryDirectoryPath: jest.fn(),
|
||||
PicturesDirectoryPath: jest.fn(),
|
||||
}));
|
||||
14
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-gesture-handler.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/* global jest: false */
|
||||
jest.mock('NativeModules', () => ({
|
||||
UIManager: {
|
||||
RCTView: () => {},
|
||||
},
|
||||
RNGestureHandlerModule: {
|
||||
attachGestureHandler: jest.fn(),
|
||||
createGestureHandler: jest.fn(),
|
||||
dropGestureHandler: jest.fn(),
|
||||
updateGestureHandler: jest.fn(),
|
||||
State: {},
|
||||
Directions: {},
|
||||
},
|
||||
}));
|
||||
35
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-google-signin.js
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/* global jest: false */
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
jest.mock('@react-native-community/google-signin', () => {
|
||||
const mockGoogleSignin = require.requireActual('@react-native-community/google-signin');
|
||||
|
||||
mockGoogleSignin.GoogleSignin.hasPlayServices = () => Promise.resolve(true);
|
||||
mockGoogleSignin.GoogleSignin.configure = () => Promise.resolve();
|
||||
mockGoogleSignin.GoogleSignin.currentUserAsync = () => Promise.resolve({
|
||||
name: 'name',
|
||||
email: 'test@example.com',
|
||||
// .... other user data
|
||||
});
|
||||
|
||||
// ... and other functions you want to mock
|
||||
|
||||
return mockGoogleSignin;
|
||||
});
|
||||
|
||||
NativeModules.RNGoogleSignin = {
|
||||
BUTTON_SIZE_ICON: 0,
|
||||
BUTTON_SIZE_STANDARD: 0,
|
||||
BUTTON_SIZE_WIDE: 0,
|
||||
BUTTON_COLOR_AUTO: 0,
|
||||
BUTTON_COLOR_LIGHT: 0,
|
||||
BUTTON_COLOR_DARK: 0,
|
||||
SIGN_IN_CANCELLED: '0',
|
||||
IN_PROGRESS: '1',
|
||||
PLAY_SERVICES_NOT_AVAILABLE: '2',
|
||||
SIGN_IN_REQUIRED: '3',
|
||||
configure: jest.fn(),
|
||||
currentUserAsync: jest.fn(),
|
||||
};
|
||||
|
||||
export { NativeModules };
|
||||
15
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-haptic-feedback.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/* global jest: false */
|
||||
jest.mock('react-native-haptic-feedback', () => ({
|
||||
trigger: jest.fn(),
|
||||
}));
|
||||
|
||||
// import { NativeModules } from 'react-native';
|
||||
|
||||
// NativeModules.RNReactNativeHapticFeedback = {
|
||||
// trigger: jest.fn(),
|
||||
// };
|
||||
|
||||
// const ReactNativeHapticFeedback = jest.genMockFromModule('react-native-haptic-feedback');
|
||||
|
||||
|
||||
// module.exports = ReactNativeHapticFeedback;
|
||||
5
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-keychain.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/* global jest: false */
|
||||
|
||||
export const setGenericPassword = () => jest.fn();
|
||||
export const getGenericPassword = () => jest.fn(Promise.resolve(''));
|
||||
export const resetGenericPassword = () => jest.fn();
|
||||
60
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-localize.js
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/* global jest: true */
|
||||
// https://github.com/react-native-community/react-native-localize/blob/master/README.md#how-to-test-your-code
|
||||
const getLocales = () => [
|
||||
// you can choose / add the locales you want
|
||||
{
|
||||
countryCode: 'US',
|
||||
languageTag: 'en',
|
||||
languageCode: 'en',
|
||||
isRTL: false,
|
||||
},
|
||||
{
|
||||
countryCode: 'DE',
|
||||
languageTag: 'de',
|
||||
languageCode: 'de',
|
||||
isRTL: false,
|
||||
},
|
||||
{
|
||||
countryCode: 'JA',
|
||||
languageTag: 'ja',
|
||||
languageCode: 'ja',
|
||||
isRTL: false,
|
||||
},
|
||||
];
|
||||
|
||||
// use a provided translation, or return undefined to test your fallback
|
||||
const findBestAvailableLanguage = () => ({
|
||||
languageTag: 'en',
|
||||
isRTL: false,
|
||||
});
|
||||
|
||||
const getNumberFormatSettings = () => ({
|
||||
decimalSeparator: '.',
|
||||
groupingSeparator: ',',
|
||||
});
|
||||
|
||||
const getCalendar = () => 'gregorian'; // or 'japanese', 'buddhist'
|
||||
const getCountry = () => 'US'; // the country code you want
|
||||
const getCurrencies = () => ['USD', 'EUR']; // can be empty array
|
||||
const getTemperatureUnit = () => 'celsius'; // or 'fahrenheit'
|
||||
const getTimeZone = () => 'Europe/Paris'; // the timezone you want
|
||||
const uses24HourClock = () => true;
|
||||
const usesMetricSystem = () => true;
|
||||
|
||||
const addEventListener = jest.fn();
|
||||
const removeEventListener = jest.fn();
|
||||
|
||||
export {
|
||||
findBestAvailableLanguage,
|
||||
getLocales,
|
||||
getNumberFormatSettings,
|
||||
getCalendar,
|
||||
getCountry,
|
||||
getCurrencies,
|
||||
getTemperatureUnit,
|
||||
getTimeZone,
|
||||
uses24HourClock,
|
||||
usesMetricSystem,
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
};
|
||||
10
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-nixplay-core.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/* global jest: true */
|
||||
const NixplayCore = jest.genMockFromModule('react-native-nixplay-core');
|
||||
|
||||
NixplayCore.setUploadSessionIdentifier = () => Promise.resolve();
|
||||
NixplayCore.setApiURL = () => Promise.resolve();
|
||||
NixplayCore.setBucketPrefix = () => Promise.resolve();
|
||||
NixplayCore.setFileSizeLimit = () => Promise.resolve();
|
||||
NixplayCore.startUpload = () => Promise.resolve();
|
||||
|
||||
export default NixplayCore;
|
||||
13
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-push-notification.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* global jest: true */
|
||||
|
||||
const PushNotification = jest.genMockFromModule('react-native-push-notification');
|
||||
|
||||
PushNotification.configure = jest.fn();
|
||||
PushNotification.onRegister = jest.fn();
|
||||
PushNotification.onNotification = jest.fn();
|
||||
PushNotification.addEventListener = jest.fn();
|
||||
PushNotification.requestPermissions = jest.fn();
|
||||
PushNotification.cancelAllLocalNotifications = jest.fn();
|
||||
PushNotification.setApplicationIconBadgeNumber = jest.fn();
|
||||
|
||||
export default PushNotification;
|
||||
3
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-reanimated.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
const NativeEventEmitter = {};
|
||||
|
||||
export default NativeEventEmitter;
|
||||
14
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-safe-area.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/* global jest: true */
|
||||
const SafeArea = {};
|
||||
|
||||
SafeArea.getSafeAreaInsetsForRootView = () => ({
|
||||
safeAreaInsets: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
},
|
||||
});
|
||||
SafeArea.addEventListener = jest.fn();
|
||||
|
||||
export default SafeArea;
|
||||
7
ioneapps-maagapp-ee31119a522d/__mocks__/react-native-share-extension.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/* global jest: true */
|
||||
|
||||
const ShareExtension = {
|
||||
data: jest.fn(() => Promise.resolve({})),
|
||||
close: jest.fn(() => Promise.resolve(true)),
|
||||
};
|
||||
export default ShareExtension;
|
||||
@@ -0,0 +1,8 @@
|
||||
/* global jest: true */
|
||||
|
||||
const FilesystemStorage = {
|
||||
getItem: jest.fn(() => Promise.resolve()),
|
||||
setItem: jest.fn(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
export default FilesystemStorage;
|
||||
159
ioneapps-maagapp-ee31119a522d/__tests__/reducers/albums.js
Normal file
@@ -0,0 +1,159 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { albums as albumsReducer, initialState } from '~/reducers/albums';
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
GET_ALBUMS,
|
||||
CREATE_ALBUM,
|
||||
GET_ALBUMS_SUCCESS,
|
||||
GET_ALBUMS_ERROR,
|
||||
CREATE_ALBUM_ERROR,
|
||||
GET_ALBUM_CONTENT,
|
||||
GET_ALBUM_CONTENT_SUCCESS,
|
||||
GET_ALBUM_CONTENT_ERROR,
|
||||
CREATE_ALBUM_SUCCESS,
|
||||
LOGOUT_SUCCESS,
|
||||
|
||||
} from '~/store/actionTypes';
|
||||
import {
|
||||
DEFAULT_ALBUM_NAME,
|
||||
DEFAULT_ALBUM_TYPE,
|
||||
} from '~/store/contentTypes';
|
||||
|
||||
describe('albums reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(albumsReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with loading when type is GET_ALBUMS or CREATE_ALBUM', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
expect(albumsReducer(initialState, { type: GET_ALBUMS })).toEqual(expectedState);
|
||||
expect(albumsReducer(initialState, { type: CREATE_ALBUM })).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return albums with meta property when type is GET_ALBUMS_SUCCESS', () => {
|
||||
const albums = [{ id: 1 }, { id: 2 }];
|
||||
const stateResult = albumsReducer(undefined, { type: GET_ALBUMS_SUCCESS, payload: { albums } });
|
||||
expect(stateResult).toHaveProperty('albums');
|
||||
expect(stateResult.albums).toHaveLength(albums.length);
|
||||
stateResult.albums.forEach(album => {
|
||||
expect(album).toHaveProperty('meta');
|
||||
});
|
||||
});
|
||||
|
||||
test('CASE 5: should return correct state when type is GET_ALBUMS_ERROR or CREATE_ALBUM_ERROR', () => {
|
||||
const albumErr = new Error('getAlbumsError');
|
||||
const expectedState = { ...initialState, meta: { error: albumErr, loading: false } };
|
||||
expect(albumsReducer(initialState, {
|
||||
type: GET_ALBUMS_ERROR,
|
||||
payload: { error: albumErr },
|
||||
})).toEqual(expectedState);
|
||||
expect(albumsReducer(initialState, {
|
||||
type: CREATE_ALBUM_ERROR,
|
||||
payload: { error: albumErr },
|
||||
})).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6: should return state with album loading to TRUE when type is GET_ALBUM_CONTENT', () => {
|
||||
const albums = [{ id: 1 }, { id: 2 }];
|
||||
const payload = {
|
||||
albumId: 1,
|
||||
};
|
||||
const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
const stateResult = albumsReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
type: GET_ALBUM_CONTENT,
|
||||
payload,
|
||||
});
|
||||
const expectedStateAlbums = [
|
||||
{ id: 1, meta: { error: '', loading: true } },
|
||||
{ id: 2 },
|
||||
];
|
||||
expect(stateResult.albums).toEqual(expectedStateAlbums);
|
||||
});
|
||||
|
||||
test('CASE 7: should return state with album content when type is GET_ALBUM_CONTENT_SUCCESS', () => {
|
||||
const albums = [{ id: 1 }, { id: 2 }];
|
||||
const content = [
|
||||
{ id: 5 }, // photo id
|
||||
{ id: 4 }, // photo id
|
||||
];
|
||||
const payload = {
|
||||
albumId: 1,
|
||||
content,
|
||||
};
|
||||
const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
const stateResult = albumsReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
type: GET_ALBUM_CONTENT_SUCCESS,
|
||||
payload,
|
||||
});
|
||||
expect(stateResult.albums[0]).toHaveProperty('content', _.orderBy(content, ['id'], ['desc']));
|
||||
// expect(stateResult.albums[0]).toHaveProperty('cover');
|
||||
// expect(stateResult.albums[0]).toHaveProperty('thumbs');
|
||||
});
|
||||
|
||||
test('CASE 8: should return state with album error when type is GET_ALBUM_CONTENT_ERROR', () => {
|
||||
const albums = [{ id: 1 }, { id: 2 }];
|
||||
const albumErr = new Error('getAlbumsContentError');
|
||||
const payload = {
|
||||
albumId: 1,
|
||||
error: albumErr,
|
||||
};
|
||||
const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
const stateResult = albumsReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
type: GET_ALBUM_CONTENT_ERROR,
|
||||
payload,
|
||||
});
|
||||
const expectedStateAlbums = [
|
||||
{ id: 1, meta: { error: albumErr, loading: false } },
|
||||
{ id: 2 },
|
||||
];
|
||||
expect(stateResult.albums).toEqual(expectedStateAlbums);
|
||||
});
|
||||
|
||||
test('CASE 9: should add album on CREATE_ALBUM_SUCCESS with meta', () => {
|
||||
const albums = [{ id: 2 }, { id: 3 }];
|
||||
const payload = {
|
||||
album: { id: 1 },
|
||||
};
|
||||
const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
const stateResult = albumsReducer({ albums, ...originalState, meta: { error: '' } }, {
|
||||
type: CREATE_ALBUM_SUCCESS,
|
||||
payload,
|
||||
});
|
||||
const expectedStateAlbums = [
|
||||
{ id: 1, meta: { error: '', loading: false } },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
];
|
||||
expect(stateResult.albums).toEqual(expectedStateAlbums);
|
||||
});
|
||||
|
||||
test('CASE 10: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
const existingState = [{ id: 1 }, { id: 2 }];
|
||||
expect(albumsReducer(existingState, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 11: should return albums with defaultAlbumId property when type is GET_ALBUMS_SUCCESS', () => {
|
||||
const albums = [{ id: 1, name: DEFAULT_ALBUM_NAME, type: DEFAULT_ALBUM_TYPE }, { id: 2 }];
|
||||
const stateResult = albumsReducer(undefined, { type: GET_ALBUMS_SUCCESS, payload: { albums } });
|
||||
expect(stateResult).toHaveProperty('albums');
|
||||
expect(stateResult).toHaveProperty('defaultAlbumId');
|
||||
expect(stateResult.albums).toHaveLength(albums.length);
|
||||
expect(stateResult.defaultAlbumId).toEqual(1);
|
||||
stateResult.albums.forEach(album => {
|
||||
expect(album).toHaveProperty('meta');
|
||||
});
|
||||
});
|
||||
test('CASE 12: should return albums with defaultAlbumId 0 property when type is GET_ALBUMS_SUCCESS', () => {
|
||||
const albums = [{ id: 1 }, { id: 2 }];
|
||||
const stateResult = albumsReducer(undefined, { type: GET_ALBUMS_SUCCESS, payload: { albums } });
|
||||
expect(stateResult).toHaveProperty('albums');
|
||||
expect(stateResult).toHaveProperty('defaultAlbumId');
|
||||
expect(stateResult.albums).toHaveLength(albums.length);
|
||||
expect(stateResult.defaultAlbumId).toEqual(0);
|
||||
stateResult.albums.forEach(album => {
|
||||
expect(album).toHaveProperty('meta');
|
||||
});
|
||||
});
|
||||
});
|
||||
71
ioneapps-maagapp-ee31119a522d/__tests__/reducers/app.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { app } from '~/reducers/app';
|
||||
import {
|
||||
CHANGE_APP_ROOT,
|
||||
UPDATE_APP_STATE,
|
||||
UPDATE_SHOW_NOTIFICATION,
|
||||
ACCEPT_TNC_LICENSE,
|
||||
ACCEPT_TNC_LICENSE_SUCCESS,
|
||||
ACCEPT_TNC_LICENSE_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
|
||||
describe('app reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
const expectedState = {
|
||||
root: 'splash',
|
||||
sharedPlaylistOnboardingTutorialState: 0,
|
||||
location: 'United States',
|
||||
appStatus: 'active',
|
||||
hasLoggedInOnce: false,
|
||||
showNotification: false,
|
||||
fromSplashScreen: false,
|
||||
ssid: '',
|
||||
config: {},
|
||||
};
|
||||
expect(app(undefined, { type: 'Default' }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return the correct state when actionType is `CHANGE_APP_ROOT` and payload is valid root', () => {
|
||||
const expectedState = { root: 'home' };
|
||||
expect(app({}, { type: CHANGE_APP_ROOT, payload: { root: 'home' } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return the initial state when actionType is `CHANGE_APP_ROOT` and payload is not valid root', () => {
|
||||
const expectedState = {};
|
||||
expect(app({}, { type: CHANGE_APP_ROOT, payload: { root: 'something else' } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 8: default should return the appStatus active', () => {
|
||||
const expectedState = { appStatus: 'active' };
|
||||
expect(app({ appStatus: 'active' }, { type: UPDATE_APP_STATE, payload: 'active' }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 9: default should return the showNotification false', () => {
|
||||
const expectedState = { showNotification: false };
|
||||
expect(app({ showNotification: false }, { type: UPDATE_SHOW_NOTIFICATION, payload: false }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 10: default should return the state ACCEPT_TNC_LICENSE', () => {
|
||||
const expectedState = { config: { user_accepted_tnc: true } };
|
||||
expect(app({ config: { user_accepted_tnc: true } }, { type: ACCEPT_TNC_LICENSE, payload: false }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 11: default should return the state ACCEPT_TNC_LICENSE_SUCCESS', () => {
|
||||
const expectedState = { config: { user_accepted_tnc: true } };
|
||||
expect(app({ config: { user_accepted_tnc: true } }, { type: ACCEPT_TNC_LICENSE_SUCCESS, payload: false }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 12: default should return the config error', () => {
|
||||
const expectedState = { config: {} };
|
||||
expect(app({ config: {} }, { type: ACCEPT_TNC_LICENSE_ERROR, payload: false }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
122
ioneapps-maagapp-ee31119a522d/__tests__/reducers/avatar.js
Normal file
@@ -0,0 +1,122 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import {
|
||||
avatar as avatarReducer,
|
||||
initialState,
|
||||
} from '~/reducers/avatar';
|
||||
import {
|
||||
GET_AVATAR_UPLOADPOLICY,
|
||||
GET_AVATAR_UPLOADPOLICY_SUCCESS,
|
||||
GET_AVATAR_UPLOADPOLICY_ERROR,
|
||||
GET_AVATAR,
|
||||
GET_AVATAR_SUCCESS,
|
||||
GET_AVATAR_ERROR,
|
||||
ACTIVATE_AVATAR,
|
||||
ACTIVATE_AVATAR_SUCCESS,
|
||||
ACTIVATE_AVATAR_ERROR,
|
||||
DELETE_AVATAR,
|
||||
DELETE_AVATAR_SUCCESS,
|
||||
DELETE_AVATAR_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('avatar reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(avatarReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
test('CASE 2: should return state with meta set to loading when type is GET_AVATAR', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: GET_AVATAR, payload: {},
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 3: should return state with meta set to loading when type is ACTIVATE_AVATAR', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: ACTIVATE_AVATAR, payload: {},
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 4: should return state with meta set to loading when type is GET_AVATAR_UPLOADPOLICY', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: GET_AVATAR_UPLOADPOLICY, payload: {},
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 5: should return state with meta set to loading when type is DELETE_AVATAR', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: DELETE_AVATAR, payload: {},
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 6: should return state with error when type is GET_AVATAR_ERROR', () => {
|
||||
const error = new Error('getAvatarError');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, error } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: GET_AVATAR_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 6: should return state with error when type is ACTIVATE_AVATAR_ERROR', () => {
|
||||
const error = new Error('activateAvatarError');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, error } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: ACTIVATE_AVATAR_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 8: should return state with error when type is GET_AVATAR_UPLOADPOLICY_ERROR', () => {
|
||||
const error = new Error('getUploadPolicyAvatarError');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, error } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: GET_AVATAR_UPLOADPOLICY_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 9: should return state with error when type is DELETE_AVATAR_ERROR', () => {
|
||||
const error = new Error('deleteAvatarError');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, error } };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: DELETE_AVATAR_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 10: should return state with meta set to loading when type is GET_AVATAR_SUCCESS', () => {
|
||||
const payload = { uri: undefined };
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: GET_AVATAR_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult.source).toEqual(payload);
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
test('CASE 11: should return state with meta set to loading when type is ACTIVATE_AVATAR_SUCCESS', () => {
|
||||
const payload = { uri: undefined };
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: ACTIVATE_AVATAR_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult.source).toEqual(payload);
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
test('CASE 12: should return state with meta set to loading when type is GET_AVATAR_UPLOADPOLICY_SUCCESS', () => {
|
||||
const payload = { };
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: GET_AVATAR_UPLOADPOLICY_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult.uploadPolicy).toEqual(payload);
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
test('CASE 13: should return state with meta set to loading when type is DELETE_AVATAR_SUCCESS', () => {
|
||||
const payload = { };
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = avatarReducer(initialState, {
|
||||
type: DELETE_AVATAR_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult).toEqual(initialState);
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { framePairing as framePairingReducer, initialState } from '~/reducers/framePairing';
|
||||
import {
|
||||
FRAME_DISCOVER_START,
|
||||
FRAME_DISCOVER_STARTED_SUCCESS,
|
||||
FRAME_DISCOVER_ERROR,
|
||||
FRAME_DISCOVER_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('framePairing reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(framePairingReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with loading when type is FRAME_DISCOVER_START or FRAME_DISCOVER_STARTED_SUCCESS', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
expect(framePairingReducer(initialState, {
|
||||
type: FRAME_DISCOVER_START,
|
||||
})).toEqual(expectedState);
|
||||
expect(framePairingReducer(initialState, {
|
||||
type: FRAME_DISCOVER_STARTED_SUCCESS,
|
||||
})).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return frames with meta property when type is FRAME_DISCOVER_SUCCESS', () => {
|
||||
const services = [{
|
||||
txt: {
|
||||
serialNumber: '',
|
||||
model: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
txt: {
|
||||
serialNumber: '',
|
||||
model: 2,
|
||||
},
|
||||
}];
|
||||
const specs = {
|
||||
1: {
|
||||
name: '',
|
||||
colors: [1, 2],
|
||||
photo: [
|
||||
'',
|
||||
'',
|
||||
],
|
||||
},
|
||||
2: {
|
||||
name: '',
|
||||
colors: [1, 2],
|
||||
photo: [
|
||||
'',
|
||||
'',
|
||||
],
|
||||
},
|
||||
};
|
||||
const stateResult = framePairingReducer(undefined, {
|
||||
type: FRAME_DISCOVER_SUCCESS,
|
||||
payload: { services, specs },
|
||||
});
|
||||
expect(stateResult).toHaveProperty('frames');
|
||||
expect(stateResult.frames).toHaveLength(services.length);
|
||||
expect(stateResult).toHaveProperty('meta');
|
||||
});
|
||||
|
||||
test('CASE 5: should return correct state when type is FRAME_DISCOVER_ERROR', () => {
|
||||
const err = new Error('discoverFrameErr');
|
||||
const expectedState = { ...initialState, meta: { error: err, loading: false } };
|
||||
expect(framePairingReducer(initialState, {
|
||||
type: FRAME_DISCOVER_ERROR,
|
||||
payload: { error: err },
|
||||
})).toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
438
ioneapps-maagapp-ee31119a522d/__tests__/reducers/frames.js
Normal file
@@ -0,0 +1,438 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { frames as framesReducer, initialState } from '~/reducers/frames';
|
||||
import Factory from 'helper/factories/api';
|
||||
import {
|
||||
GET_FRAMES,
|
||||
GET_FRAMES_SUCCESS,
|
||||
GET_FRAMES_ERROR,
|
||||
LOGOUT_SUCCESS,
|
||||
GET_FRAME_STATE_SUCCESS,
|
||||
GET_FRAME_STATE_ERROR,
|
||||
SET_CURRENT_FRAME_PLAYLIST,
|
||||
GET_FRAMES_STATUS_SUCCESS,
|
||||
SET_FRAME_POWER_STATE_SUCCESS,
|
||||
SET_CURRENT_FRAME,
|
||||
UPDATE_FRAME_PLAYLIST_ASSIGNMENT,
|
||||
GET_FRAME_STATE,
|
||||
UNPAIR_FRAME,
|
||||
UNPAIR_FRAME_SUCCESS,
|
||||
UNPAIR_FRAME_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
import { FRAME_ORIENTATION, FRAME_POWER } from '~/store/frameConstants';
|
||||
|
||||
describe('frames reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(framesReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with meta set to loading when type is GET_FRAMES', () => {
|
||||
const frames = [{ id: 1 }, { id: 2 }];
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = framesReducer(initialState, {
|
||||
type: GET_FRAMES, payload: { frames },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3a: should return with removed frame with existing frameState when type is GET_FRAMES_SUCCESS', () => {
|
||||
const frames = [{
|
||||
id: 1,
|
||||
}];
|
||||
const currentState = {
|
||||
framePreventPlaylistAssignChange: {},
|
||||
frames: ['1ea790afd4c67c77', 'U6XYMRIEWBJ82RLL'].map((f, i) => (
|
||||
{ id: i, ...Factory.build('FrameState', { frameId: f }) })),
|
||||
};
|
||||
const meta = { loading: false, error: '' };
|
||||
const specs = { 'W08A-01': { colors: [], photo: {} } };
|
||||
const stateResult = framesReducer(currentState, {
|
||||
type: GET_FRAMES_SUCCESS, payload: { frames, specs },
|
||||
});
|
||||
expect(stateResult.frames[0]).toHaveProperty('meta', meta);
|
||||
expect(stateResult.frames[0]).toHaveProperty('orientation');
|
||||
expect(stateResult.frames[0]).toHaveProperty('power');
|
||||
expect(stateResult.frames).toHaveLength(frames.length);
|
||||
});
|
||||
|
||||
test('CASE 3b: should return with added frame with existing frameState and needUpdate as true when type is GET_FRAMES_SUCCESS', () => {
|
||||
const frames = [
|
||||
{ id: 1, softwareVersion: '5.0.0' },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
];
|
||||
const currentState = {
|
||||
framePreventPlaylistAssignChange: {},
|
||||
frames: ['1ea790afd4c67c77', 'U6XYMRIEWBJ82RLL'].map((f, i) => (
|
||||
{ id: i, softwareVersion: '5.0.0', ...Factory.build('FrameState', { frameId: f }) })),
|
||||
};
|
||||
|
||||
const meta = { loading: false, error: '' };
|
||||
const specs = { 'W08A-01': { colors: [], photo: {}, minVersionSupported: '6.0.0' } };
|
||||
const stateResult = framesReducer(currentState, {
|
||||
type: GET_FRAMES_SUCCESS, payload: { frames, specs },
|
||||
});
|
||||
expect(stateResult.frames[0]).toHaveProperty('meta', meta);
|
||||
expect(stateResult.frames[0]).toHaveProperty('orientation');
|
||||
expect(stateResult.frames[0]).toHaveProperty('power');
|
||||
expect(stateResult.frames[0]).toHaveProperty('needUpdate', true);
|
||||
expect(stateResult.frames).toHaveLength(frames.length);
|
||||
});
|
||||
|
||||
test('CASE 3c: should return with added frame with existing frameState and needUpdate set to false when type is GET_FRAMES_SUCCESS and checkEnabled is false', () => {
|
||||
const frames = [
|
||||
{ id: 1, softwareVersion: '5.0.0' },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
];
|
||||
const currentState = {
|
||||
framePreventPlaylistAssignChange: {},
|
||||
frames: ['1ea790afd4c67c77', 'U6XYMRIEWBJ82RLL'].map((f, i) => (
|
||||
{ id: i, softwareVersion: '5.0.0', ...Factory.build('FrameState', { frameId: f }) })),
|
||||
};
|
||||
|
||||
const meta = { loading: false, error: '' };
|
||||
const specs = { 'W08A-01': { colors: [], photo: {}, minVersionSupported: '6.0.0' } };
|
||||
const stateResult = framesReducer(currentState, {
|
||||
type: GET_FRAMES_SUCCESS, payload: { frames, specs, checkEnabled: false },
|
||||
});
|
||||
expect(stateResult.frames[0]).toHaveProperty('meta', meta);
|
||||
expect(stateResult.frames[0]).toHaveProperty('orientation');
|
||||
expect(stateResult.frames[0]).toHaveProperty('power');
|
||||
expect(stateResult.frames[0]).toHaveProperty('needUpdate', false);
|
||||
expect(stateResult.frames).toHaveLength(frames.length);
|
||||
});
|
||||
|
||||
test('CASE 5: should return state with error and loading = `false` when type is GET_FRAMES_ERROR', () => {
|
||||
const error = new Error('getFramesError');
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
meta:
|
||||
{ ...initialState.meta, error, loading: false },
|
||||
};
|
||||
const stateResult = framesReducer(initialState, {
|
||||
type: GET_FRAMES_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
const existingState = [{ id: 1 }, { id: 2 }];
|
||||
expect(framesReducer(existingState, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 7a: should return state with frameState on GET_FRAME_STATE_SUCCESS', () => {
|
||||
const playlistId = 321;
|
||||
const existingState = { framePreventPlaylistPlayingChange: {}, framePreventPowerChange: {}, frames: [{ id: 1, frameId: '1ea790afd4c67c77', playlists: [{ id: playlistId }] }, { id: 2 }] };
|
||||
const expectedState = {
|
||||
framePreventPlaylistPlayingChange: {},
|
||||
framePreventPowerChange: {},
|
||||
frames: [
|
||||
{
|
||||
id: 1,
|
||||
frameId: '1ea790afd4c67c77',
|
||||
orientation: FRAME_ORIENTATION.LANDSCAPE,
|
||||
slideshow: playlistId,
|
||||
playlists: [{ id: playlistId }],
|
||||
power: 'on',
|
||||
},
|
||||
{ id: 2 },
|
||||
],
|
||||
meta: { stateLoading: false, error: '' },
|
||||
};
|
||||
|
||||
const frameState = Factory.build('FrameState', { frameId: existingState.frames[0].frameId, slideshow: { value: playlistId } });
|
||||
expect(framesReducer(existingState, { type: GET_FRAME_STATE_SUCCESS, payload: { frameState } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 7b: should return state with slideshow=`-1` on GET_FRAME_STATE_SUCCESS when playlist is no longer assigned', () => {
|
||||
const playlistId = 321;
|
||||
const existingState = { framePreventPlaylistPlayingChange: {}, framePreventPowerChange: {}, frames: [{ id: 1, frameId: '1ea790afd4c67c77', playlists: [] }, { id: 2 }] };
|
||||
const expectedState = {
|
||||
framePreventPlaylistPlayingChange: {},
|
||||
framePreventPowerChange: {},
|
||||
frames: [
|
||||
{
|
||||
id: 1,
|
||||
frameId: '1ea790afd4c67c77',
|
||||
orientation: FRAME_ORIENTATION.LANDSCAPE,
|
||||
slideshow: -1,
|
||||
playlists: [],
|
||||
power: 'on',
|
||||
},
|
||||
{ id: 2 },
|
||||
],
|
||||
meta: { stateLoading: false, error: '' },
|
||||
};
|
||||
|
||||
const frameState = Factory.build('FrameState', { frameId: existingState.frames[0].frameId, slideshow: { value: playlistId } });
|
||||
expect(framesReducer(existingState, { type: GET_FRAME_STATE_SUCCESS, payload: { frameState } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 7c: should return state with slideshow=`-1` on GET_FRAME_STATE_SUCCESS when frameState.slideshow is `null`', () => {
|
||||
const playlistId = 'null';
|
||||
const existingState = { framePreventPlaylistPlayingChange: {}, framePreventPowerChange: {}, frames: [{ id: 1, frameId: '1ea790afd4c67c77', playlists: [] }, { id: 2 }] };
|
||||
const expectedState = {
|
||||
framePreventPlaylistPlayingChange: {},
|
||||
framePreventPowerChange: {},
|
||||
frames: [
|
||||
{
|
||||
id: 1,
|
||||
frameId: '1ea790afd4c67c77',
|
||||
orientation: FRAME_ORIENTATION.LANDSCAPE,
|
||||
slideshow: -1,
|
||||
playlists: [],
|
||||
power: 'on',
|
||||
},
|
||||
{ id: 2 },
|
||||
],
|
||||
meta: { stateLoading: false, error: '' },
|
||||
};
|
||||
|
||||
const frameState = Factory.build('FrameState', { frameId: existingState.frames[0].frameId, slideshow: { value: playlistId } });
|
||||
expect(framesReducer(existingState, { type: GET_FRAME_STATE_SUCCESS, payload: { frameState } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 8: should return state with corrent frame playlist on SET_CURRENT_FRAME_PLAYLIST', () => {
|
||||
const existingState = {
|
||||
frames: [
|
||||
{
|
||||
id: 1,
|
||||
frameId: '1ea790afd4c67c77',
|
||||
orientation: FRAME_ORIENTATION.LANDSCAPE,
|
||||
slideshow: 123,
|
||||
power: 'on',
|
||||
},
|
||||
{ id: 2 },
|
||||
],
|
||||
};
|
||||
|
||||
const payload = {
|
||||
framePk: 1,
|
||||
playlistId: 234,
|
||||
};
|
||||
expect(framesReducer(existingState, { type: SET_CURRENT_FRAME_PLAYLIST, payload }).frames[0])
|
||||
.toHaveProperty('slideshow', 234);
|
||||
});
|
||||
|
||||
test('CASE 9: should return state with correct frameState on GET_FRAMES_STATUS_SUCCESS', () => {
|
||||
const framesStatus = {
|
||||
frames: [
|
||||
{ lastSeen: null, lastConnected: null, framePk: 17544 },
|
||||
{ lastSeen: 1535338881548, lastConnected: 1535338819374, framePk: 18122 },
|
||||
{
|
||||
connected: true, lastSeen: 1539065938946, lastConnected: 1539065965182, framePk: 18429,
|
||||
},
|
||||
{
|
||||
connected: true, lastSeen: 1539066031822, lastConnected: 1539066063638, framePk: 18438,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const currentState = {
|
||||
frames: [17544, 18122, 18429, 18438, 18433].map((f) => (
|
||||
{ id: f, ...Factory.build('FrameState') })),
|
||||
};
|
||||
|
||||
const payload = { framesStatus };
|
||||
const newState = framesReducer(currentState, { type: GET_FRAMES_STATUS_SUCCESS, payload });
|
||||
expect(newState.frames)
|
||||
.toEqual(expect.arrayContaining(framesStatus.frames.map(() =>
|
||||
expect.objectContaining({ online: expect.any(Boolean) }))));
|
||||
});
|
||||
|
||||
test('CASE 10: should return state with frameState on SET_FRAME_POWER_STATE_SUCCESS', () => {
|
||||
const emptyObject = {};
|
||||
const currentState = {
|
||||
framePreventPowerChange: { 1: true },
|
||||
};
|
||||
|
||||
const payload = { framePk: 1, powerState: FRAME_POWER.OFF };
|
||||
const newState = framesReducer(currentState, { type: SET_FRAME_POWER_STATE_SUCCESS, payload });
|
||||
expect(newState)
|
||||
.toHaveProperty('framePreventPowerChange', emptyObject);
|
||||
});
|
||||
|
||||
test('CASE 11: should return currentFrameId set to the payload.id when action is SET_CURRENT_FRAME', () => {
|
||||
const currentState = {
|
||||
frames: [
|
||||
{ id: 1 },
|
||||
{ id: 2 },
|
||||
],
|
||||
currentFrameId: 2,
|
||||
};
|
||||
|
||||
const payload = { id: 1 };
|
||||
const newState = framesReducer(currentState, { type: SET_CURRENT_FRAME, payload });
|
||||
expect(newState)
|
||||
.toHaveProperty('currentFrameId', 1);
|
||||
});
|
||||
|
||||
test('CASE 12: should return state with loading = `false` on GET_FRAME_STATE_ERROR', () => {
|
||||
const currentState = {
|
||||
framePreventPlaylistAssignChange: {},
|
||||
framePreventPlaylistPlayingChange: {},
|
||||
framePreventPowerChange: {},
|
||||
frames: [],
|
||||
currentFrameId: 0,
|
||||
meta: {
|
||||
loading: true,
|
||||
stateLoading: false,
|
||||
statusLoading: false,
|
||||
error: '',
|
||||
},
|
||||
};
|
||||
|
||||
const newState = framesReducer(initialState, { type: GET_FRAME_STATE_ERROR });
|
||||
expect(newState)
|
||||
.toEqual(currentState);
|
||||
});
|
||||
|
||||
test('CASE 13a: should return state with updated playlists when operation = `add` on UPDATE_FRAME_PLAYLIST_ASSIGNMENT', () => {
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
currentFrameId: 0,
|
||||
meta: { loading: false, error: '' },
|
||||
};
|
||||
const playlistIds = [103];
|
||||
const payload = { frameIds, playlistIds, operation: 'add' };
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: UPDATE_FRAME_PLAYLIST_ASSIGNMENT, payload },
|
||||
);
|
||||
expect(newState.frames)
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
playlists: [
|
||||
{ id: expect.any(Number) },
|
||||
{ id: expect.any(Number) },
|
||||
{ id: expect.any(Number) },
|
||||
],
|
||||
})]));
|
||||
});
|
||||
|
||||
test('CASE 13b: should return state with removed playlists when operation = `remove` on UPDATE_FRAME_PLAYLIST_ASSIGNMENT', () => {
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
currentFrameId: 0,
|
||||
meta: { loading: false, error: '' },
|
||||
};
|
||||
const playlistIds = [currentState.frames[0].playlists[0].id];
|
||||
const payload = { frameIds, playlistIds, operation: 'remove' };
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: UPDATE_FRAME_PLAYLIST_ASSIGNMENT, payload },
|
||||
);
|
||||
expect(newState.frames)
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
playlists: [
|
||||
{ id: expect.any(Number) },
|
||||
],
|
||||
})]));
|
||||
});
|
||||
|
||||
test('CASE 13c: should return state with new playlists when operation is not specified on UPDATE_FRAME_PLAYLIST_ASSIGNMENT', () => {
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
currentFrameId: 0,
|
||||
meta: { loading: false, error: '' },
|
||||
};
|
||||
const playlistIds = [111];
|
||||
const payload = { frameIds, playlistIds };
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: UPDATE_FRAME_PLAYLIST_ASSIGNMENT, payload },
|
||||
);
|
||||
expect(newState.frames)
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
playlists: [
|
||||
{ id: playlistIds[0] },
|
||||
],
|
||||
})]));
|
||||
});
|
||||
|
||||
test('CASE 14: should return state loading = `false` when action is GET_FRAME_STATE', () => {
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
currentFrameId: 0,
|
||||
meta: { error: '' },
|
||||
};
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: GET_FRAME_STATE },
|
||||
);
|
||||
expect(newState.meta)
|
||||
.toEqual({ stateLoading: true, error: '' });
|
||||
});
|
||||
|
||||
test('CASE 15: should return state loading = `true` when action is UNPAIR_FRAME', () => {
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
currentFrameId: 0,
|
||||
meta: { error: '' },
|
||||
};
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: UNPAIR_FRAME },
|
||||
);
|
||||
expect(newState.meta)
|
||||
.toEqual({ loading: true, error: '' });
|
||||
});
|
||||
test('CASE 16: should return state loading = `false` when action is UNPAIR_FRAME_SUCCESS', () => {
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
|
||||
const specs = { 'W08A-01': { colors: [], photo: {} } };
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
specs,
|
||||
currentFrameId: 0,
|
||||
meta: { error: '', loading: false },
|
||||
};
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: UNPAIR_FRAME_SUCCESS, payload: { framePk: 0 } },
|
||||
);
|
||||
expect(newState.meta)
|
||||
.toEqual({ loading: false, error: '' });
|
||||
});
|
||||
test('CASE 17: should return state loading = `false` error message when action is UNPAIR_FRAME_ERROR', () => {
|
||||
const error = 'unpair frame error';
|
||||
const frameIds = [17544, 18122, 18429, 18438, 18433];
|
||||
const currentState = {
|
||||
frames: frameIds.map((f) => (
|
||||
Factory.build('Frame', { id: f })
|
||||
)),
|
||||
currentFrameId: 0,
|
||||
meta: { error: '' },
|
||||
};
|
||||
const newState = framesReducer(
|
||||
currentState,
|
||||
{ type: UNPAIR_FRAME_ERROR, payload: { error } },
|
||||
);
|
||||
expect(newState.meta)
|
||||
.toEqual({ loading: false, error });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { initialState, friendActivities } from '~/reducers/friendActivities';
|
||||
import {
|
||||
GET_COMMENTS_SUCCESS,
|
||||
DELETE_ACTIVITY_PHOTO,
|
||||
DELETE_ACTIVITY_PHOTO_ERROR,
|
||||
DELETE_ACTIVITY_PHOTO_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
import Factory from 'helper/factories/api';
|
||||
|
||||
describe('friendActivities reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(friendActivities(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2a: should return with comments when comment is related to the friend and actionType is GET_COMMENTS_SUCCESS', () => {
|
||||
const friend = { username: 'friend@mynixplay.com' };
|
||||
const originalState = {
|
||||
friend,
|
||||
nextTimestamp: 0,
|
||||
activities: [],
|
||||
};
|
||||
const comments = Factory.buildList('Comment', 2, { friend: friend.username });
|
||||
const payload = { comments };
|
||||
const newState = friendActivities(originalState, { type: GET_COMMENTS_SUCCESS, payload });
|
||||
expect(newState.mediaViewer.comments)
|
||||
.toHaveLength(2);
|
||||
});
|
||||
|
||||
test('CASE 2b: should return without comments when comment is not related to the friend and actionType is GET_COMMENTS_SUCCESS', () => {
|
||||
const friend = { username: 'friend@mynixplay.com' };
|
||||
const originalState = {
|
||||
friend,
|
||||
nextTimestamp: 0,
|
||||
activities: [],
|
||||
};
|
||||
const comments = Factory.buildList('Comment', 2, { friend: 'other@mynixplay.com' });
|
||||
const payload = { comments };
|
||||
const newState = friendActivities(originalState, { type: GET_COMMENTS_SUCCESS, payload });
|
||||
expect(newState.mediaViewer.comments)
|
||||
.toHaveLength(0);
|
||||
});
|
||||
|
||||
test('CASE 3: friendActivities should update meta loading state when type is DELETE_ACTIVITY_PHOTO', (s3Key = '', albumId = '', timestamp = '', friend = '') => {
|
||||
const existingState = { ...initialState, meta: { loading: true, error: '' } };
|
||||
const stateResult = friendActivities(existingState, {
|
||||
type: DELETE_ACTIVITY_PHOTO,
|
||||
payload: {
|
||||
s3Key,
|
||||
albumId,
|
||||
timestamp,
|
||||
friend,
|
||||
},
|
||||
});
|
||||
expect(stateResult).toEqual(existingState);
|
||||
});
|
||||
|
||||
test('CASE 4: friendActivities should update meta loading state when type is DELETE_ACTIVITY_PHOTO_ERROR', () => {
|
||||
const existingState = { ...initialState, actions: { submitting: false, error: '' } };
|
||||
const stateResult = friendActivities(existingState, {
|
||||
type: DELETE_ACTIVITY_PHOTO_ERROR,
|
||||
payload: {
|
||||
error: '',
|
||||
},
|
||||
});
|
||||
expect(stateResult).toEqual(existingState);
|
||||
});
|
||||
|
||||
test('CASE 5: friendActivities should update meta loading state when type is DELETE_ACTIVITY_PHOTO_SUCCESS', (s3Key = '', albumId = '', timestamp = '', friend = '') => {
|
||||
const existingState = { ...initialState, meta: { loading: false, error: '' } };
|
||||
const stateResult = friendActivities(existingState, {
|
||||
type: DELETE_ACTIVITY_PHOTO_SUCCESS,
|
||||
payload: {
|
||||
s3Key,
|
||||
albumId,
|
||||
timestamp,
|
||||
friend,
|
||||
},
|
||||
});
|
||||
expect(stateResult).toEqual(existingState);
|
||||
});
|
||||
});
|
||||
187
ioneapps-maagapp-ee31119a522d/__tests__/reducers/friends.js
Normal file
@@ -0,0 +1,187 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import {
|
||||
friends as friendsReducer,
|
||||
initialState,
|
||||
initAddFriend,
|
||||
addFriend as addFriendReducer,
|
||||
} from '~/reducers/friends';
|
||||
import {
|
||||
GET_FRIENDS,
|
||||
GET_FRIENDS_SUCCESS,
|
||||
GET_FRIENDS_ERROR,
|
||||
UPDATE_SEEN_TIMESTAMP_SUCCESS,
|
||||
LOGOUT_SUCCESS,
|
||||
UPDATE_ADD_FRIEND,
|
||||
ACCEPT_FRIEND_INVITE_SUCCESS,
|
||||
ACCEPT_FRIEND_INVITE_ERROR,
|
||||
REJECT_FRIEND_INVITE_SUCCESS,
|
||||
REJECT_FRIEND_INVITE_ERROR,
|
||||
RESET_ADD_FRIEND_ERROR,
|
||||
RESET_ADD_FRIEND_PLAYLIST,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('friends reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(friendsReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with meta set to loading when type is GET_FRIENDS', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = friendsReducer(initialState, {
|
||||
type: GET_FRIENDS, payload: {},
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return state with meta set to loading when type is GET_FRIENDS_SUCCESS', () => {
|
||||
const friends = [{ username: '1', activity: { timestamp: 0 } }, { username: '2', activity: { timestamp: 0 } }];
|
||||
const invites = [{ requester: '1' }, { requester: '2' }];
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = friendsReducer(initialState, {
|
||||
type: GET_FRIENDS_SUCCESS, payload: { friends: { friends, invites } },
|
||||
});
|
||||
expect(stateResult.friends).toEqual([]);
|
||||
expect(stateResult.invites[0]).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 4: should return state with error when type is GET_FRIENDS_ERROR', () => {
|
||||
const error = new Error('getFriendsError');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, error } };
|
||||
const stateResult = friendsReducer(initialState, {
|
||||
type: GET_FRIENDS_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 5: should return state when type is UPDATE_SEEN_TIMESTAMP_SUCCESS', () => {
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = friendsReducer(initialState, { type: UPDATE_SEEN_TIMESTAMP_SUCCESS });
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 6: should return state with loading = false when type is ACCEPT_FRIEND_INVITE_SUCCESS', () => {
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = friendsReducer(initialState, { type: ACCEPT_FRIEND_INVITE_SUCCESS });
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 7: should return state with loading = false when type is ACCEPT_FRIEND_INVITE_ERROR', () => {
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = friendsReducer(initialState, { type: ACCEPT_FRIEND_INVITE_ERROR, payload: { error: '' } });
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 8: should return state with loading = false when type is REJECT_FRIEND_INVITE_SUCCESS', () => {
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = friendsReducer(initialState, { type: REJECT_FRIEND_INVITE_SUCCESS });
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 9: should return state with loading = false when type is REJECT_FRIEND_INVITE_ERROR', () => {
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = friendsReducer(initialState, { type: REJECT_FRIEND_INVITE_ERROR, payload: { error: '' } });
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 10: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
const existingState = {};
|
||||
expect(friendsReducer(existingState, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 11: addFriend should return initial state', () => {
|
||||
expect(addFriendReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initAddFriend);
|
||||
});
|
||||
|
||||
test('CASE 12: addFriend should return state when type is UPDATE_ADD_FRIEND', () => {
|
||||
const stateResult = friendsReducer(initAddFriend, {
|
||||
type: UPDATE_ADD_FRIEND,
|
||||
payload: {
|
||||
lookupKey: '',
|
||||
friendName: '',
|
||||
playlistId: -1,
|
||||
hasError: '',
|
||||
isNewPlaylist: 0,
|
||||
popCount: 2,
|
||||
},
|
||||
});
|
||||
expect(stateResult).toEqual(initAddFriend);
|
||||
});
|
||||
|
||||
test('CASE 13: addFriend should update error state when type is UPDATE_ADD_FRIEND', (hasError = '') => {
|
||||
const {
|
||||
lookupKey,
|
||||
friendName,
|
||||
playlistId,
|
||||
isNewPlaylist,
|
||||
} = initAddFriend;
|
||||
const stateResult = friendsReducer(initAddFriend, {
|
||||
type: RESET_ADD_FRIEND_ERROR,
|
||||
payload: {
|
||||
lookupKey,
|
||||
friendName,
|
||||
playlistId,
|
||||
hasError,
|
||||
isNewPlaylist,
|
||||
},
|
||||
});
|
||||
expect(stateResult).toEqual(initAddFriend);
|
||||
});
|
||||
|
||||
test('CASE 14: addFriend should update error state when type is RESET_ADD_FRIEND_ERROR', (hasError = '') => {
|
||||
const stateResult = friendsReducer(initAddFriend, {
|
||||
type: RESET_ADD_FRIEND_ERROR,
|
||||
payload: { hasError },
|
||||
});
|
||||
expect(stateResult).toEqual(initAddFriend);
|
||||
});
|
||||
|
||||
test('CASE 15: addFriend should update error state when type is RESET_ADD_FRIEND_PLAYLIST', (isNewPlaylist = 0) => {
|
||||
const stateResult = friendsReducer(initAddFriend, {
|
||||
type: RESET_ADD_FRIEND_PLAYLIST,
|
||||
payload: { isNewPlaylist },
|
||||
});
|
||||
expect(stateResult).toEqual(initAddFriend);
|
||||
});
|
||||
|
||||
test('CASE 16: Badge should be true when a new friend invite has been added to state GET_FRIENDS_SUCCESS', () => {
|
||||
const existingState = { ...initialState, invites: [{ requester: '1' }, { requester: '2' }] };
|
||||
const friends = {
|
||||
invites: [{ requester: '1' }, { requester: '3' }],
|
||||
friends: [{ username: '1', activity: { timestamp: 0 } }],
|
||||
};
|
||||
const stateResult = friendsReducer(existingState, {
|
||||
type: GET_FRIENDS_SUCCESS,
|
||||
payload: { friends },
|
||||
});
|
||||
expect(stateResult).toHaveProperty('isBadged', true);
|
||||
});
|
||||
|
||||
test('CASE 17: Badge should be true when a new friend invite GET_FRIENDS_SUCCESS', () => {
|
||||
const existingState = { ...initialState, invites: [{ requester: '1' }, { requester: '2' }] };
|
||||
const friends = {
|
||||
invites: [{ requester: '1' }],
|
||||
friends: [{ username: '1', activity: { timestamp: 0 } }],
|
||||
};
|
||||
const stateResult = friendsReducer(existingState, {
|
||||
type: GET_FRIENDS_SUCCESS,
|
||||
payload: { friends },
|
||||
});
|
||||
expect(stateResult).toHaveProperty('isBadged', false);
|
||||
});
|
||||
|
||||
test('CASE 18: Badge should be true when a friend gets a new activity', () => {
|
||||
const existingState = { ...initialState, invites: [], friends: [{ username: '1', activity: { timestamp: 1 } }] };
|
||||
const friends = {
|
||||
invites: [],
|
||||
friends: [{ username: '1', activity: { timestamp: 2 } }],
|
||||
};
|
||||
const stateResult = friendsReducer(existingState, {
|
||||
type: GET_FRIENDS_SUCCESS,
|
||||
payload: { friends },
|
||||
});
|
||||
expect(stateResult).toHaveProperty('isBadged', false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { fujifilmCategories as fujifilmCategoriesReducer, initialState } from '~/reducers/fujifilmCategories';
|
||||
import {
|
||||
GET_FUJIFILM_CHILD_CATEGORY_PROPDUCTS_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('fujifilmCategories reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(fujifilmCategoriesReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
test('CASE 2: should return correct state when type is GET_FUJIFILM_CHILD_CATEGORY_PROPDUCTS_SUCCESS', () => {
|
||||
const categoryId = 1;
|
||||
const products = [{
|
||||
ProductCode: '1',
|
||||
}, {
|
||||
ProductCode: '2',
|
||||
}];
|
||||
const serviceType = 'MailOrder';
|
||||
const childCategoryProducts = {
|
||||
1: [{
|
||||
ProductCode: '1',
|
||||
}, {
|
||||
ProductCode: '2',
|
||||
}],
|
||||
};
|
||||
|
||||
const stateResult = fujifilmCategoriesReducer(initialState, {
|
||||
type: GET_FUJIFILM_CHILD_CATEGORY_PROPDUCTS_SUCCESS,
|
||||
payload: { categoryId, products, serviceType },
|
||||
});
|
||||
|
||||
expect(stateResult).toHaveProperty('childCategoryProducts');
|
||||
expect(stateResult.childCategoryProducts).toEqual(childCategoryProducts);
|
||||
expect(stateResult).toHaveProperty('meta');
|
||||
});
|
||||
});
|
||||
335
ioneapps-maagapp-ee31119a522d/__tests__/reducers/google.js
Normal file
@@ -0,0 +1,335 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { google as googleReducer, initialState } from '~/reducers/google';
|
||||
import {
|
||||
SET_GOOGLE_INFO,
|
||||
GET_GOOGLE_TOKEN,
|
||||
GET_GOOGLE_TOKEN_SUCCESS,
|
||||
LOGOUT_SUCCESS,
|
||||
LOGOUT_FROM_GOOGLE_SUCCESS,
|
||||
GET_GOOGLE_TOKEN_ERROR,
|
||||
GET_GOOGLE_ALBUMS,
|
||||
GET_GOOGLE_CATEGORIES,
|
||||
GET_GOOGLE_ALBUMS_ERROR,
|
||||
GET_GOOGLE_CATEGORIES_ERROR,
|
||||
GET_GOOGLE_ALBUMS_SUCCESS,
|
||||
GET_GOOGLE_CATEGORIES_SUCCESS,
|
||||
GET_DYNAMIC_PLAYLISTS_ERROR,
|
||||
GET_DYNAMIC_PLAYLISTS_SUCCESS,
|
||||
GET_GOOGLE_ALBUM_CONTENT_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
import Factory from 'helper/factories/google';
|
||||
|
||||
describe('google reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(googleReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with Google info set when type is SET_GOOGLE_INFO', () => {
|
||||
const googleInfo = {
|
||||
email: 'user@gmail.com',
|
||||
photo: 'https://lh4.googleusercontent.com/photo.jpg',
|
||||
idToken: '{idToken}',
|
||||
id: '{id}',
|
||||
familyName: '{lastName}',
|
||||
serverAuthCode: '{serverAuthCode}',
|
||||
accessToken: '{accessToken}',
|
||||
givenName: '{firstName}',
|
||||
accessTokenExpirationDate: 3260.7057960033417,
|
||||
name: '{firstName} {lastName}',
|
||||
};
|
||||
const expectedState = { ...initialState, auth: googleInfo };
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: SET_GOOGLE_INFO, payload: googleInfo,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return state with meta set when type is GET_GOOGLE_TOKEN', () => {
|
||||
const expectedState = initialState;
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_GOOGLE_TOKEN,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 4: should return state with Google set when type is GET_GOOGLE_TOKEN_SUCCESS', () => {
|
||||
const googleInfo = {
|
||||
email: 'user@gmail.com',
|
||||
photo: 'https://lh4.googleusercontent.com/photo.jpg',
|
||||
idToken: '{idToken}',
|
||||
id: '{id}',
|
||||
familyName: '{lastName}',
|
||||
serverAuthCode: '{serverAuthCode}',
|
||||
accessToken: '{accessToken}',
|
||||
givenName: '{firstName}',
|
||||
accessTokenExpirationDate: 3260.7057960033417,
|
||||
name: '{firstName} {lastName}',
|
||||
};
|
||||
const googleToken = { googleId: googleInfo.email, valid: true };
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
auth: googleInfo,
|
||||
};
|
||||
const stateResult = googleReducer({ ...initialState, auth: googleInfo }, {
|
||||
type: GET_GOOGLE_TOKEN_SUCCESS,
|
||||
payload: { googleToken },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 5: should return state with Google unset when type is GET_GOOGLE_TOKEN_SUCCESS and server Token is invalid', () => {
|
||||
const googleInfo = {
|
||||
email: 'user@gmail.com',
|
||||
photo: 'https://lh4.googleusercontent.com/photo.jpg',
|
||||
idToken: '{idToken}',
|
||||
id: '{id}',
|
||||
familyName: '{lastName}',
|
||||
serverAuthCode: '{serverAuthCode}',
|
||||
accessToken: '{accessToken}',
|
||||
givenName: '{firstName}',
|
||||
accessTokenExpirationDate: 3260.7057960033417,
|
||||
name: '{firstName} {lastName}',
|
||||
};
|
||||
const googleToken = { googleId: googleInfo.email, valid: false };
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
auth: {},
|
||||
};
|
||||
const stateResult = googleReducer({ ...initialState, auth: googleInfo }, {
|
||||
type: GET_GOOGLE_TOKEN_SUCCESS,
|
||||
payload: { googleToken },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6: should return state with Google unset when type is GET_GOOGLE_TOKEN_SUCCESS and server Token is valid but googleId does not match the email', () => {
|
||||
const googleInfo = {
|
||||
email: 'user@gmail.com',
|
||||
photo: 'https://lh4.googleusercontent.com/photo.jpg',
|
||||
idToken: '{idToken}',
|
||||
id: '{id}',
|
||||
familyName: '{lastName}',
|
||||
serverAuthCode: '{serverAuthCode}',
|
||||
accessToken: '{accessToken}',
|
||||
givenName: '{firstName}',
|
||||
accessTokenExpirationDate: 3260.7057960033417,
|
||||
name: '{firstName} {lastName}',
|
||||
};
|
||||
const googleToken = { googleId: 'other@gmail.com', valid: true };
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
auth: {},
|
||||
};
|
||||
const stateResult = googleReducer({ ...initialState, auth: googleInfo }, {
|
||||
type: GET_GOOGLE_TOKEN_SUCCESS,
|
||||
payload: { googleToken },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 7: should return state with meta loading set to false when actionType is GET_GOOGLE_TOKEN_ERROR', () => {
|
||||
const expectedState = initialState;
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_GOOGLE_TOKEN_ERROR,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 7: should return initialState when actionType is LOGOUT_FROM_GOOGLE_SUCCESS', () => {
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: LOGOUT_FROM_GOOGLE_SUCCESS,
|
||||
});
|
||||
expect(stateResult).toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 8: should return initialState when actionType is LOGOUT_SUCCESS', () => {
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: LOGOUT_SUCCESS,
|
||||
});
|
||||
expect(stateResult).toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 9: should return loading for albums set to true when actionType is GET_GOOGLE_ALBUMS', () => {
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
meta: { loading: { ...initialState.meta.loading, albums: true } },
|
||||
};
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_GOOGLE_ALBUMS,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 10: should return loading for categories set to true when actionType is GET_GOOGLE_CATEGORIES', () => {
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
meta: { loading: { ...initialState.meta.loading, categories: true } },
|
||||
};
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_GOOGLE_CATEGORIES,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 11: should return loading for categories set to false when actionType is GET_GOOGLE_ALBUMS_ERROR', () => {
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
meta: { loading: { ...initialState.meta.loading, categories: false } },
|
||||
};
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_GOOGLE_ALBUMS_ERROR,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 12: should return loading for categories set to false when actionType is GET_GOOGLE_CATEGORIES_ERROR', () => {
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
meta: { loading: { ...initialState.meta.loading, categories: false } },
|
||||
};
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_GOOGLE_CATEGORIES_ERROR,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 12: should return albums with alreadySynced set correctly when actionType is GET_GOOGLE_ALBUMS_SUCCESS', () => {
|
||||
const googleId = 'user@gmail.com';
|
||||
const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
|
||||
const albums = Factory.buildList('GoogleAlbum', 2);
|
||||
const prevState = {
|
||||
auth: { email: googleId },
|
||||
categories: [],
|
||||
albums: [],
|
||||
allPhotos: {},
|
||||
playlists,
|
||||
meta: { loading: { albums: false, categories: false } },
|
||||
};
|
||||
const expectedState = {
|
||||
...prevState,
|
||||
meta: { loading: { ...initialState.meta.loading, categories: false } },
|
||||
albums: [
|
||||
{ title: 'Album 1', id: 'album1', alreadySynced: true },
|
||||
{ title: 'Album 2', id: 'album2', alreadySynced: true },
|
||||
],
|
||||
allPhotos: {},
|
||||
};
|
||||
const stateResult = googleReducer(prevState, {
|
||||
type: GET_GOOGLE_ALBUMS_SUCCESS,
|
||||
payload: albums,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 13: should return categories with alreadySynced set correctly when actionType is GET_GOOGLE_CATEGORIES_SUCCESS', () => {
|
||||
const googleId = 'user@gmail.com';
|
||||
const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
|
||||
const categories = [
|
||||
{ id: 'ANIMAL' },
|
||||
{ id: 'PEOPLE' },
|
||||
{ id: 'LANDSCAPE' },
|
||||
];
|
||||
const prevState = {
|
||||
auth: { email: googleId },
|
||||
categories: [],
|
||||
albums: [],
|
||||
playlists,
|
||||
meta: { loading: { albums: false, categories: false } },
|
||||
};
|
||||
const expectedState = {
|
||||
...prevState,
|
||||
meta: { loading: { ...initialState.meta.loading, categories: false } },
|
||||
categories: [
|
||||
{ id: 'ANIMAL', alreadySynced: true },
|
||||
{ id: 'PEOPLE', alreadySynced: true },
|
||||
{ id: 'LANDSCAPE' },
|
||||
],
|
||||
allPhotos: { alreadySynced: false },
|
||||
};
|
||||
const stateResult = googleReducer(prevState, {
|
||||
type: GET_GOOGLE_CATEGORIES_SUCCESS,
|
||||
payload: { categories, allPhotos: {} },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 14: should return alreadySynced set correctly when actionType is GET_DYNAMIC_PLAYLISTS_SUCCESS', () => {
|
||||
const googleId = 'user@gmail.com';
|
||||
const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
|
||||
const albums = Factory.buildList('GoogleAlbum', 2);
|
||||
const categories = [
|
||||
{ id: 'ANIMAL' },
|
||||
{ id: 'PEOPLE' },
|
||||
{ id: 'LANDSCAPE' },
|
||||
];
|
||||
const prevState = {
|
||||
auth: { email: googleId },
|
||||
categories,
|
||||
albums,
|
||||
playlists: [],
|
||||
meta: { loading: { albums: false, categories: false } },
|
||||
allPhotos: {},
|
||||
};
|
||||
const expectedState = {
|
||||
...prevState,
|
||||
meta: { loading: { albums: false, categories: false } },
|
||||
categories: [
|
||||
{ id: 'ANIMAL', alreadySynced: true },
|
||||
{ id: 'PEOPLE', alreadySynced: true },
|
||||
{ id: 'LANDSCAPE' },
|
||||
],
|
||||
albums,
|
||||
playlists,
|
||||
allPhotos: { alreadySynced: false },
|
||||
};
|
||||
const stateResult = googleReducer(prevState, {
|
||||
type: GET_DYNAMIC_PLAYLISTS_SUCCESS,
|
||||
payload: { google: playlists },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
|
||||
test('CASE 15: should return categories with alreadySynced set correctly when actionType is GET_DYNAMIC_PLAYLISTS_ERROR', () => {
|
||||
const stateResult = googleReducer(initialState, {
|
||||
type: GET_DYNAMIC_PLAYLISTS_ERROR,
|
||||
});
|
||||
expect(stateResult).toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 16: should return album with mediaItems set correctly when actionType is GET_GOOGLE_ALBUM_CONTENT_SUCCESS', () => {
|
||||
const googleId = 'user@gmail.com';
|
||||
const playlists = Factory.buildList('DynamicPlaylist', 4, { googleId });
|
||||
const albums = Factory.buildList('GoogleAlbum', 1);
|
||||
const prevState = {
|
||||
auth: { email: googleId },
|
||||
albums,
|
||||
playlists,
|
||||
meta: { loading: { albums: false, categories: false } },
|
||||
};
|
||||
|
||||
const payload = {
|
||||
title: albums[0].title,
|
||||
id: albums[0].id,
|
||||
mediaItems: [
|
||||
{ id: 'AGj1epUmh4wiG3g2bKOKDoclVoRTsE-_STHFhWdUdhvR142wa0wx4-y-rb9mYq2363Cr0_Gid19iJw4' },
|
||||
{ id: 'AGj1epWNpu29AtPtEyX3ICRDLOcxyUxhCt45UG1C4swn1me84xFxculsQDCJaclsC3mBeX54MBM7HL8' },
|
||||
{ id: 'AGj1epWAvBQE-WStq6wzHkv-4oW28J154cd5SU4KDCUTL-XB9hJdxyT7GCaOLett4qVyRXFFmYHpYJ4' },
|
||||
],
|
||||
};
|
||||
|
||||
const expectedState = {
|
||||
...prevState,
|
||||
meta: { loading: { albums: false, categories: false } },
|
||||
albums: [payload],
|
||||
playlists,
|
||||
};
|
||||
|
||||
const stateResult = googleReducer(prevState, {
|
||||
type: GET_GOOGLE_ALBUM_CONTENT_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
17
ioneapps-maagapp-ee31119a522d/__tests__/reducers/locale.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { locale } from '~/reducers/locale';
|
||||
import { CHANGE_LOCALE } from '~/store/actionTypes';
|
||||
|
||||
describe('locale reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
const expectedState = { locale: 'en' };
|
||||
expect(locale(undefined, { type: 'Default' }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return correct state when action is `CHANGE_LOCALE`', () => {
|
||||
const expectedState = { locale: 'de' };
|
||||
expect(locale(undefined, { type: CHANGE_LOCALE, payload: { locale: 'de' } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
121
ioneapps-maagapp-ee31119a522d/__tests__/reducers/photoPrint.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { photoPrint as photoPrintReducer, initialState } from '~/reducers/photoPrint';
|
||||
import {
|
||||
PLACE_PHOTO_PRINT_ORDER,
|
||||
PLACE_PHOTO_PRINT_ORDER_SUCCESS,
|
||||
PLACE_PHOTO_PRINT_ORDER_ERROR,
|
||||
SET_PHOTOS_TO_QUEUE,
|
||||
SET_PHOTOS_TO_QUEUE_SUCCESS,
|
||||
SET_PHOTOS_TO_QUEUE_ERROR,
|
||||
REMOVE_PHOTO_FROM_QUEUE,
|
||||
REMOVE_PHOTO_FROM_QUEUE_SUCCESS,
|
||||
REMOVE_PHOTO_FROM_QUEUE_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('photoPrint reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(photoPrintReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
test('CASE 2: should return state with loading when type is PLACE_PHOTO_PRINT_ORDER, SET_PHOTOS_TO_QUEUE or REMOVE_PHOTO_FROM_QUEUE', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
expect(photoPrintReducer(initialState, { type: PLACE_PHOTO_PRINT_ORDER })).toEqual(expectedState);
|
||||
expect(photoPrintReducer(initialState, { type: SET_PHOTOS_TO_QUEUE })).toEqual(expectedState);
|
||||
expect(photoPrintReducer(initialState, { type: REMOVE_PHOTO_FROM_QUEUE })).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 4: should return correct state when type is PLACE_PHOTO_PRINT_ORDER_SUCCESS', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: false }, orderNumbers: ['1234567'] };
|
||||
expect(photoPrintReducer(
|
||||
initialState,
|
||||
{
|
||||
type: PLACE_PHOTO_PRINT_ORDER_SUCCESS,
|
||||
payload: {
|
||||
orderNumber: '1234567',
|
||||
},
|
||||
},
|
||||
)).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 5: should return correct state when type is REMOVE_PHOTO_FROM_QUEUE_SUCCESS', () => {
|
||||
const images = ['image1', 'image2', 'image3'];
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
images,
|
||||
count: 3,
|
||||
meta: {
|
||||
...initialState.meta,
|
||||
loading: false,
|
||||
},
|
||||
};
|
||||
expect(photoPrintReducer(
|
||||
initialState,
|
||||
{
|
||||
type: REMOVE_PHOTO_FROM_QUEUE_SUCCESS,
|
||||
payload: {
|
||||
images,
|
||||
},
|
||||
},
|
||||
)).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6: should return correct state when type is SET_PHOTOS_TO_QUEUE_SUCCESS', () => {
|
||||
const images = ['image1', 'image2', 'image3'];
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
images,
|
||||
count:
|
||||
3,
|
||||
meta:
|
||||
{
|
||||
...initialState.meta,
|
||||
loading:
|
||||
false,
|
||||
},
|
||||
};
|
||||
expect(photoPrintReducer(
|
||||
initialState,
|
||||
{
|
||||
type: SET_PHOTOS_TO_QUEUE_SUCCESS,
|
||||
payload: {
|
||||
images,
|
||||
},
|
||||
},
|
||||
)).toEqual(expectedState);
|
||||
});
|
||||
|
||||
|
||||
test('CASE 7: should return error state when type is PLACE_PHOTO_PRINT_ORDER_ERROR', () => {
|
||||
const error = new Error('Error');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: false, error } };
|
||||
expect(photoPrintReducer(
|
||||
initialState,
|
||||
{
|
||||
type: PLACE_PHOTO_PRINT_ORDER_ERROR,
|
||||
payload: { error },
|
||||
},
|
||||
)).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 8: should return error state when type is SET_PHOTOS_TO_QUEUE_ERROR', () => {
|
||||
const error = new Error('Error');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: false, error } };
|
||||
expect(photoPrintReducer(
|
||||
initialState,
|
||||
{
|
||||
type: SET_PHOTOS_TO_QUEUE_ERROR,
|
||||
payload: { error },
|
||||
},
|
||||
)).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 9: should return error state when type is REMOVE_PHOTO_FROM_QUEUE_ERROR', () => {
|
||||
const error = new Error('Error');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: false, error } };
|
||||
expect(photoPrintReducer(
|
||||
initialState,
|
||||
{
|
||||
type: REMOVE_PHOTO_FROM_QUEUE_ERROR,
|
||||
payload: { error },
|
||||
},
|
||||
)).toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
339
ioneapps-maagapp-ee31119a522d/__tests__/reducers/playlists.js
Normal file
@@ -0,0 +1,339 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { playlists as playlistsReducer, initialState } from '~/reducers/playlists';
|
||||
import {
|
||||
GET_PLAYLISTS,
|
||||
GET_PLAYLISTS_SUCCESS,
|
||||
GET_PLAYLISTS_ERROR,
|
||||
GET_PLAYLIST_CONTENT,
|
||||
GET_PLAYLIST_CONTENT_SUCCESS,
|
||||
GET_PLAYLIST_CONTENT_ERROR,
|
||||
LOGOUT_SUCCESS,
|
||||
CREATE_DYNAMIC_PLAYLIST_SUCCESS,
|
||||
GET_DYNAMIC_PLAYLISTS_SUCCESS,
|
||||
UPLOAD_ITEM_STARTED,
|
||||
UPLOAD_ITEMS_SUCCESS,
|
||||
UPLOAD_ITEMS_ERROR,
|
||||
PLAYLIST_PROCESSING_STARTED,
|
||||
PLAYLIST_PROCESSING_DONE,
|
||||
UPLOAD_SUCCESS,
|
||||
UPLOAD_ALL_CANCELLED,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
import Factory from 'helper/factories/api';
|
||||
|
||||
describe('playlists reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(playlistsReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with meta set to loading when type is GET_PLAYLISTS', () => {
|
||||
const playlists = [{ id: 1 }, { id: 2 }];
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: false } };
|
||||
const stateResult = playlistsReducer(initialState, {
|
||||
type: GET_PLAYLISTS, payload: { playlists },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3a: should return state with playlist content merged with dynamic playlist when type is GET_PLAYLISTS_SUCCESS', () => {
|
||||
const playlists = Factory.buildList('Playlist', 6);
|
||||
const googleId = 'someone@gmail.com';
|
||||
const dynamicPlaylists = playlists.map(playlist => Factory.build('GoogleDynamicPlaylist', { playlistId: playlist.id, googleId }));
|
||||
const statePlaylists = playlists.map((item) => ({ ...item, slides: [{ url: 'url' }] }));
|
||||
const originalState = {
|
||||
...initialState, playlists: statePlaylists, dynamicPlaylists,
|
||||
};
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLISTS_SUCCESS, payload: { playlists },
|
||||
});
|
||||
expect(stateResult.playlists).toEqual(expect.arrayContaining([expect.objectContaining({
|
||||
name: expect.any(String),
|
||||
googleId: expect.any(String),
|
||||
status: expect.any(String),
|
||||
slides: expect.any(Array),
|
||||
dynamicPlaylistName: expect.any(String),
|
||||
lastSynced: expect.any(String),
|
||||
})]));
|
||||
});
|
||||
|
||||
test('CASE 3b: should return state with playlist content merged with dynamic playlist when type is GET_PLAYLISTS_SUCCESS', () => {
|
||||
const playlists = Factory.buildList('Playlist', 1);
|
||||
const googleId = 'someone@gmail.com';
|
||||
const dynamicPlaylists = playlists.map(playlist => Factory.build('GoogleDynamicPlaylist', { playlistId: playlist.id, googleId }));
|
||||
const originalState = { ...initialState, dynamicPlaylists };
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLISTS_SUCCESS, payload: { playlists },
|
||||
});
|
||||
expect(stateResult.playlists).toEqual(expect.arrayContaining([expect.objectContaining({
|
||||
name: expect.any(String),
|
||||
googleId: expect.any(String),
|
||||
status: expect.any(String),
|
||||
dynamicPlaylistName: expect.any(String),
|
||||
lastSynced: expect.any(String),
|
||||
googleCollectionType: expect.any(String),
|
||||
})]));
|
||||
});
|
||||
|
||||
test('CASE 3c: should return state with playlist content merged with dynamic playlist when type is GET_PLAYLISTS_SUCCESS', () => {
|
||||
const playlists = Factory.buildList('Playlist', 1);
|
||||
const googleId = 'someone@gmail.com';
|
||||
const dynamicPlaylists = playlists.map(playlist => Factory.build('GoogleDynamicPlaylist', { playlistId: playlist.id, googleId }));
|
||||
const statePlaylists = playlists.map((item) => ({ ...item, slides: [{ url: 'url' }] }));
|
||||
const originalState = {
|
||||
...initialState, playlists: statePlaylists, dynamicPlaylists,
|
||||
};
|
||||
const count = Math.floor((Math.random() * 500) + 1);
|
||||
const thumbs = [0, 1, 2].map(item => ({ src: `https://loremflickr.com/1024/768/cats?asdf=${item}`, rotation: 0, orientation: 1 }));
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLISTS_SUCCESS, payload: { playlists: [{ ...playlists[0], count, thumbs }] },
|
||||
});
|
||||
// The count and thumbs properties should be overridden by the new playlists data
|
||||
expect(stateResult.playlists[0].count).toEqual(count);
|
||||
expect(stateResult.playlists[0].thumbs).toEqual(thumbs);
|
||||
});
|
||||
|
||||
test('CASE 4: should return state with error when type is GET_PLAYLISTS_ERROR', () => {
|
||||
const error = new Error('getPlaylistError');
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, error } };
|
||||
const stateResult = playlistsReducer(initialState, {
|
||||
type: GET_PLAYLISTS_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 5: should return state with meta set to loading when type is GET_PLAYLIST_CONTENT', () => {
|
||||
const playlists = [
|
||||
{ id: 1 },
|
||||
{ id: 2 },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
const payload = { playlistId: 1 };
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
playlists: [{
|
||||
id: 1,
|
||||
meta: { error: '', loading: true },
|
||||
},
|
||||
{ id: 2 }],
|
||||
meta: { error: '', loading: false, uploading: false },
|
||||
};
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLIST_CONTENT, payload,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6a: should return state with playlist content set when type is GET_PLAYLIST_CONTENT_SUCCESS', () => {
|
||||
const playlists = [
|
||||
{ id: 1 },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
const payload = {
|
||||
playlistId: 1,
|
||||
playlist: { name: 'PL one', slides: [] },
|
||||
offset: 0,
|
||||
};
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLIST_CONTENT_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult.playlists[0]).toHaveProperty('name', payload.playlist.name);
|
||||
expect(stateResult.playlists[0]).toHaveProperty('slides');
|
||||
// expect(stateResult.playlists[0]).toHaveProperty('thumbs');
|
||||
});
|
||||
|
||||
test('CASE 6b: GET_PLAYLIST_CONTENT_SUCCESS should combine playlist slides if offset is > 0', () => {
|
||||
const initialSlides = ['a', 'b', 'c'];
|
||||
const nextSlides = ['d', 'e', 'f'];
|
||||
const playlists = [
|
||||
{
|
||||
id: 1, slides: initialSlides, pictureCount: 6, offset: 3,
|
||||
},
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
const payload = {
|
||||
playlistId: 1,
|
||||
playlist: {
|
||||
name: 'PL one',
|
||||
slides: nextSlides,
|
||||
offset: 5,
|
||||
pictureCount: 6,
|
||||
},
|
||||
startOffset: 3,
|
||||
endOffset: 6,
|
||||
};
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLIST_CONTENT_SUCCESS, payload,
|
||||
});
|
||||
expect(stateResult.playlists[0]).toHaveProperty('slides', [...initialSlides, ...nextSlides]);
|
||||
});
|
||||
|
||||
test('CASE 7: should return state error when type is GET_PLAYLIST_CONTENT_ERROR', () => {
|
||||
const playlists = [
|
||||
{ id: 1, meta: { error: '', loading: true } },
|
||||
{ id: 2, meta: { error: '', loading: false } },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
// console.log({ originalState: JSON.stringify(originalState) });
|
||||
const error = new Error('getPlaylistError');
|
||||
const payload = {
|
||||
playlistId: 1,
|
||||
error,
|
||||
};
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
playlists: [{
|
||||
id: 1,
|
||||
meta: { error, loading: false },
|
||||
},
|
||||
{ id: 2, meta: { error: '', loading: false } }],
|
||||
meta: { error: '', loading: false, uploading: false },
|
||||
};
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_PLAYLIST_CONTENT_ERROR, payload,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 9: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
const existingState = [{ id: 1 }, { id: 2 }];
|
||||
expect(playlistsReducer(existingState, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 10: should current state on CREATE_DYNAMIC_PLAYLIST_SUCCESS', () => {
|
||||
const existingState = [{ id: 1 }, { id: 2 }];
|
||||
expect(playlistsReducer(existingState, { type: CREATE_DYNAMIC_PLAYLIST_SUCCESS }))
|
||||
.toEqual(existingState);
|
||||
});
|
||||
|
||||
test('CASE 11: should return state with dynamicPlaylist set when type is GET_DYNAMIC_PLAYLISTS_SUCCESS', () => {
|
||||
const playlists = Factory.buildList('Playlist', 6);
|
||||
const googleId = 'someone@gmail.com';
|
||||
const dynamicPlaylists = playlists.map(playlist => Factory.build('GoogleDynamicPlaylist', { playlistId: playlist.id, googleId }));
|
||||
const originalState = { ...initialState, playlists };
|
||||
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: GET_DYNAMIC_PLAYLISTS_SUCCESS, payload: { google: dynamicPlaylists },
|
||||
});
|
||||
expect(stateResult.playlists).toEqual(expect.arrayContaining([expect.objectContaining({
|
||||
name: expect.any(String),
|
||||
googleId: expect.any(String),
|
||||
status: expect.any(String),
|
||||
dynamicPlaylistName: expect.any(String),
|
||||
lastSynced: expect.any(String),
|
||||
})]));
|
||||
|
||||
expect(stateResult.dynamicPlaylists).toEqual(dynamicPlaylists);
|
||||
});
|
||||
test('CASE 12: should return state with upload state set when type is UPLOAD_ITEM_STARTED', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, uploading: true } };
|
||||
const stateResult = playlistsReducer(initialState, {
|
||||
type: UPLOAD_ITEM_STARTED,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 13: should return state with upload state set when type is UPLOAD_ITEMS_SUCCESS or UPLOAD_ITEMS_ERROR', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, uploading: false } };
|
||||
const stateResult = playlistsReducer(initialState, {
|
||||
type: UPLOAD_ITEMS_SUCCESS,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
|
||||
const expectedState2 = { ...initialState, meta: { ...initialState.meta, uploading: false } };
|
||||
const stateResult2 = playlistsReducer(initialState, {
|
||||
type: UPLOAD_ITEMS_ERROR,
|
||||
});
|
||||
expect(stateResult2).toEqual(expectedState2);
|
||||
});
|
||||
|
||||
test('CASE 14: should return state with trackerId set when type is PLAYLIST_PROCESSING_STARTED', () => {
|
||||
const playlists = [
|
||||
{ id: 1, meta: { error: '', loading: true } },
|
||||
{ id: 2, meta: { error: '', loading: false } },
|
||||
{ id: 3, meta: { error: '', loading: true } },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
|
||||
|
||||
const playlistsWithTracker = [
|
||||
{ id: 1, trackerId: 'a74d2e06f17e2893017431375b416b76', meta: { error: '', loading: true } },
|
||||
{ id: 2, meta: { error: '', loading: false } },
|
||||
{ id: 3, trackerId: '5b0e992791ed43ca79928eed54ca0b4f', meta: { error: '', loading: true } },
|
||||
];
|
||||
|
||||
const expectedState = { ...originalState, playlists: playlistsWithTracker };
|
||||
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: PLAYLIST_PROCESSING_STARTED,
|
||||
payload: {
|
||||
data: [
|
||||
{ receiver: '1', trackerId: 'a74d2e06f17e2893017431375b416b76' },
|
||||
{ receiver: '3', trackerId: '5b0e992791ed43ca79928eed54ca0b4f' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 15: should return state without trackerId set when type is PLAYLIST_PROCESSING_DONE', () => {
|
||||
const playlists = [
|
||||
{ id: 1, trackerId: 'a74d2e06f17e2893017431375b416b76', meta: { error: '', loading: true } },
|
||||
{ id: 2, meta: { error: '', loading: false } },
|
||||
{ id: 3, trackerId: '5b0e992791ed43ca79928eed54ca0b4f', meta: { error: '', loading: true } },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
|
||||
|
||||
const playlistsWithTracker = [
|
||||
{ id: 1, trackerId: 'a74d2e06f17e2893017431375b416b76', meta: { error: '', loading: true } },
|
||||
{ id: 2, meta: { error: '', loading: false } },
|
||||
{ id: 3, meta: { error: '', loading: true } },
|
||||
];
|
||||
|
||||
const expectedState = { ...originalState, playlists: playlistsWithTracker };
|
||||
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: PLAYLIST_PROCESSING_DONE,
|
||||
payload: {
|
||||
playlistId: 3, trackerId: '5b0e992791ed43ca79928eed54ca0b4f',
|
||||
},
|
||||
});
|
||||
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 16: should return state with meta.uploading set to false when type is UPLOAD_SUCCESS', () => {
|
||||
const playlists = [
|
||||
{ id: 1, meta: { error: '', uploading: true } },
|
||||
{ id: 2, meta: { error: '', uploading: false } },
|
||||
{ id: 3, meta: { error: '', uploading: true } },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: UPLOAD_SUCCESS,
|
||||
});
|
||||
|
||||
stateResult.playlists.forEach((item) => {
|
||||
expect(item.meta).toHaveProperty('uploading', false);
|
||||
});
|
||||
});
|
||||
|
||||
test('CASE 17: should return state with no trackerId and meta.uploading set to false when type is UPLOAD_ITEMS_ERROR or UPLOAD_ALL_CANCELLED', () => {
|
||||
const playlists = [
|
||||
{ id: 1, trackerId: 'a74d2e06f17e2893017431375b416b76', meta: { error: '', uploading: true } },
|
||||
{ id: 2, meta: { error: '', uploading: false } },
|
||||
{ id: 3, meta: { error: '', uploading: true } },
|
||||
];
|
||||
const originalState = { ...initialState, playlists };
|
||||
const stateResult = playlistsReducer(originalState, {
|
||||
type: UPLOAD_ALL_CANCELLED,
|
||||
});
|
||||
|
||||
stateResult.playlists.forEach((item) => {
|
||||
expect(item.meta).toHaveProperty('uploading', false);
|
||||
expect(item).not.toHaveProperty('trackerId');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { receivers as receiversReducer, initialState } from '~/reducers/receivers';
|
||||
import {
|
||||
GET_RECEIVERS_TOKEN,
|
||||
GET_RECEIVERS_TOKEN_SUCCESS,
|
||||
GET_RECEIVERS_TOKEN_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('receivers reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(receiversReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with meta set to loading when type is GET_RECEIVERS_TOKEN', () => {
|
||||
const receiversToken = { meta: { error: '', loading: true }, receiversToken: '' };
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
const stateResult = receiversReducer(initialState, {
|
||||
type: GET_RECEIVERS_TOKEN, payload: receiversToken,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return state with meta set to loading when type is GET_RECEIVERS_TOKEN_SUCCESS', () => {
|
||||
const receiversToken = { meta: { error: '', loading: false }, receiversToken: { meta: { error: '', loading: false } } };
|
||||
const expectedState = { ...initialState, receiversToken: { meta: { error: '', loading: false } } };
|
||||
const stateResult = receiversReducer(initialState, {
|
||||
type: GET_RECEIVERS_TOKEN_SUCCESS, payload: receiversToken,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 4: should return state with error when type is GET_RECEIVERS_TOKEN_ERROR', () => {
|
||||
const error = { meta: { error: '', loading: false }, receiversToken: '' };
|
||||
const expectedState = { ...initialState };
|
||||
const stateResult = receiversReducer(initialState, {
|
||||
type: GET_RECEIVERS_TOKEN_ERROR, payload: error,
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
34
ioneapps-maagapp-ee31119a522d/__tests__/reducers/settings.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { settings as settingsReducer, initialState } from '~/reducers/settings';
|
||||
import {
|
||||
GET_SETTINGS_SUCCESS,
|
||||
SET_SETTINGS_SUCCESS,
|
||||
LOGOUT_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('settings reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(settingsReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
expect(settingsReducer({ languageCode: 'en' }, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return settings on GET_SETTINGS_SUCCESS', () => {
|
||||
const settings = { autoAcceptFriend: true, defaultPlaylistId: 123 };
|
||||
const expectedState = { ...initialState, ...settings };
|
||||
expect(settingsReducer(undefined, { type: GET_SETTINGS_SUCCESS, payload: { settings } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return settings on SET_SETTINGS_SUCCESS', () => {
|
||||
const settings = { defaultPlaylistId: 123 };
|
||||
const existingState = { autoAcceptFriend: false, defaultPlaylistId: -1 };
|
||||
const expectedState = { ...existingState, ...settings };
|
||||
expect(settingsReducer(existingState, { type: SET_SETTINGS_SUCCESS, payload: { settings } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import {
|
||||
shareExtension as shareExtReducer,
|
||||
initialState,
|
||||
} from '~/reducers/shareExtension';
|
||||
import {
|
||||
SET_SHARE_EXT,
|
||||
DEFAULT_SHARE_EXT,
|
||||
LOGOUT_SUCCESS,
|
||||
GET_SHARE_EXT_DATA,
|
||||
GET_SHARE_EXT_DATA_SUCCESS,
|
||||
GET_SHARE_EXT_DATA_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('shareExtension reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(shareExtReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
expect(shareExtReducer({}, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return share extension on DEFAULT_SHARE_EXT', () => {
|
||||
const expectedState = { ...initialState };
|
||||
expect(shareExtReducer(undefined, { type: DEFAULT_SHARE_EXT, payload: { } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 4: should return share extension on SET_SHARE_EXT', () => {
|
||||
const albumId = 123;
|
||||
const shareExtension = { albumId };
|
||||
const expectedState = { ...initialState, ...shareExtension };
|
||||
expect(shareExtReducer(initialState, { type: SET_SHARE_EXT, payload: { albumId } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
test('CASE 5: should return share extension on GET_SHARE_EXT_DATA', () => {
|
||||
const shareExtension = { images: [], meta: { loading: true, error: '' } };
|
||||
const expectedState = { ...initialState, ...shareExtension };
|
||||
expect(shareExtReducer(initialState, { type: GET_SHARE_EXT_DATA, payload: { props1: '', props2: [] } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6: should return share extension on GET_SHARE_EXT_DATA_SUCCESS', () => {
|
||||
const images = [
|
||||
{
|
||||
meta: { loading: false, error: '' },
|
||||
fullFilePath: '/data/user/0/com.creedon.Nixplay.qa/cache/IMG_8246.JPG',
|
||||
uri: 'file:///data/user/0/com.creedon.Nixplay.qa/cache/IMG_8246.JPG',
|
||||
type: 'jpg',
|
||||
fileSize: '27209639',
|
||||
caption: '',
|
||||
mime: 'jpg',
|
||||
fileName: 'IMG_8246.JPG',
|
||||
id: 'id1',
|
||||
},
|
||||
{
|
||||
meta: { loading: false, error: '' },
|
||||
fullFilePath: '/data/user/0/com.creedon.Nixplay.qa/cache/IMG_8244.JPG',
|
||||
uri: 'file:///data/user/0/com.creedon.Nixplay.qa/cache/IMG_8244.JPG',
|
||||
type: 'jpg',
|
||||
fileSize: '54096296',
|
||||
caption: '',
|
||||
mime: 'jpg',
|
||||
fileName: 'IMG_8244.JPG',
|
||||
id: 'id2',
|
||||
}];
|
||||
const shareExtension = { images, meta: { loading: false, error: '' } };
|
||||
const expectedState = { ...initialState, ...shareExtension };
|
||||
expect(shareExtReducer(initialState, { type: GET_SHARE_EXT_DATA_SUCCESS, payload: { images } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 7: should return share extension on GET_SHARE_EXT_DATA_ERROR', () => {
|
||||
const shareExtension = { images: [], meta: { loading: false, error: 'error' } };
|
||||
const expectedState = { ...initialState, ...shareExtension };
|
||||
expect(shareExtReducer(initialState, { type: GET_SHARE_EXT_DATA_ERROR, payload: { error: 'error' } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 8: should return update caption share extension on GET_SHARE_EXT_DATA_SUCCESS SET_SHARE_EXT', () => {
|
||||
const images = [
|
||||
{
|
||||
meta: { loading: false, error: '' },
|
||||
fullFilePath: '/data/user/0/com.creedon.Nixplay.qa/cache/IMG_8246.JPG',
|
||||
uri: 'file:///data/user/0/com.creedon.Nixplay.qa/cache/IMG_8246.JPG',
|
||||
type: 'jpg',
|
||||
fileSize: '27209639',
|
||||
caption: '',
|
||||
mime: 'jpg',
|
||||
fileName: 'IMG_8246.JPG',
|
||||
id: 'id1',
|
||||
},
|
||||
{
|
||||
meta: { loading: false, error: '' },
|
||||
fullFilePath: '/data/user/0/com.creedon.Nixplay.qa/cache/IMG_8244.JPG',
|
||||
uri: 'file:///data/user/0/com.creedon.Nixplay.qa/cache/IMG_8244.JPG',
|
||||
type: 'jpg',
|
||||
fileSize: '54096296',
|
||||
caption: '',
|
||||
mime: 'jpg',
|
||||
fileName: 'IMG_8244.JPG',
|
||||
id: 'id2',
|
||||
}];
|
||||
const shareExtension = { images, meta: { loading: false, error: '' } };
|
||||
const expectedState = { ...initialState, ...shareExtension };
|
||||
expect(shareExtReducer(initialState, { type: GET_SHARE_EXT_DATA_SUCCESS, payload: { images } }))
|
||||
.toEqual(expectedState);
|
||||
|
||||
|
||||
const images2 = [
|
||||
{
|
||||
meta: { loading: false, error: '' },
|
||||
fullFilePath: '/data/user/0/com.creedon.Nixplay.qa/cache/IMG_8246.JPG',
|
||||
uri: 'file:///data/user/0/com.creedon.Nixplay.qa/cache/IMG_8246.JPG',
|
||||
type: 'jpg',
|
||||
fileSize: '27209639',
|
||||
caption: 'caption1',
|
||||
mime: 'jpg',
|
||||
fileName: 'IMG_8246.JPG',
|
||||
id: 'id1',
|
||||
},
|
||||
{
|
||||
meta: { loading: false, error: '' },
|
||||
fullFilePath: '/data/user/0/com.creedon.Nixplay.qa/cache/IMG_8244.JPG',
|
||||
uri: 'file:///data/user/0/com.creedon.Nixplay.qa/cache/IMG_8244.JPG',
|
||||
type: 'jpg',
|
||||
fileSize: '54096296',
|
||||
caption: 'caption2',
|
||||
mime: 'jpg',
|
||||
fileName: 'IMG_8244.JPG',
|
||||
id: 'id2',
|
||||
}];
|
||||
const expectedState2 = { ...initialState, ...shareExtension, images: images2 };
|
||||
expect(shareExtReducer(initialState, { type: SET_SHARE_EXT, payload: { images: images2 } }))
|
||||
.toEqual(expectedState2);
|
||||
});
|
||||
});
|
||||
223
ioneapps-maagapp-ee31119a522d/__tests__/reducers/upload.js
Normal file
@@ -0,0 +1,223 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
/* eslint-disable max-len */
|
||||
import { upload as uploadReducer, initialState } from '~/reducers/upload';
|
||||
import {
|
||||
UPLOAD_ITEM_STARTED,
|
||||
UPLOAD_SUCCESS,
|
||||
UPLOAD_ITEMS,
|
||||
UPLOAD_ITEMS_STATE_CHANGED,
|
||||
UPLOAD_ITEMS_ERROR,
|
||||
} from '~/store/actionTypes';
|
||||
import {
|
||||
UPLOAD_STATUS_COMPLETED,
|
||||
UPLOAD_STATUS_UPLOADING,
|
||||
UPLOAD_STATUS_ERROR,
|
||||
} from '~/lib/uploaders/constants';
|
||||
|
||||
describe('Upload reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(uploadReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
test('CASE 2: should return new state with items when type is UPLOAD_ITEMS', () => {
|
||||
const items = [{ uri: '1.jpg' }, { uri: '2.jpg' }];
|
||||
|
||||
const stateResult = uploadReducer(undefined, { type: UPLOAD_ITEMS, payload: { items } });
|
||||
expect(stateResult).toHaveProperty('items');
|
||||
expect(stateResult.items).toHaveLength(items.length);
|
||||
stateResult.items.forEach(item => {
|
||||
expect(item).toHaveProperty('meta');
|
||||
});
|
||||
});
|
||||
test('CASE 3: should return state with loading when type is UPLOAD_ITEM_STARTED', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true } };
|
||||
expect(uploadReducer(initialState, { type: UPLOAD_ITEM_STARTED })).toEqual(expectedState);
|
||||
});
|
||||
test('CASE 4: should return empty items with meta property when type is UPLOAD_SUCCESS', () => {
|
||||
const expectedState = {
|
||||
items: [],
|
||||
meta: {
|
||||
error: '',
|
||||
status: UPLOAD_STATUS_COMPLETED,
|
||||
loading: false,
|
||||
elapsed: 0,
|
||||
},
|
||||
receivers: [],
|
||||
};
|
||||
expect(uploadReducer(initialState, { type: UPLOAD_SUCCESS })).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 5: should return items with meta property when type is UPLOAD_ITEMS_STATE_CHANGED', () => {
|
||||
// add pending items
|
||||
const items = [{ fullFilePath: '1.jpg' }, { fullFilePath: '2.jpg' }];
|
||||
const item = { fullFilePath: '1.jpg', progress: 1 };
|
||||
const pendingItemState = uploadReducer(initialState, { type: UPLOAD_ITEMS, payload: { items } });
|
||||
|
||||
const stateResult = uploadReducer(
|
||||
pendingItemState,
|
||||
{
|
||||
type: UPLOAD_ITEMS_STATE_CHANGED,
|
||||
payload: {
|
||||
item,
|
||||
elapsed: 1,
|
||||
},
|
||||
},
|
||||
);
|
||||
const expectedState = {
|
||||
items: [{
|
||||
fullFilePath: '1.jpg',
|
||||
meta: {
|
||||
progress: 1,
|
||||
error: '',
|
||||
status: UPLOAD_STATUS_UPLOADING,
|
||||
loading: true,
|
||||
},
|
||||
}, {
|
||||
fullFilePath: '2.jpg',
|
||||
meta: {
|
||||
progress: 0.0,
|
||||
error: '',
|
||||
status: UPLOAD_STATUS_UPLOADING,
|
||||
loading: true,
|
||||
},
|
||||
}],
|
||||
meta: {
|
||||
error: '',
|
||||
status: UPLOAD_STATUS_UPLOADING,
|
||||
loading: true,
|
||||
elapsed: 1,
|
||||
},
|
||||
};
|
||||
stateResult.items.forEach(i => {
|
||||
expect(i).toHaveProperty('meta');
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 6: should return correct state when type is UPLOAD_ITEMS_ERROR', () => {
|
||||
const items = [{ fullFilePath: '1.jpg' }, { fullFilePath: '2.jpg' }];
|
||||
const item = { fullFilePath: '1.jpg', error: 'error' };
|
||||
const pendingItemState = uploadReducer(initialState, { type: UPLOAD_ITEMS, payload: { items } });
|
||||
const stateResult = uploadReducer(
|
||||
pendingItemState,
|
||||
{
|
||||
type: UPLOAD_ITEMS_ERROR,
|
||||
payload: {
|
||||
item,
|
||||
error: item.error,
|
||||
},
|
||||
},
|
||||
);
|
||||
const expectedState = {
|
||||
items: [],
|
||||
meta: {
|
||||
error: 'error',
|
||||
status: UPLOAD_STATUS_ERROR,
|
||||
loading: false,
|
||||
elapsed: 0,
|
||||
},
|
||||
};
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
// test('CASE 6: should return state with album loading to TRUE when type is GET_ALBUM_CONTENT', () => {
|
||||
// const albums = [{ id: 1 }, { id: 2 }];
|
||||
// const payload = {
|
||||
// albumId: 1,
|
||||
// };
|
||||
// const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
// const stateResult = uploadReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
// type: GET_ALBUM_CONTENT,
|
||||
// payload,
|
||||
// });
|
||||
// const expectedState = {
|
||||
// albums: [{
|
||||
// id: 1,
|
||||
// meta: { error: '', loading: true },
|
||||
// },
|
||||
// { id: 2 }],
|
||||
// meta: { error: '' },
|
||||
// };
|
||||
// expect(stateResult).toEqual(expectedState);
|
||||
// });
|
||||
|
||||
// test('CASE 7: should return state with album content when type is GET_ALBUM_CONTENT_SUCCESS', () => {
|
||||
// const albums = [{ id: 1 }, { id: 2 }];
|
||||
// const content = {
|
||||
// name: 'album name',
|
||||
// photos: [
|
||||
// { id: 4 },
|
||||
// { id: 5 },
|
||||
// ],
|
||||
// };
|
||||
// const payload = {
|
||||
// albumId: 1,
|
||||
// content,
|
||||
// };
|
||||
// const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
// const stateResult = uploadReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
// type: GET_ALBUM_CONTENT_SUCCESS,
|
||||
// payload,
|
||||
// });
|
||||
// const expectedState = {
|
||||
// albums: [{
|
||||
// id: 1,
|
||||
// content,
|
||||
// meta: { error: '', loading: false },
|
||||
// },
|
||||
// { id: 2 }],
|
||||
// meta: { error: '' },
|
||||
// };
|
||||
// expect(stateResult).toEqual(expectedState);
|
||||
// });
|
||||
|
||||
// test('CASE 8: should return state with album error when type is GET_ALBUM_CONTENT_ERROR', () => {
|
||||
// const albums = [{ id: 1 }, { id: 2 }];
|
||||
// const albumErr = new Error('getAlbumsContentError');
|
||||
// const payload = {
|
||||
// albumId: 1,
|
||||
// error: albumErr,
|
||||
// };
|
||||
// const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
// const stateResult = uploadReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
// type: GET_ALBUM_CONTENT_ERROR,
|
||||
// payload,
|
||||
// });
|
||||
// const expectedState = {
|
||||
// albums: [{
|
||||
// id: 1,
|
||||
// meta: { error: albumErr, loading: false },
|
||||
// },
|
||||
// { id: 2 }],
|
||||
// meta: { error: '' },
|
||||
// };
|
||||
// expect(stateResult).toEqual(expectedState);
|
||||
// });
|
||||
|
||||
// test('CASE 9: should return state with album error when type is CREATE_ALBUM_SUCCESS', () => {
|
||||
// const albums = [{ id: 1 }, { id: 2 }];
|
||||
// const payload = {
|
||||
// album: { id: 3 },
|
||||
// };
|
||||
// const originalState = { ...initialState, albums, meta: { error: '' } };
|
||||
// const stateResult = uploadReducer({ ...originalState, albums, meta: { error: '' } }, {
|
||||
// type: CREATE_ALBUM_SUCCESS,
|
||||
// payload,
|
||||
// });
|
||||
// const expectedState = {
|
||||
// albums: [
|
||||
// { id: 1 },
|
||||
// { id: 2 },
|
||||
// { id: 3, meta: { error: '', loading: false } },
|
||||
// ],
|
||||
// meta: { error: '', loading: false },
|
||||
// };
|
||||
// expect(stateResult).toEqual(expectedState);
|
||||
// });
|
||||
|
||||
// test('CASE 10: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
// const existingState = [{ id: 1 }, { id: 2 }];
|
||||
// expect(uploadReducer(existingState, { type: LOGOUT_SUCCESS }))
|
||||
// .toEqual(initialState);
|
||||
// });
|
||||
});
|
||||
73
ioneapps-maagapp-ee31119a522d/__tests__/reducers/user.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import { user } from '~/reducers/user';
|
||||
import {
|
||||
SUBMIT_LOGIN_SUCCESS,
|
||||
LOGOUT_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
|
||||
describe('user reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
const expectedState = {
|
||||
checkUserStorage: false,
|
||||
showLanguageChangedDialog: false,
|
||||
enableLanguageDiscrepancyPopup: false,
|
||||
displayUploadDialogue: true,
|
||||
showStorageFull: false,
|
||||
showLanguageDiscrepancy: false,
|
||||
meta: { loading: false, error: '' },
|
||||
isFullStoragePopup: false,
|
||||
todo: {
|
||||
avatar: {
|
||||
avatarChanged: true,
|
||||
tutorialDismissed: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(user(undefined, {}))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return correct state when actionType is `SUBMIT_LOGIN_SUCCESS`', () => {
|
||||
const expectedState = {
|
||||
token: 'token',
|
||||
username: 'username',
|
||||
email: 'email@email.com',
|
||||
firstName: 'first',
|
||||
lastName: 'last',
|
||||
checkUserStorage: true,
|
||||
meta: { loading: false, error: '' },
|
||||
isFullStoragePopup: false,
|
||||
todo: {
|
||||
avatar: {
|
||||
avatarChanged: true,
|
||||
tutorialDismissed: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(user({}, { type: SUBMIT_LOGIN_SUCCESS, payload: { user: expectedState } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return correct state when actionType is `LOGOUT_SUCCESS`', () => {
|
||||
const enableLanguageDiscrepancyPopup = false;
|
||||
const expectedState = {
|
||||
checkUserStorage: false,
|
||||
displayUploadDialogue: true,
|
||||
showLanguageChangedDialog: false,
|
||||
enableLanguageDiscrepancyPopup,
|
||||
showStorageFull: false,
|
||||
showLanguageDiscrepancy: false,
|
||||
meta: { loading: false, error: '' },
|
||||
isFullStoragePopup: false,
|
||||
todo: {
|
||||
avatar: {
|
||||
avatarChanged: true,
|
||||
tutorialDismissed: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(user({ enableLanguageDiscrepancyPopup }, { type: LOGOUT_SUCCESS, payload: { user: expectedState } }))
|
||||
.toEqual(expectedState);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
/* global describe: true, test:true, expect:true */
|
||||
import {
|
||||
userActivities as userActivitiesReducer,
|
||||
initialState,
|
||||
} from '~/reducers/userActivities';
|
||||
import {
|
||||
GET_USER_ACTIVITIES,
|
||||
GET_USER_ACTIVITIES_SUCCESS,
|
||||
GET_USER_ACTIVITIES_ERROR,
|
||||
SET_SHOWN_MEDIA_STATUS,
|
||||
LOGOUT_SUCCESS,
|
||||
} from '~/store/actionTypes';
|
||||
|
||||
describe('user activities reducer', () => {
|
||||
test('CASE 1: should return initial state', () => {
|
||||
expect(userActivitiesReducer(undefined, { type: 'Default' }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 2: should return state with meta set to loading when type is GET_USER_ACTIVITIES', () => {
|
||||
const expectedState = { ...initialState, meta: { ...initialState.meta, loading: true, error: '' } };
|
||||
const stateResult = userActivitiesReducer(initialState, {
|
||||
type: GET_USER_ACTIVITIES, payload: {},
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 3: should return state with meta set to loading when type is GET_USER_ACTIVITIES_SUCCESS', () => {
|
||||
const activities = [{ mediaExchange: {} }];
|
||||
const meta = { loading: false, error: '' };
|
||||
const stateResult = userActivitiesReducer(initialState, {
|
||||
type: GET_USER_ACTIVITIES_SUCCESS, payload: { activities: { activities } },
|
||||
});
|
||||
expect(stateResult).toHaveProperty('meta', meta);
|
||||
});
|
||||
|
||||
test('CASE 4: should return state with error when type is GET_USER_ACTIVITIES_ERROR', () => {
|
||||
const error = new Error('getFriendsError');
|
||||
const expectedState = {
|
||||
...initialState,
|
||||
meta: { ...initialState.meta, error, loading: false },
|
||||
};
|
||||
const stateResult = userActivitiesReducer(initialState, {
|
||||
type: GET_USER_ACTIVITIES_ERROR, payload: { error },
|
||||
});
|
||||
expect(stateResult).toEqual(expectedState);
|
||||
});
|
||||
|
||||
test('CASE 5: should update isShown state when type is SET_SHOWN_MEDIA_STATUS', (isShown = false) => {
|
||||
const stateResult = userActivitiesReducer(initialState, {
|
||||
type: SET_SHOWN_MEDIA_STATUS,
|
||||
payload: { isShown },
|
||||
});
|
||||
expect(stateResult).toEqual(initialState);
|
||||
});
|
||||
|
||||
test('CASE 6: should empty the state on LOGOUT_SUCCESS', () => {
|
||||
const existingState = {};
|
||||
expect(userActivitiesReducer(existingState, { type: LOGOUT_SUCCESS }))
|
||||
.toEqual(initialState);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { configure } from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
|
||||
global.fetch = require('jest-fetch-mock');
|
||||
|
||||
// https://github.com/oblador/react-native-vector-icons/issues/433#issuecomment-354663885
|
||||
const { NativeModules } = require('react-native');
|
||||
const mockIcon = require('~/images/general/logo-color.png');
|
||||
|
||||
NativeModules.RNVectorIconsManager = {
|
||||
getImageForFont: function getImageForFont(fontFamily, glyph, fontSize, color, callback) {
|
||||
return callback(null, mockIcon);
|
||||
},
|
||||
};
|
||||
55
ioneapps-maagapp-ee31119a522d/android/app/BUCK
Normal file
@@ -0,0 +1,55 @@
|
||||
# To learn about Buck see [Docs](https://buckbuild.com/).
|
||||
# To run your application with Buck:
|
||||
# - install Buck
|
||||
# - `npm start` - to start the packager
|
||||
# - `cd android`
|
||||
# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
|
||||
# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
|
||||
# - `buck install -r android/app` - compile, install and run application
|
||||
#
|
||||
|
||||
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
|
||||
|
||||
lib_deps = []
|
||||
|
||||
create_aar_targets(glob(["libs/*.aar"]))
|
||||
|
||||
create_jar_targets(glob(["libs/*.jar"]))
|
||||
|
||||
android_library(
|
||||
name = "all-libs",
|
||||
exported_deps = lib_deps,
|
||||
)
|
||||
|
||||
android_library(
|
||||
name = "app-code",
|
||||
srcs = glob([
|
||||
"src/main/java/**/*.java",
|
||||
]),
|
||||
deps = [
|
||||
":all-libs",
|
||||
":build_config",
|
||||
":res",
|
||||
],
|
||||
)
|
||||
|
||||
android_build_config(
|
||||
name = "build_config",
|
||||
package = "com.creedon.Nixplay",
|
||||
)
|
||||
|
||||
android_resource(
|
||||
name = "res",
|
||||
package = "com.creedon.Nixplay",
|
||||
res = "src/main/res",
|
||||
)
|
||||
|
||||
android_binary(
|
||||
name = "app",
|
||||
keystore = "//android/keystores:debug",
|
||||
manifest = "src/main/AndroidManifest.xml",
|
||||
package_type = "debug",
|
||||
deps = [
|
||||
":app-code",
|
||||
],
|
||||
)
|
||||
346
ioneapps-maagapp-ee31119a522d/android/app/build.gradle
Normal file
@@ -0,0 +1,346 @@
|
||||
project.ext.envConfigFiles = [
|
||||
dev: ".env.dev",
|
||||
rnd: ".env.rnd",
|
||||
qa: ".env.qa",
|
||||
alpha: ".env.alpha",
|
||||
beta: ".env.beta",
|
||||
prod: ".env",
|
||||
]
|
||||
|
||||
apply plugin: "com.android.application"
|
||||
apply plugin: "com.google.firebase.firebase-perf"
|
||||
apply plugin: "io.fabric"
|
||||
//apply plugin: 'com.appsee.appsee-plugin'
|
||||
// apply plugin: 'io.fabric'
|
||||
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
maven { url 'https://maven.google.com' }
|
||||
}
|
||||
|
||||
import com.android.build.OutputFile
|
||||
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||
* and bundleReleaseJsAndAssets).
|
||||
* These basically call `react-native bundle` with the correct arguments during the Android build
|
||||
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
|
||||
* bundle directly from the development server. Below you can see all the possible configurations
|
||||
* and their defaults. If you decide to add a configuration block, make sure to add it before the
|
||||
* `apply from: "../../node_modules/react-native/react.gradle"` line.
|
||||
*
|
||||
* project.ext.react = [
|
||||
* // the name of the generated asset file containing your JS bundle
|
||||
* bundleAssetName: "index.android.bundle",
|
||||
*
|
||||
* // the entry file for bundle generation
|
||||
* entryFile: "index.android.js",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
* bundleInDebug: false,
|
||||
*
|
||||
* // whether to bundle JS and assets in release mode
|
||||
* bundleInRelease: true,
|
||||
*
|
||||
* // whether to bundle JS and assets in another build variant (if configured).
|
||||
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'bundleIn${productFlavor}${buildType}'
|
||||
* // 'bundleIn${buildType}'
|
||||
* // bundleInFreeDebug: true,
|
||||
* // bundleInPaidRelease: true,
|
||||
* // bundleInBeta: true,
|
||||
*
|
||||
* // whether to disable dev mode in custom build variants (by default only disabled in release)
|
||||
* // for example: to disable dev mode in the staging build type (if configured)
|
||||
* devDisabledInStaging: true,
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'devDisabledIn${productFlavor}${buildType}'
|
||||
* // 'devDisabledIn${buildType}'
|
||||
*
|
||||
* // the root of your project, i.e. where "package.json" lives
|
||||
* root: "../../",
|
||||
*
|
||||
* // where to put the JS bundle asset in debug mode
|
||||
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
|
||||
*
|
||||
* // where to put the JS bundle asset in release mode
|
||||
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in debug mode
|
||||
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in release mode
|
||||
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
|
||||
*
|
||||
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
|
||||
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
|
||||
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
|
||||
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
|
||||
* // for example, you might want to remove it from here.
|
||||
* inputExcludes: ["android/**", "ios/**"],
|
||||
*
|
||||
* // override which node gets called and with what additional arguments
|
||||
* nodeExecutableAndArgs: ["node"],
|
||||
*
|
||||
* // supply additional arguments to the packager
|
||||
* extraPackagerArgs: []
|
||||
* ]
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
entryFile: "index.js",
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
// This change is to support the merged_assets update using gradle 3.2.0 which is a Firebase Dependency
|
||||
// https://github.com/Microsoft/react-native-code-push/issues/1427
|
||||
// TODO: SHOULD BE REMOVED AFTER THE 57.8 UPDATE!!!
|
||||
// jsBundleDirQaDebug: "$buildDir/intermediates/merged_assets/qaDebug/mergeQaDebugAssets/out",
|
||||
// jsBundleDirQaRelease: "$buildDir/intermediates/merged_assets/qaRelease/mergeQaReleaseAssets/out",
|
||||
// jsBundleDirRndDebug: "$buildDir/intermediates/merged_assets/rndDebug/mergeRndDebugAssets/out",
|
||||
// jsBundleDirRndRelease: "$buildDir/intermediates/merged_assets/rndRelease/mergeRndReleaseAssets/out",
|
||||
// jsBundleDirProdDebug: "$buildDir/intermediates/merged_assets/prodDebug/mergeProdDebugAssets/out",
|
||||
// jsBundleDirProdRelease: "$buildDir/intermediates/merged_assets/prodRelease/mergeProdReleaseAssets/out",
|
||||
// jsBundleDirAlphaDebug: "$buildDir/intermediates/merged_assets/alphaDebug/mergeAlphaDebugAssets/out",
|
||||
// jsBundleDirAlphaRelease: "$buildDir/intermediates/merged_assets/alphaRelease/mergeAlphaReleaseAssets/out",
|
||||
// jsBundleDirBetaDebug: "$buildDir/intermediates/merged_assets/betaDebug/mergeBetaDebugAssets/out",
|
||||
// jsBundleDirBetaRelease: "$buildDir/intermediates/merged_assets/betaRelease/mergBetaReleaseAssets/out",
|
||||
]
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
|
||||
|
||||
/**
|
||||
* Set this to true to create two separate APKs instead of one:
|
||||
* - An APK that only works on ARM devices
|
||||
* - An APK that only works on x86 devices
|
||||
* The advantage is the size of the APK is reduced by about 4MB.
|
||||
* Upload all the APKs to the Play Store and people will download
|
||||
* the correct one based on the CPU architecture of their device.
|
||||
*/
|
||||
def enableSeparateBuildPerCPUArchitecture = false
|
||||
|
||||
/**
|
||||
* Run Proguard to shrink the Java bytecode in release builds.
|
||||
*/
|
||||
def enableProguardInReleaseBuilds = false
|
||||
def supportLibVersion = project.hasProperty('supportLibVersion') ? project.supportLibVersion : "28.0.0"
|
||||
|
||||
android {
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('/Users/nixplay/Documents/Opensource/ssskeystore/sssmobile_keystore.jks')
|
||||
storePassword 'sssmobile123'
|
||||
keyPassword 'sssmobile123'
|
||||
keyAlias = 'sssmobile'
|
||||
}
|
||||
}
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
// buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.ioneres.maagap" +
|
||||
""
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 19
|
||||
versionName "0.1.15"
|
||||
multiDexEnabled true
|
||||
renderscriptTargetApi 23
|
||||
renderscriptSupportModeEnabled true
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a","arm64-v8a","x86","x86_64"
|
||||
}
|
||||
|
||||
resValue "string", "build_config_package", "com.ioneres.maagap"
|
||||
addManifestPlaceholders([NOTIFICATION_CHANNEL_NAME: "MAAGApp(SW) "])
|
||||
addManifestPlaceholders([NOTIFICATION_CHANNEL_DESCRIPTION: "MAAGApp(SW) Notification"])
|
||||
}
|
||||
packagingOptions{
|
||||
doNotStrip '*/mips/*.so'
|
||||
doNotStrip '*/mips64/*.so'
|
||||
exclude 'META-INF/DEPENDENCIES.txt'
|
||||
exclude 'META-INF/LICENSE.txt'
|
||||
exclude 'META-INFTICE.txt'
|
||||
exclude 'META-INFTICE'
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/DEPEND' +
|
||||
'' +
|
||||
'ENCIES'
|
||||
exclude 'META-INFtice.txt'
|
||||
exclude 'META-INFcense.txt'
|
||||
exclude 'META-INF/dependencies.txt'
|
||||
exclude 'META-INF/LGPL2.1'
|
||||
exclude 'META-INF/MANIFEST.MF'
|
||||
exclude 'META-INF/maven/com.google.protobuf/protobuf-java/pom.xml'
|
||||
exclude 'META-INF/maven/com.google.protobuf/protobuf-java/pom.properties'
|
||||
|
||||
}
|
||||
|
||||
flavorDimensions "release"
|
||||
productFlavors {
|
||||
rndSW {
|
||||
dimension = "release"
|
||||
addManifestPlaceholders([APP_NAME: "MAAGApp(SW-D)"])
|
||||
addManifestPlaceholders([APP_ID: "com.ioneres.maagap"])
|
||||
addManifestPlaceholders([APP_ICON:"@mipmap/ic_launcher_rnd"])
|
||||
}
|
||||
prodSW {
|
||||
dimension = "release"
|
||||
addManifestPlaceholders([APP_NAME: "MAAGApp(SW)"])
|
||||
addManifestPlaceholders([APP_ID: "com.ioneres.maagapp.sw"])
|
||||
addManifestPlaceholders([APP_ICON:"@mipmap/ic_launcher_rnd"])
|
||||
}
|
||||
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
zipAlignEnabled true
|
||||
}
|
||||
}
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
||||
}
|
||||
}
|
||||
}
|
||||
dexOptions {
|
||||
jumboMode true
|
||||
javaMaxHeapSize "4g"
|
||||
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
aaptOptions.cruncherEnabled = false
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
// maven { url 'https://maven.google.com' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// These docs use an open ended version so that our plugin
|
||||
// can be updated quickly in response to Android tooling updates
|
||||
|
||||
// We recommend changing it to the latest version from our changelog:
|
||||
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
|
||||
// classpath 'io.fabric.tools:gradle:1.22.2'
|
||||
// classpath 'com.google.gms:google-services:4.2.0'
|
||||
classpath 'io.fabric.tools:gradle:1.27.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
dependencies {
|
||||
// implementation project(':react-native-spring-scrollview')
|
||||
implementation project(':@react-native-community_cameraroll')
|
||||
// implementation project(':@react-native-community_art')
|
||||
implementation project(':react-native-config')
|
||||
implementation project(':@react-native-community_geolocation')
|
||||
implementation project(':react-native-geocoder')
|
||||
implementation project(':@react-native-community_viewpager')
|
||||
// implementation project(':react-native-photo-view-ex')
|
||||
implementation project(':react-native-detect-navbar-android')
|
||||
implementation project(':@react-native-community_blur')
|
||||
implementation project(':@react-native-community_netinfo')
|
||||
implementation project(':react-native-localize')
|
||||
implementation project(':@react-native-community_async-storage')
|
||||
implementation project(':@react-native-community_slider')
|
||||
implementation project(':react-native-webview')
|
||||
implementation project(':react-native-default-preference')
|
||||
implementation project(':react-native-firebase')
|
||||
implementation project(':react-native-app-settings')
|
||||
implementation project(':react-native-svg')
|
||||
// implementation project(':react-native-network-info')
|
||||
implementation project(':react-native-splash-screen')
|
||||
implementation project(':react-native-haptic-feedback')
|
||||
implementation project(':react-native-push-notification')
|
||||
// implementation project(':react-native-google-signin')
|
||||
implementation project(':react-native-keychain')
|
||||
implementation project(':react-native-linear-gradient')
|
||||
implementation project(':react-native-view-overflow')
|
||||
implementation project(':rn-fetch-blob')
|
||||
implementation project(':react-native-image-resizer')
|
||||
implementation project(':react-native-fs')
|
||||
implementation project(':react-native-creedon-imagepicker')
|
||||
implementation project(':react-native-device-info')
|
||||
implementation project(':react-native-fabric')
|
||||
implementation project(':react-native-vector-icons')
|
||||
implementation project(':react-native-permissions')
|
||||
implementation project(':react-native-mixpanel')
|
||||
implementation project(':react-native-randombytes')
|
||||
implementation project(':react-native-bluetooth-escpos-printer')
|
||||
implementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') {
|
||||
transitive = true
|
||||
}
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
// implementation "com.android.support:support-compat:${rootProject.ext.supportLibVersion}"
|
||||
// implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
|
||||
// implementation 'com.android.support:multidex:1.0.3'
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
|
||||
// implementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
implementation "com.facebook.fresco:animated-gif:1.3.0"
|
||||
implementation "com.facebook.fresco:animated-base-support:1.3.0"
|
||||
// implementation "com.android.support.constraint:constraint-layout:1.1.3"
|
||||
// implementation "com.android.support:exifinterface:${rootProject.ext.supportLibVersion}"
|
||||
implementation 'androidx.exifinterface:exifinterface:1.0.0'
|
||||
|
||||
// implementation 'io.intercom.android:intercom-sdk-base:5.1.5'
|
||||
implementation "com.google.firebase:firebase-core:16.0.8"
|
||||
implementation "com.google.firebase:firebase-perf:16.2.5"
|
||||
|
||||
if (enableHermes) {
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
} else {
|
||||
implementation jscFlavor
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
// puts all compile dependencies into folder libs for BUCK to use
|
||||
task copyDownloadableDepsToLibs(type: Copy) {
|
||||
from configurations.compile
|
||||
into 'libs'
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
// conflict with react-native-codepush dependencies need to skip version checking, should remove it in the future
|
||||
com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
20
ioneapps-maagapp-ee31119a522d/android/app/build_defs.bzl
Normal file
@@ -0,0 +1,20 @@
|
||||
"""Helper definitions to glob .aar and .jar targets"""
|
||||
|
||||
def create_aar_targets(aarfiles):
|
||||
for aarfile in aarfiles:
|
||||
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
|
||||
lib_deps.append(":" + name)
|
||||
android_prebuilt_aar(
|
||||
name = name,
|
||||
aar = aarfile,
|
||||
)
|
||||
|
||||
def create_jar_targets(jarfiles):
|
||||
for jarfile in jarfiles:
|
||||
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
|
||||
lib_deps.append(":" + name)
|
||||
prebuilt_jar(
|
||||
name = name,
|
||||
binary_jar = jarfile,
|
||||
)
|
||||
|
||||
127
ioneapps-maagapp-ee31119a522d/android/app/google-services.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "570052590774",
|
||||
"firebase_url": "https://maagap-fd046.firebaseio.com",
|
||||
"project_id": "maagap-fd046",
|
||||
"storage_bucket": "maagap-fd046.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:570052590774:android:2c6f0b3dc2562ebe447a17",
|
||||
"android_client_info": {
|
||||
"package_name": "com.ioneres.maagap"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyA0Qmx57KvXiND_6KQPGfzhlgY7brCtrzc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:570052590774:android:25c0f3d85975d938447a17",
|
||||
"android_client_info": {
|
||||
"package_name": "com.ioneres.maagap.beneficiary"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyA0Qmx57KvXiND_6KQPGfzhlgY7brCtrzc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:570052590774:android:5142e1392f1aa782447a17",
|
||||
"android_client_info": {
|
||||
"package_name": "com.ioneres.maagapp.beneficiary"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyA0Qmx57KvXiND_6KQPGfzhlgY7brCtrzc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:570052590774:android:c50fd580d03f5739447a17",
|
||||
"android_client_info": {
|
||||
"package_name": "com.ioneres.maagapp.sw"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyA0Qmx57KvXiND_6KQPGfzhlgY7brCtrzc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "570052590774-ktmpt3jo0b7aq4hc3sg790qkck9m9098.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
108
ioneapps-maagapp-ee31119a522d/android/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Disabling obfuscation is useful if you collect stack traces from production crashes
|
||||
# (unless you are using a system that supports de-obfuscate the stack traces).
|
||||
-dontobfuscate
|
||||
|
||||
# React Native
|
||||
|
||||
# Keep our interfaces so they can be used by other ProGuard rules.
|
||||
# See http://sourceforge.net/p/proguard/bugs/466/
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
|
||||
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
|
||||
|
||||
# Do not strip any method/class that is annotated with @DoNotStrip
|
||||
-keep @com.facebook.proguard.annotations.DoNotStrip class *
|
||||
-keep @com.facebook.common.internal.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.proguard.annotations.DoNotStrip *;
|
||||
@com.facebook.common.internal.DoNotStrip *;
|
||||
}
|
||||
|
||||
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
|
||||
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
|
||||
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
|
||||
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
|
||||
|
||||
-dontwarn com.facebook.react.**
|
||||
|
||||
# TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
|
||||
# See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
|
||||
-dontwarn android.text.StaticLayout
|
||||
|
||||
# okhttp
|
||||
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-keep class okhttp3.** { *; }
|
||||
-keep interface okhttp3.** { *; }
|
||||
-dontwarn okhttp3.**
|
||||
|
||||
# okio
|
||||
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-dontwarn okio.**
|
||||
|
||||
# config
|
||||
-keep class com.creedon.Nixplay.BuildConfig { *; }
|
||||
|
||||
-keep class com.bumptech.** {*;}
|
||||
-keepclassmembers class com.bumptech.** {*;}
|
||||
-keep class com.bumptech.glide.integration.okhttp.OkHttpGlideModule
|
||||
|
||||
# fast image
|
||||
-keep public class com.dylanvann.fastimage.* {*;}
|
||||
-keep public class com.dylanvann.fastimage.** {*;}
|
||||
-keep class com.facebook.imagepipeline.animated.factory.AnimatedFactoryImpl { public AnimatedFactoryImpl(com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory, com.facebook.imagepipeline.core.ExecutorSupplier); }
|
||||
|
||||
#appsee
|
||||
-keep class com.appsee.** { *; }
|
||||
-dontwarn com.appsee.**
|
||||
-keep class android.support.** { *; }
|
||||
-keep interface android.support.** { *; }
|
||||
-keep class androidx.** { *; }
|
||||
-keep interface androidx.** { *; }
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
#fujifilm-spa-sdk
|
||||
-keepclassmembers enum * { *; }
|
||||
-keepclassmembers class com.fujifilmssd.FujifilmSPASDKActivity.** {*;}
|
||||
-keep public class com.fujifilmssd.FujifilmSPASDKActivity.**
|
||||
-keepnames class io.card.payment.** {*;}
|
||||
-keep public class io.card.payment.** {*;}
|
||||
-dontwarn io.card.payment.CardIOActivity
|
||||
-dontwarn io.card.payment.CreditCard
|
||||
|
||||
|
||||
#iap
|
||||
-keepattributes *Annotation*
|
||||
-keepclassmembers class ** {
|
||||
@org.greenrobot.eventbus.Subscribe <methods>;
|
||||
}
|
||||
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
|
||||
</manifest>
|
||||
@@ -0,0 +1,107 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.ioneres.maagap">
|
||||
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.INTERNET"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.CAMERA"/>
|
||||
<uses-permission
|
||||
android:required="true"
|
||||
android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera"/>
|
||||
<uses-feature android:name="android.hardware.location"/>
|
||||
|
||||
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
|
||||
<!--<uses-permission android:name="android.permission.WAKE_LOCK" />-->
|
||||
<!--<permission-->
|
||||
<!--android:name="${applicationId}.permission.C2D_MESSAGE"-->
|
||||
<!--android:protectionLevel="signature" />-->
|
||||
<!--<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />-->
|
||||
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<!-- Require OpenGL ES >= 2.0. -->
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:icon="${APP_ICON}"
|
||||
android:label="${APP_NAME}"
|
||||
android:largeHeap="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:allowBackup="false"
|
||||
tools:replace="android:label, android:allowBackup">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:label="${APP_NAME}"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http" android:host="www.maagap.com" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths_public"
|
||||
tools:replace="android:resource"/>
|
||||
</provider>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"app_secret": "7c35b0d3-f6d4-40ff-92eb-a143d36ea885"
|
||||
}
|
||||
|
After Width: | Height: | Size: 41 KiB |
@@ -0,0 +1,43 @@
|
||||
package com.ioneres.maagap;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreen;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
SplashScreen.show(this); // here
|
||||
super.onCreate(savedInstanceState);
|
||||
// ATTENTION: This was auto-generated to handle app links.
|
||||
Intent appLinkIntent = getIntent();
|
||||
String appLinkAction = appLinkIntent.getAction();
|
||||
Uri appLinkData = appLinkIntent.getData();
|
||||
}
|
||||
@Override
|
||||
protected void onPause() {
|
||||
SplashScreen.hide(this);
|
||||
super.onPause();
|
||||
}
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "MAAGApp";
|
||||
}
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new ReactActivityDelegate(this, getMainComponentName()) {
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
return new RNGestureHandlerEnabledRootView(MainActivity.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.ioneres.maagap;
|
||||
|
||||
import androidx.multidex.BuildConfig;
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
import android.content.Context;
|
||||
import com.facebook.react.PackageList;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.microsoft.codepush.react.CodePush;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage;
|
||||
import io.invertase.firebase.fabric.crashlytics.RNFirebaseCrashlyticsPackage;
|
||||
|
||||
public class MainApplication extends MultiDexApplication implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
|
||||
@Override
|
||||
protected String getJSBundleFile() {
|
||||
return CodePush.getJSBundleFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
packages.add(new RNFirebaseAnalyticsPackage());
|
||||
packages.add(new RNFirebaseCrashlyticsPackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
initializeFlipper(this); // Remove this line if you don't want Flipper enabled
|
||||
}
|
||||
/**
|
||||
* Loads Flipper in React Native templates.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private static void initializeFlipper(Context context) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
|
||||
aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/launch_screen" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/launch_screen" />
|
||||
|
||||
</LinearLayout>
|
||||