@becollective/utils 1.7.2 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.semaphore/utils.yml +1 -1
- package/README.md +41 -25
- package/bundle.js +19 -6
- package/index.js +2 -6
- package/jestconfig.json +1 -3
- package/package.json +2 -2
- package/rollup.config.js +2 -4
- package/setup.ts +1 -4
- package/src/FeatureFlag.ts +3 -11
- package/src/date-time.js +17 -4
- package/src/locality.js +3 -4
- package/src/money.js +2 -7
- package/src/opportunity.js +1 -1
- package/src/opportunityUser.js +14 -5
- package/src/password.js +10 -9
- package/tests/date-time.test.js +86 -3
- package/tests/featureFlag.test.ts +5 -5
- package/tests/money.test.js +5 -15
- package/tests/password.test.js +3 -9
- package/tslint.json +10 -39
package/.semaphore/utils.yml
CHANGED
package/README.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# @becollective/utils
|
|
2
2
|
|
|
3
3
|
## Description
|
|
4
|
+
|
|
4
5
|
---
|
|
6
|
+
|
|
5
7
|
A collection of helper methods for handling regional issues, feature-flags and password checking functionality.
|
|
6
8
|
|
|
7
9
|
These include:
|
|
10
|
+
|
|
8
11
|
- Age, underSixteen and date diff checks
|
|
9
12
|
- Turns shift dates into readable text
|
|
10
13
|
- Fetch feature-flags from feature flag service
|
|
@@ -13,7 +16,9 @@ These include:
|
|
|
13
16
|
- Password checks
|
|
14
17
|
|
|
15
18
|
## :computer: Pre-requisites
|
|
19
|
+
|
|
16
20
|
---
|
|
21
|
+
|
|
17
22
|
Some projects have different node versions I would recommend using:
|
|
18
23
|
[nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
|
|
19
24
|
|
|
@@ -26,7 +31,9 @@ Ensure you have done the following in the [confluence](https://becollective.atla
|
|
|
26
31
|
- `Dependency services for local Be Collective Services`
|
|
27
32
|
|
|
28
33
|
## :wave: Getting started
|
|
34
|
+
|
|
29
35
|
---
|
|
36
|
+
|
|
30
37
|
- Clone the repository
|
|
31
38
|
|
|
32
39
|
```
|
|
@@ -36,6 +43,7 @@ git clone <https://github.com/tickboxAU/becollective-npm.git>
|
|
|
36
43
|
```
|
|
37
44
|
cd becollective-npm
|
|
38
45
|
```
|
|
46
|
+
|
|
39
47
|
```
|
|
40
48
|
cd packages/utils
|
|
41
49
|
```
|
|
@@ -43,59 +51,68 @@ cd packages/utils
|
|
|
43
51
|
```
|
|
44
52
|
bcDocker
|
|
45
53
|
```
|
|
54
|
+
|
|
46
55
|
- `bcDocker` [confluence](https://becollective.atlassian.net/wiki/spaces/ENGINEERIN/pages/1605849/1+-+Setup+Local+Development+Environment#Dependency-services-for-local-Be-Collective-Services)
|
|
47
56
|
|
|
48
57
|
- Install dependencies
|
|
58
|
+
|
|
49
59
|
```
|
|
50
60
|
npm install
|
|
51
61
|
```
|
|
52
62
|
|
|
53
63
|
- how to run tests
|
|
64
|
+
|
|
54
65
|
```
|
|
55
66
|
npm run test
|
|
56
67
|
```
|
|
57
68
|
|
|
58
69
|
- how to build
|
|
70
|
+
|
|
59
71
|
```
|
|
60
72
|
npm run build
|
|
61
73
|
```
|
|
62
74
|
|
|
63
75
|
## Project Structure
|
|
76
|
+
|
|
64
77
|
---
|
|
78
|
+
|
|
65
79
|
The folder structure of this project is explained below:
|
|
66
80
|
|
|
67
|
-
| Name | Description
|
|
68
|
-
|
|
69
|
-
| **node_modules** | Contains all
|
|
70
|
-
| **.semaphore** | Contains the deployment yml for semaphore
|
|
71
|
-
| **src/date-time** | Date-time helper methods
|
|
72
|
-
| **src/FeatureFlag** | Feature flag helper methods
|
|
73
|
-
| **src/locality** | Location helper methods
|
|
74
|
-
| **src/money** | Money string helper methods
|
|
75
|
-
| **src/opportunity** | Opportunity types
|
|
76
|
-
| **src/opportunityUser** | Opportunity time helper methods
|
|
77
|
-
| **src/password** | Password validation helper methods
|
|
78
|
-
| **tests** | Contain all tests
|
|
79
|
-
| **jestconfig.js** | Test configuration
|
|
80
|
-
| **package.json** | Contains npm dependencies as well as build scripts
|
|
81
|
-
| **rollup.config.js** | config for babel and rollup combination
|
|
82
|
-
| **setup.ts** | Test setup script
|
|
83
|
-
| **tsconfig.json** | Config settings for TS transpiling
|
|
84
|
-
| **tslint.json** | Config settings for TSLint code style checking
|
|
81
|
+
| Name | Description |
|
|
82
|
+
| ----------------------- | -------------------------------------------------- |
|
|
83
|
+
| **node_modules** | Contains all npm dependencies |
|
|
84
|
+
| **.semaphore** | Contains the deployment yml for semaphore |
|
|
85
|
+
| **src/date-time** | Date-time helper methods |
|
|
86
|
+
| **src/FeatureFlag** | Feature flag helper methods |
|
|
87
|
+
| **src/locality** | Location helper methods |
|
|
88
|
+
| **src/money** | Money string helper methods |
|
|
89
|
+
| **src/opportunity** | Opportunity types |
|
|
90
|
+
| **src/opportunityUser** | Opportunity time helper methods |
|
|
91
|
+
| **src/password** | Password validation helper methods |
|
|
92
|
+
| **tests** | Contain all tests |
|
|
93
|
+
| **jestconfig.js** | Test configuration |
|
|
94
|
+
| **package.json** | Contains npm dependencies as well as build scripts |
|
|
95
|
+
| **rollup.config.js** | config for babel and rollup combination |
|
|
96
|
+
| **setup.ts** | Test setup script |
|
|
97
|
+
| **tsconfig.json** | Config settings for TS transpiling |
|
|
98
|
+
| **tslint.json** | Config settings for TSLint code style checking |
|
|
85
99
|
|
|
86
100
|
### :sparkles: Guidelines
|
|
101
|
+
|
|
87
102
|
---
|
|
103
|
+
|
|
88
104
|
Remember that these packages will be consumed by other services, many of which are lambda's that have strict size restrictions.
|
|
89
105
|
Please be mindful of any packages you add here, as they could potentially cause inoperable deployments of ingesting services.
|
|
90
|
-
|
|
106
|
+
_Basically, only import if you really, really need it_
|
|
91
107
|
|
|
92
108
|
## Import and usage syntax
|
|
109
|
+
|
|
93
110
|
```
|
|
94
111
|
import {
|
|
95
112
|
isUnderSixteen,
|
|
96
113
|
FeatureFlag,
|
|
97
114
|
getAge,
|
|
98
|
-
getCurrencyFromCurrencyCode
|
|
115
|
+
getCurrencyFromCurrencyCode
|
|
99
116
|
makeMoneyString,
|
|
100
117
|
password
|
|
101
118
|
} from '@becollective/utils';
|
|
@@ -118,16 +135,15 @@ const isValid = password.isValid('this-is-a-password');
|
|
|
118
135
|
```
|
|
119
136
|
|
|
120
137
|
---
|
|
138
|
+
|
|
121
139
|
### Running npm scripts
|
|
122
140
|
|
|
123
141
|
| Npm Script | Description |
|
|
124
|
-
|
|
142
|
+
| ----------------- | ------------------------------------------ |
|
|
125
143
|
| `npm run test` | Run the tests |
|
|
126
144
|
| `npm run build` | runs rollup |
|
|
127
|
-
| `npm run prepare` | runs build (not sure why this is required) |
|
|
145
|
+
| `npm run prepare` | runs build (not sure why this is required) |
|
|
128
146
|
|
|
129
147
|
### :red_circle: Common Issues & FAQ
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
|
|
133
148
|
|
|
149
|
+
---
|
package/bundle.js
CHANGED
|
@@ -66,7 +66,7 @@ var moment = require('moment-timezone');
|
|
|
66
66
|
* @param {string} dateOfBirth
|
|
67
67
|
* @param {string} unit the measurement of the the difference
|
|
68
68
|
* The supported measurements are:
|
|
69
|
-
* years, months, weeks, days, hours, minutes, and seconds.
|
|
69
|
+
* years, months, weeks, days, hours, minutes, and seconds.
|
|
70
70
|
* @returns {number} age
|
|
71
71
|
*/
|
|
72
72
|
|
|
@@ -105,6 +105,18 @@ var isUnderSixteen = function isUnderSixteen(dateOfBirth) {
|
|
|
105
105
|
var age = getAge(dateOfBirth);
|
|
106
106
|
return isNaN(age) ? false : age < 16;
|
|
107
107
|
};
|
|
108
|
+
var isUnderAge = function isUnderAge(dateOfBirth, limit, maxAcknowledgedAge) {
|
|
109
|
+
if ((!dateOfBirth || !moment(dateOfBirth).isValid()) && !maxAcknowledgedAge) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (dateOfBirth) {
|
|
114
|
+
var age = getAge(dateOfBirth);
|
|
115
|
+
return isNaN(age) ? false : age < limit;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return maxAcknowledgedAge < limit;
|
|
119
|
+
};
|
|
108
120
|
var datesByThemselves = function datesByThemselves(a, b) {
|
|
109
121
|
if (!a.from) return 1;
|
|
110
122
|
return moment(a.from) - moment(b.from);
|
|
@@ -189,9 +201,9 @@ var readableOpportunityType = function readableOpportunityType(type) {
|
|
|
189
201
|
var _require = require('lodash'),
|
|
190
202
|
pick = _require.pick;
|
|
191
203
|
/**
|
|
192
|
-
*
|
|
193
|
-
* @param {*} opportunityUser
|
|
194
|
-
* @param {*} opportunity
|
|
204
|
+
*
|
|
205
|
+
* @param {*} opportunityUser
|
|
206
|
+
* @param {*} opportunity
|
|
195
207
|
*/
|
|
196
208
|
|
|
197
209
|
|
|
@@ -205,8 +217,8 @@ var getTimeInfo = function getTimeInfo(opportunityUser) {
|
|
|
205
217
|
};
|
|
206
218
|
|
|
207
219
|
/**
|
|
208
|
-
*
|
|
209
|
-
* @param {Array} locationList
|
|
220
|
+
*
|
|
221
|
+
* @param {Array} locationList
|
|
210
222
|
*/
|
|
211
223
|
var getHomeLocalityFromLocationList = function getHomeLocalityFromLocationList(locationList) {
|
|
212
224
|
var homeLocation = Array.isArray(locationList) && locationList.find(function (location) {
|
|
@@ -20977,6 +20989,7 @@ class FeatureFlag {
|
|
|
20977
20989
|
var util = {
|
|
20978
20990
|
getAge: getAge,
|
|
20979
20991
|
getCurrencyFromCurrencyCode: getCurrencyFromCurrencyCode,
|
|
20992
|
+
isUnderAge: isUnderAge,
|
|
20980
20993
|
isUnderSixteen: isUnderSixteen,
|
|
20981
20994
|
makeMoneyString: makeMoneyString,
|
|
20982
20995
|
password: password,
|
package/index.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { password } from './src/password';
|
|
2
|
-
import {
|
|
3
|
-
isUnderSixteen,
|
|
4
|
-
getAge,
|
|
5
|
-
datesByThemselves,
|
|
6
|
-
getShiftText,
|
|
7
|
-
} from './src/date-time';
|
|
2
|
+
import { isUnderSixteen, isUnderAge, getAge, datesByThemselves, getShiftText } from './src/date-time';
|
|
8
3
|
import { getCurrencyFromCurrencyCode, makeMoneyString } from './src/money';
|
|
9
4
|
import { readableOpportunityType } from './src/opportunity';
|
|
10
5
|
import { getTimeInfo } from './src/opportunityUser';
|
|
@@ -13,6 +8,7 @@ import FeatureFlag from './src/FeatureFlag';
|
|
|
13
8
|
const util = {
|
|
14
9
|
getAge,
|
|
15
10
|
getCurrencyFromCurrencyCode,
|
|
11
|
+
isUnderAge,
|
|
16
12
|
isUnderSixteen,
|
|
17
13
|
makeMoneyString,
|
|
18
14
|
password,
|
package/jestconfig.json
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@becollective/utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "Common utilities",
|
|
5
5
|
"main": "bundle.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "NODE_ENV=localtest jest --config jestconfig.json --detectOpenHandles --verbose --forceExit",
|
|
7
|
+
"test": "npm run build && NODE_ENV=localtest jest --config jestconfig.json --detectOpenHandles --verbose --forceExit",
|
|
8
8
|
"build": "rollup -c",
|
|
9
9
|
"prepare": "npm run build"
|
|
10
10
|
},
|
package/rollup.config.js
CHANGED
|
@@ -8,7 +8,7 @@ export default {
|
|
|
8
8
|
input: 'index.js',
|
|
9
9
|
output: {
|
|
10
10
|
file: 'bundle.js',
|
|
11
|
-
format: 'cjs'
|
|
11
|
+
format: 'cjs',
|
|
12
12
|
},
|
|
13
13
|
plugins: [
|
|
14
14
|
json(),
|
|
@@ -18,9 +18,7 @@ export default {
|
|
|
18
18
|
babel({
|
|
19
19
|
exclude: 'node_modules/**', // only transpile our source code
|
|
20
20
|
babelrc: false,
|
|
21
|
-
presets: [
|
|
22
|
-
"@babel/preset-env",
|
|
23
|
-
],
|
|
21
|
+
presets: ['@babel/preset-env'],
|
|
24
22
|
}),
|
|
25
23
|
],
|
|
26
24
|
};
|
package/setup.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
// Jest will set NODE_ENV to "test" if not specified
|
|
2
|
-
if (
|
|
3
|
-
process.env.NODE_ENV !== 'compose' &&
|
|
4
|
-
process.env.NODE_ENV !== 'localtest'
|
|
5
|
-
) {
|
|
2
|
+
if (process.env.NODE_ENV !== 'compose' && process.env.NODE_ENV !== 'localtest') {
|
|
6
3
|
process.env.NODE_ENV = 'localtest';
|
|
7
4
|
}
|
package/src/FeatureFlag.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { memoize, get as lodashGet } from 'lodash';
|
|
3
3
|
|
|
4
|
-
const fetchFeatureActive = async (
|
|
5
|
-
feature: string,
|
|
6
|
-
options: { env: string; region?: string },
|
|
7
|
-
): Promise<boolean> => {
|
|
4
|
+
const fetchFeatureActive = async (feature: string, options: { env: string; region?: string }): Promise<boolean> => {
|
|
8
5
|
const getFlagByFeatureUrl = `https://lb-central.becollective.com/api/v2/feature-flags/${feature}`;
|
|
9
6
|
let isFeatureActive = false;
|
|
10
7
|
const featureFlags = await axios.get(getFlagByFeatureUrl);
|
|
@@ -15,9 +12,7 @@ const fetchFeatureActive = async (
|
|
|
15
12
|
return isFeatureActive;
|
|
16
13
|
};
|
|
17
14
|
|
|
18
|
-
const memoizedFeatureActive = memoize(fetchFeatureActive, (feature, options) =>
|
|
19
|
-
JSON.stringify({ feature, options }),
|
|
20
|
-
);
|
|
15
|
+
const memoizedFeatureActive = memoize(fetchFeatureActive, (feature, options) => JSON.stringify({ feature, options }));
|
|
21
16
|
|
|
22
17
|
class FeatureFlag {
|
|
23
18
|
ttl: number;
|
|
@@ -26,10 +21,7 @@ class FeatureFlag {
|
|
|
26
21
|
this.ttl = ttl || 1000 * 60 * 5; // default to 5 minutes
|
|
27
22
|
this.expiry = Date.now() + ttl;
|
|
28
23
|
}
|
|
29
|
-
async isFeatureActive(
|
|
30
|
-
feature: string,
|
|
31
|
-
options: { env: string; region?: string },
|
|
32
|
-
): Promise<boolean> {
|
|
24
|
+
async isFeatureActive(feature: string, options: { env: string; region?: string }): Promise<boolean> {
|
|
33
25
|
// Lazy expiration upon function call
|
|
34
26
|
const now = Date.now();
|
|
35
27
|
if (now >= this.expiry) {
|
package/src/date-time.js
CHANGED
|
@@ -5,10 +5,10 @@ const moment = require('moment-timezone');
|
|
|
5
5
|
* @param {string} dateOfBirth
|
|
6
6
|
* @param {string} unit the measurement of the the difference
|
|
7
7
|
* The supported measurements are:
|
|
8
|
-
* years, months, weeks, days, hours, minutes, and seconds.
|
|
8
|
+
* years, months, weeks, days, hours, minutes, and seconds.
|
|
9
9
|
* @returns {number} age
|
|
10
10
|
*/
|
|
11
|
-
export const getAge = (dateOfBirth, unit='years') => {
|
|
11
|
+
export const getAge = (dateOfBirth, unit = 'years') => {
|
|
12
12
|
const age = moment().diff(dateOfBirth, unit);
|
|
13
13
|
if (isNaN(age)) {
|
|
14
14
|
throw new Error('Invalid date');
|
|
@@ -30,7 +30,7 @@ export const getAge = (dateOfBirth, unit='years') => {
|
|
|
30
30
|
* data to have a consistent birthdate property.
|
|
31
31
|
* Then we should throw error if birthdate is not valid
|
|
32
32
|
*/
|
|
33
|
-
export const isUnderSixteen = dateOfBirth => {
|
|
33
|
+
export const isUnderSixteen = (dateOfBirth) => {
|
|
34
34
|
if (!dateOfBirth || !moment(dateOfBirth).isValid()) {
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
@@ -38,6 +38,18 @@ export const isUnderSixteen = dateOfBirth => {
|
|
|
38
38
|
return isNaN(age) ? false : age < 16;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
export const isUnderAge = (dateOfBirth, limit, maxAcknowledgedAge) => {
|
|
42
|
+
if ((!dateOfBirth || !moment(dateOfBirth).isValid()) && !maxAcknowledgedAge) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if(dateOfBirth) {
|
|
47
|
+
const age = getAge(dateOfBirth);
|
|
48
|
+
return isNaN(age) ? false : age < limit;
|
|
49
|
+
}
|
|
50
|
+
return maxAcknowledgedAge < limit;
|
|
51
|
+
};
|
|
52
|
+
|
|
41
53
|
export const datesByThemselves = (a, b) => {
|
|
42
54
|
if (!a.from) return 1;
|
|
43
55
|
return moment(a.from) - moment(b.from);
|
|
@@ -49,7 +61,8 @@ export const getShiftText = (from, to, timezone) => {
|
|
|
49
61
|
const startToTimezone = moment(from).tz(timezone);
|
|
50
62
|
const endToTimezone = moment(to).tz(timezone);
|
|
51
63
|
return `${moment(startToTimezone).format('dddd, DD MMMM YYYY, h:mma')}-${moment(endToTimezone).format('h:mma')}`;
|
|
52
|
-
}
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
53
66
|
return '';
|
|
54
67
|
}
|
|
55
68
|
};
|
package/src/locality.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {Array} locationList
|
|
2
|
+
*
|
|
3
|
+
* @param {Array} locationList
|
|
4
4
|
*/
|
|
5
5
|
export const getHomeLocalityFromLocationList = (locationList) => {
|
|
6
|
-
const homeLocation = Array.isArray(locationList) &&
|
|
7
|
-
locationList.find((location) => location.name === 'Home');
|
|
6
|
+
const homeLocation = Array.isArray(locationList) && locationList.find((location) => location.name === 'Home');
|
|
8
7
|
|
|
9
8
|
if (homeLocation && homeLocation.locality && homeLocation.locality.long) {
|
|
10
9
|
return homeLocation.locality.long;
|
package/src/money.js
CHANGED
|
@@ -3,7 +3,7 @@ const { currencies } = require('@becollective/constants');
|
|
|
3
3
|
// We should probably throw and error on bad input instead of falling back to a default.
|
|
4
4
|
// We're making an assumption that whoever is calling this function can safely work
|
|
5
5
|
// with AUD. But this assumption removes a lot of error handling elsewhere.
|
|
6
|
-
export const getCurrencyFromCurrencyCode = currencyCode => {
|
|
6
|
+
export const getCurrencyFromCurrencyCode = (currencyCode) => {
|
|
7
7
|
if (typeof currencyCode !== 'string' || !currencies[currencyCode]) {
|
|
8
8
|
console.error(new Error(`Invalid currencyCode: ${currencyCode}. Falling back to 'AUD'.`));
|
|
9
9
|
return currencies.AUD;
|
|
@@ -12,12 +12,7 @@ export const getCurrencyFromCurrencyCode = currencyCode => {
|
|
|
12
12
|
return currencies[currencyCode];
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
export const makeMoneyString = ({
|
|
16
|
-
amount: inputAmount,
|
|
17
|
-
currencyCode,
|
|
18
|
-
rounded = false,
|
|
19
|
-
showCurrencyCode = false,
|
|
20
|
-
}) => {
|
|
15
|
+
export const makeMoneyString = ({ amount: inputAmount, currencyCode, rounded = false, showCurrencyCode = false }) => {
|
|
21
16
|
let amount = Number(inputAmount);
|
|
22
17
|
if (isNaN(amount)) {
|
|
23
18
|
console.error(new Error(`Invalid amount: ${inputAmount}. Falling back to 0.`));
|
package/src/opportunity.js
CHANGED
package/src/opportunityUser.js
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
const { pick } = require('lodash');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {*} opportunityUser
|
|
6
|
-
* @param {*} opportunity
|
|
4
|
+
*
|
|
5
|
+
* @param {*} opportunityUser
|
|
6
|
+
* @param {*} opportunity
|
|
7
7
|
*/
|
|
8
8
|
export const getTimeInfo = (opportunityUser, opportunity = null) => {
|
|
9
9
|
const opp = opportunity || opportunityUser.opportunity;
|
|
10
10
|
const isEoi = (opportunityUser && opportunityUser.eoi) || (opp && opp.eoi);
|
|
11
11
|
const record = isEoi ? opportunityUser : opp;
|
|
12
|
-
const fields = pick(record, [
|
|
13
|
-
'
|
|
12
|
+
const fields = pick(record, [
|
|
13
|
+
'startDate',
|
|
14
|
+
'endDate',
|
|
15
|
+
'type',
|
|
16
|
+
'dates',
|
|
17
|
+
'recurrenceRule',
|
|
18
|
+
'timezone',
|
|
19
|
+
'location',
|
|
20
|
+
'locationOther',
|
|
21
|
+
'locationVirtual',
|
|
22
|
+
]);
|
|
14
23
|
|
|
15
24
|
return fields;
|
|
16
25
|
};
|
package/src/password.js
CHANGED
|
@@ -9,17 +9,18 @@ export const password = {
|
|
|
9
9
|
return !!input.match(/[0-9]/);
|
|
10
10
|
},
|
|
11
11
|
validate: (input) => {
|
|
12
|
-
if(typeof input !== 'string') {
|
|
12
|
+
if (typeof input !== 'string') {
|
|
13
13
|
throw new Error('not-string');
|
|
14
|
-
}
|
|
14
|
+
}
|
|
15
|
+
else if (input.length < 12) {
|
|
15
16
|
throw new Error('invalid-length');
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
let rules = 0;
|
|
19
|
-
if(password.hasUppercase(input)) rules++;
|
|
20
|
-
if(password.hasLowerCase(input)) rules++;
|
|
21
|
-
if(password.hasNumeral(input)) rules++;
|
|
22
|
-
if(rules < 3) {
|
|
20
|
+
if (password.hasUppercase(input)) rules++;
|
|
21
|
+
if (password.hasLowerCase(input)) rules++;
|
|
22
|
+
if (password.hasNumeral(input)) rules++;
|
|
23
|
+
if (rules < 3) {
|
|
23
24
|
throw new Error('invalid-minimum-rules');
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -31,7 +32,7 @@ export const password = {
|
|
|
31
32
|
return true;
|
|
32
33
|
}
|
|
33
34
|
catch (e) {
|
|
34
|
-
return false
|
|
35
|
+
return false;
|
|
35
36
|
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
37
|
+
},
|
|
38
|
+
};
|
package/tests/date-time.test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { isUnderSixteen, getAge, getShiftText } = require('../bundle.js');
|
|
1
|
+
const { isUnderSixteen, isUnderAge, getAge, getShiftText } = require('../bundle.js');
|
|
2
2
|
const moment = require('moment');
|
|
3
3
|
|
|
4
4
|
describe('getAge', () => {
|
|
@@ -21,6 +21,7 @@ describe('getAge', () => {
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
test('Throws Error if dob is not a valid date-string', () => {
|
|
24
|
+
// eslint-disable-next-line no-undef
|
|
24
25
|
expect(() => getAge(notDefined)).toThrow(/not defined/);
|
|
25
26
|
expect(() => getAge(null)).toThrow(/Invalid date/);
|
|
26
27
|
expect(() => getAge('not-valid')).toThrow(/Invalid date/);
|
|
@@ -55,16 +56,98 @@ describe('isUnderSixteen', () => {
|
|
|
55
56
|
});
|
|
56
57
|
});
|
|
57
58
|
|
|
59
|
+
describe('isUnderAge - dateOfBirth', () => {
|
|
60
|
+
const refPoint = moment().subtract(13, 'years');
|
|
61
|
+
const obj = {};
|
|
62
|
+
test('Is not U13 if dob is 13 years ago', () => {
|
|
63
|
+
const dob = moment(refPoint);
|
|
64
|
+
|
|
65
|
+
expect(isUnderAge(dob.subtract(1, 'minute').utc().format(), 13)).toBe(false);
|
|
66
|
+
expect(isUnderAge(dob.subtract(100, 'year').utc().format(), 13)).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('Is U16 if dob is less than 16 years ago', () => {
|
|
70
|
+
const dob = moment(refPoint);
|
|
71
|
+
|
|
72
|
+
expect(isUnderAge(dob.add(1, 'minute').utc().format(), 13)).toBe(true);
|
|
73
|
+
expect(isUnderAge(dob.add(100, 'year').utc().format(), 13)).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('Undefined dob', () => {
|
|
77
|
+
expect(isUnderAge(obj.notDefined, 13)).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
test('Null dob', () => {
|
|
80
|
+
expect(isUnderAge(null, 13)).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
test('Invalid date string', () => {
|
|
83
|
+
expect(isUnderAge('not-valid', 13)).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('isUnderAge - maxAcknowledgedAge', () => {
|
|
88
|
+
const obj = {};
|
|
89
|
+
test('Is not U13 if maxAcknowledgedAge is 13 years ago', () => {
|
|
90
|
+
expect(isUnderAge(null, 13, 13)).toBe(false);
|
|
91
|
+
expect(isUnderAge(null, 13, 14)).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('Is U13 if maxAcknowledgedAge is less than X years ago', () => {
|
|
95
|
+
expect(isUnderAge(null, 13, 10)).toBe(true);
|
|
96
|
+
expect(isUnderAge(null, 13, 12)).toBe(true);
|
|
97
|
+
expect(isUnderAge(null, 13, 12.5)).toBe(true);
|
|
98
|
+
expect(isUnderAge(null, 13, 13)).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('Undefined maxAcknowledgedAge', () => {
|
|
102
|
+
expect(isUnderAge(null, 13, obj.notDefined)).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
test('Null maxAcknowledgedAge', () => {
|
|
105
|
+
expect(isUnderAge(null, 13, null)).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
test('Invalid value', () => {
|
|
108
|
+
expect(isUnderAge(null, 13, '13x')).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('isUnderAge - 10', () => {
|
|
113
|
+
const refPoint = moment().subtract(10, 'years');
|
|
114
|
+
const obj = {};
|
|
115
|
+
test('Is not U13 if dob is 10 years ago', () => {
|
|
116
|
+
const dob = moment(refPoint);
|
|
117
|
+
|
|
118
|
+
expect(isUnderAge(dob.subtract(1, 'minute').utc().format(), 10)).toBe(false);
|
|
119
|
+
expect(isUnderAge(dob.subtract(100, 'year').utc().format(), 10)).toBe(false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('Is U10 if dob is less than 10 years ago', () => {
|
|
123
|
+
const dob = moment(refPoint);
|
|
124
|
+
|
|
125
|
+
expect(isUnderAge(dob.add(1, 'minute').utc().format(), 10)).toBe(true);
|
|
126
|
+
expect(isUnderAge(dob.add(100, 'year').utc().format(), 10)).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('isUnderAge - over 13', () => {
|
|
131
|
+
const refPoint = moment().subtract(15, 'years');
|
|
132
|
+
const obj = {};
|
|
133
|
+
test('Is not U13 if dob is 15 years ago', () => {
|
|
134
|
+
const dob = moment(refPoint);
|
|
135
|
+
|
|
136
|
+
expect(isUnderAge(dob.subtract(1, 'minute').utc().format(), 15)).toBe(false);
|
|
137
|
+
expect(isUnderAge(dob.subtract(100, 'year').utc().format(), 15)).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
58
141
|
describe('getShiftText', () => {
|
|
59
142
|
const from = new Date(Date.UTC(2020, 6, 30, 0, 0, 0));
|
|
60
143
|
const to = new Date(Date.UTC(2020, 6, 30, 5, 30, 0));
|
|
61
144
|
const melbourne = 'Australia/Melbourne';
|
|
62
145
|
const auckland = 'Pacific/Auckland';
|
|
63
146
|
test('get shift text with melbourne timezone', () => {
|
|
64
|
-
expect(getShiftText(from, to,melbourne)).toBe(
|
|
147
|
+
expect(getShiftText(from, to, melbourne)).toBe('Thursday, 30 July 2020, 10:00am-3:30pm');
|
|
65
148
|
});
|
|
66
149
|
test('get shift text with auckland timezone', () => {
|
|
67
|
-
expect(getShiftText(from, to,auckland)).toBe(
|
|
150
|
+
expect(getShiftText(from, to, auckland)).toBe('Thursday, 30 July 2020, 12:00pm-5:30pm');
|
|
68
151
|
});
|
|
69
152
|
test('with empty data', () => {
|
|
70
153
|
expect(getShiftText()).toBe('');
|
|
@@ -11,7 +11,7 @@ describe('Make feature decision based on feature flags', () => {
|
|
|
11
11
|
mockAxios.get.mockReturnValue(
|
|
12
12
|
Promise.resolve({
|
|
13
13
|
data: { Environments: ['localtest', 'compose'] },
|
|
14
|
-
})
|
|
14
|
+
})
|
|
15
15
|
);
|
|
16
16
|
const isActive = await featureFlag.isFeatureActive(feature, {
|
|
17
17
|
env: 'localtest',
|
|
@@ -23,7 +23,7 @@ describe('Make feature decision based on feature flags', () => {
|
|
|
23
23
|
mockAxios.get.mockReturnValue(
|
|
24
24
|
Promise.resolve({
|
|
25
25
|
data: { Environments: ['dev-au'] },
|
|
26
|
-
})
|
|
26
|
+
})
|
|
27
27
|
);
|
|
28
28
|
const isActive = await featureFlag.isFeatureActive(feature, {
|
|
29
29
|
env: 'localtest',
|
|
@@ -44,7 +44,7 @@ describe('Make feature decision based on feature flags', () => {
|
|
|
44
44
|
mockAxios.get.mockReturnValue(
|
|
45
45
|
Promise.resolve({
|
|
46
46
|
data: { Environments: ['localtest', 'compose'] },
|
|
47
|
-
})
|
|
47
|
+
})
|
|
48
48
|
);
|
|
49
49
|
const isActive = await featureFlag.isFeatureActive(feature, {
|
|
50
50
|
env: 'localtest',
|
|
@@ -64,7 +64,7 @@ describe('Make feature decision based on feature flags', () => {
|
|
|
64
64
|
mockAxios.get.mockReturnValue(
|
|
65
65
|
Promise.resolve({
|
|
66
66
|
data: { Environments: ['localtest', 'compose'] },
|
|
67
|
-
})
|
|
67
|
+
})
|
|
68
68
|
);
|
|
69
69
|
const isActive = await featureFlag.isFeatureActive(feature, {
|
|
70
70
|
env: 'localtest',
|
|
@@ -84,7 +84,7 @@ describe('Make feature decision based on feature flags', () => {
|
|
|
84
84
|
mockAxios.get.mockReturnValue(
|
|
85
85
|
Promise.resolve({
|
|
86
86
|
data: { Environments: ['localtest', 'compose'] },
|
|
87
|
-
})
|
|
87
|
+
})
|
|
88
88
|
);
|
|
89
89
|
const isActive = await featureFlag.isFeatureActive(feature, {
|
|
90
90
|
env: 'localtest',
|
package/tests/money.test.js
CHANGED
|
@@ -10,13 +10,8 @@ describe('getCurrencyFromCurrencyCode', () => {
|
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
test('Returns AUD currency if currencyCode not found or invalid', () => {
|
|
13
|
-
const bogusCurrencyCodes = [
|
|
14
|
-
|
|
15
|
-
1234,
|
|
16
|
-
'some junk that is not a currency code',
|
|
17
|
-
{ foo: 'bar' },
|
|
18
|
-
];
|
|
19
|
-
bogusCurrencyCodes.forEach(bogusCurrencyCode => {
|
|
13
|
+
const bogusCurrencyCodes = [undefined, 1234, 'some junk that is not a currency code', { foo: 'bar' }];
|
|
14
|
+
bogusCurrencyCodes.forEach((bogusCurrencyCode) => {
|
|
20
15
|
expect(getCurrencyFromCurrencyCode(bogusCurrencyCode)).toMatchObject(currencies.AUD);
|
|
21
16
|
});
|
|
22
17
|
});
|
|
@@ -60,13 +55,8 @@ describe('makeMoneyString', () => {
|
|
|
60
55
|
});
|
|
61
56
|
|
|
62
57
|
test('Outputs a money string for AUD if bad input is provided', () => {
|
|
63
|
-
const bogusCurrencyCodes = [
|
|
64
|
-
|
|
65
|
-
1234,
|
|
66
|
-
'some junk that is not a currency code',
|
|
67
|
-
{ foo: 'bar' },
|
|
68
|
-
];
|
|
69
|
-
bogusCurrencyCodes.forEach(bogusCurrencyCode => {
|
|
58
|
+
const bogusCurrencyCodes = [undefined, 1234, 'some junk that is not a currency code', { foo: 'bar' }];
|
|
59
|
+
bogusCurrencyCodes.forEach((bogusCurrencyCode) => {
|
|
70
60
|
expect(
|
|
71
61
|
makeMoneyString({
|
|
72
62
|
amount: 123.05,
|
|
@@ -87,7 +77,7 @@ describe('makeMoneyString', () => {
|
|
|
87
77
|
).toEqual('£100');
|
|
88
78
|
|
|
89
79
|
const bogusAmountValues = [undefined, null, 'some junk that is not a number', { foo: 'bar' }];
|
|
90
|
-
bogusAmountValues.forEach(bogusAmountValue => {
|
|
80
|
+
bogusAmountValues.forEach((bogusAmountValue) => {
|
|
91
81
|
expect(
|
|
92
82
|
makeMoneyString({
|
|
93
83
|
amount: bogusAmountValue,
|
package/tests/password.test.js
CHANGED
|
@@ -6,7 +6,8 @@ describe('password.valiate', () => {
|
|
|
6
6
|
let result;
|
|
7
7
|
try {
|
|
8
8
|
result = util.password.validate(password);
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
10
11
|
result = e;
|
|
11
12
|
}
|
|
12
13
|
expect(result).toBe(true);
|
|
@@ -47,14 +48,7 @@ describe('password.valiate', () => {
|
|
|
47
48
|
}).toThrow('not-string');
|
|
48
49
|
}, 1000);
|
|
49
50
|
test('returns false for invalid passwords', async () => {
|
|
50
|
-
const someValid = [
|
|
51
|
-
'short',
|
|
52
|
-
'1234567a',
|
|
53
|
-
'123456aa',
|
|
54
|
-
'1aB!',
|
|
55
|
-
]
|
|
56
|
-
.map(util.password.isValid)
|
|
57
|
-
.some(val => val);
|
|
51
|
+
const someValid = ['short', '1234567a', '123456aa', '1aB!'].map(util.password.isValid).some((val) => val);
|
|
58
52
|
expect(someValid).toBe(false);
|
|
59
53
|
});
|
|
60
54
|
test('returns true for a valid password', async () => {
|
package/tslint.json
CHANGED
|
@@ -1,51 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": ["tslint:recommended", "tslint-config-prettier"],
|
|
3
3
|
"rules": {
|
|
4
|
-
"align": [
|
|
5
|
-
true,
|
|
6
|
-
"parameters",
|
|
7
|
-
"arguments",
|
|
8
|
-
"statements"
|
|
9
|
-
],
|
|
4
|
+
"align": [true, "parameters", "arguments", "statements"],
|
|
10
5
|
"ban": false,
|
|
11
6
|
"class-name": true,
|
|
12
|
-
"comment-format": [
|
|
13
|
-
true,
|
|
14
|
-
"check-space"
|
|
15
|
-
],
|
|
7
|
+
"comment-format": [true, "check-space"],
|
|
16
8
|
"curly": true,
|
|
17
9
|
"eofline": false,
|
|
18
10
|
"forin": true,
|
|
19
|
-
"indent": [
|
|
11
|
+
"indent": [true, "spaces"],
|
|
20
12
|
"interface-name": [true, "never-prefix"],
|
|
21
13
|
"jsdoc-format": true,
|
|
22
14
|
"jsx-no-lambda": false,
|
|
23
15
|
"jsx-no-multiline-js": false,
|
|
24
16
|
"label-position": true,
|
|
25
|
-
"max-line-length": [
|
|
17
|
+
"max-line-length": [true, 120],
|
|
26
18
|
"member-ordering": [
|
|
27
19
|
true,
|
|
28
20
|
{
|
|
29
|
-
"order": [
|
|
30
|
-
"public-before-private",
|
|
31
|
-
"static-before-instance",
|
|
32
|
-
"variables-before-functions"
|
|
33
|
-
]
|
|
21
|
+
"order": ["public-before-private", "static-before-instance", "variables-before-functions"]
|
|
34
22
|
}
|
|
35
23
|
],
|
|
36
24
|
"no-any": true,
|
|
37
25
|
"no-arg": true,
|
|
38
26
|
"no-bitwise": true,
|
|
39
|
-
"no-console": [
|
|
40
|
-
true,
|
|
41
|
-
"log",
|
|
42
|
-
"error",
|
|
43
|
-
"debug",
|
|
44
|
-
"info",
|
|
45
|
-
"time",
|
|
46
|
-
"timeEnd",
|
|
47
|
-
"trace"
|
|
48
|
-
],
|
|
27
|
+
"no-console": [true, "log", "error", "debug", "info", "time", "timeEnd", "trace"],
|
|
49
28
|
"no-consecutive-blank-lines": true,
|
|
50
29
|
"no-construct": true,
|
|
51
30
|
"no-debugger": true,
|
|
@@ -57,24 +36,16 @@
|
|
|
57
36
|
"no-switch-case-fall-through": true,
|
|
58
37
|
"no-trailing-whitespace": false,
|
|
59
38
|
"no-unused-expression": true,
|
|
60
|
-
"one-line": [
|
|
61
|
-
true,
|
|
62
|
-
"check-open-brace",
|
|
63
|
-
"check-whitespace"
|
|
64
|
-
],
|
|
39
|
+
"one-line": [true, "check-open-brace", "check-whitespace"],
|
|
65
40
|
"quotemark": [true, "single", "jsx-double"],
|
|
66
41
|
"radix": true,
|
|
67
42
|
"semicolon": [true, "always"],
|
|
68
43
|
"switch-default": true,
|
|
69
44
|
|
|
70
|
-
"trailing-comma": [true, {"multiline": "always", "singleline": "never"}],
|
|
45
|
+
"trailing-comma": [true, { "multiline": "always", "singleline": "never" }],
|
|
71
46
|
|
|
72
|
-
"triple-equals": [
|
|
73
|
-
"typedef": [
|
|
74
|
-
true,
|
|
75
|
-
"parameter",
|
|
76
|
-
"property-declaration"
|
|
77
|
-
],
|
|
47
|
+
"triple-equals": [true, "allow-null-check"],
|
|
48
|
+
"typedef": [true, "parameter", "property-declaration"],
|
|
78
49
|
"typedef-whitespace": [
|
|
79
50
|
true,
|
|
80
51
|
{
|