From 627b4af8eafdca47ab96b3bfc6af73f0913cfa21 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Mon, 20 Jan 2025 16:43:45 -0500 Subject: [PATCH] test: Enable transcript in libraries --- .../TranscriptWidget/LanguageSelector.jsx | 3 - .../__snapshots__/index.test.jsx.snap | 2 + .../TranscriptWidget/index.test.jsx | 9 +++ .../VideoPreviewWidget/index.test.jsx | 4 +- .../data/redux/thunkActions/requests.js | 2 +- .../data/redux/thunkActions/requests.test.js | 56 ++++++++++++++++++- src/editors/data/redux/thunkActions/video.js | 2 +- src/editors/data/services/cms/api.test.ts | 31 ++++++++++ src/editors/data/services/cms/api.ts | 2 +- src/editors/data/services/cms/urls.test.ts | 17 ++++++ src/editors/data/services/cms/urls.ts | 6 +- 11 files changed, 122 insertions(+), 12 deletions(-) diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/LanguageSelector.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/LanguageSelector.jsx index e418e14fa2..90d3ec235b 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/LanguageSelector.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/LanguageSelector.jsx @@ -54,7 +54,6 @@ const LanguageSelector = ({ language, // Redux openLanguages, // Only allow those languages not already associated with a transcript to be selected - transcriptHandlerUrl, // intl intl, @@ -123,7 +122,6 @@ LanguageSelector.defaultProps = { LanguageSelector.propTypes = { openLanguages: PropTypes.arrayOf(PropTypes.string), - transcriptHandlerUrl: PropTypes.string.isRequired, index: PropTypes.number.isRequired, language: PropTypes.string.isRequired, intl: intlShape.isRequired, @@ -131,7 +129,6 @@ LanguageSelector.propTypes = { export const mapStateToProps = (state) => ({ openLanguages: selectors.video.openLanguages(state), - transcriptHandlerUrl: selectors.video.transcriptHandlerUrl(state), }); export const mapDispatchToProps = {}; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap index 904d6433b2..4bfc289700 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/TranscriptWidget/__snapshots__/index.test.jsx.snap @@ -242,6 +242,8 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with `; +exports[`TranscriptWidget component snapshots snapshot: renders when isLibrary is true 1`] = `undefined`; + exports[`TranscriptWidget component snapshots snapshots: renders as expected with allowTranscriptDownloads true 1`] = ` ({ }, selectors: { + app: { + isLibrary: jest.fn(state => ({ isLibrary: state })), + }, video: { transcripts: jest.fn(state => ({ transcripts: state })), selectedVideoTranscriptUrls: jest.fn(state => ({ selectedVideoTranscriptUrls: state })), @@ -103,6 +106,7 @@ describe('TranscriptWidget', () => { updateField: jest.fn().mockName('args.updateField'), isUploadError: false, isDeleteError: false, + isLibrary: false, }; describe('snapshots', () => { @@ -151,6 +155,11 @@ describe('TranscriptWidget', () => { shallow().snapshot, ).toMatchSnapshot(); }); + test('snapshot: renders when isLibrary is true', () => { + expect( + shallow().snapshot, + ).toMatchSnapshot(); + }); }); describe('mapStateToProps', () => { const testState = { A: 'pple', B: 'anana', C: 'ucumber' }; diff --git a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoPreviewWidget/index.test.jsx b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoPreviewWidget/index.test.jsx index fc7f89a5cd..131c9b53ba 100644 --- a/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoPreviewWidget/index.test.jsx +++ b/src/editors/containers/VideoEditor/components/VideoSettingsModal/components/VideoPreviewWidget/index.test.jsx @@ -30,7 +30,7 @@ describe('VideoPreviewWidget', () => { expect(screen.queryByText('No transcripts added')).toBeInTheDocument(); }); - test('hides transcripts section in preview for libraries', () => { + test('renders transcripts section in preview for libraries', () => { render( { thumbnail="" />, ); - expect(screen.queryByText('No transcripts added')).not.toBeInTheDocument(); + expect(screen.queryByText('No transcripts added')).toBeInTheDocument(); }); }); }); diff --git a/src/editors/data/redux/thunkActions/requests.js b/src/editors/data/redux/thunkActions/requests.js index 05cbad8396..8230433c7d 100644 --- a/src/editors/data/redux/thunkActions/requests.js +++ b/src/editors/data/redux/thunkActions/requests.js @@ -321,7 +321,7 @@ export const getTranscriptFile = ({ language, videoId, ...rest }) => (dispatch, export const getHandlerlUrl = ({ handlerName, ...rest }) => (dispatch, getState) => { dispatch(module.networkRequest({ - requestKey: RequestKeys.getHandlerlUrl, + requestKey: RequestKeys.getHandlerUrl, promise: api.getHandlerUrl({ studioEndpointUrl: selectors.app.studioEndpointUrl(getState()), blockId: selectors.app.blockId(getState()), diff --git a/src/editors/data/redux/thunkActions/requests.test.js b/src/editors/data/redux/thunkActions/requests.test.js index ece5411780..8b5eec9fb7 100644 --- a/src/editors/data/redux/thunkActions/requests.test.js +++ b/src/editors/data/redux/thunkActions/requests.test.js @@ -6,6 +6,7 @@ import { actions, selectors } from '../index'; const testState = { some: 'data', + isLibrary: false, }; jest.mock('../app/selectors', () => ({ @@ -18,6 +19,11 @@ jest.mock('../app/selectors', () => ({ blockType: (state) => ({ blockType: state }), learningContextId: (state) => ({ learningContextId: state }), blockTitle: (state) => ({ title: state }), + isLibrary: (state) => (state.isLibrary), +})); + +jest.mock('../video/selectors', () => ({ + transcriptHandlerUrl: () => ('transcriptHandlerUrl'), })); jest.mock('../../services/cms/api', () => ({ @@ -35,6 +41,8 @@ jest.mock('../../services/cms/api', () => ({ uploadTranscript: (args) => args, deleteTranscript: (args) => args, getTranscript: (args) => args, + getHandlerUrl: (args) => args, + uploadTranscriptV2: (args) => args, checkTranscriptsForImport: (args) => args, importTranscript: (args) => args, fetchVideoFeatures: (args) => args, @@ -158,10 +166,11 @@ describe('requests thunkActions module', () => { args, expectedData, expectedString, + state, }) => { let dispatchedAction; beforeEach(() => { - action({ ...args, onSuccess, onFailure })(dispatch, () => testState); + action({ ...args, onSuccess, onFailure })(dispatch, () => state || testState); [[dispatchedAction]] = dispatch.mock.calls; }); it('dispatches networkRequest', () => { @@ -500,6 +509,23 @@ describe('requests thunkActions module', () => { }, }); }); + describe('getHandlerUrl', () => { + const handlerName = 'transcript'; + testNetworkRequestAction({ + action: requests.getHandlerlUrl, + args: { handlerName, ...fetchParams }, + expectedString: 'with getHandlerUrl promise', + expectedData: { + ...fetchParams, + requestKey: RequestKeys.getHandlerUrl, + promise: api.getHandlerUrl({ + studioEndpointUrl: selectors.app.studioEndpointUrl(testState), + blockId: selectors.app.blockId(testState), + handlerName, + }), + }, + }); + }); describe('updateTranscriptLanguage', () => { const languageBeforeChange = 'SoME laNGUage CoNtent As String'; const newLanguageCode = 'SoME NEW laNGUage CoNtent As String'; @@ -553,6 +579,34 @@ describe('requests thunkActions module', () => { }, }); }); + describe('uploadTranscript V2', () => { + const language = 'SoME laNGUage CoNtent As String'; + const videoId = 'SoME VidEOid CoNtent As String'; + const transcript = 'SoME tRANscRIPt CoNtent As String'; + testNetworkRequestAction({ + action: requests.uploadTranscript, + args: { + transcript, + language, + videoId, + ...fetchParams, + }, + expectedString: 'with uploadTranscript promise', + expectedData: { + ...fetchParams, + requestKey: RequestKeys.uploadTranscript, + promise: api.uploadTranscriptV2({ + handlerUrl: 'transcriptHandlerUrl', + transcript, + videoId, + language, + }), + }, + state: { + isLibrary: true, + }, + }); + }); describe('fetchVideoFeatures', () => { testNetworkRequestAction({ action: requests.fetchVideoFeatures, diff --git a/src/editors/data/redux/thunkActions/video.js b/src/editors/data/redux/thunkActions/video.js index 04c8b79b8b..0ea4d84cea 100644 --- a/src/editors/data/redux/thunkActions/video.js +++ b/src/editors/data/redux/thunkActions/video.js @@ -383,7 +383,7 @@ export const updateTranscriptLanguage = ({ newLanguageCode, languageBeforeChange })); }; -export const updateTranscriptHandlerUrl = () => (dispatch, getState) => { +export const updateTranscriptHandlerUrl = () => (dispatch) => { dispatch(requests.getHandlerlUrl({ handlerName: 'studio_transcript', onSuccess: (response) => { diff --git a/src/editors/data/services/cms/api.test.ts b/src/editors/data/services/cms/api.test.ts index c3df32ccbf..0eb8ef4771 100644 --- a/src/editors/data/services/cms/api.test.ts +++ b/src/editors/data/services/cms/api.test.ts @@ -23,6 +23,8 @@ jest.mock('./urls', () => ({ .mockImplementation( ({ studioEndpointUrl, learningContextId }) => `${studioEndpointUrl}/some_video_upload_url/${learningContextId}`, ), + handlerUrl: jest.fn().mockReturnValue('urls.handlerUrl'), + uploadTrascriptXblockV2: jest.fn().mockReturnValue('url.uploadTranscriptV2'), })); jest.mock('./utils', () => ({ @@ -152,6 +154,14 @@ describe('cms api', () => { }); }); + describe('getHandlerUrl', () => { + it('should call get with url.handlerUrl', () => { + const handlerName = 'transcript'; + apiMethods.getHandlerUrl({ studioEndpointUrl, blockId, handlerName }); + expect(get).toHaveBeenCalledWith(urls.handlerUrl({ studioEndpointUrl, blockId, handlerName })); + }); + }); + describe('normalizeContent', () => { test('return value for blockType: html', () => { const content = 'Im baby palo santo ugh celiac fashion axe. La croix lo-fi venmo whatever. Beard man braid migas single-origin coffee forage ramps.'; @@ -410,6 +420,27 @@ describe('cms api', () => { ); }); }); + describe('uploadTranscriptV2', () => { + const transcript = new Blob(['dAta']); + it('should call post with urls.uploadTranscriptV2 and transcript data', () => { + const mockFormdata = new FormData(); + const transcriptHandlerUrl = 'handlerUrl'; + mockFormdata.append('file', transcript); + mockFormdata.append('edx_video_id', videoId); + mockFormdata.append('language_code', language); + mockFormdata.append('new_language_code', language); + apiMethods.uploadTranscriptV2({ + handlerUrl: transcriptHandlerUrl, + transcript, + videoId, + language, + }); + expect(post).toHaveBeenCalledWith( + urls.uploadTrascriptXblockV2({ transcriptHandlerUrl }), + mockFormdata, + ); + }); + }); describe('transcript delete', () => { it('should call deleteObject with urls.videoTranscripts and transcript data', () => { const mockDeleteJSON = { data: { lang: language, edx_video_id: videoId } }; diff --git a/src/editors/data/services/cms/api.ts b/src/editors/data/services/cms/api.ts index 926b541fbb..a1ca8e2334 100644 --- a/src/editors/data/services/cms/api.ts +++ b/src/editors/data/services/cms/api.ts @@ -259,7 +259,7 @@ export const apiMethods = { data.append('language_code', language); data.append('new_language_code', newLanguage || language); return post( - urls.uploadTrascriptXblockV2({ handlerUrl }), + urls.uploadTrascriptXblockV2({ transcriptHandlerUrl: handlerUrl }), data, ); }, diff --git a/src/editors/data/services/cms/urls.test.ts b/src/editors/data/services/cms/urls.test.ts index 95a3968959..82696069c5 100644 --- a/src/editors/data/services/cms/urls.test.ts +++ b/src/editors/data/services/cms/urls.test.ts @@ -17,6 +17,8 @@ import { mediaTranscriptURL, videoFeatures, courseVideos, + handlerUrl, + uploadTrascriptXblockV2, } from './urls'; describe('cms url methods', () => { @@ -189,4 +191,19 @@ describe('cms url methods', () => { .toEqual(`${studioEndpointUrl}${transcriptUrl}`); }); }); + describe('handlerUrl', () => { + it('returns url with studioEndpointUrl, blockId and handlerName', () => { + const handlerName = 'transcript'; + expect(handlerUrl({ studioEndpointUrl, blockId, handlerName })) + .toEqual(`${studioEndpointUrl}/api/xblock/v2/xblocks/${blockId}/handler_url/transcript/`); + }); + }); + describe('uploadTrascriptXblockV2', () => { + it('returns url with transcriptHandlerUrl', () => { + const handlerName = 'transcript'; + const transcriptHandlerUrl = handlerUrl({ studioEndpointUrl, blockId, handlerName }); + expect(uploadTrascriptXblockV2({ transcriptHandlerUrl })) + .toEqual(`${transcriptHandlerUrl}translation`); + }); + }); }); diff --git a/src/editors/data/services/cms/urls.ts b/src/editors/data/services/cms/urls.ts index fdd35e31da..cca1b8bffe 100644 --- a/src/editors/data/services/cms/urls.ts +++ b/src/editors/data/services/cms/urls.ts @@ -112,10 +112,10 @@ export const courseVideos = (({ studioEndpointUrl, learningContextId }) => ( `${studioEndpointUrl}/videos/${learningContextId}` )) satisfies UrlFunction; -export const handlerUrl = (({studioEndpointUrl, blockId, handlerName}) => ( +export const handlerUrl = (({ studioEndpointUrl, blockId, handlerName }) => ( `${studioEndpointUrl}/api/xblock/v2/xblocks/${blockId}/handler_url/${handlerName}/` )) satisfies UrlFunction; -export const uploadTrascriptXblockV2 = (({ handlerUrl }) => ( - `${handlerUrl}translation` +export const uploadTrascriptXblockV2 = (({ transcriptHandlerUrl }) => ( + `${transcriptHandlerUrl}translation` )) satisfies UrlFunction;