vycxexra8: Play feed videos from hlsUrl with a thumbnail fallback

This commit is contained in:
2026-10-19 14:03:12 -06:00
parent 18e0386a99
commit 69e3c1ba2f
8 changed files with 178 additions and 2 deletions
+55
View File
@@ -0,0 +1,55 @@
import { describe, expect, it } from "vitest";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { PostCard } from "@/components/PostCard";
import { toCardPosts } from "@/lib/feed-model";
import { choosePlayback, supportsNativeHls } from "@/lib/video-playback";
const HLS = "https://stream.mux.com/abc.m3u8";
const item = (media: Record<string, unknown>) => ({
type: "post",
publishedAt: "2026-10-19T10:00:00Z",
post: { id: "1", content: "hi", author: { displayName: "Ann" }, mediaItems: [media] },
});
const html = (media: Record<string, unknown>) =>
renderToStaticMarkup(createElement(PostCard, { post: toCardPosts([item(media)])[0] }));
describe("choosePlayback", () => {
it("no hlsUrl means no player", () => {
expect(choosePlayback(null, { nativeHls: true, hlsJsSupported: true })).toBe("none");
expect(choosePlayback(undefined, { nativeHls: false, hlsJsSupported: true })).toBe("none");
});
it("uses native HLS where supported, hls.js otherwise", () => {
expect(choosePlayback(HLS, { nativeHls: true, hlsJsSupported: true })).toBe("native");
expect(choosePlayback(HLS, { nativeHls: false, hlsJsSupported: true })).toBe("hlsjs");
});
it("falls back to none when neither is available", () => {
expect(choosePlayback(HLS, { nativeHls: false, hlsJsSupported: false })).toBe("none");
});
it("detects native HLS from canPlayType", () => {
expect(supportsNativeHls({ canPlayType: () => "maybe" })).toBe(true);
expect(supportsNativeHls({ canPlayType: () => "" })).toBe(false);
});
});
describe("video media in the card", () => {
const video = { mediaType: "video", thumbnailUrl: "https://i/v.jpg" };
it("hlsUrl present renders an accessible controls player with the poster", () => {
const out = html({ ...video, hlsUrl: HLS });
expect(out).toContain("<video");
expect(out).toContain("controls");
expect(out).toContain('poster="https://i/v.jpg"');
expect(out).toContain('aria-label="Video from Ann"');
expect(out).not.toContain("autoplay");
});
it("hlsUrl absent shows the thumbnail only, no player", () => {
const out = html(video);
expect(out).not.toContain("<video");
expect(out).toContain('src="https://i/v.jpg"');
});
it("rejects an hlsUrl not on stream.mux.com", () => {
const out = html({ ...video, hlsUrl: "https://evil.example/x.m3u8" });
expect(out).not.toContain("<video");
expect(out).toContain('src="https://i/v.jpg"');
});
});