@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.
Files changed (54) hide show
  1. package/README.md +29 -19
  2. package/demo/app-root.ts +37 -31
  3. package/demo/index.html +1 -0
  4. package/dist/demo/app-root.d.ts +11 -15
  5. package/dist/demo/app-root.js +26 -26
  6. package/dist/demo/app-root.js.map +1 -1
  7. package/dist/src/interfaces/custom-theater-interface.d.ts +20 -0
  8. package/dist/src/interfaces/custom-theater-interface.js +2 -0
  9. package/dist/src/interfaces/custom-theater-interface.js.map +1 -0
  10. package/dist/src/interfaces/event-interfaces.d.ts +11 -11
  11. package/dist/src/interfaces/event-interfaces.js.map +1 -1
  12. package/dist/src/interfaces/menu-interfaces.d.ts +6 -7
  13. package/dist/src/interfaces/menu-interfaces.js.map +1 -1
  14. package/dist/src/interfaces/nav-controller-interface.d.ts +11 -6
  15. package/dist/src/interfaces/nav-controller-interface.js.map +1 -1
  16. package/dist/src/item-inspector/item-inspector.d.ts +0 -47
  17. package/dist/src/item-inspector/item-inspector.js +253 -271
  18. package/dist/src/item-inspector/item-inspector.js.map +1 -1
  19. package/dist/src/item-navigator.d.ts +41 -28
  20. package/dist/src/item-navigator.js +96 -113
  21. package/dist/src/item-navigator.js.map +1 -1
  22. package/dist/src/no-theater-available.d.ts +9 -0
  23. package/dist/src/no-theater-available.js +79 -0
  24. package/dist/src/no-theater-available.js.map +1 -0
  25. package/dist/test/book-nav-stub.d.ts +22 -0
  26. package/dist/test/book-nav-stub.js +49 -0
  27. package/dist/test/book-nav-stub.js.map +1 -0
  28. package/dist/test/ia-item-navigator.test.d.ts +1 -0
  29. package/dist/test/ia-item-navigator.test.js +279 -131
  30. package/dist/test/ia-item-navigator.test.js.map +1 -1
  31. package/dist/test/ia-stub.d.ts +22 -0
  32. package/dist/test/ia-stub.js +34 -3
  33. package/dist/test/ia-stub.js.map +1 -1
  34. package/dist/test/no-theater-available.test.d.ts +1 -0
  35. package/dist/test/no-theater-available.test.js +27 -0
  36. package/dist/test/no-theater-available.test.js.map +1 -0
  37. package/package.json +4 -3
  38. package/src/interfaces/custom-theater-interface.ts +28 -0
  39. package/src/interfaces/event-interfaces.ts +15 -11
  40. package/src/interfaces/menu-interfaces.ts +9 -10
  41. package/src/item-navigator.ts +133 -144
  42. package/src/no-theater-available.ts +85 -0
  43. package/test/book-nav-stub.ts +47 -0
  44. package/test/ia-item-navigator.test.ts +365 -156
  45. package/test/ia-stub.ts +78 -2
  46. package/test/no-theater-available.test.ts +32 -0
  47. package/demo/demo-book-manifest.json +0 -1163
  48. package/src/interfaces/nav-controller-interface.ts +0 -18
  49. package/src/item-inspector/files-by-type/files-by-type-provider.ts +0 -43
  50. package/src/item-inspector/files-by-type/ia-files-by-type.ts +0 -100
  51. package/src/item-inspector/item-inspector.ts +0 -296
  52. package/src/item-inspector/share-provider.ts +0 -51
  53. package/src/item-inspector/visual-mod-provider.ts +0 -65
  54. 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
- // import { IntLoadingStateUpdatedEvent } from '../src/interfaces/event-interfaces';
12
- import { ItemNavigator } from '../src/item-navigator';
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
- // class ItemStub implements MetadataResponse {
17
- // constructor() {
18
- // this.rawResponse = '';
19
- // this.created = 1;
20
- // this.d1 = 'hello';
21
- // this.d2 = 'boop';
22
- // this.dir = 'whee';
23
- // this.files = [];
24
- // this.files_count = 0;
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
- // rawResponse: any;
21
+ afterEach(() => {
22
+ Sinon.restore();
23
+ });
34
24
 
35
- // created: number;
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
- // d1: string;
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
- // d2: string;
44
+ await el.updateComplete;
40
45
 
41
- // dir: string;
46
+ el.toggleMenu();
47
+ await el.updateComplete;
42
48
 
43
- // files: File[];
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
- // files_count: number;
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
- // item_last_updated: number;
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
- // item_size: number;
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
- // metadata: Metadata;
108
+ // hydrate item
109
+ el.item = new ItemStub();
110
+ await el.updateComplete;
52
111
 
53
- // server: string;
112
+ // spy fires
113
+ expect(spy.called).to.equal(true);
114
+ expect(spy.callCount).to.equal(1);
115
+ });
116
+ });
54
117
 
55
- // uniq: number;
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
- // workable_servers: string[];
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
- // speech_vs_music_asr?: SpeechMusicASREntry[] | undefined;
134
+ await fixture<ItemNavigator>(
135
+ html`<ia-item-navigator
136
+ .sharedObserver=${sharedObserver}
137
+ ></ia-item-navigator>`
138
+ );
60
139
 
