@internetarchive/ia-book-actions 0.0.7-10 → 0.0.7-13

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
@@ -106,18 +106,19 @@
106
106
 
107
107
  let lendingBarPostInit = function lendingBarPostInit() {
108
108
  setTimeout(function() {
109
- console.log('executed');
109
+ console.log('executed', 'br.init()');
110
110
  }, 100);
111
111
  }
112
+
112
113
  // set defaultLendingStatus for unavailable (without borrowables) book
113
114
  iaBookActions.userid = userid;
114
115
  iaBookActions.identifier = identifier;
115
116
  iaBookActions.bookTitle = 'Contemporary Black biography. Volume 39 : profiles from the interContemporary Black biography. Volume 39';
116
117
  iaBookActions.lendingStatus = canBrowseAndBorrow;
117
118
  iaBookActions.bwbPurchaseUrl = '';
118
- iaBookActions.barType = '';
119
119
  iaBookActions.modalConfig = modalConfig;
120
120
  iaBookActions.lendingBarPostInit = lendingBarPostInit;
121
+ iaBookActions.tokenDelay = 2000; // 2 seconds
121
122
 
122
123
  let lendingStatus1 = iaBookActions.lendingStatus;
123
124
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.0.7-10",
3
+ "version": "0.0.7-13",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -16,7 +16,7 @@ export default class ActionsHandler extends LitElement {
16
16
  constructor(identifier) {
17
17
  super();
18
18
  this.identifier = identifier;
19
- this.ajaxTimeout = 7000;
19
+ this.ajaxTimeout = 6000;
20
20
  this.localCache = new LocalCache();
21
21
  this.bindEvents();
22
22
  }
@@ -178,7 +178,6 @@ export default class ActionsHandler extends LitElement {
178
178
  });
179
179
  }
180
180
 
181
-
182
181
  /**
183
182
  * Dispatches event when an error occured on action
184
183
  * Notes:- toggle <collapsible-action-group> visibility (enable/disable).
@@ -1,6 +1,4 @@
1
- import { LitElement } from 'lit-element';
2
1
  import { LocalCache } from '@internetarchive/local-cache';
3
-
4
2
  import ActionsHandlerService from './actions-handler/actions-handler-service.js';
5
3
 
6
4
  /**
@@ -8,26 +6,30 @@ import ActionsHandlerService from './actions-handler/actions-handler-service.js'
8
6
  *
9
7
  * ActionsHandlerService is a function being used to execute
10
8
  */
