Prevent pending audio files from being embedded

When audio file uploaded and being processed by notorious, prevent
embedding it from side tray > All Files while it is in pending state.

fixes MAT-959
flag=none

Prerequisites
* You'll need a large-ish audio file to upload to your local canvas.
I attached one (10MB) to the JIRA ticket that you can use
* You need to have notorious running locally
* You need the corresponding changes from the canvas-rce-api repo
https://gerrit.instructure.com/c/canvas-rce-api/+/305519

Test Plan
- Go to RCE and from Tools menu: Insert > Document > Course Documents.
-- Leave this side tray open.
- Open another tab to Files page in canvas
** The next steps need to be done in quick succession
- In Files, click the Upload button and upload the test audio file
- Quickly go back to the RCE with the side tray open. Switch dropdown
that says "Documents" to "All"
- Click on the "Course Files" icon
VERIFY:
1. the uploaded file name is not used; it instead says:
"Media file is processing. Please try again later."
2. Clicking on the file does not embed it in the RCE
3. Clicking on any other file does embed it in the RCE
- Close the side tray, wait a short while (~1 min?)
- Re-open the side tray and switch to "All" again
VERIFY
1. The uploaded audio file name is now displayed
2. Clicking on the uploaded audio file embeds it in the RCE

Change-Id: I9418692de0bcf64c31d802487eaf6503a341c3d6
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/305518
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ed Schiebel <eschiebel@instructure.com>
QA-Review: Ed Schiebel <eschiebel@instructure.com>
Product-Review: David Lyons <lyons@instructure.com>
This commit is contained in:
Joe Hernandez 2022-11-16 10:40:06 -06:00
parent 3c949b432d
commit 36cbb49c33
3 changed files with 72 additions and 2 deletions

View File

@ -27,6 +27,8 @@ import {getIconFromType, isImage} from '../rce/plugins/shared/fileTypeUtils'
import {showFlashError} from '../common/FlashAlert'
import natcompare from '../common/natcompare'
export const PENDING_MEDIA_ENTRY_ID = 'maybe'
class FileBrowser extends React.Component {
static propTypes = {
allowUpload: PropTypes.bool,
@ -291,10 +293,12 @@ class FileBrowser extends React.Component {
formatFileInfo(apiFile, opts = {}) {
const {collections} = this.state
const context = collections[apiFile.folderId].context
const isMediaPending = apiFile.mediaEntryId === PENDING_MEDIA_ENTRY_ID
const file = {
api: apiFile,
id: apiFile.id,
name: apiFile.name,
isDisabled: isMediaPending,
src: `${context}/files/${apiFile.id}/preview${
context.includes('user') ? `?verifier=${apiFile.uuid}` : ''
}`,
@ -305,6 +309,9 @@ class FileBrowser extends React.Component {
// it's a media_object
file.src = apiFile.iframeUrl
}
if (isMediaPending) {
file.descriptor = formatMessage('Media file is processing. Please try again later.')
}
return file
}
@ -348,7 +355,10 @@ class FileBrowser extends React.Component {
}
onFileClick = file => {
this.props.selectFile(this.state.items[file.id])
const selectedItem = this.state.items[file.id]
if (selectedItem.isDisabled) return
this.props.selectFile(selectedItem)
}
findFolderForFile(file) {

View File

@ -75,6 +75,42 @@ describe('FileBrowser', () => {
expect(file).toBeInTheDocument()
})
describe('when a media file is still processing', () => {
it('the view contains the file name and a "media ... processing..." message', async () => {
const {getByText} = subject(props)
const folder = await waitFor(() => getByText('My files'))
fireEvent.click(folder)
const mediaProcessingMessage = await waitFor(() =>
getByText('Media file is processing. Please try again later.')
)
const pendingMediaFileName = await waitFor(() => getByText('im-still-pending.mp4'))
expect(mediaProcessingMessage).toBeInTheDocument()
expect(pendingMediaFileName).toBeInTheDocument()
})
it('clicking on the file does not invoke "selectFile"', async () => {
const {getByText} = subject(props)
const folder = await waitFor(() => getByText('My files'))
fireEvent.click(folder)
const pendingMediaFileName = await waitFor(() => getByText('im-still-pending.mp4'))
fireEvent.click(pendingMediaFileName)
expect(props.selectFile).not.toHaveBeenCalled()
})
})
describe('when file is an Icon Maker icon', () => {
it('clicking on the file invokes "selectFile"', async () => {
const {getByText} = subject(props)
const folder = await waitFor(() => getByText('My files'))
fireEvent.click(folder)
const iconMakerFile = await waitFor(() => getByText('icon-maker-icon.svg'))
expect(iconMakerFile).toBeInTheDocument()
fireEvent.click(iconMakerFile)
expect(props.selectFile).toHaveBeenCalled()
})
})
describe('when "useContextAssets" is true', () => {
beforeEach(() => (props = defaultProps({useContextAssets: true})))

View File

@ -16,6 +16,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import {PENDING_MEDIA_ENTRY_ID} from '../FileBrowser'
const folderFor = (context, overrides, bookmark) => {
const id = overrides?.id || 26
return {
@ -131,6 +133,29 @@ const filesFor = (folder, overrides, bookmark) => ({
folderId: folder.id,
...overrides,
},
{
id: 181,
uuid: 'JEI31pWCjvr1yK3xOT0pwLUGnzxTQ0HEVjiCKqhQ',
type: 'audio/mp4',
name: 'im-still-pending.mp4',
url: 'http://canvas.docker/files/181/download?download_frd=1',
embed: {type: 'audio'},
folderId: folder.id,
mediaEntryId: PENDING_MEDIA_ENTRY_ID,
...overrides,
},
{
id: 182,
uuid: 'KEI31pWCjvr1yK3xOT0pwLUGnzxTQ0HEVjiCKqhQ',
type: 'image/svg+xml',
name: 'icon-maker-icon.svg',
url: 'http://canvas.docker/files/182/download?download_frd=1',
embed: {type: 'image'},
folderId: folder.id,
thumbnailUrl: 'http://canvas.docker/files/182/download?download_frd=1',
mediaEntryId: null,
...overrides,
},
],
bookmark,
})
@ -155,7 +180,6 @@ export const apiSource = () => ({
const filesFolder = folderFor({type: 'course', id: 1}).folders[0]
responseData = filesFor(filesFolder, {folderId: parseInt(folderId, 10)})
}
onSuccess(responseData)
return Promise.resolve(responseData)
}),