@internetarchive/ia-book-actions 1.4.1 → 1.4.3-alpha-adminsticky
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/.github/workflows/ci.yml +8 -7
- package/.github/workflows/pr-preview.yml +32 -5
- package/README.md +11 -2
- package/package.json +15 -12
- package/src/core/services/actions-handler/actions-handler.js +2 -1
- package/src/ia-book-actions.js +8 -6
- package/test/core/services/actions-handler.test.js +91 -0
- package/web-test-runner.config.mjs +1 -1
package/.github/workflows/ci.yml
CHANGED
|
@@ -11,16 +11,17 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
- uses: actions/setup-node@
|
|
14
|
+
- uses: actions/checkout@v4.1.1
|
|
15
|
+
- uses: actions/setup-node@v4.0.2
|
|
16
16
|
with:
|
|
17
|
-
node-version:
|
|
17
|
+
node-version: 20.x
|
|
18
18
|
|
|
19
19
|
- name: Install dependencies
|
|
20
20
|
run: yarn install
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: yarn run test
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
- uses: codecov/codecov-action@v5
|
|
26
|
+
with:
|
|
27
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -12,26 +12,53 @@ on:
|
|
|
12
12
|
- synchronize
|
|
13
13
|
- closed
|
|
14
14
|
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
pull-requests: write
|
|
18
|
+
|
|
15
19
|
concurrency: preview-${{ github.ref }}
|
|
16
20
|
|
|
21
|
+
env:
|
|
22
|
+
PREVIEW_BRANCH: gh-pages
|
|
17
23
|
jobs:
|
|
18
24
|
deploy-preview:
|
|
19
|
-
runs-on: ubuntu-
|
|
25
|
+
runs-on: ubuntu-latest
|
|
20
26
|
steps:
|
|
21
27
|
- name: Checkout
|
|
22
28
|
uses: actions/checkout@v4
|
|
23
|
-
|
|
24
|
-
- uses: actions/setup-node@v3
|
|
25
|
-
with:
|
|
26
|
-
node-version: 20.x
|
|
29
|
+
- uses: actions/setup-node@v4
|
|
27
30
|
|
|
28
31
|
- name: Install and Build
|
|
29
32
|
run: |
|
|
30
33
|
yarn install
|
|
31
34
|
yarn prepare:ghpages
|
|
35
|
+
|
|
32
36
|
# Reference: https://github.com/rossjrw/pr-preview-action
|
|
33
37
|
- name: Deploy preview
|
|
34
38
|
uses: rossjrw/pr-preview-action@v1
|
|
39
|
+
id: preview-step
|
|
35
40
|
with:
|
|
36
41
|
source-dir: ./ghpages/
|
|
37
42
|
umbrella-dir: pr
|
|
43
|
+
preview-branch: ${{ env.PREVIEW_BRANCH }}
|
|
44
|
+
comment: false
|
|
45
|
+
|
|
46
|
+
- uses: marocchino/sticky-pull-request-comment@v2
|
|
47
|
+
if: steps.preview-step.outputs.deployment-action == 'deploy'
|
|
48
|
+
with:
|
|
49
|
+
header: pr-preview
|
|
50
|
+
message: |
|
|
51
|
+
[PR Preview Action](https://github.com/rossjrw/pr-preview-action) ${{ steps.preview-step.outputs.action-version }}
|
|
52
|
+
:---:
|
|
53
|
+
| <p></p> :rocket: View preview at <br> ${{ steps.preview-step.outputs.preview-url }} <br><br>
|
|
54
|
+
| <h6>Built to branch [`${{ env.PREVIEW_BRANCH }}`](${{ github.server_url }}/${{ github.repository }}/tree/${{ env.PREVIEW_BRANCH }}) at ${{ steps.preview-step.outputs.action-start-time }}. <br> Preview will be ready when the [GitHub Pages deployment](${{ github.server_url }}/${{ github.repository }}/deployments) is complete. <br><br> </h6>
|
|
55
|
+
|
|
56
|
+
- uses: marocchino/sticky-pull-request-comment@v2
|
|
57
|
+
if: steps.preview-step.outputs.deployment-action == 'remove'
|
|
58
|
+
with:
|
|
59
|
+
header: pr-preview
|
|
60
|
+
message: |
|
|
61
|
+
[PR Preview Action](https://github.com/rossjrw/pr-preview-action) ${{ steps.preview-step.outputs.action-version }}
|
|
62
|
+
:---:
|
|
63
|
+
Preview removed because the pull request was closed.
|
|
64
|
+
${{ steps.preview-step.outputs.action-start-time }}
|
package/README.md
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
# Component for lendable and embed items
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
 [](https://codecov.io/gh/internetarchive/iaux-book-actions)
|
|
3
|
+
|
|
4
|
+
# Internet Archive Book Lending Actions
|
|
5
|
+
|
|
6
|
+
This WebComponent, built using the [IA Typescript WebComponent Template](https://github.com/internetarchive/iaux-typescript-wc-template), provides support for Bookreader actions for borrowable books on Internet Archive. It extends the [Open WebComponents generator](https://open-wc.org/docs/development/generator/) with Internet Archive-specific features and developer tools.
|
|
4
7
|
|
|
5
8
|
## Installation
|
|
6
9
|
```bash
|
|
7
10
|
yarn install --save @internetarchive/ia-book-actions
|
|
8
11
|
```
|
|
9
12
|
|
|
13
|
+
## Local Demo with `web-dev-server`
|
|
14
|
+
```bash
|
|
15
|
+
yarn start
|
|
16
|
+
```
|
|
17
|
+
To run a local development server that serves the basic demo located in `index.html`
|
|
18
|
+
|
|
10
19
|
## Usage of Book Actions
|
|
11
20
|
```html
|
|
12
21
|
<!-- index.html -->
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "1.4.1",
|
|
4
3
|
"description": "Bookreader actions for borrowable book",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/internetarchive/iaux-account-settings.git"
|
|
7
|
+
},
|
|
5
8
|
"author": "Internet Archive",
|
|
6
9
|
"license": "AGPL-3.0-only",
|
|
10
|
+
"version": "1.4.3-alpha-adminsticky",
|
|
7
11
|
"main": "index.js",
|
|
8
12
|
"module": "index.js",
|
|
9
13
|
"publishConfig": {
|
|
@@ -15,28 +19,27 @@
|
|
|
15
19
|
"prepare": "rimraf dist && husky install",
|
|
16
20
|
"lint": "eslint --ext \"./src/*.js\",.html . --ignore-path .gitignore && prettier \"./src/*.js\" --check --ignore-path .gitignore",
|
|
17
21
|
"format": "eslint --ext \"./src/*.js\",.html . --fix --ignore-path .gitignore && prettier \"./src/*.js\" --write --ignore-path .gitignore",
|
|
18
|
-
"test": "yarn run lint && yarn test:fast",
|
|
19
|
-
"test:fast": "web-test-runner
|
|
22
|
+
"test": "yarn run format && yarn run lint && yarn test:fast --coverage",
|
|
23
|
+
"test:fast": "web-test-runner",
|
|
20
24
|
"test:watch": "web-test-runner --watch --playwright --browsers chromium firefox webkit",
|
|
21
25
|
"deploy": "yarn run deploy:run -e $(git branch --show-current)",
|
|
22
26
|
"deploy:run": "yarn run prepare:ghpages && touch ghpages/.nojekyll && yarn run deploy:gh",
|
|
23
27
|
"deploy:gh": "gh-pages -t -d ghpages -m \"Build for $(git log --pretty=format:\"%h %an %ai %s\" -n1) [skip ci]\""
|
|
24
28
|
},
|
|
25
29
|
"dependencies": {
|
|
26
|
-
"@internetarchive/icon-info": "1.
|
|
30
|
+
"@internetarchive/icon-info": "^1.4.1",
|
|
27
31
|
"@internetarchive/local-cache": "^0.2.1",
|
|
28
|
-
"@internetarchive/modal-manager": "2.0.0",
|
|
32
|
+
"@internetarchive/modal-manager": "^2.0.0",
|
|
29
33
|
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
30
|
-
"
|
|
31
|
-
"lit": "^2.8.0"
|
|
34
|
+
"lit": "^2.8.0 || ^3.3.2"
|
|
32
35
|
},
|
|
33
36
|
"devDependencies": {
|
|
34
37
|
"@open-wc/eslint-config": "^4.2.0",
|
|
35
|
-
"@open-wc/testing": "^
|
|
36
|
-
"@web/dev-server": "^0.
|
|
37
|
-
"@web/dev-server-esbuild": "^0.
|
|
38
|
-
"@web/test-runner": "^0.
|
|
39
|
-
"@web/test-runner-playwright": "^0.
|
|
38
|
+
"@open-wc/testing": "^4.0.0",
|
|
39
|
+
"@web/dev-server": "^0.4.6",
|
|
40
|
+
"@web/dev-server-esbuild": "^1.0.5",
|
|
41
|
+
"@web/test-runner": "^0.20.2",
|
|
42
|
+
"@web/test-runner-playwright": "^0.11.1",
|
|
40
43
|
"eslint": "^7.32.0",
|
|
41
44
|
"eslint-config-prettier": "^6.11.0",
|
|
42
45
|
"eslint-plugin-import": "^2.22.1",
|
|
@@ -409,6 +409,7 @@ export default class ActionsHandler extends LitElement {
|
|
|
409
409
|
*/
|
|
410
410
|
setStickyAdminAccess(value) {
|
|
411
411
|
const domain = window.location.hostname === 'localhost' ? 'localhost' : '.archive.org';
|
|
412
|
-
|
|
412
|
+
const expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days from now
|
|
413
|
+
Cookies.setItem('sticky-admin-access', value, expires, '/', domain);
|
|
413
414
|
}
|
|
414
415
|
}
|
package/src/ia-book-actions.js
CHANGED
|
@@ -120,7 +120,12 @@ export default class IABookActions extends LitElement {
|
|
|
120
120
|
* @property {boolean} renewNow - key to determine if need to renew now
|
|
121
121
|
* @property {number} secondsLeft - seconds left in active loan
|
|
122
122
|
*/
|
|
123
|
-
this.loanRenewResult = {
|
|
123
|
+
this.loanRenewResult = {
|
|
124
|
+
texts: '',
|
|
125
|
+
renewNow: false,
|
|
126
|
+
secondsLeft: 0,
|
|
127
|
+
renewType: '',
|
|
128
|
+
};
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
disconnectedCallback() {
|
|
@@ -535,11 +540,8 @@ export default class IABookActions extends LitElement {
|
|
|
535
540
|
async startBrowseTimer() {
|
|
536
541
|
window?.IALendingIntervals?.clearBrowseExpireTimeout();
|
|
537
542
|
|
|
538
|
-
const {
|
|
539
|
-
|
|
540
|
-
user_has_browsed,
|
|
541
|
-
secondsLeftOnLoan,
|
|
542
|
-
} = this.lendingStatus;
|
|
543
|
+
const { browsingExpired, user_has_browsed, secondsLeftOnLoan } =
|
|
544
|
+
this.lendingStatus;
|
|
543
545
|
|
|
544
546
|
if (!user_has_browsed || browsingExpired) {
|
|
545
547
|
log('startBrowseTimer --- !user_has_browsed || browsingExpired', {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
|
|
4
|
+
import ActionsHandler from '../../../src/core/services/actions-handler/actions-handler.js';
|
|
5
|
+
|
|
6
|
+
// Define a temporary tag for this element for testing
|
|
7
|
+
const TEST_TAG = 'ia-actions-handler-test';
|
|
8
|
+
if (!customElements.get(TEST_TAG)) {
|
|
9
|
+
customElements.define(TEST_TAG, ActionsHandler);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('ActionsHandler#setStickyAdminAccess', () => {
|
|
13
|
+
let clock;
|
|
14
|
+
let lastSetCookie;
|
|
15
|
+
let cookieOverridden = false;
|
|
16
|
+
let actionsHandlerFixture;
|
|
17
|
+
|
|
18
|
+
beforeEach(async () => {
|
|
19
|
+
// Intercept document.cookie writes to capture the full cookie string
|
|
20
|
+
Object.defineProperty(document, 'cookie', {
|
|
21
|
+
configurable: true,
|
|
22
|
+
get() {
|
|
23
|
+
return '';
|
|
24
|
+
},
|
|
25
|
+
set(value) {
|
|
26
|
+
lastSetCookie = value;
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
cookieOverridden = true;
|
|
30
|
+
|
|
31
|
+
// Create the element via fixture (portable across browsers)
|
|
32
|
+
actionsHandlerFixture = await fixture(`<${TEST_TAG}></${TEST_TAG}>`);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
sinon.restore();
|
|
37
|
+
if (clock) {
|
|
38
|
+
clock.restore();
|
|
39
|
+
clock = undefined;
|
|
40
|
+
}
|
|
41
|
+
// restore document.cookie
|
|
42
|
+
if (cookieOverridden) {
|
|
43
|
+
try {
|
|
44
|
+
// remove our instance-level override
|
|
45
|
+
// eslint-disable-next-line no-param-reassign
|
|
46
|
+
delete document.cookie;
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// ignore
|
|
49
|
+
}
|
|
50
|
+
cookieOverridden = false;
|
|
51
|
+
}
|
|
52
|
+
lastSetCookie = undefined;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('sets the sticky-admin-access cookie with correct domain, path, and 30-day expiration', async () => {
|
|
56
|
+
// Arrange: fix time and stub cookie writer
|
|
57
|
+
const now = new Date('2025-01-01T00:00:00.000Z');
|
|
58
|
+
clock = sinon.useFakeTimers({ now: now.getTime() });
|
|
59
|
+
|
|
60
|
+
// Calculate expected values based on current environment
|
|
61
|
+
const expectedDomain = window.location.hostname === 'localhost' ? 'localhost' : '.archive.org';
|
|
62
|
+
const expectedExpires = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
|
|
63
|
+
|
|
64
|
+
// Act: call the method on the element created in beforeEach
|
|
65
|
+
actionsHandlerFixture.setStickyAdminAccess(true);
|
|
66
|
+
|
|
67
|
+
// Assert: verify the composed cookie string
|
|
68
|
+
expect(lastSetCookie).to.be.a('string');
|
|
69
|
+
// Name and value
|
|
70
|
+
expect(lastSetCookie).to.contain(`${encodeURIComponent('sticky-admin-access')}=${encodeURIComponent('true')}`);
|
|
71
|
+
// Domain
|
|
72
|
+
expect(lastSetCookie).to.contain(`domain=${expectedDomain}`);
|
|
73
|
+
// Path
|
|
74
|
+
expect(lastSetCookie).to.contain('path=/');
|
|
75
|
+
// Expiration close to 30 days from now
|
|
76
|
+
const match = /expires=([^;]+)/.exec(lastSetCookie);
|
|
77
|
+
expect(match).to.not.equal(null);
|
|
78
|
+
const expiresStr = match && match[1];
|
|
79
|
+
const parsed = expiresStr ? new Date(expiresStr) : null;
|
|
80
|
+
expect(parsed).to.be.instanceOf(Date);
|
|
81
|
+
expect(parsed && parsed.getTime()).to.equal(expectedExpires.getTime());
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('sets the cookie value to false when disabling', async () => {
|
|
85
|
+
// Act
|
|
86
|
+
actionsHandlerFixture.setStickyAdminAccess(false);
|
|
87
|
+
|
|
88
|
+
expect(lastSetCookie).to.be.a('string');
|
|
89
|
+
expect(lastSetCookie).to.contain(`${encodeURIComponent('sticky-admin-access')}=${encodeURIComponent('false')}`);
|
|
90
|
+
});
|
|
91
|
+
});
|