11
- export class LoanTokenPoller extends LitElement {
12
- constructor() {
13
- super();
14
- this.identifier = '';
15
- this.loanTokenPollingDelay = window.location.pathname === '/demo/' ? 2000 : 120000; // 120000 ms = 2 min
9
+ export class LoanTokenPoller {
10
+ constructor(id, borrowType, successCallback, errorCallback, pollerDelay) {
11
+ this.identifier = id;
12
+ this.borrowType = borrowType;
13
+ this.successCallback = successCallback; // callback function to be called after loan token is created
14
+ this.errorCallback = errorCallback; // callback function to be called after loan token is created
15
+ this.pollerDelay = pollerDelay; // value in ms (1000 ms = 1 sec)
16
+
16
17
  this.loanTokenInterval = undefined;
17
18
  this.localCache = new LocalCache();
19
+ this.enableBookAccess();
18
20
  }
19
21
 
20
- disconnectedCallback() {
22
+ disconnectedInterval() {
23
+ clearInterval(this.loanTokenInterval);
21
24
  this.loanTokenInterval = undefined;
22
25
  }
23
26
 
24
- async enableBookAccess(identifier, borrowType) {
25
- this.identifier = identifier
27
+ async enableBookAccess() {
26
28
  let consecutiveLoanCounts = 1;
27
29
 
28
- if (borrowType) {
30
+ if (this.borrowType) {
29
31
  // send consecutiveLoanCounts for browsed books only.
30
- if (borrowType === 'browsed') {
32
+ if (this.borrowType === 'browsed') {
31
33
  try {
32
34
  const existingCount = await this.localCache.get(
33
35
  'consecutive-loan-count'
@@ -39,22 +41,22 @@ export class LoanTokenPoller extends LitElement {
39
41
  }
40
42
 
41
43
  // Do an initial token, then set an interval
42
- this.handleLoanTokenPoller();
44
+ this.handleLoanTokenPoller(true);
43
45
 
44
46
  this.loanTokenInterval = setInterval(() => {
45
47
  this.handleLoanTokenPoller();
46
- }, this.loanTokenPollingDelay);
48
+ }, this.pollerDelay);
47
49
 
48
50
  // event category and action for browsing book access
49
- const category = `${borrowType}BookAccess`;
51
+ const category = `${this.borrowType}BookAccess`;
50
52
  const action = `${
51
- borrowType === 'browsed' ? 'BrowseCounts-' : 'Counts-'
53
+ this.borrowType === 'browsed' ? 'BrowseCounts-' : 'Counts-'
52
54
  }${consecutiveLoanCounts}`;
53
- console.log(consecutiveLoanCounts)
55
+
54
56
  this.sendEvent(category, action);
55
57
  } else {
56
58
  // if book is not browsed, just clear token polling interval
57
- clearInterval(this.loanTokenInterval);
59
+ this.disconnectedInterval(); // stop token fetch api
58
60
  }
59
61
  }
60
62
 
@@ -68,36 +70,18 @@ export class LoanTokenPoller extends LitElement {
68
70
  );
69
71
  }
70
72
 
71
- async handleLoanTokenPoller() {
73
+ async handleLoanTokenPoller(isInitial = false) {
72
74
  const action = 'create_token';
73
- // await new Promise(r => setTimeout(r, 3000));
74
75
  ActionsHandlerService({
75
76
  identifier: this.identifier,
76
77
  action,
77
78
  error: data => {
78
- console.log('error', data);
79
- this.handleLendingActionError({detail: { action, data }})
80
- // this.dispatchActionError(action, data);
81
- clearInterval(this.loanTokenInterval); // stop token fetch api
79
+ this.disconnectedInterval(); // stop token fetch api
80
+ this.errorCallback({ detail: { action, data } });
81
+ },
82
+ success: () => {
83
+ if (isInitial) this.successCallback();
82
84
  },
83
85
  });
84
86
  }
85
-
86
- /**
87
- * Dispatches event when an error occured on action
88
- * Notes:- toggle <collapsible-action-group> visibility (enable/disable).
89
- *
90
- * @param { String } action - name of action like browse_book, borrow_book
91
- * @param { Object } data - erroneous response from api call
92
- *
93
- * @fires ActionsHandler#lendingActionError
94
- */
95
- dispatchActionError(action, data = {}) {
96
- console.log('disptaced');
97
- this.dispatchEvent(
98
- new CustomEvent('lendingActionError', {
99
- detail: { action, data },
100
- })
101
- );
102
- }
103
87
  }
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable camelcase */
2
- import { html, css } from 'lit-element';
2
+ import { html, css, LitElement } from 'lit-element';
3
3
 
4
4
  import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
5
5
  import { ModalConfig } from '@internetarchive/modal-manager';
@@ -13,7 +13,7 @@ import GetLendingActions from './core/services/get-lending-actions.js';
13
13
  import { mobileContainerWidth } from './core/config/constants.js';
14
14
  import { LoanTokenPoller } from './core/services/loan-token-poller.js';
15
15
 
16
- export default class IABookActions extends LoanTokenPoller {
16
+ export default class IABookActions extends LitElement {
17
17
  static get properties() {
18
18
  return {
19
19
  userid: { type: String },
@@ -22,11 +22,15 @@ export default class IABookActions extends LoanTokenPoller {
22
22
  lendingStatus: { type: Object },
23
23
  width: { type: Number },
24
24
  bwbPurchaseUrl: { type: String },
25
- lendingBarPostInit: { type: Function },
25
+ lendingBarPostInit: {
26
+ type: Function,
27
+ attribute: false,
28
+ },
26
29
  barType: { type: String },
27
30
  sharedObserver: { attribute: false },
28
31
  disableActionGroup: { type: Boolean },
29
32
  modal: { Object },
33
+ tokenDelay: { type: Number },
30
34
  };
31
35
  }
32
36
 
@@ -43,6 +47,7 @@ export default class IABookActions extends LoanTokenPoller {
43
47
  this.sharedObserver = undefined;
44
48
  this.disableActionGroup = false;
45
49
  this.modal = undefined;
50
+ this.tokenDelay = 120000; // 2 minutes
46
51
 
47
52
  // private props
48
53
  this.primaryActions = [];
@@ -66,7 +71,6 @@ export default class IABookActions extends LoanTokenPoller {
66
71
  }
67
72
 
68
73
  updated(changed) {
69
- console.log(changed)
70
74
  if (changed.has('lendingStatus') || changed.has('bwbPurchaseUrl')) {
71
75
  this.setupLendingToolbarActions();
72
76
  this.update();
@@ -158,27 +162,51 @@ export default class IABookActions extends LoanTokenPoller {
158
162
  this.startBrowseTimer();
159
163
  }
160
164
 
161
- console.log('this.borrowType', this.borrowType);
162
- // enable access of borrowed/browsed books
163
- if (this.borrowType) {
164
- await this.enableBookAccess(this.identifier, this.borrowType);
165
- }
166
-
167
165
  /**
168
- * this callback function use to:-
169
- * - disptach lenfingFlow::PostInit event
170
- * - initialize bookreader using br.init()
166
+ * enable access of borrowed/browsed books
167
+ *
168
+ * LoanTokenPoller is a class that polls the loan token
169
+ * it takes 5 params
170
+ * 1. this.identifier
171
+ * 2. this.borrowType
172
+ * 3. successCallback - it used to
173
+ * - disptach lendingFlow::PostInit event
174
+ * - initialize bookreader using br.init()
175
+ * 4. errorCallback
176
+ * 5. tokenPollerDelay
171
177
  */
172
- console.log(this.lendingBarPostInit);
173
- this.lendingBarPostInit();
178
+ if (this.barType === 'action') {
179
+ if (this.tokenPoller) {
180
+ this.tokenPoller.disconnectedInterval();
181
+ }
182
+
183
+ const successCallback = () => {
184
+ this.lendingBarPostInit();
185
+ };
186
+ const errorCallback = eventObj => {
187
+ this.handleLendingActionError(eventObj);
188
+ };
189
+
190
+ this.tokenPoller = new LoanTokenPoller(
191
+ this.identifier,
192
+ this.borrowType,
193
+ successCallback,
194
+ errorCallback,
195
+ this.tokenDelay // 1000 ms = 1 sec
196
+ );
197
+ }
174
198
  }
175
199
 
176
200
  render() {
177
201
  if (this.barType === 'title') {
178
- return html`<section class="lending-wrapper">${this.bookTitleBar}</section>`;
202
+ return html`<section class="lending-wrapper">
203
+ ${this.bookTitleBar}
204
+ </section>`;
179
205
  }
180
206
 
181
- return html`<section class="lending-wrapper">${this.bookActionBar}</section>`;
207
+ return html`<section class="lending-wrapper">
208
+ ${this.bookActionBar}
209
+ </section>`;
182
210
  }
183
211
 
184
212
  get bookTitleBar() {
@@ -275,12 +303,18 @@ export default class IABookActions extends LoanTokenPoller {
275
303
  });
276
304
 
277
305
  if (action === 'create_token') {
306
+ const refreshButton = html`<button
307
+ style="background:none;font-size:inherit;border:0;padding:0;color:#0000ee;cursor:pointer;text-decoration:underline"
308
+ @click=${() => window.location.reload(true)}
309
+ >
310
+ refresh
311
+ </button>`;
312
+
278
313
  modalConfig.closeOnBackdropClick = false;
279
314
  modalConfig.showCloseButton = false;
280
315
  modalConfig.message = html` Uh oh, something went wrong trying to access
281
316
  this book.<br />
282
- Please <a href="${() => window.location.reload(true)}">refresh</a> to
283
- try again or send us an email to
317
+ Please ${refreshButton} to try again or send us an email to
284
318
  <a
285
319
  href="mailto:info@archive.org?subject=Help: cannot access my borrowed book: ${this
286
320
  .identifier}"
@@ -0,0 +1,40 @@
1
+ import { expect } from '@open-wc/testing';
2
+ import Sinon from 'sinon';
3
+
4
+ import { LocalCache } from '@internetarchive/local-cache';
5
+ import { LoanTokenPoller } from '../../../src/core/services/loan-token-poller.js';
6
+
7
+ describe('Get Loan Token', () => {
8
+ it('get loan token for browsed books', async () => {
9
+ const localCacheStub = new LocalCache();
10
+ const localCacheGetSpy = Sinon.spy(localCacheStub, 'get');
11
+
12
+ const tokenPoller = new LoanTokenPoller(
13
+ 'identifier1',
14
+ 'browsed',
15
+ () => {
16
+ console.log('success callback is executed!');
17
+ },
18
+ () => {
19
+ console.log('error callback is executed!');
20
+ },
21
+ 2000 // 2 minutes'
22
+ );
23
+ const successCallbackSpy = Sinon.stub(tokenPoller, 'successCallback');
24
+ successCallbackSpy();
25
+ expect(successCallbackSpy.callCount).to.equal(1);
26
+
27
+ localCacheGetSpy();
28
+ expect(localCacheGetSpy.callCount).to.equal(1);
29
+
30
+ expect(tokenPoller.localCache.namespace).to.equal('LocalCache');
31
+ expect(tokenPoller.localCache.get).to.be.a('function');
32
+
33
+ tokenPoller.disconnectedInterval(); // clear token poller interval
34
+ expect(tokenPoller.loanTokenInterval).to.equal(undefined);
35
+
36
+ tokenPoller.handleLoanTokenPoller(true);
37
+ expect(tokenPoller.errorCallback).to.be.a('function');
38
+ expect(tokenPoller.successCallback).have;
39
+ });
40
+ });