shufflecom-calculations 1.12.19 → 1.12.21
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/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/derive-vip-bonus.js +6 -8
- package/lib/utils/derive-vip-bonus.js.map +1 -1
- package/lib/utils/validate-cashout-avaliable.d.ts +3 -7
- package/lib/utils/validate-cashout-avaliable.js +36 -37
- package/lib/utils/validate-cashout-avaliable.js.map +1 -1
- package/lib/utils/vip-bonus.type.d.ts +2 -1
- package/lib/utils/vip-bonus.type.js.map +1 -1
- package/package.json +2 -2
- package/src/utils/derive-vip-bonus.spec.ts +214 -127
- package/src/utils/derive-vip-bonus.ts +26 -14
- package/src/utils/validate-cashout-avaliable.ts +50 -46
- package/src/utils/vip-bonus.type.ts +2 -1
|
@@ -18,7 +18,7 @@ describe('VipBonusUtils', () => {
|
|
|
18
18
|
const expiryPerOccurrence = 5 * 60;
|
|
19
19
|
const firstOccurrenceActivationPeriod = 5;
|
|
20
20
|
const occurrence = 4;
|
|
21
|
-
const bonusClaims: VipBonusIssuanceModel[] = []
|
|
21
|
+
const bonusClaims: VipBonusIssuanceModel[] = [];
|
|
22
22
|
|
|
23
23
|
const vipBonus: VipBonusPartial = {
|
|
24
24
|
type: VipBonusType.RELOADED,
|
|
@@ -28,56 +28,63 @@ describe('VipBonusUtils', () => {
|
|
|
28
28
|
occurrence,
|
|
29
29
|
cancelledAt: null,
|
|
30
30
|
createdAt: startDate.toISOString(),
|
|
31
|
-
endAt: startDate
|
|
31
|
+
endAt: startDate
|
|
32
|
+
.add(firstOccurrenceActivationPeriod, 'hours')
|
|
33
|
+
.add(expiryPerOccurrence * occurrence, 'seconds')
|
|
34
|
+
.toISOString(),
|
|
32
35
|
bonusClaims,
|
|
33
36
|
firstOccurrenceActivationPeriod,
|
|
34
37
|
expiryPerOccurrence,
|
|
35
|
-
}
|
|
38
|
+
};
|
|
36
39
|
|
|
37
|
-
let timeNow = startDate
|
|
40
|
+
let timeNow = startDate;
|
|
38
41
|
mockdatetime(timeNow.toDate());
|
|
39
42
|
|
|
40
|
-
let issuances = deriveBonusIssuances(vipBonus)
|
|
43
|
+
let issuances = deriveBonusIssuances(vipBonus);
|
|
41
44
|
|
|
42
|
-
let firstIssuance = issuances[0]
|
|
43
|
-
expect(firstIssuance.expiryDate).toEqual(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
expect(secondIssuance.expiryDate).toBeUndefined()
|
|
49
|
-
expect(secondIssuance.availableDate).toBeUndefined()
|
|
50
|
-
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED)
|
|
45
|
+
let firstIssuance = issuances[0];
|
|
46
|
+
expect(firstIssuance.expiryDate).toEqual(
|
|
47
|
+
startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
|
|
48
|
+
);
|
|
49
|
+
expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
|
|
50
|
+
expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
|
|
51
51
|
|
|
52
|
+
let secondIssuance = issuances[1];
|
|
53
|
+
expect(secondIssuance.expiryDate).toBeUndefined();
|
|
54
|
+
expect(secondIssuance.availableDate).toBeUndefined();
|
|
55
|
+
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
52
56
|
|
|
53
57
|
// first claim before the activation period ends
|
|
54
|
-
timeNow = startDate.add(firstOccurrenceActivationPeriod / 2, 'hours')
|
|
55
|
-
mockdatetime(timeNow.toDate())
|
|
58
|
+
timeNow = startDate.add(firstOccurrenceActivationPeriod / 2, 'hours');
|
|
59
|
+
mockdatetime(timeNow.toDate());
|
|
56
60
|
|
|
57
61
|
bonusClaims.push({
|
|
58
62
|
currency: Currency.BTC,
|
|
63
|
+
amount: '10',
|
|
59
64
|
bonusAmountUsd: BigNumber(bonusAmountUsd).dividedBy(occurrence).toString(),
|
|
60
65
|
occurrenceIndex: 1,
|
|
61
66
|
createdAt: timeNow.toISOString(),
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
vipBonus.bonusClaims = bonusClaims
|
|
67
|
+
});
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
vipBonus.bonusClaims = bonusClaims;
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
expect(firstIssuance.expiryDate).toEqual(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString())
|
|
70
|
-
expect(firstIssuance.availableDate).toEqual(startDate.toISOString())
|
|
71
|
-
expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED)
|
|
71
|
+
issuances = deriveBonusIssuances(vipBonus);
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
expect(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
expect(
|
|
73
|
+
firstIssuance = issuances[0];
|
|
74
|
+
expect(firstIssuance.expiryDate).toEqual(
|
|
75
|
+
startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
|
|
76
|
+
);
|
|
77
|
+
expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
|
|
78
|
+
expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
|
|
79
|
+
expect(firstIssuance.amount).toEqual('10');
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
secondIssuance = issuances[1];
|
|
82
|
+
expect(secondIssuance.expiryDate).toEqual(timeNow.add(cadence + expiryPerOccurrence, 'seconds').toISOString());
|
|
83
|
+
expect(secondIssuance.availableDate).toEqual(timeNow.add(cadence, 'seconds').toISOString());
|
|
84
|
+
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
85
|
+
expect(secondIssuance.currency).toEqual(Currency.BTC);
|
|
86
|
+
expect(secondIssuance.amount).toEqual(undefined);
|
|
87
|
+
});
|
|
81
88
|
|
|
82
89
|
it('should derive bonus issuance status correctly (first claim after activation period)', () => {
|
|
83
90
|
const bonusAmountUsd = '100';
|
|
@@ -86,7 +93,7 @@ describe('VipBonusUtils', () => {
|
|
|
86
93
|
const expiryPerOccurrence = 20 * 60;
|
|
87
94
|
const firstOccurrenceActivationPeriod = 5;
|
|
88
95
|
const occurrence = 4;
|
|
89
|
-
const bonusClaims: VipBonusIssuanceModel[] = []
|
|
96
|
+
const bonusClaims: VipBonusIssuanceModel[] = [];
|
|
90
97
|
|
|
91
98
|
const vipBonus: VipBonusPartial = {
|
|
92
99
|
type: VipBonusType.RELOADED,
|
|
@@ -96,56 +103,65 @@ describe('VipBonusUtils', () => {
|
|
|
96
103
|
occurrence,
|
|
97
104
|
cancelledAt: null,
|
|
98
105
|
createdAt: startDate.toISOString(),
|
|
99
|
-
endAt: startDate
|
|
106
|
+
endAt: startDate
|
|
107
|
+
.add(firstOccurrenceActivationPeriod, 'hours')
|
|
108
|
+
.add(expiryPerOccurrence * occurrence, 'seconds')
|
|
109
|
+
.toISOString(),
|
|
100
110
|
bonusClaims,
|
|
101
111
|
firstOccurrenceActivationPeriod,
|
|
102
112
|
expiryPerOccurrence,
|
|
103
|
-
}
|
|
113
|
+
};
|
|
104
114
|
|
|
105
|
-
let timeNow = startDate
|
|
115
|
+
let timeNow = startDate;
|
|
106
116
|
mockdatetime(timeNow.toDate());
|
|
107
117
|
|
|
108
|
-
let issuances = deriveBonusIssuances(vipBonus)
|
|
118
|
+
let issuances = deriveBonusIssuances(vipBonus);
|
|
109
119
|
|
|
110
|
-
let firstIssuance = issuances[0]
|
|
111
|
-
expect(firstIssuance.expiryDate).toEqual(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
expect(secondIssuance.expiryDate).toBeUndefined()
|
|
117
|
-
expect(secondIssuance.availableDate).toBeUndefined()
|
|
118
|
-
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED)
|
|
120
|
+
let firstIssuance = issuances[0];
|
|
121
|
+
expect(firstIssuance.expiryDate).toEqual(
|
|
122
|
+
startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
|
|
123
|
+
);
|
|
124
|
+
expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
|
|
125
|
+
expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
|
|
119
126
|
|
|
127
|
+
let secondIssuance = issuances[1];
|
|
128
|
+
expect(secondIssuance.expiryDate).toBeUndefined();
|
|
129
|
+
expect(secondIssuance.availableDate).toBeUndefined();
|
|
130
|
+
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
120
131
|
|
|
121
132
|
// first claim after the activation period ends
|
|
122
|
-
timeNow = startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence / 2, 'seconds')
|
|
123
|
-
const activationTime = startDate.add(firstOccurrenceActivationPeriod, 'hours')
|
|
124
|
-
mockdatetime(timeNow.toDate())
|
|
133
|
+
timeNow = startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence / 2, 'seconds');
|
|
134
|
+
const activationTime = startDate.add(firstOccurrenceActivationPeriod, 'hours');
|
|
135
|
+
mockdatetime(timeNow.toDate());
|
|
125
136
|
|
|
126
137
|
bonusClaims.push({
|
|
127
138
|
currency: Currency.BTC,
|
|
139
|
+
amount: '10',
|
|
128
140
|
bonusAmountUsd: BigNumber(bonusAmountUsd).dividedBy(occurrence).toString(),
|
|
129
141
|
occurrenceIndex: 1,
|
|
130
142
|
createdAt: timeNow.toISOString(),
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
vipBonus.bonusClaims = bonusClaims
|
|
134
|
-
|
|
135
|
-
issuances = deriveBonusIssuances(vipBonus)
|
|
136
|
-
firstIssuance = issuances[0]
|
|
137
|
-
expect(firstIssuance.expiryDate).toEqual(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString())
|
|
138
|
-
expect(firstIssuance.availableDate).toEqual(startDate.toISOString())
|
|
139
|
-
expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED)
|
|
140
|
-
|
|
141
|
-
secondIssuance = issuances[1]
|
|
142
|
-
expect(secondIssuance.expiryDate).toEqual(activationTime.add(cadence + expiryPerOccurrence, 'seconds').toISOString())
|
|
143
|
-
expect(secondIssuance.availableDate).toEqual(activationTime.add(cadence, 'seconds').toISOString())
|
|
144
|
-
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM)
|
|
145
|
-
expect(secondIssuance.currency).toEqual(Currency.BTC)
|
|
143
|
+
});
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
vipBonus.bonusClaims = bonusClaims;
|
|
146
|
+
|
|
147
|
+
issuances = deriveBonusIssuances(vipBonus);
|
|
148
|
+
firstIssuance = issuances[0];
|
|
149
|
+
expect(firstIssuance.expiryDate).toEqual(
|
|
150
|
+
startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
|
|
151
|
+
);
|
|
152
|
+
expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
|
|
153
|
+
expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
|
|
154
|
+
expect(firstIssuance.amount).toEqual('10');
|
|
155
|
+
|
|
156
|
+
secondIssuance = issuances[1];
|
|
157
|
+
expect(secondIssuance.expiryDate).toEqual(activationTime.add(cadence + expiryPerOccurrence, 'seconds').toISOString());
|
|
158
|
+
expect(secondIssuance.availableDate).toEqual(activationTime.add(cadence, 'seconds').toISOString());
|
|
159
|
+
expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
|
|
160
|
+
expect(secondIssuance.currency).toEqual(Currency.BTC);
|
|
161
|
+
expect(secondIssuance.amount).toEqual(undefined);
|
|
162
|
+
|
|
163
|
+
timeNow = startDate.add(firstOccurrenceActivationPeriod, 'hours').add(cadence + 1, 'seconds');
|
|
164
|
+
mockdatetime(timeNow.toDate());
|
|
149
165
|
const bonusClaimNotInOrder = [
|
|
150
166
|
{
|
|
151
167
|
currency: Currency.BTC,
|
|
@@ -153,14 +169,19 @@ describe('VipBonusUtils', () => {
|
|
|
153
169
|
occurrenceIndex: 2,
|
|
154
170
|
createdAt: timeNow.toISOString(),
|
|
155
171
|
},
|
|
156
|
-
bonusClaims[0]
|
|
157
|
-
]
|
|
158
|
-
|
|
159
|
-
vipBonus.bonusClaims = bonusClaimNotInOrder
|
|
160
|
-
issuances = deriveBonusIssuances(vipBonus)
|
|
161
|
-
firstIssuance = issuances[0]
|
|
162
|
-
expect(firstIssuance.createdAt).toEqual(
|
|
163
|
-
|
|
172
|
+
bonusClaims[0],
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
vipBonus.bonusClaims = bonusClaimNotInOrder;
|
|
176
|
+
issuances = deriveBonusIssuances(vipBonus);
|
|
177
|
+
firstIssuance = issuances[0];
|
|
178
|
+
expect(firstIssuance.createdAt).toEqual(
|
|
179
|
+
startDate
|
|
180
|
+
.add(firstOccurrenceActivationPeriod, 'hours')
|
|
181
|
+
.add(expiryPerOccurrence / 2, 'seconds')
|
|
182
|
+
.toISOString(),
|
|
183
|
+
);
|
|
184
|
+
});
|
|
164
185
|
|
|
165
186
|
it('should update bonus issuance status correctly sequential vip reload', () => {
|
|
166
187
|
const vipBonusId = uuidv4();
|
|
@@ -173,15 +194,22 @@ describe('VipBonusUtils', () => {
|
|
|
173
194
|
const firstOccurrenceActivationPeriod = 0;
|
|
174
195
|
const occurrence = 10;
|
|
175
196
|
const claimed = [2, 3];
|
|
176
|
-
const activationTime = dayjs(startDate)
|
|
197
|
+
const activationTime = dayjs(startDate);
|
|
177
198
|
|
|
178
|
-
const issuances = range(1, occurrence + 1).map(
|
|
199
|
+
const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
|
|
179
200
|
vipBonusId,
|
|
180
201
|
userId,
|
|
181
202
|
currency,
|
|
182
203
|
bonusAmountUsd,
|
|
183
204
|
occurrenceIndex,
|
|
184
|
-
expiryDate: getReloadExpiryDate(
|
|
205
|
+
expiryDate: getReloadExpiryDate(
|
|
206
|
+
activationTime,
|
|
207
|
+
cadence,
|
|
208
|
+
expiryPerOccurrence,
|
|
209
|
+
occurrenceIndex,
|
|
210
|
+
startDate,
|
|
211
|
+
firstOccurrenceActivationPeriod,
|
|
212
|
+
)?.toISOString(),
|
|
185
213
|
availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
|
|
186
214
|
status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
|
|
187
215
|
createdAt: startDate.toISOString(),
|
|
@@ -192,7 +220,7 @@ describe('VipBonusUtils', () => {
|
|
|
192
220
|
|
|
193
221
|
// fast forward into reward 3 claiming interval
|
|
194
222
|
mockdatetime(startDate.add(cadence * fastForward + 1, 'seconds').toDate());
|
|
195
|
-
let updatedStatusList = issuances.map(
|
|
223
|
+
let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
196
224
|
|
|
197
225
|
updatedStatusList.forEach((issuance, index) => {
|
|
198
226
|
if (claimed.includes(index + 1)) {
|
|
@@ -207,7 +235,7 @@ describe('VipBonusUtils', () => {
|
|
|
207
235
|
// fast forward into reward 6 claiming interval
|
|
208
236
|
fastForward = 5;
|
|
209
237
|
mockdatetime(startDate.add(cadence * fastForward, 'seconds').toDate());
|
|
210
|
-
updatedStatusList = issuances.map(
|
|
238
|
+
updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
211
239
|
|
|
212
240
|
updatedStatusList.forEach((issuance, index) => {
|
|
213
241
|
if (claimed.includes(index + 1)) {
|
|
@@ -233,27 +261,41 @@ describe('VipBonusUtils', () => {
|
|
|
233
261
|
const firstOccurrenceActivationPeriod = 10;
|
|
234
262
|
const occurrence = 10;
|
|
235
263
|
let activationTime: Dayjs | null = null; // first one not claimed yet
|
|
236
|
-
|
|
237
|
-
let issuances = range(1, occurrence + 1).map(
|
|
264
|
+
|
|
265
|
+
let issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
|
|
238
266
|
vipBonusId,
|
|
239
267
|
userId,
|
|
240
268
|
currency,
|
|
241
269
|
bonusAmountUsd,
|
|
242
270
|
occurrenceIndex,
|
|
243
|
-
expiryDate: getReloadExpiryDate(
|
|
271
|
+
expiryDate: getReloadExpiryDate(
|
|
272
|
+
activationTime,
|
|
273
|
+
cadence,
|
|
274
|
+
expiryPerOccurrence,
|
|
275
|
+
occurrenceIndex,
|
|
276
|
+
startDate,
|
|
277
|
+
firstOccurrenceActivationPeriod,
|
|
278
|
+
)?.toISOString(),
|
|
244
279
|
availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
|
|
245
280
|
status: null as VipBonusIssuanceStatus | null,
|
|
246
281
|
createdAt: startDate.toISOString(),
|
|
247
282
|
expiryPerOccurrence,
|
|
248
283
|
firstOccurrenceActivationPeriod,
|
|
249
|
-
}))
|
|
284
|
+
}));
|
|
250
285
|
|
|
251
286
|
// fast forward within first occurrence activation period
|
|
252
287
|
mockdatetime(startDate.add(firstOccurrenceActivationPeriod / 2, 'hours').toDate());
|
|
253
288
|
// first issuance has to recalculate based on current time
|
|
254
|
-
issuances[0].expiryDate = getReloadExpiryDate(
|
|
289
|
+
issuances[0].expiryDate = getReloadExpiryDate(
|
|
290
|
+
activationTime,
|
|
291
|
+
cadence,
|
|
292
|
+
expiryPerOccurrence,
|
|
293
|
+
1,
|
|
294
|
+
startDate,
|
|
295
|
+
firstOccurrenceActivationPeriod,
|
|
296
|
+
)?.toISOString();
|
|
255
297
|
|
|
256
|
-
let updatedStatusList = issuances.map(
|
|
298
|
+
let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
257
299
|
|
|
258
300
|
updatedStatusList.forEach((issuance, index) => {
|
|
259
301
|
if (index + 1 === 1) {
|
|
@@ -261,39 +303,63 @@ describe('VipBonusUtils', () => {
|
|
|
261
303
|
} else {
|
|
262
304
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
263
305
|
}
|
|
264
|
-
})
|
|
306
|
+
});
|
|
265
307
|
|
|
266
308
|
// fast forward after first occurrence activation period
|
|
267
|
-
mockdatetime(
|
|
268
|
-
|
|
269
|
-
|
|
309
|
+
mockdatetime(
|
|
310
|
+
startDate
|
|
311
|
+
.add(firstOccurrenceActivationPeriod, 'hours')
|
|
312
|
+
.add(expiryPerOccurrence / 2, 'seconds')
|
|
313
|
+
.toDate(),
|
|
314
|
+
);
|
|
315
|
+
issuances[0].expiryDate = getReloadExpiryDate(
|
|
316
|
+
activationTime,
|
|
317
|
+
cadence,
|
|
318
|
+
expiryPerOccurrence,
|
|
319
|
+
1,
|
|
320
|
+
startDate,
|
|
321
|
+
firstOccurrenceActivationPeriod,
|
|
322
|
+
)?.toISOString();
|
|
323
|
+
updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
270
324
|
|
|
271
325
|
updatedStatusList.forEach((issuance, index) => {
|
|
272
|
-
if (index + 1 === 1) {
|
|
326
|
+
if (index + 1 === 1) {
|
|
273
327
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
|
|
274
328
|
} else {
|
|
275
329
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
276
330
|
}
|
|
277
|
-
})
|
|
331
|
+
});
|
|
278
332
|
|
|
279
333
|
// fast forward after expiry
|
|
280
|
-
mockdatetime(
|
|
281
|
-
|
|
282
|
-
|
|
334
|
+
mockdatetime(
|
|
335
|
+
startDate
|
|
336
|
+
.add(firstOccurrenceActivationPeriod, 'hours')
|
|
337
|
+
.add(expiryPerOccurrence + 1, 'seconds')
|
|
338
|
+
.toDate(),
|
|
339
|
+
);
|
|
340
|
+
activationTime = dayjs(startDate).add(firstOccurrenceActivationPeriod, 'hours');
|
|
341
|
+
issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
|
|
283
342
|
vipBonusId,
|
|
284
343
|
userId,
|
|
285
344
|
currency,
|
|
286
345
|
bonusAmountUsd,
|
|
287
346
|
occurrenceIndex,
|
|
288
|
-
expiryDate: getReloadExpiryDate(
|
|
347
|
+
expiryDate: getReloadExpiryDate(
|
|
348
|
+
activationTime,
|
|
349
|
+
cadence,
|
|
350
|
+
expiryPerOccurrence,
|
|
351
|
+
occurrenceIndex,
|
|
352
|
+
startDate,
|
|
353
|
+
firstOccurrenceActivationPeriod,
|
|
354
|
+
)?.toISOString(),
|
|
289
355
|
availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
|
|
290
356
|
status: null as VipBonusIssuanceStatus | null,
|
|
291
357
|
createdAt: startDate.toISOString(),
|
|
292
358
|
expiryPerOccurrence,
|
|
293
359
|
firstOccurrenceActivationPeriod,
|
|
294
|
-
}))
|
|
360
|
+
}));
|
|
295
361
|
|
|
296
|
-
updatedStatusList = issuances.map(
|
|
362
|
+
updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
297
363
|
|
|
298
364
|
updatedStatusList.forEach((issuance, index) => {
|
|
299
365
|
if (index + 1 === 1) {
|
|
@@ -301,8 +367,8 @@ describe('VipBonusUtils', () => {
|
|
|
301
367
|
} else {
|
|
302
368
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
303
369
|
}
|
|
304
|
-
})
|
|
305
|
-
})
|
|
370
|
+
});
|
|
371
|
+
});
|
|
306
372
|
|
|
307
373
|
it('should update bonus issuance status correctly for independent vip reload (overlapping vip reloads)', () => {
|
|
308
374
|
const vipBonusId = uuidv4();
|
|
@@ -315,15 +381,22 @@ describe('VipBonusUtils', () => {
|
|
|
315
381
|
const firstOccurrenceActivationPeriod = 10;
|
|
316
382
|
const occurrence = 10;
|
|
317
383
|
const claimed = [1];
|
|
318
|
-
const activationTime = dayjs(startDate).add(5, 'hours') // user claimed within first occurrence activation period
|
|
384
|
+
const activationTime = dayjs(startDate).add(5, 'hours'); // user claimed within first occurrence activation period
|
|
319
385
|
|
|
320
|
-
const issuances = range(1, occurrence + 1).map(
|
|
386
|
+
const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
|
|
321
387
|
vipBonusId,
|
|
322
388
|
userId,
|
|
323
389
|
currency,
|
|
324
390
|
bonusAmountUsd,
|
|
325
391
|
occurrenceIndex,
|
|
326
|
-
expiryDate: getReloadExpiryDate(
|
|
392
|
+
expiryDate: getReloadExpiryDate(
|
|
393
|
+
activationTime,
|
|
394
|
+
cadence,
|
|
395
|
+
expiryPerOccurrence,
|
|
396
|
+
occurrenceIndex,
|
|
397
|
+
startDate,
|
|
398
|
+
firstOccurrenceActivationPeriod,
|
|
399
|
+
)?.toISOString(),
|
|
327
400
|
availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
|
|
328
401
|
status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
|
|
329
402
|
createdAt: startDate.toISOString(),
|
|
@@ -335,9 +408,9 @@ describe('VipBonusUtils', () => {
|
|
|
335
408
|
|
|
336
409
|
// fast forward into reward 3 claiming interval
|
|
337
410
|
mockdatetime(activationTime.add(cadence * fastForward + 1, 'seconds').toDate());
|
|
338
|
-
let updatedStatusList = issuances.map(
|
|
411
|
+
let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
339
412
|
|
|
340
|
-
let pendingClaims = [2, 3]
|
|
413
|
+
let pendingClaims = [2, 3];
|
|
341
414
|
updatedStatusList.forEach((issuance, index) => {
|
|
342
415
|
if (claimed.includes(index + 1)) {
|
|
343
416
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
|
|
@@ -348,14 +421,14 @@ describe('VipBonusUtils', () => {
|
|
|
348
421
|
}
|
|
349
422
|
});
|
|
350
423
|
|
|
351
|
-
fastForward = 7
|
|
424
|
+
fastForward = 7;
|
|
352
425
|
|
|
353
426
|
// fast forward into reward 8 just after expiry
|
|
354
427
|
mockdatetime(activationTime.add(cadence * fastForward + expiryPerOccurrence + 1, 'seconds').toDate());
|
|
355
|
-
updatedStatusList = issuances.map(
|
|
428
|
+
updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
356
429
|
|
|
357
|
-
pendingClaims = [9, 10]
|
|
358
|
-
|
|
430
|
+
pendingClaims = [9, 10];
|
|
431
|
+
const expired = [2, 3, 4, 5, 6, 7, 8];
|
|
359
432
|
updatedStatusList.forEach((issuance, index) => {
|
|
360
433
|
if (claimed.includes(index + 1)) {
|
|
361
434
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
|
|
@@ -366,8 +439,8 @@ describe('VipBonusUtils', () => {
|
|
|
366
439
|
} else {
|
|
367
440
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
|
|
368
441
|
}
|
|
369
|
-
})
|
|
370
|
-
})
|
|
442
|
+
});
|
|
443
|
+
});
|
|
371
444
|
|
|
372
445
|
it('should update bonus issuance status correctly for independent vip reload (no overlapping vip reloads', () => {
|
|
373
446
|
const vipBonusId = uuidv4();
|
|
@@ -381,26 +454,33 @@ describe('VipBonusUtils', () => {
|
|
|
381
454
|
const occurrence = 10;
|
|
382
455
|
const claimed = [2, 3];
|
|
383
456
|
const activationTime = dayjs(startDate).add(firstOccurrenceActivationPeriod, 'hours');
|
|
384
|
-
|
|
385
|
-
const issuances = range(1, occurrence + 1).map(
|
|
457
|
+
|
|
458
|
+
const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
|
|
386
459
|
vipBonusId,
|
|
387
460
|
userId,
|
|
388
461
|
currency,
|
|
389
462
|
bonusAmountUsd,
|
|
390
463
|
occurrenceIndex,
|
|
391
|
-
expiryDate: getReloadExpiryDate(
|
|
464
|
+
expiryDate: getReloadExpiryDate(
|
|
465
|
+
activationTime,
|
|
466
|
+
cadence,
|
|
467
|
+
expiryPerOccurrence,
|
|
468
|
+
occurrenceIndex,
|
|
469
|
+
startDate,
|
|
470
|
+
firstOccurrenceActivationPeriod,
|
|
471
|
+
)?.toISOString(),
|
|
392
472
|
availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
|
|
393
473
|
status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
|
|
394
474
|
createdAt: startDate.toISOString(),
|
|
395
475
|
expiryPerOccurrence,
|
|
396
476
|
firstOccurrenceActivationPeriod,
|
|
397
|
-
}))
|
|
477
|
+
}));
|
|
398
478
|
|
|
399
479
|
let fastForward = 2;
|
|
400
|
-
let pendingClaims = [4, 5, 6, 7, 8, 9, 10]
|
|
480
|
+
let pendingClaims = [4, 5, 6, 7, 8, 9, 10];
|
|
401
481
|
// fast forward into reward 3 claiming interval
|
|
402
482
|
mockdatetime(activationTime.add(cadence * fastForward + 1, 'seconds').toDate());
|
|
403
|
-
let updatedStatusList = issuances.map(
|
|
483
|
+
let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
404
484
|
|
|
405
485
|
updatedStatusList.forEach((issuance, index) => {
|
|
406
486
|
if (claimed.includes(index + 1)) {
|
|
@@ -410,14 +490,14 @@ describe('VipBonusUtils', () => {
|
|
|
410
490
|
} else {
|
|
411
491
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.EXPIRED);
|
|
412
492
|
}
|
|
413
|
-
})
|
|
493
|
+
});
|
|
414
494
|
|
|
415
|
-
fastForward = 7
|
|
416
|
-
pendingClaims = [9, 10]
|
|
495
|
+
fastForward = 7;
|
|
496
|
+
pendingClaims = [9, 10];
|
|
417
497
|
|
|
418
498
|
// fast forward into reward 8 just after expiry
|
|
419
499
|
mockdatetime(activationTime.add(cadence * fastForward + expiryPerOccurrence + 1, 'seconds').toDate());
|
|
420
|
-
updatedStatusList = issuances.map(
|
|
500
|
+
updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
|
|
421
501
|
|
|
422
502
|
updatedStatusList.forEach((issuance, index) => {
|
|
423
503
|
if (claimed.includes(index + 1)) {
|
|
@@ -427,9 +507,9 @@ describe('VipBonusUtils', () => {
|
|
|
427
507
|
} else {
|
|
428
508
|
expect(issuance.status).toEqual(VipBonusIssuanceStatus.EXPIRED);
|
|
429
509
|
}
|
|
430
|
-
})
|
|
431
|
-
})
|
|
432
|
-
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
|
|
433
513
|
it('should update bonus issuance status correctly with cancelledAt', () => {
|
|
434
514
|
const vipBonusId = uuidv4();
|
|
435
515
|
const userId = uuidv4();
|
|
@@ -445,15 +525,22 @@ describe('VipBonusUtils', () => {
|
|
|
445
525
|
const cancelledAt = dayjs(startDate)
|
|
446
526
|
.add(cadence * (cancelledIndex - 1), 'seconds')
|
|
447
527
|
.toDate();
|
|
448
|
-
const activationTime = dayjs(startDate)
|
|
528
|
+
const activationTime = dayjs(startDate);
|
|
449
529
|
|
|
450
|
-
const issuances = range(1, occurrence + 1).map(
|
|
530
|
+
const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
|
|
451
531
|
vipBonusId,
|
|
452
532
|
userId,
|
|
453
533
|
currency,
|
|
454
534
|
bonusAmountUsd,
|
|
455
535
|
occurrenceIndex,
|
|
456
|
-
expiryDate: getReloadExpiryDate(
|
|
536
|
+
expiryDate: getReloadExpiryDate(
|
|
537
|
+
activationTime,
|
|
538
|
+
cadence,
|
|
539
|
+
expiryPerOccurrence,
|
|
540
|
+
occurrenceIndex,
|
|
541
|
+
startDate,
|
|
542
|
+
firstOccurrenceActivationPeriod,
|
|
543
|
+
)?.toISOString(),
|
|
457
544
|
availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
|
|
458
545
|
status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
|
|
459
546
|
createdAt: startDate.toISOString(),
|
|
@@ -464,7 +551,7 @@ describe('VipBonusUtils', () => {
|
|
|
464
551
|
// fast forward into reward 7 claiming interval
|
|
465
552
|
let fastForward = 6;
|
|
466
553
|
mockdatetime(startDate.add(cadence * fastForward, 'seconds').toDate());
|
|
467
|
-
let updatedStatusList = issuances.map(
|
|
554
|
+
let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, cancelledAt, dayjs()));
|
|
468
555
|
|
|
469
556
|
updatedStatusList.forEach((issuance, index) => {
|
|
470
557
|
if (claimed.includes(index + 1)) {
|
|
@@ -481,7 +568,7 @@ describe('VipBonusUtils', () => {
|
|
|
481
568
|
// fast forward into reward 8 claiming interval
|
|
482
569
|
fastForward = 7;
|
|
483
570
|
mockdatetime(startDate.add(cadence * fastForward, 'seconds').toDate());
|
|
484
|
-
updatedStatusList = issuances.map(
|
|
571
|
+
updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, cancelledAt, dayjs()));
|
|
485
572
|
|
|
486
573
|
updatedStatusList.forEach((issuance, index) => {
|
|
487
574
|
if (claimed.includes(index + 1)) {
|