diff --git a/services/web/frontend/js/features/binary-file/components/binary-file-header.js b/services/web/frontend/js/features/binary-file/components/binary-file-header.js index d5b09c8fdc..93dd30789d 100644 --- a/services/web/frontend/js/features/binary-file/components/binary-file-header.js +++ b/services/web/frontend/js/features/binary-file/components/binary-file-header.js @@ -1,12 +1,14 @@ import React, { useState, useCallback } from 'react' import PropTypes from 'prop-types' +import { Trans, useTranslation } from 'react-i18next' + import Icon from '../../../shared/components/icon' import { formatTime, relativeDate } from '../../utils/format-date' -import { Trans, useTranslation } from 'react-i18next' -import importOverleafModules from '../../../../macros/import-overleaf-module.macro' import { postJSON } from '../../../infrastructure/fetch-json' import useIsMounted from '../../../shared/hooks/use-is-mounted' +import { useEditorContext } from '../../../shared/context/editor-context' +import importOverleafModules from '../../../../macros/import-overleaf-module.macro' const tprLinkedFileInfo = importOverleafModules('tprLinkedFileInfo') const tprLinkedFileRefreshError = importOverleafModules( 'tprLinkedFileRefreshError' @@ -30,11 +32,14 @@ function shortenedUrl(url) { } export default function BinaryFileHeader({ file, storeReferencesKeys }) { + const { projectId } = useEditorContext({ + projectId: PropTypes.string.isRequired, + }) + const { t } = useTranslation() + const isMounted = useIsMounted() + const [refreshing, setRefreshing] = useState(false) const [refreshError, setRefreshError] = useState(null) - const { t } = useTranslation() - - const isMounted = useIsMounted() let fileInfo if (file.linkedFileData) { @@ -63,7 +68,7 @@ export default function BinaryFileHeader({ file, storeReferencesKeys }) { setRefreshing(true) // Replacement of the file handled by the file tree window.expectingLinkedFileRefreshedSocketFor = file.name - postJSON(`/project/${window.project_id}/linked_file/${file.id}/refresh`) + postJSON(`/project/${projectId}/linked_file/${file.id}/refresh`) .then(() => { if (isMounted.current) { setRefreshing(false) @@ -90,7 +95,7 @@ export default function BinaryFileHeader({ file, storeReferencesKeys }) { body: { shouldBroadcast: true }, } - postJSON(`/project/${window.project_id}/references/indexAll`, opts) + postJSON(`/project/${projectId}/references/indexAll`, opts) .then(response => { // Later updated by the socket but also updated here for immediate use storeReferencesKeys(response.keys) @@ -99,7 +104,7 @@ export default function BinaryFileHeader({ file, storeReferencesKeys }) { console.log(error) }) } - }, [file, isMounted, storeReferencesKeys]) + }, [file, projectId, isMounted, storeReferencesKeys]) return (
@@ -120,7 +125,7 @@ export default function BinaryFileHeader({ file, storeReferencesKeys }) { )}   diff --git a/services/web/frontend/js/features/binary-file/components/binary-file-image.js b/services/web/frontend/js/features/binary-file/components/binary-file-image.js index d5499f3cb1..2a0ed4e6c5 100644 --- a/services/web/frontend/js/features/binary-file/components/binary-file-image.js +++ b/services/web/frontend/js/features/binary-file/components/binary-file-image.js @@ -1,10 +1,15 @@ import React from 'react' import PropTypes from 'prop-types' +import { useEditorContext } from '../../../shared/context/editor-context' export default function BinaryFileImage({ fileName, fileId, onLoad, onError }) { + const { projectId } = useEditorContext({ + projectId: PropTypes.string.isRequired, + }) + return ( { - let path = `/project/${window.project_id}/file/${file.id}` + let path = `/project/${projectId}/file/${file.id}` fetch(path, { method: 'HEAD' }) .then(response => { if (!response.ok) throw new Error('HTTP Error Code: ' + response.status) @@ -45,7 +50,7 @@ export default function BinaryFileText({ file, onLoad, onError }) { .catch(err => { onError() }) - }, [file.id, onError, onLoad]) + }, [projectId, file.id, onError, onLoad]) return (
{textPreview && ( diff --git a/services/web/frontend/js/features/binary-file/controllers/binary-file-controller.js b/services/web/frontend/js/features/binary-file/controllers/binary-file-controller.js index fe4d1ff74e..d3906d0467 100644 --- a/services/web/frontend/js/features/binary-file/controllers/binary-file-controller.js +++ b/services/web/frontend/js/features/binary-file/controllers/binary-file-controller.js @@ -2,6 +2,7 @@ import App from '../../../base' import { react2angular } from 'react2angular' import _ from 'lodash' +import { rootContext } from '../../../shared/context/root-context' import BinaryFile from '../components/binary-file' export default App.controller( @@ -18,5 +19,5 @@ export default App.controller( App.component( 'binaryFile', - react2angular(BinaryFile, ['storeReferencesKeys', 'file']) + react2angular(rootContext.use(BinaryFile), ['storeReferencesKeys', 'file']) ) diff --git a/services/web/frontend/stories/binary-file.stories.js b/services/web/frontend/stories/binary-file.stories.js index fb459c47eb..99d1ba78ec 100644 --- a/services/web/frontend/stories/binary-file.stories.js +++ b/services/web/frontend/stories/binary-file.stories.js @@ -1,10 +1,9 @@ import React from 'react' +import { ContextRoot } from '../js/shared/context/root-context' import BinaryFile from '../js/features/binary-file/components/binary-file' import useFetchMock from './hooks/use-fetch-mock' -window.project_id = 'proj123' - const setupFetchMock = fetchMock => { fetchMock .head('express:/project/:project_id/file/:file_id', { @@ -20,12 +19,10 @@ const setupFetchMock = fetchMock => { }) } -window.project_id = '1234' - const fileData = { id: 'file-id', name: 'file.tex', - created: new Date(), + created: new Date().toISOString(), } export const FileFromUrl = args => { @@ -181,7 +178,9 @@ export default { Story => ( <> - + + + ), ], diff --git a/services/web/test/frontend/features/binary-file/components/binary-file-header.test.js b/services/web/test/frontend/features/binary-file/components/binary-file-header.test.js index ba43a90980..9c89743001 100644 --- a/services/web/test/frontend/features/binary-file/components/binary-file-header.test.js +++ b/services/web/test/frontend/features/binary-file/components/binary-file-header.test.js @@ -1,6 +1,5 @@ import React from 'react' import { - render, screen, fireEvent, waitForElementToBeRemoved, @@ -9,6 +8,7 @@ import { expect } from 'chai' import fetchMock from 'fetch-mock' import sinon from 'sinon' +import { renderWithEditorContext } from '../../../helpers/render-with-context' import BinaryFileHeader from '../../../../../frontend/js/features/binary-file/components/binary-file-header.js' describe('', function () { @@ -50,16 +50,15 @@ describe('', function () { created: new Date(2021, 1, 17, 3, 24).toISOString(), } - let storeReferencesKeys - beforeEach(function () { fetchMock.reset() - storeReferencesKeys = sinon.stub() }) describe('header text', function () { it('Renders the correct text for a file with the url provider', function () { - render( {}} />) + renderWithEditorContext( + {}} /> + ) screen.getByText('Imported from', { exact: false }) screen.getByText('at 3:24 am Wed, 17th Feb 21', { exact: false, @@ -67,7 +66,7 @@ describe('', function () { }) it('Renders the correct text for a file with the project_file provider', function () { - render( + renderWithEditorContext( {}} /> ) screen.getByText('Imported from', { exact: false }) @@ -78,7 +77,7 @@ describe('', function () { }) it('Renders the correct text for a file with the project_output_file provider', function () { - render( + renderWithEditorContext( {}} @@ -93,20 +92,6 @@ describe('', function () { }) describe('The refresh button', async function () { - let reindexResponse - - beforeEach(function () { - window.project_id = '123abc' - reindexResponse = { - projectId: '123abc', - keys: ['reference1', 'reference2', 'reference3', 'reference4'], - } - }) - - afterEach(function () { - delete window.project_id - }) - it('Changes text when the file is refreshing', async function () { fetchMock.post( 'express:/project/:project_id/linked_file/:file_id/refresh', @@ -115,7 +100,7 @@ describe('', function () { } ) - render( + renderWithEditorContext( {}} /> ) @@ -135,12 +120,18 @@ describe('', function () { } ) + const reindexResponse = { + projectId: '123abc', + keys: ['reference1', 'reference2', 'reference3', 'reference4'], + } fetchMock.post( 'express:/project/:project_id/references/indexAll', reindexResponse ) - render( + const storeReferencesKeys = sinon.stub() + + renderWithEditorContext( ', function () { describe('The download button', function () { it('exists', function () { - render( {}} />) + renderWithEditorContext( + {}} /> + ) screen.getByText('Download', { exact: false }) }) diff --git a/services/web/test/frontend/features/binary-file/components/binary-file-image.test.js b/services/web/test/frontend/features/binary-file/components/binary-file-image.test.js index ca1756a6ed..e08f14e16a 100644 --- a/services/web/test/frontend/features/binary-file/components/binary-file-image.test.js +++ b/services/web/test/frontend/features/binary-file/components/binary-file-image.test.js @@ -1,6 +1,7 @@ import React from 'react' -import { render, screen } from '@testing-library/react' +import { screen } from '@testing-library/react' +import { renderWithEditorContext } from '../../../helpers/render-with-context' import BinaryFileImage from '../../../../../frontend/js/features/binary-file/components/binary-file-image.js' describe('', function () { @@ -14,7 +15,7 @@ describe('', function () { } it('renders an image', function () { - render( + renderWithEditorContext( ', function () { @@ -18,11 +19,6 @@ describe('', function () { beforeEach(function () { fetchMock.reset() - window.project_id = '123abc' - }) - - afterEach(function () { - delete window.project_id }) it('renders a text view', async function () { @@ -35,7 +31,9 @@ describe('', function () { 'Text file content' ) - render( {}} onLoad={() => {}} />) + renderWithEditorContext( + {}} onLoad={() => {}} /> + ) await screen.findByText('Text file content', { exact: false }) }) diff --git a/services/web/test/frontend/features/binary-file/components/binary-file.test.js b/services/web/test/frontend/features/binary-file/components/binary-file.test.js index 47ac1c9bba..3df2834e80 100644 --- a/services/web/test/frontend/features/binary-file/components/binary-file.test.js +++ b/services/web/test/frontend/features/binary-file/components/binary-file.test.js @@ -1,12 +1,12 @@ import React from 'react' import { - render, screen, waitForElementToBeRemoved, fireEvent, } from '@testing-library/react' import fetchMock from 'fetch-mock' +import { renderWithEditorContext } from '../../../helpers/render-with-context' import BinaryFile from '../../../../../frontend/js/features/binary-file/components/binary-file.js' describe('', function () { @@ -35,16 +35,20 @@ describe('', function () { }) describe('for a text file', function () { - it('it shows a loading indicator while the file is loading', async function () { - render( {}} />) + it('shows a loading indicator while the file is loading', async function () { + renderWithEditorContext( + {}} /> + ) await waitForElementToBeRemoved(() => screen.getByText('Loading', { exact: false }) ) }) - it('it shows messaging if the text view could not be loaded', async function () { - render( {}} />) + it('shows messaging if the text view could not be loaded', async function () { + renderWithEditorContext( + {}} /> + ) await screen.findByText('Sorry, no preview is available', { exact: false, @@ -53,14 +57,18 @@ describe('', function () { }) describe('for an image file', function () { - it('it shows a loading indicator while the file is loading', async function () { - render( {}} />) + it('shows a loading indicator while the file is loading', async function () { + renderWithEditorContext( + {}} /> + ) screen.getByText('Loading', { exact: false }) }) - it('it shows messaging if the image could not be loaded', function () { - render( {}} />) + it('shows messaging if the image could not be loaded', function () { + renderWithEditorContext( + {}} /> + ) // Fake the image request failing as the request is handled by the browser fireEvent.error(screen.getByRole('img'))