@internetarchive/bookreader 5.0.0-24-sortingstate-final → 5.0.0-27

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,190 @@
1
+ import BookReader from '@/src/BookReader.js';
2
+ import * as utils from '@/src/BookReader/utils.js';
3
+
4
+ let br;
5
+ beforeAll(() => {
6
+ document.body.innerHTML = '<div id="BookReader">';
7
+ br = new BookReader();
8
+ });
9
+
10
+ afterEach(() => {
11
+ jest.clearAllMocks();
12
+ });
13
+
14
+ /**
15
+ * Only run init() once. Otherwise multiple EventListeners will be added.
16
+ */
17
+ test('Initialzation enables IntersectionObserver and defaults', () => {
18
+ const observe = jest.fn();
19
+ window.IntersectionObserver = jest.fn(() => ({
20
+ observe
21
+ }));
22
+ br.init();
23
+ expect(br.hasKeyFocus).toBe(true);
24
+ expect(observe).toHaveBeenCalledTimes(1);
25
+ });
26
+
27
+ describe('Keyboard shortcuts turned off', () => {
28
+
29
+ test('Focus flag disables', () => {
30
+ br.next = jest.fn();
31
+ br.hasKeyFocus = false;
32
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'ArrowDown'});
33
+ keyEvent.preventDefault = jest.fn();
34
+ document.dispatchEvent(keyEvent);
35
+ expect(br.next).toHaveBeenCalledTimes(0);
36
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(0);
37
+ // Must reset for following tests
38
+ br.hasKeyFocus = true;
39
+ });
40
+
41
+ test('Input active disables', () => {
42
+ // eslint-disable-next-line no-import-assign
43
+ utils.isInputActive = jest.fn(() => true);
44
+ br.next = jest.fn();
45
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'ArrowDown'});
46
+ keyEvent.preventDefault = jest.fn();
47
+ document.dispatchEvent(keyEvent);
48
+ expect(br.next).toHaveBeenCalledTimes(0);
49
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(0);
50
+ // Must reset for following tests
51
+ utils.isInputActive.mockReset();
52
+ });
53
+
54
+ });
55
+
56
+ describe('Keyboard shortcuts', () => {
57
+
58
+ test('Home key', () => {
59
+ br.first = jest.fn();
60
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'Home'});
61
+ keyEvent.preventDefault = jest.fn();
62
+ document.dispatchEvent(keyEvent);
63
+ expect(br.first).toHaveBeenCalledTimes(1);
64
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
65
+ });
66
+
67
+ test('End key', () => {
68
+ br.last = jest.fn();
69
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'End'});
70
+ keyEvent.preventDefault = jest.fn();
71
+ document.dispatchEvent(keyEvent);
72
+ expect(br.last).toHaveBeenCalledTimes(1);
73
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
74
+ });
75
+
76
+ test('ArrowDown key', () => {
77
+ br.mode = br.constMode2up;
78
+ br.next = jest.fn();
79
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'ArrowDown'});
80
+ keyEvent.preventDefault = jest.fn();
81
+ document.dispatchEvent(keyEvent);
82
+ expect(br.next).toHaveBeenCalledTimes(1);
83
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
84
+ });
85
+
86
+ test('PageDown key', () => {
87
+ br.mode = br.constMode2up;
88
+ br.next = jest.fn();
89
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'PageDown'});
90
+ keyEvent.preventDefault = jest.fn();
91
+ document.dispatchEvent(keyEvent);
92
+ expect(br.next).toHaveBeenCalledTimes(1);
93
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
94
+ });
95
+
96
+ test('ArrowUp key', () => {
97
+ br.mode = br.constMode2up;
98
+ br.prev = jest.fn();
99
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'ArrowUp'});
100
+ keyEvent.preventDefault = jest.fn();
101
+ document.dispatchEvent(keyEvent);
102
+ expect(br.prev).toHaveBeenCalledTimes(1);
103
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
104
+ });
105
+
106
+ test('PageUp key', () => {
107
+ br.mode = br.constMode2up;
108
+ br.prev = jest.fn();
109
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'PageUp'});
110
+ keyEvent.preventDefault = jest.fn();
111
+ document.dispatchEvent(keyEvent);
112
+ expect(br.prev).toHaveBeenCalledTimes(1);
113
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
114
+ });
115
+
116
+ test('ArrowLeft key', () => {
117
+ br.mode = br.constMode2up;
118
+ br.left = jest.fn();
119
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'ArrowLeft'});
120
+ keyEvent.preventDefault = jest.fn();
121
+ document.dispatchEvent(keyEvent);
122
+ expect(br.left).toHaveBeenCalledTimes(1);
123
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
124
+ });
125
+
126
+ test('ArrowRight key', () => {
127
+ br.mode = br.constMode2up;
128
+ br.right = jest.fn();
129
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'ArrowRight'});
130
+ keyEvent.preventDefault = jest.fn();
131
+ document.dispatchEvent(keyEvent);
132
+ expect(br.right).toHaveBeenCalledTimes(1);
133
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
134
+ });
135
+
136
+ test('Subtract key', () => {
137
+ br.zoom = jest.fn();
138
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'Subtract'});
139
+ keyEvent.preventDefault = jest.fn();
140
+ document.dispatchEvent(keyEvent);
141
+ expect(br.zoom).toHaveBeenCalledTimes(1);
142
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
143
+ });
144
+
145
+ test('- key', () => {
146
+ br.zoom = jest.fn();
147
+ const keyEvent = new KeyboardEvent('keydown', {'key': '-'});
148
+ keyEvent.preventDefault = jest.fn();
149
+ document.dispatchEvent(keyEvent);
150
+ expect(br.zoom).toHaveBeenCalledTimes(1);
151
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
152
+ });
153
+
154
+ test('Add key', () => {
155
+ br.zoom = jest.fn();
156
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'Add'});
157
+ keyEvent.preventDefault = jest.fn();
158
+ document.dispatchEvent(keyEvent);
159
+ expect(br.zoom).toHaveBeenCalledTimes(1);
160
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
161
+ });
162
+
163
+ test('+ key', () => {
164
+ br.zoom = jest.fn();
165
+ const keyEvent = new KeyboardEvent('keydown', {'key': '+'});
166
+ keyEvent.preventDefault = jest.fn();
167
+ document.dispatchEvent(keyEvent);
168
+ expect(br.zoom).toHaveBeenCalledTimes(1);
169
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
170
+ });
171
+
172
+ test('= key', () => {
173
+ br.zoom = jest.fn();
174
+ const keyEvent = new KeyboardEvent('keydown', {'key': '='});
175
+ keyEvent.preventDefault = jest.fn();
176
+ document.dispatchEvent(keyEvent);
177
+ expect(br.zoom).toHaveBeenCalledTimes(1);
178
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
179
+ });
180
+
181
+ test('F key', () => {
182
+ br.toggleFullscreen = jest.fn();
183
+ const keyEvent = new KeyboardEvent('keydown', {'key': 'F'});
184
+ keyEvent.preventDefault = jest.fn();
185
+ document.dispatchEvent(keyEvent);
186
+ expect(br.toggleFullscreen).toHaveBeenCalledTimes(1);
187
+ expect(keyEvent.preventDefault).toHaveBeenCalledTimes(1);
188
+ });
189
+
190
+ });
@@ -1,7 +1,6 @@
1
+
1
2
  import BookReader from '@/src/BookReader.js';
