diff --git a/examples/default-provider/videos/storage.googleapis.com_muxdemofiles_mux.mp4.json b/examples/default-provider/videos/storage.googleapis.com_muxdemofiles_mux.mp4.json index 2b1f1af..f275c44 100644 --- a/examples/default-provider/videos/storage.googleapis.com_muxdemofiles_mux.mp4.json +++ b/examples/default-provider/videos/storage.googleapis.com_muxdemofiles_mux.mp4.json @@ -1 +1 @@ -{"status":"ready","originalFilePath":"https://storage.googleapis.com/muxdemofiles/mux.mp4","provider":"mux","providerMetadata":{"mux":{"assetId":"EploFGgmKULMpiyDFwsy5c6lmGcg8dkObaVvnPMcdkQ","playbackId":"jxEf6XiJs6JY017pSzpv8Hd6tTbdAOecHTq4FiFAn564"}},"createdAt":1710979438730,"updatedAt":1710979441038,"sources":[{"src":"https://stream.mux.com/.m3u8","type":"application/x-mpegURL"}],"poster":"https://image.mux.com//thumbnail.webp","blurDataURL":"data:image/webp;base64,UklGRlAAAABXRUJQVlA4IEQAAACwAQCdASoQAAkAAQAcJZwAAueBHFYwAP7+sPJ01xp5AM+XuhDsRQ67ZYXXhHDkrqsIkUGjQSCMuENc5y3Qg0o9pZgAAA=="} +{"status":"ready","originalFilePath":"https://storage.googleapis.com/muxdemofiles/mux.mp4","provider":"mux","providerMetadata":{"mux":{"assetId":"EploFGgmKULMpiyDFwsy5c6lmGcg8dkObaVvnPMcdkQ","playbackId":"jxEf6XiJs6JY017pSzpv8Hd6tTbdAOecHTq4FiFAn564"}},"createdAt":1710979438730,"updatedAt":1710979441038,"sources":[{"src":"https://stream.mux.com/jxEf6XiJs6JY017pSzpv8Hd6tTbdAOecHTq4FiFAn564.m3u8","type":"application/x-mpegURL"}],"poster":"https://image.mux.com//thumbnail.webp","blurDataURL":"data:image/webp;base64,UklGRlAAAABXRUJQVlA4IEQAAACwAQCdASoQAAkAAQAcJZwAAueBHFYwAP7+sPJ01xp5AM+XuhDsRQ67ZYXXhHDkrqsIkUGjQSCMuENc5y3Qg0o9pZgAAA=="} diff --git a/package.json b/package.json index ba7cb9f..e4f94a9 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "postbuild:cjs": "node --eval \"fs.writeFileSync('./dist/cjs/package.json', '{\\\"type\\\": \\\"commonjs\\\"}')\"", "prepare": "npm run build", "cli": "node --loader tsx --no-warnings ./src/cli", - "test": "glob -c \"c8 --src src --exclude 'next.config.js' --exclude 'tests/**' --exclude 'dist/**' node --loader tsx --no-warnings --test\" \"./tests/**/*.test.{ts,tsx}\"", + "test": "NODE_ENV=test glob -c \"c8 --src src --exclude 'next.config.js' --exclude 'tests/**' --exclude 'dist/**' node --loader tsx --no-warnings --test\" \"./tests/**/*.test.{ts,tsx}\"", "coverage": "c8 report --reporter=text-lcov > ./coverage/lcov.info" }, "peerDependencies": { diff --git a/src/components/video.tsx b/src/components/video.tsx index 9a2c649..a73deb3 100644 --- a/src/components/video.tsx +++ b/src/components/video.tsx @@ -11,7 +11,7 @@ import type { DefaultPlayerProps } from './players/default-player.js'; import type { Asset } from '../assets.js'; import type { VideoLoaderProps, VideoProps, VideoPropsInternal } from './types.js'; -const DEV_MODE = process.env.NODE_ENV === 'development'; +const DEV_MODE = ['development', 'test'].includes(process.env.NODE_ENV); const NextVideo = forwardRef((props: VideoProps, forwardedRef) => { let { diff --git a/tests/components/utils.test.tsx b/tests/components/utils.test.tsx new file mode 100644 index 0000000..711a7b8 --- /dev/null +++ b/tests/components/utils.test.tsx @@ -0,0 +1,24 @@ +import assert from 'node:assert'; +import { test } from 'node:test'; +import React from 'react'; +import { isReactComponent, getUrlExtension } from '../../src/components/utils.js'; + +test('isReactComponent', () => { + assert.ok(isReactComponent(() => null), 'function component'); + assert.ok(isReactComponent(class extends React.Component {}), 'class component'); + assert.ok(isReactComponent(React.memo(() => null)), 'memo'); + assert.ok(isReactComponent(React.forwardRef(() => null)), 'forwardRef'); +}); + +test('getUrlExtension', () => { + assert.strictEqual(getUrlExtension('https://example.com/image.jpg'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg?foo=bar'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg#foo'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg?foo=bar#foo'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg?foo=bar&baz=qux'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg?foo=bar&baz=qux#foo'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg#foo?foo=bar&baz=qux'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg#foo?foo=bar&baz=qux#foo'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg?foo=bar&baz=qux#foo?foo=bar&baz=qux'), 'jpg'); + assert.strictEqual(getUrlExtension('https://example.com/image.jpg?foo=bar&baz=qux#foo?foo=bar&baz=qux#foo'), 'jpg'); +}); diff --git a/tests/components/video.test.tsx b/tests/components/video.test.tsx index b52cb8d..03a2c06 100644 --- a/tests/components/video.test.tsx +++ b/tests/components/video.test.tsx @@ -1,5 +1,5 @@ import assert from 'node:assert'; -import { test } from 'node:test'; +import { test, mock } from 'node:test'; import { setTimeout } from 'node:timers/promises'; import { create } from 'react-test-renderer'; import React from 'react'; @@ -36,3 +36,59 @@ test('renders mux-player with imported source', async () => { 'zNYmqdvJ61gt5uip02zPid01rYIPyyzVRVKQChgSgJlaY' ); }); + +test('renders mux-player with string source', async () => { + await import('@mux/mux-player-react'); + + let keepalive = globalThis.setTimeout(() => {}, 5_000); + + let resolve; + const pollReady = new Promise((res) => { + resolve = res; + }); + + let count = 0; + + mock.method(global, 'fetch', async () => { + return { + ok: true, + status: 200, + json: async () => { + count++; + + if (count < 2) { + return { + status: 'uploading', + provider: 'mux', + }; + } + + resolve(); + + return { + status: 'ready', + provider: 'mux', + sources: [{ + type: 'application/x-mpegURL', + src: 'https://stream.mux.com/jxEf6XiJs6JY017pSzpv8Hd6tTbdAOecHTq4FiFAn564.m3u8' + }] + }; + } + }; + }); + + const wrapper = create(