diff --git a/src/components/microlearning/VideoDetailPage.jsx b/src/components/microlearning/VideoDetailPage.jsx
index cc521a7989..e63b7784c8 100644
--- a/src/components/microlearning/VideoDetailPage.jsx
+++ b/src/components/microlearning/VideoDetailPage.jsx
@@ -78,11 +78,11 @@ const VideoDetailPage = () => {
{videoData?.courseTitle}
-
+
{videoData?.videoDuration && `(${videoData?.videoDuration} minutes)`}
-
+
{videoData?.videoSummary}
{ videoData?.videoSkills?.length > 0 && (
@@ -110,9 +110,11 @@ const VideoDetailPage = () => {
)}
-
-
-
+ { videoData?.videoUrl && (
+
+
+
+ )}
{matches => matches && (
diff --git a/src/components/video/data/tests/hooks.test.js b/src/components/video/data/tests/hooks.test.js
new file mode 100644
index 0000000000..1c0b24a2fb
--- /dev/null
+++ b/src/components/video/data/tests/hooks.test.js
@@ -0,0 +1,70 @@
+import { renderHook } from '@testing-library/react-hooks';
+import { logError } from '@edx/frontend-platform/logging';
+import { useTranscripts } from '../hooks';
+import { fetchAndAddTranscripts } from '../service';
+
+// Mocking dependencies
+jest.mock('../service', () => ({
+ fetchAndAddTranscripts: jest.fn(),
+}));
+
+jest.mock('@edx/frontend-platform/logging', () => ({
+ logError: jest.fn(),
+}));
+
+describe('useTranscripts', () => {
+ const customOptions = {
+ showTranscripts: true,
+ transcriptUrls: {
+ en: 'https://example.com/transcript-en.txt',
+ },
+ };
+ const mockPlayer = {};
+
+ it('should set isLoading to true initially if showTranscripts is true', () => {
+ const { result } = renderHook(() => useTranscripts({ player: mockPlayer, customOptions }));
+ expect(result.current.isLoading).toBe(true);
+ });
+
+ it('should fetch and set textTracks and transcriptUrl correctly', async () => {
+ const textTracks = { en: 'https://example.com/transcript-en.txt' };
+ fetchAndAddTranscripts.mockResolvedValueOnce(textTracks);
+
+ const { result, waitForNextUpdate } = renderHook(() => useTranscripts({ player: mockPlayer, customOptions }));
+
+ await waitForNextUpdate();
+
+ expect(result.current.isLoading).toBe(false);
+ expect(result.current.textTracks).toEqual(textTracks);
+ expect(result.current.transcriptUrl).toBe(textTracks.en);
+ });
+
+ it('should log error and set isLoading to false if fetching transcripts fails', async () => {
+ const errorMessage = 'Error fetching transcripts';
+ fetchAndAddTranscripts.mockRejectedValueOnce(new Error(errorMessage));
+
+ const { result, waitForNextUpdate } = renderHook(() => useTranscripts({ player: mockPlayer, customOptions }));
+
+ await waitForNextUpdate();
+
+ expect(logError).toHaveBeenCalledWith(`Error fetching transcripts for player: Error: ${errorMessage}`);
+ expect(result.current.isLoading).toBe(false);
+ expect(result.current.textTracks).toEqual([]);
+ expect(result.current.transcriptUrl).toBeNull();
+ });
+
+ it('should not fetch transcripts if showTranscripts is false', async () => {
+ const customOptionsWithoutTranscripts = {
+ showTranscripts: false,
+ transcriptUrls: undefined,
+ };
+
+ const { result } = renderHook(() => useTranscripts({
+ player: mockPlayer,
+ customOptions: customOptionsWithoutTranscripts,
+ }));
+
+ expect(result.current.textTracks).toEqual([]);
+ expect(result.current.transcriptUrl).toBeNull();
+ });
+});
diff --git a/src/components/video/tests/VideoJS.test.jsx b/src/components/video/tests/VideoJS.test.jsx
index d2bcf0e8a5..c21aaf0be0 100644
--- a/src/components/video/tests/VideoJS.test.jsx
+++ b/src/components/video/tests/VideoJS.test.jsx
@@ -1,8 +1,15 @@
import React from 'react';
-import { VideoJS } from '..';
+import { waitFor } from '@testing-library/react';
import { renderWithRouter } from '../../../utils/tests';
+import VideoJS from '../VideoJS';
+import { useTranscripts } from '../data';
+// Mocking the 'videojs-vjstranscribe' and 'useTranscripts' hook
jest.mock('videojs-vjstranscribe');
+jest.mock('../data', () => ({
+ useTranscripts: jest.fn(),
+ usePlayerOptions: jest.fn(),
+}));
const hlsUrl = 'https://test-domain.com/test-prefix/id.m3u8';
const ytUrl = 'https://www.youtube.com/watch?v=oHg5SJYRHA0';
@@ -26,6 +33,14 @@ const YoutubeVideoOptions = {
};
describe('VideoJS', () => {
+ beforeEach(() => {
+ useTranscripts.mockReturnValue({
+ isLoading: false,
+ textTracks: {},
+ transcriptUrl: null,
+ });
+ });
+
it('Renders VideoJS components correctly for HLS videos.', () => {
const { container } = renderWithRouter();
expect(container.querySelector('.video-js-wrapper')).toBeTruthy();
@@ -39,4 +54,53 @@ describe('VideoJS', () => {
expect(container.querySelector('.vjs-big-play-centered')).toBeTruthy();
expect(container.querySelector('video-js')).toBeTruthy();
});
+
+ it('Renders VideoJS components correctly with transcripts.', async () => {
+ const customOptions = {
+ showTranscripts: true,
+ transcriptUrls: {
+ en: 'https://example.com/transcript-en.txt',
+ },
+ };
+
+ useTranscripts.mockReturnValue({
+ isLoading: false,
+ textTracks: {
+ en: 'https://example.com/transcript-en.txt',
+ },
+ transcriptUrl: 'https://example.com/transcript-en.txt',
+ });
+
+ const { container } = renderWithRouter();
+
+ await waitFor(() => {
+ expect(container.querySelector('.video-js-wrapper')).toBeTruthy();
+ expect(container.querySelector('.vjs-big-play-centered')).toBeTruthy();
+ expect(container.querySelector('video-js')).toBeTruthy();
+ expect(container.querySelector('#vjs-transcribe')).toBeTruthy();
+ });
+ });
+
+ it('Does not initialize VideoJS player while transcripts are loading.', async () => {
+ const customOptions = {
+ showTranscripts: true,
+ transcriptUrls: {
+ en: 'https://example.com/transcript-en.txt',
+ },
+ };
+
+ useTranscripts.mockReturnValue({
+ isLoading: true,
+ textTracks: {},
+ transcriptUrl: null,
+ });
+
+ const { container } = renderWithRouter();
+
+ await waitFor(() => {
+ expect(container.querySelector('.video-js-wrapper')).toBeTruthy();
+ expect(container.querySelector('.vjs-big-play-centered')).toBeFalsy();
+ expect(container.querySelector('video-js')).toBeFalsy();
+ });
+ });
});
diff --git a/src/components/video/tests/VideoPlayer.test.jsx b/src/components/video/tests/VideoPlayer.test.jsx
index 83d0cd4a38..61711c6108 100644
--- a/src/components/video/tests/VideoPlayer.test.jsx
+++ b/src/components/video/tests/VideoPlayer.test.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import { waitFor } from '@testing-library/react';
-import { VideoPlayer } from '..'; // Assuming VideoPlayer is exported as named export
+import VideoPlayer from '../VideoPlayer';
import { renderWithRouter } from '../../../utils/tests';
const hlsUrl = 'https://test-domain.com/test-prefix/id.m3u8';