@internetarchive/ia-book-actions 0.0.29-alpha38 → 0.0.29-alpha39
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/demo/index.html
CHANGED
|
@@ -133,8 +133,8 @@
|
|
|
133
133
|
|
|
134
134
|
let isDevBox = true;
|
|
135
135
|
iaBookActions.loanRenewConfig = {
|
|
136
|
-
totalTime: isDevBox ?
|
|
137
|
-
autoCheckAt: isDevBox ?
|
|
136
|
+
totalTime: isDevBox ? 13 : 3600, // 60 second = 1 min
|
|
137
|
+
autoCheckAt: isDevBox ? 10 : 3540, // at last 10th minute
|
|
138
138
|
pageChangedInLast: isDevBox ? 5 : 900, // within last 15 second/minute
|
|
139
139
|
isDevBox: isDevBox,
|
|
140
140
|
};
|
package/package.json
CHANGED
package/src/ia-book-actions.js
CHANGED
|
@@ -220,6 +220,13 @@ export default class IABookActions extends LitElement {
|
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
// initial timer state for 1-hour loan
|
|
224
|
+
if (this.borrowType === 'browsed' && !this.loanRenewResult.renewNow) {
|
|
225
|
+
setTimeout(() => {
|
|
226
|
+
this.resetTimerCountState();
|
|
227
|
+
}, 100);
|
|
228
|
+
}
|
|
229
|
+
|
|
223
230
|
/**
|
|
224
231
|
* tokenPoller determines if user has loan token for this book
|
|
225
232
|
* - if book is going to renew, need to wait until renew is completed
|
|
@@ -228,17 +235,13 @@ export default class IABookActions extends LitElement {
|
|
|
228
235
|
setTimeout(
|
|
229
236
|
() => {
|
|
230
237
|
this.startLoanTokenPoller();
|
|
231
|
-
|
|
232
|
-
if (this.borrowType === 'browsed' && !this.loanRenewResult.renewNow) {
|
|
233
|
-
this.resetTimerCountState();
|
|
234
|
-
}
|
|
235
238
|
},
|
|
236
239
|
this.loanRenewResult.renewNow ? this.tokenDelay * 1000 : 100
|
|
237
240
|
);
|
|
238
241
|
}
|
|
239
242
|
|
|
240
243
|
/**
|
|
241
|
-
* Bind 1 hour loan auto renew,
|
|
244
|
+
* Bind 1 hour loan auto renew event,
|
|
242
245
|
* There are two events we want to use,
|
|
243
246
|
* 1. BookReader:pageChanged - dispatched from bookreader side
|
|
244
247
|
* 2. IABookActions:loanRenew - dispatched from timer-countdown component
|
|
@@ -371,11 +374,11 @@ export default class IABookActions extends LitElement {
|
|
|
371
374
|
* Execute when loan is expired
|
|
372
375
|
*/
|
|
373
376
|
async browseHasExpired() {
|
|
377
|
+
this.tokenPoller?.disconnectedInterval();
|
|
378
|
+
|
|
374
379
|
const currStatus = { ...this.lendingStatus, browsingExpired: true };
|
|
375
380
|
this.lendingStatus = currStatus;
|
|
376
381
|
|
|
377
|
-
this.tokenPoller?.disconnectedInterval();
|
|
378
|
-
|
|
379
382
|
// remove respected key:value for loan-renew
|
|
380
383
|
await this.localCache.delete(`${this.identifier}-loanTime`);
|
|
381
384
|
await this.localCache.delete(`${this.identifier}-pageChangedTime`);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { html, fixture, expect, aTimeout } from '@open-wc/testing';
|
|
2
|
+
import '../../src/components/timer-countdown.js';
|
|
3
|
+
|
|
4
|
+
const container = ({ timeLeftOnLoan, loanRenewConfig } = {}) =>
|
|
5
|
+
html`<timer-countdown
|
|
6
|
+
.timeLeftOnLoan=${timeLeftOnLoan}
|
|
7
|
+
.loanRenewConfig=${loanRenewConfig}
|
|
8
|
+
></timer-countdown>`;
|
|
9
|
+
|
|
10
|
+
describe('<timer-countdown>', () => {
|
|
11
|
+
it('timer interval is undefined when loan is expired', async () => {
|
|
12
|
+
const el = await fixture(
|
|
13
|
+
container({
|
|
14
|
+
timeLeftOnLoan: 0, // in seconds
|
|
15
|
+
loanRenewConfig: {
|
|
16
|
+
totalTime: 14, // in seconds
|
|
17
|
+
autoCheckAt: 5, // in seconds
|
|
18
|
+
pageChangedInLast: 5, // in seconds
|
|
19
|
+
isDevBox: true,
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
await el.updateComplete;
|
|
25
|
+
expect(el.timerInterval).to.be.undefined;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('timer interval is not undefined when loan is active', async () => {
|
|
29
|
+
const el = await fixture(
|
|
30
|
+
container({
|
|
31
|
+
timeLeftOnLoan: 2, // in seconds
|
|
32
|
+
loanRenewConfig: {
|
|
33
|
+
totalTime: 14, // in seconds
|
|
34
|
+
autoCheckAt: 5, // in seconds
|
|
35
|
+
pageChangedInLast: 5, // in seconds
|
|
36
|
+
isDevBox: true,
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
await aTimeout(1900);
|
|
42
|
+
await el.updateComplete;
|
|
43
|
+
|
|
44
|
+
expect(el.timeLeftOnLoan).to.equal(1);
|
|
45
|
+
expect(el.timerInterval).to.not.be.undefined;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { expect, aTimeout } from '@open-wc/testing';
|
|
2
|
+
|
|
3
|
+
import { LocalCache } from '@internetarchive/local-cache';
|
|
4
|
+
import { LoanRenewHelper } from '../../../src/core/services/loan-renew-helper.js';
|
|
5
|
+
|
|
6
|
+
const identifier = 'booBar';
|
|
7
|
+
const loanRenewConfig = {
|
|
8
|
+
totalTime: 13,
|
|
9
|
+
autoCheckAt: 10,
|
|
10
|
+
pageChangedInLast: 12,
|
|
11
|
+
isDevBox: true,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// localCache used for auto-loan-renew
|
|
15
|
+
const localCache = new LocalCache({
|
|
16
|
+
namespace: 'loanRenew',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
beforeEach(async () => {
|
|
20
|
+
await localCache.set({
|
|
21
|
+
key: `${identifier}-loanTime`,
|
|
22
|
+
value: new Date(new Date().getTime() + loanRenewConfig.totalTime * 1000),
|
|
23
|
+
ttl: Number(loanRenewConfig.totalTime),
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('Loan Renew Determine', () => {
|
|
28
|
+
it('flip book page while reading a book', async () => {
|
|
29
|
+
await aTimeout(1500);
|
|
30
|
+
|
|
31
|
+
await localCache.set({
|
|
32
|
+
key: `${identifier}-pageChangedTime`,
|
|
33
|
+
value: new Date(), // current time
|
|
34
|
+
ttl: Number(loanRenewConfig.totalTime),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const loanRenewHelper = new LoanRenewHelper(
|
|
38
|
+
true, // hasPageChanged
|
|
39
|
+
identifier,
|
|
40
|
+
localCache,
|
|
41
|
+
loanRenewConfig
|
|
42
|
+
);
|
|
43
|
+
await loanRenewHelper.handleLoanRenew();
|
|
44
|
+
|
|
45
|
+
expect(loanRenewHelper.result.renewNow).to.be.false;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('auto renewed book when user is currently reading', async () => {
|
|
49
|
+
await localCache.set({
|
|
50
|
+
key: `${identifier}-pageChangedTime`,
|
|
51
|
+
value: new Date(), // current time
|
|
52
|
+
ttl: Number(loanRenewConfig.totalTime),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
await aTimeout(1500);
|
|
56
|
+
|
|
57
|
+
const loanRenewHelper = new LoanRenewHelper(
|
|
58
|
+
false, // timer-countdown event
|
|
59
|
+
identifier,
|
|
60
|
+
localCache,
|
|
61
|
+
loanRenewConfig
|
|
62
|
+
);
|
|
63
|
+
await loanRenewHelper.handleLoanRenew();
|
|
64
|
+
|
|
65
|
+
expect(loanRenewHelper.result.renewNow).to.be.true;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('get toast message template', async () => {
|
|
69
|
+
const loanRenewHelper = new LoanRenewHelper(
|
|
70
|
+
false,
|
|
71
|
+
identifier,
|
|
72
|
+
localCache,
|
|
73
|
+
loanRenewConfig
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const toastMsg = loanRenewHelper.getMessageTexts(
|
|
77
|
+
loanRenewHelper.loanReturnWarning,
|
|
78
|
+
'65'
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
expect(toastMsg).to.be.equal(
|
|
82
|
+
'This book will be automatically returned in 1 minute unless you turn a page.'
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -4,11 +4,17 @@ import '../src/ia-book-actions.js';
|
|
|
4
4
|
import Sinon from 'sinon';
|
|
5
5
|
|
|
6
6
|
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
|
7
|
+
import { LocalCache } from '@internetarchive/local-cache';
|
|
7
8
|
|
|
8
9
|
afterEach(() => {
|
|
9
10
|
Sinon.restore();
|
|
10
11
|
});
|
|
11
12
|
|
|
13
|
+
// localCache used for auto-loan-renew
|
|
14
|
+
const localCache = new LocalCache({
|
|
15
|
+
namespace: 'loanRenew',
|
|
16
|
+
});
|
|
17
|
+
|
|
12
18
|
const container = ({ userid, identifier, lendingStatus = {} } = {}) =>
|
|
13
19
|
html`<ia-book-actions
|
|
14
20
|
.userid=${userid}
|
|
@@ -264,54 +270,14 @@ describe('Browsing expired status', () => {
|
|
|
264
270
|
// timer-countdown is gone now
|
|
265
271
|
expect(el.shadowRoot.querySelector('timer-countdown')).to.be.null;
|
|
266
272
|
|
|
267
|
-
// book has been expired
|
|
273
|
+
// // book has been expired
|
|
274
|
+
expect(el.loanRenewResult.renewNow).to.equal(false);
|
|
268
275
|
expect(el.loanRenewResult.timeLeft).to.equal(0);
|
|
269
276
|
expect(el.loanRenewResult.texts).to.equal(
|
|
270
277
|
'This book has been automatically returned due to inactivity.'
|
|
271
278
|
);
|
|
272
279
|
});
|
|
273
280
|
|
|
274
|
-
it('Book is browsing and eligible to renew it', async () => {
|
|
275
|
-
const el = await fixture(
|
|
276
|
-
container({
|
|
277
|
-
userid: '@userid',
|
|
278
|
-
lendingStatus: {
|
|
279
|
-
is_lendable: true,
|
|
280
|
-
user_has_browsed: true,
|
|
281
|
-
browseHasExpired: false,
|
|
282
|
-
secondsLeftOnLoan: 1,
|
|
283
|
-
},
|
|
284
|
-
})
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
// timer-countdown is still active
|
|
288
|
-
// expect(el.shadowRoot.querySelector('timer-countdown')).to.not.be.null
|
|
289
|
-
|
|
290
|
-
// let eventReceived = false;
|
|
291
|
-
// const listener = () => {
|
|
292
|
-
// eventReceived = true;
|
|
293
|
-
// };
|
|
294
|
-
// el.addEventListener('IABookReader:userAction', listener);
|
|
295
|
-
|
|
296
|
-
el.loanRenewResult = {
|
|
297
|
-
texts: 'book has been renewed',
|
|
298
|
-
renewNow: true,
|
|
299
|
-
timeLeft: 10,
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
await aTimeout(1500); // wait for 1.5 second
|
|
303
|
-
await el.updateComplete;
|
|
304
|
-
|
|
305
|
-
// // timer-countdown is gone now
|
|
306
|
-
// expect(el.shadowRoot.querySelector('timer-countdown')).to.not.be.null
|
|
307
|
-
// expect(el.shadowRoot.querySelector('toast-template')).to.not.be.null
|
|
308
|
-
|
|
309
|
-
expect(el.loanRenewResult.timeLeft).to.equal(10);
|
|
310
|
-
// // book has been expired
|
|
311
|
-
// expect(el.loanRenewResult.timeLeft).to.equal(0);
|
|
312
|
-
// expect(el.loanRenewResult.texts).to.equal('This book has been automatically returned due to inactivity.');
|
|
313
|
-
});
|
|
314
|
-
|
|
315
281
|
it('Expiring book cancels interval & emits event', async () => {
|
|
316
282
|
const baseStatus = {
|
|
317
283
|
is_lendable: true,
|
|
@@ -348,40 +314,47 @@ describe('Browsing expired status', () => {
|
|
|
348
314
|
});
|
|
349
315
|
});
|
|
350
316
|
|
|
351
|
-
describe('
|
|
352
|
-
it('
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
></ia-book-actions>`);
|
|
366
|
-
await component.updateComplete;
|
|
317
|
+
describe('Auto renew one hour loan', () => {
|
|
318
|
+
it('Book is browsing and renewed it now', async () => {
|
|
319
|
+
const el = await fixture(
|
|
320
|
+
container({
|
|
321
|
+
userid: '@userid',
|
|
322
|
+
identifier: 'Foo',
|
|
323
|
+
lendingStatus: {
|
|
324
|
+
is_lendable: true,
|
|
325
|
+
user_has_browsed: true,
|
|
326
|
+
browseHasExpired: false,
|
|
327
|
+
secondsLeftOnLoan: 12,
|
|
328
|
+
},
|
|
329
|
+
})
|
|
330
|
+
);
|
|
367
331
|
|
|
368
|
-
|
|
369
|
-
|
|
332
|
+
el.loanRenewResult = {
|
|
333
|
+
texts: 'This book has been renewed for 1 hour.',
|
|
334
|
+
renewNow: true,
|
|
335
|
+
timeLeft: 10,
|
|
336
|
+
};
|
|
370
337
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
.
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
is_lendable: true,
|
|
377
|
-
user_has_browsed: true,
|
|
378
|
-
available_to_browse: true,
|
|
379
|
-
available_to_borrow: true,
|
|
380
|
-
}}
|
|
381
|
-
></ia-book-actions>`);
|
|
338
|
+
await localCache.set({
|
|
339
|
+
key: `${el.identifier}-loanTime`,
|
|
340
|
+
value: new Date(new Date().getTime() + 10 * 1000),
|
|
341
|
+
ttl: Number(10),
|
|
342
|
+
});
|
|
382
343
|
|
|
383
|
-
|
|
384
|
-
|
|
344
|
+
const myEvent = new CustomEvent('loanAutoRenewed');
|
|
345
|
+
el.addEventListener('loanAutoRenewed', () => {
|
|
346
|
+
el.handleLoanAutoRenewed();
|
|
347
|
+
});
|
|
348
|
+
el.dispatchEvent(myEvent);
|
|
349
|
+
|
|
350
|
+
await aTimeout(1500); // wait for 1.5 second
|
|
351
|
+
await el.updateComplete;
|
|
352
|
+
|
|
353
|
+
expect(el.loanRenewResult.timeLeft).to.equal(10);
|
|
354
|
+
expect(el.loanRenewResult.renewNow).to.equal(true);
|
|
355
|
+
expect(el.loanRenewResult.texts).to.equal(
|
|
356
|
+
'This book has been renewed for 1 hour.'
|
|
357
|
+
);
|
|
385
358
|
});
|
|
386
359
|
});
|
|
387
360
|
|