Files
v10/packages/html/src/media/tests/google-cast.test.ts
T

129 lines
4.3 KiB
TypeScript

import { ContextProvider } from '@videojs/element/context';
import type { Media } from '@videojs/media/dom';
import { GoogleCast } from '@videojs/media/dom/google-cast';
import { getMediaComponents } from '@videojs/media/dom/media-host';
import { HTMLVideoElementHost } from '@videojs/media/dom/video-host';
import { afterEach, describe, expect, it } from 'vitest';
import { mediaContext } from '../../player/context';
import { MediaElement } from '../../ui/media-element';
import { GoogleCastElement } from '../google-cast';
class TestMediaProvider extends MediaElement {
readonly #provider = new ContextProvider(this, {
context: mediaContext,
initialValue: { media: null, setMedia: () => {} },
});
setMedia(media: Media | null) {
this.#provider.setValue({ media, setMedia: () => {} });
}
}
customElements.define('test-cast-provider', TestMediaProvider);
customElements.define('test-google-cast', GoogleCastElement);
function setup() {
const host = new HTMLVideoElementHost();
const provider = new TestMediaProvider();
const el = new GoogleCastElement();
provider.append(el);
document.body.append(provider);
return { host, provider, el };
}
afterEach(() => {
document.body.innerHTML = '';
});
describe('GoogleCastElement', () => {
it('registers a GoogleCast component with the media host from context', () => {
const { host, provider } = setup();
provider.setMedia(host as unknown as Media);
expect(getMediaComponents(host).get(GoogleCast)).toBeInstanceOf(GoogleCast);
});
it('leaves the component to the base class lazy getter', () => {
// An own `component` field would shadow the getter and be initialized after
// the base constructor — too late for a connected upgrade, where the media
// context callback registers the component from within that constructor.
expect(Object.getOwnPropertyNames(new GoogleCastElement())).not.toContain('component');
});
it('resolves the host from a media element host property', () => {
const { host, provider } = setup();
provider.setMedia({ host } as unknown as Media);
expect(getMediaComponents(host).get(GoogleCast)).toBeInstanceOf(GoogleCast);
});
it('ignores media that is not a media host', () => {
const { host, provider } = setup();
provider.setMedia(host as unknown as Media);
provider.setMedia(document.createElement('video') as unknown as Media);
expect(getMediaComponents(host).get(GoogleCast)).toBeUndefined();
});
it('forwards attributes to the component', () => {
const { host, provider, el } = setup();
provider.setMedia(host as unknown as Media);
el.setAttribute('receiver', 'APP_ID');
el.setAttribute('content-type', 'application/x-mpegURL');
el.setAttribute('stream-type', 'live');
el.setAttribute('src', 'https://example.com/stream.m3u8');
const component = getMediaComponents(host).get(GoogleCast)!;
expect(component.receiver).toBe('APP_ID');
expect(component.contentType).toBe('application/x-mpegURL');
expect(component.streamType).toBe('live');
expect(component.src).toBe('https://example.com/stream.m3u8');
// Properties read back from the component.
expect(el.receiver).toBe('APP_ID');
});
it('clears a component prop when its attribute is removed', () => {
const { el } = setup();
el.setAttribute('receiver', 'APP_ID');
el.removeAttribute('receiver');
expect(el.receiver).toBeUndefined();
});
it('moves the component when the media changes', () => {
const { host, provider } = setup();
const nextHost = new HTMLVideoElementHost();
provider.setMedia(host as unknown as Media);
provider.setMedia(nextHost as unknown as Media);
expect(getMediaComponents(host).get(GoogleCast)).toBeUndefined();
expect(getMediaComponents(nextHost).get(GoogleCast)).toBeInstanceOf(GoogleCast);
});
it('removes the component when the element disconnects', () => {
const { host, provider, el } = setup();
provider.setMedia(host as unknown as Media);
el.remove();
expect(getMediaComponents(host).get(GoogleCast)).toBeUndefined();
});
it('removes the component on destroy', () => {
const { host, provider, el } = setup();
provider.setMedia(host as unknown as Media);
el.destroy();
expect(getMediaComponents(host).get(GoogleCast)).toBeUndefined();
});
});