import { Component, ViewChild } from "@angular/core";
import { TestBed } from "@angular/core/testing";
import { SamVideoPlayerComponent } from "./video-player.component";
@Component({
template: `
`,
standalone: false,
})
class HostComponent {
videoId = "vid1";
title = "Test Video";
@ViewChild(SamVideoPlayerComponent) player: SamVideoPlayerComponent;
}
@Component({
template: `
`,
standalone: false,
})
class EmptyHostComponent {
videoId = "vid2";
@ViewChild(SamVideoPlayerComponent) player: SamVideoPlayerComponent;
}
describe("The Sam Video Player component", () => {
let initPxVideoSpy: ReturnType;
beforeEach(() => {
initPxVideoSpy = vi.fn();
(
globalThis as unknown as { InitPxVideo: typeof initPxVideoSpy }
).InitPxVideo = initPxVideoSpy;
});
afterEach(() => {
delete (globalThis as unknown as { InitPxVideo?: unknown }).InitPxVideo;
});
it("should initialize the player and set attributes on the progress/video elements", () => {
TestBed.configureTestingModule({
declarations: [HostComponent, SamVideoPlayerComponent],
});
const fixture = TestBed.createComponent(HostComponent);
fixture.detectChanges();
expect(initPxVideoSpy).toHaveBeenCalledWith(
expect.objectContaining({ videoId: "vid1", videoTitle: "Test Video" })
);
const videoEl = fixture.nativeElement.querySelector("video");
expect(videoEl.getAttribute("name")).toBe("vid1");
expect(videoEl.getAttribute("role")).toBe("presentation");
});
it("should default the video title and seek interval when not provided", () => {
TestBed.configureTestingModule({
declarations: [HostComponent, SamVideoPlayerComponent],
});
const fixture = TestBed.createComponent(HostComponent);
const host = fixture.componentInstance;
host.title = "";
fixture.detectChanges();
expect(initPxVideoSpy).toHaveBeenCalledWith(
expect.objectContaining({
videoTitle: "Sam Video",
seekInterval: 10,
})
);
});
it("should emit onFullScreenChange when the document fullscreenchange event fires", () => {
TestBed.configureTestingModule({
declarations: [HostComponent, SamVideoPlayerComponent],
});
const fixture = TestBed.createComponent(HostComponent);
const host = fixture.componentInstance;
fixture.detectChanges();
const emitted: boolean[] = [];
host.player.onFullScreenChange.subscribe((val: boolean) =>
emitted.push(val)
);
host.player.onToggleFullScreen({} as Event);
expect(emitted.length).toBe(1);
});
it("should log errors for each missing required content child on init", () => {
TestBed.configureTestingModule({
declarations: [EmptyHostComponent, SamVideoPlayerComponent],
});
const fixture = TestBed.createComponent(EmptyHostComponent);
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
fixture.detectChanges();
expect(errorSpy).toHaveBeenCalledTimes(3);
errorSpy.mockRestore();
});
it("should remove the aria-announce element on destroy when it exists", () => {
TestBed.configureTestingModule({
declarations: [HostComponent, SamVideoPlayerComponent],
});
const fixture = TestBed.createComponent(HostComponent);
const host = fixture.componentInstance;
fixture.detectChanges();
const announceEl = document.createElement("div");
announceEl.id = "px-video-aria-announce";
document.body.appendChild(announceEl);
host.player.ngOnDestroy();
expect(document.getElementById("px-video-aria-announce")).toBeNull();
});
});