61
- // reviews?: Review[] | undefined;
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
- afterEach(() => {
65
- Sinon.restore();
66
- });
146
+ const el = await fixture<ItemNavigator>(
147
+ html`<ia-item-navigator
148
+ .sharedObserver=${sharedObserver}
149
+ ></ia-item-navigator>`
150
+ );
67
151
 
68
- describe('ItemNavigator', () => {
69
- describe('Loading Behavior', () => {
70
- it('shows the spinning loader', async () => {
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
- expect(el.shadowRoot?.querySelector('ia-itemnav-loader')).to.be.exist;
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
- it('hides reader section if not `loaded`', async () => {
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
- const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
81
- expect(mainTheaterSection).to.be.exist;
82
- expect(mainTheaterSection?.classList.contains('hide')).to.be.true;
83
- expect(el.loaded).to.be.false;
84
- expect(el.hasAttribute('loaded')).to.equal(false);
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('shows reader once `loaded`', async () => {
205
+ it('@ViewportInFullScreen', async () => {
87
206
  const el = await fixture<ItemNavigator>(
88
207
  html`<ia-item-navigator></ia-item-navigator>`
89
208
  );
90
- el.loaded = true;
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
- const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
94
- expect(mainTheaterSection?.classList.contains('hide')).to.be.false;
95
- expect(el.loaded).to.be.true;
96
- // `loaded` property is reflected as DOM attribute
97
- expect(el.hasAttribute('loaded')).to.equal(true);
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
- // it('listens to event `loadingStateUpdated` to signal load', async () => {
101
- // const item = new ItemStub() as MetadataResponse;
102
- // const el = await fixture<ItemNavigator>(
103
- // html`<ia-item-navigator .item=${item}></ia-item-navigator>`
104
- // );
105
- // // const loadSpy = Sinon.spy();
106
- // // el.loadingStateUpdated = loadSpy;
107
- // await el.updateComplete;
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
- // expect(el?.item).to.not.be.undefined;
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
- // const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
289
+ expect(frame?.getAttribute('class')).to.contain('open');
112
290
 
113
- // const contentController = mainTheaterSection?.querySelector('ia-item-inspector');
291
+ // no menu provided
292
+ const openShortcutSpy = Sinon.spy(el, 'openShortcut');
293
+ const toggleMenuSpy = Sinon.spy(el, 'toggleMenu');
114
294
 
115
- // expect(contentController).to.equal(32324);
295
+ const noMenuProvidedEvent = new CustomEvent('updateSideMenu', {
296
+ detail: {},
297
+ }) as any;
298
+ el.manageSideMenuEvents(noMenuProvidedEvent);
299
+ await el.updateComplete;
116
300
 
117
- // // const loadingEvent = new CustomEvent('loadingStateUpdated', { detail: { loaded: true }}) as IntLoadingStateUpdatedEvent;
118
- // // contentController?.emitLoadingStatusUpdate(true);
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
- // // await contentController?.updateComplete;
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('It uses a shared ResizeObserver', () => {
127
- it('can create one', async () => {
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.sharedObserver).to.not.be.null;
133
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
134
- });
332
+ expect(el.menuContents.length).to.exist;
333
+ expect(el.shouldRenderMenu).to.be.true;
135
334
 
136
- it('can recieve one', async () => {
137
- const sharedObserver = new SharedResizeObserver();
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
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
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('It uses a shared modal component', () => {
150
- it('can create one', async () => {
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
- expect(el.sharedObserver).to.not.be.null;
156
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
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
- it('can recieve one', async () => {
160
- const sharedObserver = new SharedResizeObserver();
161
- const observerSpy = Sinon.stub(sharedObserver, 'addObserver');
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
- // describe('full browser window immersion "fullscreen"', () => {
175
- // it('creates reflected attribute `viewportinfullscreen`', () =>{
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
- // describe('Loads side menu contents', () =>{
181
- // });
413
+ // toggles it off
414
+ el.setOpenMenu({
415
+ detail: { id: 'foo' },
416
+ } as ToggleSidePanelOpenEvent);
417
+ await el.updateComplete;
182
418
 
183
- // describe('Menu Shortcuts', () => {
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
- // it('passes the a11y audit', async () => {
187
- // const el = await fixture<YourWebComponent>(
188
- // html`<your-webcomponent></your-webcomponent>`
189
- // );
427
+ el.menuOpened = true;
428
+ await el.updateComplete;
190
429
 
191
- // await expect(el).shadowDom.to.be.accessible();
192
- // });
193
- });
430
+ expect(el.menuOpened).to.be.true;
194
431
 
195
- // describe('YourWebComponent', () => {
196
- // it('has a default title "Hey there" and counter 5', async () => {
197
- // const el = await fixture<YourWebComponent>(
198
- // html`<your-webcomponent></your-webcomponent>`
199
- // );
200
-
201
- // expect(el.title).to.equal('Hey there');
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
- // const parsed = JSON.parse(raw);
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
- // export default parsed;
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;