2
3
  import '@/src/plugins/plugin.url.js';
3
- import { UrlPlugin } from '@/src/plugins/plugin.url.js';
4
- import sinon from 'sinon';
5
4
 
6
5
  let br;
7
6
  beforeAll(() => {
@@ -11,155 +10,6 @@ beforeAll(() => {
11
10
 
12
11
  afterEach(() => {
13
12
  jest.clearAllMocks();
14
- sinon.restore();
15
- });
16
-
17
-
18
- describe.only('UrlPlugin tests', () => {
19
- const urlPlugin = new UrlPlugin();
20
-
21
- describe('urlStateToUrlString tests', () => {
22
- test('urlStateToUrlString with known states in schema', () => {
23
- const urlState = { page: 'n7', mode: '1up', search: 'foo' };
24
- const urlStateWithQueries = { page: 'n7', mode: '1up', q: 'hello', view: 'theater', sort: 'title_asc' };
25
-
26
- const expectedUrlFromState = 'page/n7/mode/1up?q=foo';
27
- const expectedUrlFromStateWithQueries = 'page/n7/mode/1up?q=hello&view=theater&sort=title_asc';
28
-
29
- expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
30
- expect(urlPlugin.urlStateToUrlString(urlStateWithQueries)).toBe(expectedUrlFromStateWithQueries);
31
- });
32
-
33
- test('urlStateToUrlString with unknown states in schema', () => {
34
- const urlState = { page: 'n7', mode: '1up' };
35
- const urlStateWithQueries = { page: 'n7', mode: '1up', q: 'hello', viewer: 'theater', sortBy: 'title_asc' };
36
-
37
- const expectedUrlFromState = 'page/n7/mode/1up';
38
- const expectedUrlFromStateWithQueries = 'page/n7/mode/1up?q=hello&viewer=theater&sortBy=title_asc';
39
-
40
- expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
41
- expect(urlPlugin.urlStateToUrlString(urlStateWithQueries)).toBe(expectedUrlFromStateWithQueries);
42
- });
43
-
44
- test('urlStateToUrlString with boolean value', () => {
45
- const urlState = { page: 'n7', mode: '1up', search: 'foo', view: 'theater', wrapper: 'false' };
46
- const expectedUrlFromState = 'page/n7/mode/1up?q=foo&view=theater&wrapper=false';
47
-
48
- expect(urlPlugin.urlStateToUrlString(urlState)).toBe(expectedUrlFromState);
49
- });
50
- });
51
-
52
- describe('urlStringToUrlState tests', () => {
53
- test('urlStringToUrlState without query string', () => {
54
- const url = '/page/n7/mode/2up';
55
- const url1 = '/page/n7/mode/1up';
56
-
57
- expect(urlPlugin.urlStringToUrlState(url)).toEqual({page: 'n7', mode: '2up'});
58
- expect(urlPlugin.urlStringToUrlState(url1)).toEqual({page: 'n7', mode: '1up'});
59
- });
60
-
61
- test('urlStringToUrlState with deprecated_for', () => {
62
- const url = '/page/n7/mode/2up/search/hello';
63
-
64
- expect(urlPlugin.urlStringToUrlState(url)).toEqual({page: 'n7', mode: '2up', q: 'hello'});
65
- });
66
-
67
- test('urlStringToUrlState with query string', () => {
68
- const url = '/page/n7/mode/2up/search/hello?view=theather&foo=bar&sort=title_asc';
69
- const url1 = '/mode/2up?ref=ol&ui=embed&wrapper=false&view=theater';
70
-
71
- expect(urlPlugin.urlStringToUrlState(url)).toEqual(
72
- {page: 'n7', mode: '2up', q: 'hello', view: 'theather', foo: 'bar', sort: 'title_asc'}
73
- );
74
- expect(urlPlugin.urlStringToUrlState(url1)).toEqual(
75
- {page: 'n0', mode: '2up', ref: 'ol', ui: 'embed', wrapper: 'false', view: 'theater'}
76
- );
77
- });
78
-
79
- test('urlStringToUrlState compare search and ?q', () => {
80
- const url = '/page/n7/mode/2up/search/hello';
81
- urlPlugin.urlState = { q: 'hello' };
82
-
83
- expect(urlPlugin.urlStringToUrlState(url)).toEqual({page: 'n7', mode: '2up', q: 'hello'});
84
- });
85
- });
86
-
87
- describe('url plugin helper functions', () => {
88
- test('setUrlParam', () => {
89
- urlPlugin.urlState = {};
90
- urlPlugin.setUrlParam('page', '20');
91
- urlPlugin.setUrlParam('mode', '2up');
92
-
93
- expect(urlPlugin.urlState).toEqual({page: '20', mode: '2up'});
94
- });
95
-
96
- test('removeUrlParam', () => {
97
- urlPlugin.setUrlParam('page', '20');
98
- urlPlugin.setUrlParam('mode', '2up');
99
- urlPlugin.removeUrlParam('mode');
100
-
101
- expect(urlPlugin.urlState).toEqual({page: '20'});
102
- });
103
-
104
- test('getUrlParam', () => {
105
- urlPlugin.setUrlParam('page', '20');
106
- urlPlugin.setUrlParam('mode', '2up');
107
- expect(urlPlugin.getUrlParam('page')).toEqual('20');
108
- expect(urlPlugin.getUrlParam('mode')).toEqual('2up');
109
- });
110
- });
111
-
112
- describe('pullFromAddressBar and pushToAddressBar - hash mode', () => {
113
- test('url without mode state value - use default', () => {
114
- urlPlugin.urlState = {};
115
- urlPlugin.urlMode = 'hash';
116
-
117
- urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#page/12' });
118
- expect(urlPlugin.urlState).toEqual({page: '12', mode: '2up'});
119
-
120
- urlPlugin.pushToAddressBar();
121
- expect(window.location.hash).toEqual('#page/12/mode/2up');
122
- });
123
-
124
- test('url with query param', () => {
125
- urlPlugin.urlState = {};
126
- urlPlugin.urlMode = 'hash';
127
-
128
- urlPlugin.pullFromAddressBar({ pathname: '', search: '', hash: '#page/12?q=hello&view=theater' });
129
- expect(urlPlugin.urlState).toEqual({page: '12', mode: '2up', q: 'hello', view: 'theater'});
130
-
131
- urlPlugin.pushToAddressBar();
132
- expect(window.location.hash).toEqual('#page/12/mode/2up?q=hello&view=theater');
133
- });
134
- });
135
-
136
- describe('pullFromAddressBar and pushToAddressBar - history mode', () => {
137
- test('url without mode state value - use default', () => {
138
- urlPlugin.urlState = {};
139
- urlPlugin.urlHistoryBasePath = '/details/foo';
140
- urlPlugin.urlMode = 'history';
141
-
142
- urlPlugin.pullFromAddressBar({ pathname: '/details/foo/page/12', search: '', hash: '' });
143
- expect(urlPlugin.urlState).toEqual({page: '12', mode: '2up'});
144
-
145
- urlPlugin.pushToAddressBar();
146
- expect(window.location.pathname).toEqual('/details/foo/page/12/mode/2up');
147
- });
148
-
149
- test('url with query param', () => {
150
- urlPlugin.urlState = {};
151
- urlPlugin.urlHistoryBasePath = '/details/foo';
152
- urlPlugin.urlMode = 'history';
153
-
154
- urlPlugin.pullFromAddressBar({ pathname: '/details/foo/page/12', search: '?q=hello&view=theater', hash: '' });
155
- expect(urlPlugin.urlState).toEqual({page: '12', mode: '2up', q: 'hello', view: 'theater'});
156
-
157
- urlPlugin.pushToAddressBar();
158
- const locationUrl = `${window.location.pathname}${window.location.search}`;
159
- expect(locationUrl).toEqual('/details/foo/page/12/mode/2up?q=hello&view=theater');
160
- });
161
- });
162
-
163
13
  });
164
14
 
165
15
  describe('Plugin: URL controller', () => {
@@ -64,7 +64,7 @@ describe('Volumes Provider', () => {
64
64
  const baseHost = "https://archive.org";
65
65
  const provider = new volumesProvider(baseHost, brOptions, onSortClick);
66
66
 
67
- expect(provider.sortOrderBy).to.equal("default");
67
+ expect(provider.sortOrderBy).to.equal("orig_sort");
68
68
 
69
69
  provider.sortVolumes("title_asc");
70
70
  expect(provider.sortOrderBy).to.equal("title_asc");
@@ -74,8 +74,8 @@ describe('Volumes Provider', () => {
74
74
  expect(provider.sortOrderBy).to.equal("title_desc");
75
75
  expect(provider.sortButton.getHTML()).includes("sort-by desc-icon");
76
76
 
77
- provider.sortVolumes("default");
78
- expect(provider.sortOrderBy).to.equal("default");
77
+ provider.sortVolumes("orig_sort");
78
+ expect(provider.sortOrderBy).to.equal("orig_sort");
79
79
  expect(provider.sortButton.getHTML()).includes("sort-by neutral-icon");
80
80
  });
81
81
 
@@ -88,9 +88,9 @@ describe('Volumes Provider', () => {
88
88
  const files = Object.keys(parsedFiles).map(item => parsedFiles[item]).sort((a, b) => a.orig_sort - b.orig_sort);
89
89
  const origSortTitles = files.map(item => item.title);
90
90
 
91
- provider.sortVolumes("default");
91
+ provider.sortVolumes("orig_sort");
92
92
 
93
- expect(provider.sortOrderBy).to.equal("default");
93
+ expect(provider.sortOrderBy).to.equal("orig_sort");
94
94
  expect(provider.actionButton).to.exist;
95
95
 
96
96
  const providerFileTitles = provider.viewableFiles.map(item => item.title);
@@ -144,7 +144,7 @@ describe('Volumes Provider', () => {
144
144
  const baseHost = "https://archive.org";
145
145
  const provider = new volumesProvider(baseHost, brOptions, onSortClick);
146
146
 
147
- provider.sortOrderBy = 'default';
147
+ provider.sortOrderBy = 'orig_sort';
148
148
  const origSortButton = await fixture(provider.sortButton);
149
149
  expect(origSortButton.classList.contains('neutral-icon')).to.be.true;
150
150
 
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 14