@internetarchive/ia-item-navigator 0.0.0-a9 → 0.0.2-a2
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/README.md +29 -19
- package/demo/app-root.ts +37 -31
- package/demo/index.html +1 -0
- package/dist/demo/app-root.d.ts +11 -15
- package/dist/demo/app-root.js +26 -26
- package/dist/demo/app-root.js.map +1 -1
- package/dist/src/interfaces/custom-theater-interface.d.ts +20 -0
- package/dist/src/interfaces/custom-theater-interface.js +2 -0
- package/dist/src/interfaces/custom-theater-interface.js.map +1 -0
- package/dist/src/interfaces/event-interfaces.d.ts +11 -11
- package/dist/src/interfaces/event-interfaces.js.map +1 -1
- package/dist/src/interfaces/menu-interfaces.d.ts +6 -7
- package/dist/src/interfaces/menu-interfaces.js.map +1 -1
- package/dist/src/interfaces/nav-controller-interface.d.ts +11 -6
- package/dist/src/interfaces/nav-controller-interface.js.map +1 -1
- package/dist/src/item-inspector/item-inspector.d.ts +0 -47
- package/dist/src/item-inspector/item-inspector.js +253 -271
- package/dist/src/item-inspector/item-inspector.js.map +1 -1
- package/dist/src/item-navigator.d.ts +41 -28
- package/dist/src/item-navigator.js +96 -113
- package/dist/src/item-navigator.js.map +1 -1
- package/dist/src/no-theater-available.d.ts +9 -0
- package/dist/src/no-theater-available.js +79 -0
- package/dist/src/no-theater-available.js.map +1 -0
- package/dist/test/book-nav-stub.d.ts +22 -0
- package/dist/test/book-nav-stub.js +49 -0
- package/dist/test/book-nav-stub.js.map +1 -0
- package/dist/test/ia-item-navigator.test.d.ts +1 -0
- package/dist/test/ia-item-navigator.test.js +279 -131
- package/dist/test/ia-item-navigator.test.js.map +1 -1
- package/dist/test/ia-stub.d.ts +22 -0
- package/dist/test/ia-stub.js +34 -3
- package/dist/test/ia-stub.js.map +1 -1
- package/dist/test/no-theater-available.test.d.ts +1 -0
- package/dist/test/no-theater-available.test.js +27 -0
- package/dist/test/no-theater-available.test.js.map +1 -0
- package/package.json +4 -3
- package/src/interfaces/custom-theater-interface.ts +28 -0
- package/src/interfaces/event-interfaces.ts +15 -11
- package/src/interfaces/menu-interfaces.ts +9 -10
- package/src/item-navigator.ts +133 -144
- package/src/no-theater-available.ts +85 -0
- package/test/book-nav-stub.ts +47 -0
- package/test/ia-item-navigator.test.ts +365 -156
- package/test/ia-stub.ts +78 -2
- package/test/no-theater-available.test.ts +32 -0
- package/demo/demo-book-manifest.json +0 -1163
- package/src/interfaces/nav-controller-interface.ts +0 -18
- package/src/item-inspector/files-by-type/files-by-type-provider.ts +0 -43
- package/src/item-inspector/files-by-type/ia-files-by-type.ts +0 -100
- package/src/item-inspector/item-inspector.ts +0 -296
- package/src/item-inspector/share-provider.ts +0 -51
- package/src/item-inspector/visual-mod-provider.ts +0 -65
- package/src/item-navigator-js.js +0 -372
@@ -1,229 +1,438 @@
|
|
1
1
|
/* eslint-disable camelcase */
|
2
|
-
/* eslint-disable import/no-duplicates */
|
3
2
|
import { html, fixture, expect } from '@open-wc/testing';
|
4
3
|
import Sinon from 'sinon';
|
5
|
-
// import { MetadataResponse, Metadata, File, Review, SpeechMusicASREntry } from '@internetarchive/search-service';
|
6
|
-
import {
|
7
|
-
SharedResizeObserver,
|
8
|
-
// SharedResizeObserverInterface
|
9
|
-
} from '@internetarchive/shared-resize-observer';
|
10
4
|
|
11
|
-
|
12
|
-
import {
|
5
|
+
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
6
|
+
import { ModalManager } from '@internetarchive/modal-manager';
|
7
|
+
import { CustomTheaterInterface } from '../src/interfaces/custom-theater-interface';
|
8
|
+
import { ItemNavigator, ItemType } from '../src/item-navigator';
|
13
9
|
import '../src/item-navigator';
|
14
|
-
// import { IaItemInspector } from '../src/item-inspector/item-inspector';
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
// this.item_last_updated = 2020;
|
26
|
-
// this.item_size = 111;
|
27
|
-
// this.metadata = { identifier: 'foo' } as Metadata;
|
28
|
-
// this.server = 'foo-server';
|
29
|
-
// this.uniq = 2;
|
30
|
-
// this.workable_servers = ['abc'];
|
31
|
-
// }
|
11
|
+
import '../test/book-nav-stub';
|
12
|
+
import { ItemStub, menuProvider, shortcut } from '../test/ia-stub';
|
13
|
+
import {
|
14
|
+
ManageFullscreenEvent,
|
15
|
+
ToggleSideMenuOpenEvent,
|
16
|
+
SetSideMenuContentsEvent,
|
17
|
+
SetSideMenuShortcutsEvent,
|
18
|
+
ToggleSidePanelOpenEvent,
|
19
|
+
} from '../src/interfaces/event-interfaces';
|
32
20
|
|
33
|
-
|
21
|
+
afterEach(() => {
|
22
|
+
Sinon.restore();
|
23
|
+
});
|
34
24
|
|
35
|
-
|
25
|
+
describe('ItemNavigator', () => {
|
26
|
+
describe('Theaters', () => {
|
27
|
+
it('shows <ia-no-theater-available> by default', async () => {
|
28
|
+
const el = await fixture<ItemNavigator>(
|
29
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
30
|
+
);
|
31
|
+
expect(el.shadowRoot?.querySelector('ia-no-theater-available')).to.exist;
|
32
|
+
});
|
36
33
|
|
37
|
-
|
34
|
+
it('shows <book-navigator> if `this.itemType = "bookreader"`', async () => {
|
35
|
+
const el = await fixture<ItemNavigator>(
|
36
|
+
html`<ia-item-navigator
|
37
|
+
.itemType=${ItemType.BOOK}
|
38
|
+
.item=${new ItemStub()}
|
39
|
+
.modal=${new ModalManager()}
|
40
|
+
.sharedObserver=${new SharedResizeObserver()}
|
41
|
+
></ia-item-navigator>`
|
42
|
+
);
|
38
43
|
|
39
|
-
|
44
|
+
await el.updateComplete;
|
40
45
|
|
41
|
-
|
46
|
+
el.toggleMenu();
|
47
|
+
await el.updateComplete;
|
42
48
|
|
43
|
-
|
49
|
+
const bookNavigator = el.shadowRoot?.querySelector(
|
50
|
+
'book-navigator'
|
51
|
+
) as CustomTheaterInterface;
|
52
|
+
await bookNavigator.updateComplete;
|
53
|
+
|
54
|
+
console.log('132234234324324324');
|
55
|
+
// TODO: add BookNavigator type & import via @internetarchive/bookreader
|
56
|
+
// For now, let's check that the BookNavigator element and its properties exist w/ stub
|
57
|
+
expect(bookNavigator).to.exist;
|
58
|
+
expect(bookNavigator?.modal).to.exist;
|
59
|
+
expect(bookNavigator?.baseHost).to.exist;
|
60
|
+
expect(bookNavigator?.signedIn).to.be.null;
|
61
|
+
expect(bookNavigator?.sharedObserver).to.exist;
|
62
|
+
expect(bookNavigator?.sideMenuOpen).to.exist;
|
63
|
+
});
|
64
|
+
});
|
65
|
+
describe('`el.loaded`', () => {
|
66
|
+
it('toggles the spinning loader', async () => {
|
67
|
+
const el = await fixture<ItemNavigator>(
|
68
|
+
html`<ia-item-navigator></ia-item-navigator>`
|
69
|
+
);
|
70
|
+
expect(el.loaded).to.be.null; // initial load
|
71
|
+
expect(el.shadowRoot?.querySelector('ia-itemnav-loader')).to.exist;
|
72
|
+
});
|
73
|
+
it('hides reader section if `!loaded`', async () => {
|
74
|
+
const el = await fixture<ItemNavigator>(
|
75
|
+
html`<ia-item-navigator></ia-item-navigator>`
|
76
|
+
);
|
44
77
|
|
45
|
-
|
78
|
+
expect(
|
79
|
+
el.shadowRoot?.querySelector('#reader')?.getAttribute('class')
|
80
|
+
).to.contain('hide');
|
81
|
+
});
|
82
|
+
it('shows reader when `loaded` ', async () => {
|
83
|
+
const el = await fixture<ItemNavigator>(
|
84
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
85
|
+
);
|
46
86
|
|
47
|
-
|
87
|
+
const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
|
88
|
+
expect(mainTheaterSection?.classList.contains('hide')).to.be.false;
|
89
|
+
expect(el.loaded).to.be.true;
|
90
|
+
// `loaded` property is reflected as DOM attribute
|
91
|
+
expect(el.hasAttribute('loaded')).to.equal(true);
|
92
|
+
expect(el.shadowRoot?.querySelector('ia-no-theater-available')).to.exist;
|
93
|
+
});
|
94
|
+
it('listens to `@loadingStateUpdated` to update `loaded`', async () => {
|
95
|
+
const el = await fixture<ItemNavigator>(
|
96
|
+
html`<ia-item-navigator></ia-item-navigator>`
|
97
|
+
);
|
48
98
|
|
49
|
-
|
99
|
+
await el.updateComplete;
|
100
|
+
const spy = Sinon.spy();
|
101
|
+
el.loadingStateUpdated = spy;
|
102
|
+
el.loaded = null;
|
103
|
+
await el.updateComplete;
|
104
|
+
// check base properties
|
105
|
+
expect(el.loaded).to.equal(null);
|
106
|
+
expect(el.item).to.be.undefined;
|
50
107
|
|
51
|
-
//
|
108
|
+
// hydrate item
|
109
|
+
el.item = new ItemStub();
|
110
|
+
await el.updateComplete;
|
52
111
|
|
53
|
-
//
|
112
|
+
// spy fires
|
113
|
+
expect(spy.called).to.equal(true);
|
114
|
+
expect(spy.callCount).to.equal(1);
|
115
|
+
});
|
116
|
+
});
|
54
117
|
|
55
|
-
|
118
|
+
describe('`el.sharedObserver`', () => {
|
119
|
+
it('uses one', async () => {
|
120
|
+
const sharedObserver = new SharedResizeObserver();
|
121
|
+
const el = await fixture<ItemNavigator>(
|
122
|
+
html`<ia-item-navigator
|
123
|
+
.sharedObserver=${sharedObserver}
|
124
|
+
></ia-item-navigator>`
|
125
|
+
);
|
56
126
|
|
57
|
-
|
127
|
+
expect(el.sharedObserver).to.equal(sharedObserver);
|
128
|
+
expect(typeof el.handleResize).to.equal('function');
|
129
|
+
});
|
130
|
+
it('freshly registers handler', async () => {
|
131
|
+
const sharedObserver = new SharedResizeObserver();
|
132
|
+
const addObserverSpy = Sinon.spy(sharedObserver, 'addObserver');
|
58
133
|
|
59
|
-
|
134
|
+
await fixture<ItemNavigator>(
|
135
|
+
html`<ia-item-navigator
|
136
|
+
.sharedObserver=${sharedObserver}
|
137
|
+
></ia-item-navigator>`
|
138
|
+
);
|
60
139
|
|
61
|
-
|
62
|
-
|
140
|
+
expect(addObserverSpy.callCount).to.equal(1);
|
141
|
+
});
|
142
|
+
it('removes handler when component disconnects', async () => {
|
143
|
+
const sharedObserver = new SharedResizeObserver();
|
144
|
+
const removeObserverSpy = Sinon.spy(sharedObserver, 'removeObserver');
|
63
145
|
|
64
|
-
|
65
|
-
|
66
|
-
}
|
146
|
+
const el = await fixture<ItemNavigator>(
|
147
|
+
html`<ia-item-navigator
|
148
|
+
.sharedObserver=${sharedObserver}
|
149
|
+
></ia-item-navigator>`
|
150
|
+
);
|
67
151
|
|
68
|
-
|
69
|
-
|
70
|
-
|
152
|
+
el.disconnectedCallback();
|
153
|
+
await el.updateComplete;
|
154
|
+
|
155
|
+
expect(removeObserverSpy.callCount).to.equal(1);
|
156
|
+
});
|
157
|
+
it('sets menu to overlay if container width is <= 600px', async () => {
|
71
158
|
const el = await fixture<ItemNavigator>(
|
72
159
|
html`<ia-item-navigator></ia-item-navigator>`
|
73
160
|
);
|
74
|
-
|
161
|
+
|
162
|
+
expect(el.openMenuState).to.equal('shift'); // as starting point
|
163
|
+
|
164
|
+
const overlaySize = {
|
165
|
+
contentRect: { width: 600 },
|
166
|
+
} as ResizeObserverEntry;
|
167
|
+
el.handleResize(overlaySize);
|
168
|
+
await el.updateComplete;
|
169
|
+
|
170
|
+
expect(el.openMenuState).to.equal('overlay'); // changes open menu display to an overlay
|
171
|
+
|
172
|
+
const shiftSize = {
|
173
|
+
contentRect: { width: 601 },
|
174
|
+
} as ResizeObserverEntry;
|
175
|
+
el.handleResize(shiftSize);
|
176
|
+
await el.updateComplete;
|
177
|
+
|
178
|
+
expect(el.openMenuState).to.equal('shift');
|
179
|
+
});
|
180
|
+
});
|
181
|
+
|
182
|
+
describe('`el.modal`', () => {
|
183
|
+
it('uses one', async () => {
|
184
|
+
const modal = new ModalManager();
|
185
|
+
const el = await fixture<ItemNavigator>(
|
186
|
+
html`<ia-item-navigator .modal=${modal}></ia-item-navigator>`
|
187
|
+
);
|
188
|
+
expect(el.modal).to.equal(modal);
|
75
189
|
});
|
76
|
-
|
190
|
+
});
|
191
|
+
|
192
|
+
describe('full browser window immersion "fullscreen"', () => {
|
193
|
+
it('creates reflected attribute `viewportinfullscreen`', async () => {
|
194
|
+
/** to help with external styling adjustmnents */
|
77
195
|
const el = await fixture<ItemNavigator>(
|
78
196
|
html`<ia-item-navigator></ia-item-navigator>`
|
79
197
|
);
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
198
|
+
expect(el.getAttribute('viewportinfullscreen')).to.be.null;
|
199
|
+
|
200
|
+
el.viewportInFullscreen = true;
|
201
|
+
await el.updateComplete;
|
202
|
+
|
203
|
+
expect(el.getAttribute('viewportinfullscreen')).to.exist;
|
85
204
|
});
|
86
|
-
it('
|
205
|
+
it('@ViewportInFullScreen', async () => {
|
87
206
|
const el = await fixture<ItemNavigator>(
|
88
207
|
html`<ia-item-navigator></ia-item-navigator>`
|
89
208
|
);
|
90
|
-
el.
|
209
|
+
expect(el.viewportInFullscreen).to.be.null;
|
210
|
+
|
211
|
+
const yesFullscreenEvent = {
|
212
|
+
detail: {
|
213
|
+
isFullScreen: true,
|
214
|
+
},
|
215
|
+
} as ManageFullscreenEvent;
|
216
|
+
el.manageViewportFullscreen(yesFullscreenEvent);
|
91
217
|
await el.updateComplete;
|
218
|
+
expect(el.viewportInFullscreen).to.be.true;
|
219
|
+
|
220
|
+
const noFullscreenEvent = {
|
221
|
+
detail: {
|
222
|
+
isFullScreen: false,
|
223
|
+
},
|
224
|
+
} as ManageFullscreenEvent;
|
225
|
+
el.manageViewportFullscreen(noFullscreenEvent);
|
226
|
+
await el.updateComplete;
|
227
|
+
expect(el.viewportInFullscreen).to.be.null;
|
228
|
+
});
|
229
|
+
});
|
92
230
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
231
|
+
/* Side menu & shortcuts tests */
|
232
|
+
describe('el.menuOpened', () => {
|
233
|
+
it('toggles side menu open', async () => {
|
234
|
+
const el = await fixture<ItemNavigator>(
|
235
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
236
|
+
);
|
237
|
+
|
238
|
+
el.menuContents = [menuProvider];
|
239
|
+
await el.updateComplete;
|
240
|
+
|
241
|
+
const nav = el.shadowRoot?.querySelector('nav');
|
242
|
+
|
243
|
+
expect(nav?.querySelector('#menu')).to.exist;
|
244
|
+
// side menu starts closed
|
245
|
+
expect(el.menuOpened).to.be.false;
|
246
|
+
expect(nav?.querySelector('#menu')?.getAttribute('class')).to.contain(
|
247
|
+
'hidden'
|
248
|
+
);
|
249
|
+
|
250
|
+
// let's open menu
|
251
|
+
el.toggleMenu();
|
252
|
+
await el.updateComplete;
|
253
|
+
|
254
|
+
expect(el.menuOpened).to.be.true;
|
255
|
+
expect(nav?.querySelector('#menu')?.getAttribute('class')).to.not.contain(
|
256
|
+
'hidden'
|
257
|
+
);
|
98
258
|
});
|
99
259
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
260
|
+
it('opens menu shortcut with `@manageSideMenuEvents`', async () => {
|
261
|
+
const el = await fixture<ItemNavigator>(
|
262
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
263
|
+
);
|
264
|
+
const detail = {
|
265
|
+
menuId: 'fullscreen',
|
266
|
+
action: 'open',
|
267
|
+
};
|
108
268
|
|
109
|
-
|
269
|
+
el.menuContents = [menuProvider];
|
270
|
+
await el.updateComplete;
|
271
|
+
const frame = el.shadowRoot?.querySelector('#frame');
|
272
|
+
// default menu open behavior is to side menu open, not overlay
|
273
|
+
expect(frame?.getAttribute('class')).to.contain('shift');
|
274
|
+
|
275
|
+
expect(el.menuOpened).to.be.false;
|
276
|
+
expect(el.openMenu).to.be.undefined;
|
277
|
+
expect(frame?.getAttribute('class')).to.not.contain('open');
|
278
|
+
|
279
|
+
const event = new CustomEvent('updateSideMenu', {
|
280
|
+
detail,
|
281
|
+
}) as ToggleSideMenuOpenEvent;
|
282
|
+
el.manageSideMenuEvents(event);
|
283
|
+
await el.updateComplete;
|
284
|
+
|
285
|
+
expect(el.shouldRenderMenu).to.be.true;
|
286
|
+
expect(el.menuOpened).to.be.true;
|
287
|
+
expect(el.openMenu).to.equal(detail.menuId);
|
110
288
|
|
111
|
-
|
289
|
+
expect(frame?.getAttribute('class')).to.contain('open');
|
112
290
|
|
113
|
-
|
291
|
+
// no menu provided
|
292
|
+
const openShortcutSpy = Sinon.spy(el, 'openShortcut');
|
293
|
+
const toggleMenuSpy = Sinon.spy(el, 'toggleMenu');
|
114
294
|
|
115
|
-
|
295
|
+
const noMenuProvidedEvent = new CustomEvent('updateSideMenu', {
|
296
|
+
detail: {},
|
297
|
+
}) as any;
|
298
|
+
el.manageSideMenuEvents(noMenuProvidedEvent);
|
299
|
+
await el.updateComplete;
|
116
300
|
|
117
|
-
|
118
|
-
|
301
|
+
expect(openShortcutSpy.called).to.be.false;
|
302
|
+
expect(toggleMenuSpy.called).to.be.false;
|
303
|
+
|
304
|
+
// toggle menu
|
305
|
+
const toggleMenuEvent = new CustomEvent('updateSideMenu', {
|
306
|
+
detail: { action: 'toggle', menuId: 'fullscreen' },
|
307
|
+
}) as any;
|
308
|
+
el.manageSideMenuEvents(toggleMenuEvent);
|
309
|
+
await el.updateComplete;
|
119
310
|
|
120
|
-
|
121
|
-
// // await el.updateComplete;
|
311
|
+
expect(toggleMenuSpy.callCount).to.equal(1);
|
122
312
|
|
123
|
-
|
313
|
+
// open menu
|
314
|
+
const openMenuEvent = new CustomEvent('updateSideMenu', {
|
315
|
+
detail: { action: 'open', menuId: 'fullscreen' },
|
316
|
+
}) as any;
|
317
|
+
el.manageSideMenuEvents(openMenuEvent);
|
318
|
+
await el.updateComplete;
|
319
|
+
|
320
|
+
expect(openShortcutSpy.callCount).to.equal(1);
|
321
|
+
});
|
124
322
|
});
|
125
323
|
|
126
|
-
describe('
|
127
|
-
it('
|
324
|
+
describe('el.menuContents', () => {
|
325
|
+
it('draws side menu when populated', async () => {
|
128
326
|
const el = await fixture<ItemNavigator>(
|
129
|
-
html`<ia-item-navigator></ia-item-navigator>`
|
327
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
130
328
|
);
|
329
|
+
|
330
|
+
el.menuContents = [menuProvider];
|
131
331
|
await el.updateComplete;
|
132
|
-
expect(el.
|
133
|
-
expect(el.
|
134
|
-
});
|
332
|
+
expect(el.menuContents.length).to.exist;
|
333
|
+
expect(el.shouldRenderMenu).to.be.true;
|
135
334
|
|
136
|
-
|
137
|
-
|
335
|
+
const nav = el.shadowRoot?.querySelector('nav');
|
336
|
+
expect(nav).to.exist;
|
337
|
+
|
338
|
+
const menuSlider = nav?.querySelector('ia-menu-slider');
|
339
|
+
expect(menuSlider).to.exist;
|
340
|
+
expect(menuSlider?.getAttribute('manuallyhandleclose')).to.exist;
|
341
|
+
expect(menuSlider?.getAttribute('open')).to.exist;
|
342
|
+
});
|
343
|
+
});
|
138
344
|
|
345
|
+
describe('`el.menuShortcuts`', () => {
|
346
|
+
it('displays shortcut & toggle side menu button', async () => {
|
139
347
|
const el = await fixture<ItemNavigator>(
|
140
|
-
html`<ia-item-navigator
|
141
|
-
.sharedObserver=${sharedObserver}
|
142
|
-
></ia-item-navigator>`
|
348
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
143
349
|
);
|
350
|
+
|
351
|
+
const anotherShortcut = {
|
352
|
+
id: 'foo',
|
353
|
+
icon: html`<i class="foo-shortcut"></i>`,
|
354
|
+
};
|
355
|
+
el.menuContents = [menuProvider];
|
356
|
+
el.menuShortcuts = [shortcut, anotherShortcut];
|
144
357
|
await el.updateComplete;
|
145
|
-
|
358
|
+
|
359
|
+
const nav = el.shadowRoot?.querySelector('nav');
|
360
|
+
|
361
|
+
const shortcutsContainer = nav?.querySelector('.shortcuts');
|
362
|
+
expect(el.menuShortcuts.length).to.exist;
|
363
|
+
expect(nav).to.exist;
|
364
|
+
expect(shortcutsContainer).to.exist;
|
365
|
+
expect(shortcutsContainer?.querySelector('i.fullscreen-test')).to.exist;
|
366
|
+
expect(shortcutsContainer?.querySelector('button.shortcut.foo')).to.exist;
|
367
|
+
expect(nav?.querySelector('.toggle-menu')).to.exist;
|
146
368
|
});
|
147
369
|
});
|
148
370
|
|
149
|
-
describe('
|
150
|
-
it('
|
371
|
+
describe('Menu events', () => {
|
372
|
+
it('`el.setMenuShortcuts`', async () => {
|
151
373
|
const el = await fixture<ItemNavigator>(
|
152
|
-
html`<ia-item-navigator></ia-item-navigator>`
|
374
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
153
375
|
);
|
376
|
+
expect(el.menuShortcuts.length).to.equal(0);
|
377
|
+
|
378
|
+
const menuShortcuts = [shortcut];
|
379
|
+
|
380
|
+
el.setMenuShortcuts({
|
381
|
+
detail: menuShortcuts,
|
382
|
+
} as SetSideMenuShortcutsEvent);
|
154
383
|
await el.updateComplete;
|
155
|
-
|
156
|
-
expect(el.
|
384
|
+
|
385
|
+
expect(el.menuShortcuts.length).to.equal(1);
|
157
386
|
});
|
387
|
+
it('`el.setMenuContents`', async () => {
|
388
|
+
const el = await fixture<ItemNavigator>(
|
389
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
390
|
+
);
|
391
|
+
expect(el.menuContents.length).to.equal(0);
|
158
392
|
|
159
|
-
|
160
|
-
|
161
|
-
|
393
|
+
el.setMenuShortcuts({
|
394
|
+
detail: [menuProvider],
|
395
|
+
} as SetSideMenuContentsEvent);
|
396
|
+
await el.updateComplete;
|
162
397
|
|
398
|
+
expect(el.menuShortcuts.length).to.equal(1);
|
399
|
+
});
|
400
|
+
it('`el.setOpenMenu`', async () => {
|
163
401
|
const el = await fixture<ItemNavigator>(
|
164
|
-
html`<ia-item-navigator
|
165
|
-
.sharedObserver=${sharedObserver}
|
166
|
-
></ia-item-navigator>`
|
402
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
167
403
|
);
|
404
|
+
|
405
|
+
el.setOpenMenu({
|
406
|
+
detail: { id: 'foo' },
|
407
|
+
} as ToggleSidePanelOpenEvent);
|
168
408
|
await el.updateComplete;
|
169
|
-
expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
|
170
|
-
expect(observerSpy.called).to.equal(true);
|
171
|
-
});
|
172
|
-
});
|
173
409
|
|
174
|
-
|
175
|
-
|
176
|
-
// /** to help with external styling adjustmnents */
|
177
|
-
// });
|
178
|
-
// });
|
410
|
+
expect(el.openMenu).to.equal('foo');
|
411
|
+
expect(el.selectedMenuId).to.equal('foo');
|
179
412
|
|
180
|
-
|
181
|
-
|
413
|
+
// toggles it off
|
414
|
+
el.setOpenMenu({
|
415
|
+
detail: { id: 'foo' },
|
416
|
+
} as ToggleSidePanelOpenEvent);
|
417
|
+
await el.updateComplete;
|
182
418
|
|
183
|
-
|
184
|
-
|
419
|
+
expect(el.openMenu).to.be.undefined;
|
420
|
+
expect(el.selectedMenuId).to.equal('');
|
421
|
+
});
|
422
|
+
it('`el.closeMenu`', async () => {
|
423
|
+
const el = await fixture<ItemNavigator>(
|
424
|
+
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
425
|
+
);
|
185
426
|
|
186
|
-
|
187
|
-
|
188
|
-
// html`<your-webcomponent></your-webcomponent>`
|
189
|
-
// );
|
427
|
+
el.menuOpened = true;
|
428
|
+
await el.updateComplete;
|
190
429
|
|
191
|
-
|
192
|
-
// });
|
193
|
-
});
|
430
|
+
expect(el.menuOpened).to.be.true;
|
194
431
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
// expect(el.counter).to.equal(5);
|
203
|
-
// });
|
204
|
-
|
205
|
-
// it('increases the counter on button click', async () => {
|
206
|
-
// const el = await fixture<YourWebComponent>(
|
207
|
-
// html`<your-webcomponent></your-webcomponent>`
|
208
|
-
// );
|
209
|
-
// el.shadowRoot!.querySelector('button')!.click();
|
210
|
-
|
211
|
-
// expect(el.counter).to.equal(6);
|
212
|
-
// });
|
213
|
-
|
214
|
-
// it('can override the title via attribute', async () => {
|
215
|
-
// const el = await fixture<YourWebComponent>(
|
216
|
-
// html`<your-webcomponent title="attribute title"></your-webcomponent>`
|
217
|
-
// );
|
218
|
-
|
219
|
-
// expect(el.title).to.equal('attribute title');
|
220
|
-
// });
|
221
|
-
|
222
|
-
// it('passes the a11y audit', async () => {
|
223
|
-
// const el = await fixture<YourWebComponent>(
|
224
|
-
// html`<your-webcomponent></your-webcomponent>`
|
225
|
-
// );
|
226
|
-
|
227
|
-
// await expect(el).shadowDom.to.be.accessible();
|
228
|
-
// });
|
229
|
-
// });
|
432
|
+
el.closeMenu();
|
433
|
+
await el.updateComplete;
|
434
|
+
|
435
|
+
expect(el.menuOpened).to.be.false;
|
436
|
+
});
|
437
|
+
});
|
438
|
+
});
|
package/test/ia-stub.ts
CHANGED
@@ -1,3 +1,79 @@
|
|
1
|
-
|
1
|
+
/* eslint-disable camelcase */
|
2
|
+
import {
|
3
|
+
MetadataResponse,
|
4
|
+
Metadata,
|
5
|
+
File,
|
6
|
+
Review,
|
7
|
+
SpeechMusicASREntry,
|
8
|
+
} from '@internetarchive/search-service';
|
9
|
+
import { html } from 'lit-html';
|
10
|
+
import {
|
11
|
+
MenuShortcutInterface,
|
12
|
+
MenuProviderInterface,
|
13
|
+
} from '../src/interfaces/menu-interfaces';
|
2
14
|
|
3
|
-
|
15
|
+
export class ItemStub implements MetadataResponse {
|
16
|
+
constructor() {
|
17
|
+
this.rawResponse = '';
|
18
|
+
this.created = 1;
|
19
|
+
this.d1 = 'hello';
|
20
|
+
this.d2 = 'boop';
|
21
|
+
this.dir = 'whee';
|
22
|
+
this.files = [];
|
23
|
+
this.files_count = 0;
|
24
|
+
this.item_last_updated = 2020;
|
25
|
+
this.item_size = 111;
|
26
|
+
this.metadata = { identifier: 'foo' } as Metadata;
|
27
|
+
this.server = 'foo-server';
|
28
|
+
this.uniq = 2;
|
29
|
+
this.workable_servers = ['abc'];
|
30
|
+
}
|
31
|
+
|
32
|
+
rawResponse: any;
|
33
|
+
|
34
|
+
created: number;
|
35
|
+
|
36
|
+
d1: string;
|
37
|
+
|
38
|
+
d2: string;
|
39
|
+
|
40
|
+
dir: string;
|
41
|
+
|
42
|
+
files: File[];
|
43
|
+
|
44
|
+
files_count: number;
|
45
|
+
|
46
|
+
item_last_updated: number;
|
47
|
+
|
48
|
+
item_size: number;
|
49
|
+
|
50
|
+
metadata: Metadata;
|
51
|
+
|
52
|
+
server: string;
|
53
|
+
|
54
|
+
uniq: number;
|
55
|
+
|
56
|
+
workable_servers: string[];
|
57
|
+
|
58
|
+
speech_vs_music_asr?: SpeechMusicASREntry[] | undefined;
|
59
|
+
|
60
|
+
reviews?: Review[] | undefined;
|
61
|
+
}
|
62
|
+
|
63
|
+
export const shortcut = {
|
64
|
+
id: 'fullscreen',
|
65
|
+
icon: html`<i class="fas fullscreen-test"></i>`,
|
66
|
+
} as MenuShortcutInterface;
|
67
|
+
|
68
|
+
export const menuProvider = {
|
69
|
+
...shortcut,
|
70
|
+
label: 'foo',
|
71
|
+
menuDetails: html`<div>foo</div>`,
|
72
|
+
selected: true,
|
73
|
+
followable: false,
|
74
|
+
href: 'https://archive.foo',
|
75
|
+
item: new ItemStub(),
|
76
|
+
baseHost: 'https://archive.foo',
|
77
|
+
subPrefix: 'bar',
|
78
|
+
updated: () => {},
|
79
|
+
} as MenuProviderInterface;
|