diff --git a/app/jsx/content_shares/ReceivedTable.js b/app/jsx/content_shares/ReceivedTable.js index 3288f3b4e94..4eefec50c62 100644 --- a/app/jsx/content_shares/ReceivedTable.js +++ b/app/jsx/content_shares/ReceivedTable.js @@ -49,6 +49,24 @@ ReceivedTable.propTypes = { export default function ReceivedTable({shares, onPreview, onImport, onRemove, onUpdate}) { function renderActionMenu(share) { + const items = [] + if (share.content_export?.workflow_state === 'exported') { + items.push( + onPreview(share)}> + {I18n.t('Preview')} + + ) + items.push( + onImport(share)}> + {I18n.t('Import')} + + ) + } + items.push( + onRemove(share)}> + {I18n.t('Remove')} + + ) return ( } > - onPreview(share)}> - {I18n.t('Preview')} - - onImport(share)}> - {I18n.t('Import')} - - onRemove(share)}> - {I18n.t('Remove')} - + {items} ) } @@ -137,6 +147,28 @@ export default function ReceivedTable({shares, onPreview, onImport, onRemove, on } } + function renderReceivedColumn(content_export) { + if (content_export && content_export.workflow_state === 'exported') { + return + } else if ( + !content_export || + content_export.workflow_state === 'failed' || + content_export.workflow_state === 'deleted' + ) { + return ( + + {I18n.t('Failed')} + + ) + } else { + return ( + + {I18n.t('Pending')} + + ) + } + } + function renderRow(share) { return ( @@ -155,9 +187,7 @@ export default function ReceivedTable({shares, onPreview, onImport, onRemove, on />{' '} {share.sender.display_name} - - - + {renderReceivedColumn(share.content_export)} {renderActionMenu(share)} ) diff --git a/app/jsx/content_shares/__tests__/ReceivedTable.test.js b/app/jsx/content_shares/__tests__/ReceivedTable.test.js index f6edcb058a8..926896f660c 100644 --- a/app/jsx/content_shares/__tests__/ReceivedTable.test.js +++ b/app/jsx/content_shares/__tests__/ReceivedTable.test.js @@ -20,6 +20,7 @@ import React from 'react' import {fireEvent, render} from '@testing-library/react' import ReceivedTable from 'jsx/content_shares/ReceivedTable' import { + mockShare, assignmentShare, readDiscussionShare, unreadDiscussionShare @@ -123,4 +124,26 @@ describe('content shares table', () => { fireEvent.click(getByText('Remove')) expect(onRemove).toHaveBeenCalledWith(assignmentShare) }) + + it('handles a missing content_export', () => { + const brokenShare = mockShare({content_export: null}) + const {getByText, queryByText, queryByTestId} = render() + fireEvent.click(getByText(/manage options/i)) + expect(queryByText('Remove')).toBeInTheDocument() + expect(queryByText('Failed')).toBeInTheDocument() + expect(queryByTestId('import-menu-action')).not.toBeInTheDocument() + expect(queryByTestId('preview-menu-action')).not.toBeInTheDocument() + }) + + it('handles an incomplete content_export', () => { + const pendingShare = mockShare({content_export: {id: 4, workflow_state: 'exporting'}}) + const {getByText, queryByText, queryByTestId} = render( + + ) + fireEvent.click(getByText(/manage options/i)) + expect(queryByText('Remove')).toBeInTheDocument() + expect(queryByText('Pending')).toBeInTheDocument() + expect(queryByTestId('import-menu-action')).not.toBeInTheDocument() + expect(queryByTestId('preview-menu-action')).not.toBeInTheDocument() + }) }) diff --git a/app/jsx/content_shares/__tests__/test-utils.js b/app/jsx/content_shares/__tests__/test-utils.js index 884d1084b46..7fd6e4d6976 100644 --- a/app/jsx/content_shares/__tests__/test-utils.js +++ b/app/jsx/content_shares/__tests__/test-utils.js @@ -31,8 +31,11 @@ export function mockShare(overrides = {}) { read_state: 'read', content_export: { id: '3', + workflow_state: 'exported', + created_at: '2019-07-04T12:00:00Z', attachment: { id: '4', + created_at: '2019-07-04T12:00:00Z', url: 'https://attachment.url' } }, diff --git a/spec/selenium/admin/account_direct_share_import_spec.rb b/spec/selenium/admin/account_direct_share_import_spec.rb index af7213c39ee..c0d3c153234 100644 --- a/spec/selenium/admin/account_direct_share_import_spec.rb +++ b/spec/selenium/admin/account_direct_share_import_spec.rb @@ -37,16 +37,17 @@ describe "direct share page" do @assignment_1 = @course_1.assignments.create!(:title => 'Assignment First', :points_possible => 10) assignment_model(course: @course_1, name: 'assignment to share') @course_1.root_account.enable_feature!(:direct_share) - end - before :each do - @export_1 = @course_1.content_exports.create!(settings: {"selected_content" => {"assignments" => {CC::CCHelper.create_key(@assignment_1) => '1'}}}) - @export_2 = @course_1.content_exports.create!(settings: {"selected_content" => {"assignments" => {CC::CCHelper.create_key(@assignment_1) => '1'}}}) - @export_3 = @course_1.content_exports.create!(settings: {"selected_content" => {"assignments" => {CC::CCHelper.create_key(@assignment_1) => '1'}}}) + @export_1 = @course_1.content_exports.create!(workflow_state: 'exported', settings: {"selected_content" => {"assignments" => {CC::CCHelper.create_key(@assignment_1) => '1'}}}) + @export_2 = @course_1.content_exports.create!(workflow_state: 'exported', settings: {"selected_content" => {"assignments" => {CC::CCHelper.create_key(@assignment_1) => '1'}}}) + @export_3 = @course_1.content_exports.create!(workflow_state: 'exported', settings: {"selected_content" => {"assignments" => {CC::CCHelper.create_key(@assignment_1) => '1'}}}) @sent_share = @teacher_1.sent_content_shares.create! name: 'a-unread share1', content_export: @export_1, read_state: 'unread' @unread_share1 = @teacher_2.received_content_shares.create! name: 'a-unread share1', content_export: @export_1, sender: @teacher_1, read_state: 'unread' @unread_share2 = @teacher_2.received_content_shares.create! name: 'b-unread share2', content_export: @export_2, sender: @teacher_1, read_state: 'unread' @read_share = @teacher_2.received_content_shares.create! name: 'c-read share', content_export: @export_3, sender: @teacher_1, read_state: 'read' + end + + before :each do user_session @teacher_2 visit_content_share_page end