@internetarchive/ia-item-navigator 0.0.0-a1 → 0.0.0-a14

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