Move student view integration tests to new testing setup
Refs COMMS-2225 Test Plan: - Jenkins passes Change-Id: I7481b0a2fa3ee1e2bf592a99e341543d04059a37 Reviewed-on: https://gerrit.instructure.com/201626 Tested-by: Jenkins Reviewed-by: Steven Burnett <sburnett@instructure.com> QA-Review: Landon Gilbert-Bland <lbland@instructure.com> Product-Review: Landon Gilbert-Bland <lbland@instructure.com>
This commit is contained in:
parent
ee1fb516c1
commit
c25ce6445c
|
@ -17,26 +17,45 @@
|
||||||
*/
|
*/
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import * as uploadFileModule from '../../../shared/upload_file'
|
import * as uploadFileModule from '../../../shared/upload_file'
|
||||||
import {fireEvent, render, wait, waitForElement} from '@testing-library/react'
|
import {fireEvent, render, waitForElement} from '@testing-library/react'
|
||||||
|
import {CREATE_SUBMISSION_DRAFT} from '../graphqlData/Mutations'
|
||||||
|
import {createCache} from '../../../canvas-apollo'
|
||||||
import {MockedProvider} from 'react-apollo/test-utils'
|
import {MockedProvider} from 'react-apollo/test-utils'
|
||||||
|
import {mockQuery} from '../mocks'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {singleAttachment, submissionGraphqlMock} from '../test-utils'
|
import {STUDENT_VIEW_QUERY, SUBMISSION_ID_QUERY} from '../graphqlData/Queries'
|
||||||
import {STUDENT_VIEW_QUERY} from '../graphqlData/Queries'
|
|
||||||
import SubmissionIDQuery from '../components/SubmissionIDQuery'
|
import SubmissionIDQuery from '../components/SubmissionIDQuery'
|
||||||
|
|
||||||
let mocks
|
async function createGraphqlMocks(overrides = {}) {
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
query: SUBMISSION_ID_QUERY,
|
||||||
|
variables: {assignmentLid: '1'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
query: STUDENT_VIEW_QUERY,
|
||||||
|
variables: {assignmentLid: '1', submissionID: '1'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
query: CREATE_SUBMISSION_DRAFT,
|
||||||
|
variables: {id: '1', attempt: 0, fileIds: ['1']}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const mockResults = await Promise.all(
|
||||||
|
mocks.map(async ({query, variables}) => {
|
||||||
|
const result = await mockQuery(query, overrides, variables)
|
||||||
|
return {
|
||||||
|
request: {query, variables},
|
||||||
|
result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return mockResults
|
||||||
|
}
|
||||||
|
|
||||||
describe('SubmissionIDQuery', () => {
|
describe('SubmissionIDQuery', () => {
|
||||||
beforeAll(() => {
|
|
||||||
window.URL.createObjectURL = jest.fn()
|
|
||||||
uploadFileModule.uploadFiles = jest.fn()
|
|
||||||
$('body').append('<div role="alert" id="flash_screenreader_holder" />')
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = submissionGraphqlMock()
|
|
||||||
mocks[2].result.data.assignment.submissionsConnection.nodes[0].state = 'unsubmitted'
|
|
||||||
|
|
||||||
window.ENV = {
|
window.ENV = {
|
||||||
context_asset_string: 'test_1',
|
context_asset_string: 'test_1',
|
||||||
COURSE_ID: '1',
|
COURSE_ID: '1',
|
||||||
|
@ -45,18 +64,12 @@ describe('SubmissionIDQuery', () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const uploadFiles = (element, files) => {
|
// TODO: These three tests could be moved to the SubmissionIDQuery unit test file
|
||||||
fireEvent.change(element, {
|
|
||||||
target: {
|
|
||||||
files
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
it('renders normally', async () => {
|
it('renders normally', async () => {
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
const {getByTestId} = render(
|
const {getByTestId} = render(
|
||||||
<MockedProvider mocks={mocks} removeTypename addTypename>
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
<SubmissionIDQuery assignmentLid="1" />
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
)
|
)
|
||||||
expect(
|
expect(
|
||||||
|
@ -65,155 +78,54 @@ describe('SubmissionIDQuery', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders loading', async () => {
|
it('renders loading', async () => {
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
const {getByTitle} = render(
|
const {getByTitle} = render(
|
||||||
<MockedProvider mocks={mocks} removeTypename addTypename>
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
<SubmissionIDQuery assignmentLid="1" />
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(getByTitle('Loading')).toBeInTheDocument()
|
expect(getByTitle('Loading')).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
|
||||||
// We have to do all these tests from this root component so that the apollo
|
|
||||||
// cache is actually populated for the components that are needed. Not ideal,
|
|
||||||
// maybe we could circle back later and find an easier way to handle these.
|
|
||||||
|
|
||||||
it('displays uploaded files', async () => {
|
|
||||||
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
|
||||||
|
|
||||||
const {container, getAllByText} = render(
|
|
||||||
<MockedProvider mocks={mocks} addTypename>
|
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
|
||||||
</MockedProvider>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileInput = await waitForElement(() =>
|
|
||||||
container.querySelector('input[id="inputFileDrop"]')
|
|
||||||
)
|
|
||||||
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
|
||||||
uploadFiles(fileInput, [file])
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await waitForElement(() => getAllByText(singleAttachment().displayName)[0])
|
|
||||||
).toBeInTheDocument()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('notifies SR users when an attachment has been uploaded', async () => {
|
|
||||||
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
|
||||||
|
|
||||||
const {getByTestId, getByText} = render(
|
|
||||||
<MockedProvider mocks={mocks} addTypename>
|
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
|
||||||
</MockedProvider>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileInput = await waitForElement(() => getByTestId('input-file-drop'))
|
|
||||||
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
|
||||||
uploadFiles(fileInput, [file])
|
|
||||||
|
|
||||||
await wait(() => {
|
|
||||||
expect(getByText('Submission draft updated')).toBeInTheDocument()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('notifies users of error when attachments fail to upload in the API', async () => {
|
|
||||||
uploadFileModule.uploadFiles.mock.results = [
|
|
||||||
{type: 'throw', value: 'Error uploading file to Canvas API'}
|
|
||||||
]
|
|
||||||
|
|
||||||
const {getByTestId, getAllByText} = render(
|
|
||||||
<MockedProvider mocks={mocks} addTypename>
|
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
|
||||||
</MockedProvider>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileInput = await waitForElement(() => getByTestId('input-file-drop'))
|
|
||||||
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
|
||||||
uploadFiles(fileInput, [file])
|
|
||||||
|
|
||||||
await wait(() => {
|
|
||||||
expect(getAllByText('Error updating submission draft')[0]).toBeInTheDocument()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('notifies users of error when a submission fails to upload via graphql', async () => {
|
|
||||||
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
|
||||||
|
|
||||||
mocks[0].error = new Error('aw shucks')
|
|
||||||
const {getByTestId, getAllByText} = render(
|
|
||||||
<MockedProvider defaultOptions={{mutate: {errorPolicy: 'all'}}} mocks={mocks} addTypename>
|
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
|
||||||
</MockedProvider>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileInput = await waitForElement(() => getByTestId('input-file-drop'))
|
|
||||||
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
|
||||||
uploadFiles(fileInput, [file])
|
|
||||||
|
|
||||||
await wait(() => {
|
|
||||||
expect(getAllByText('Error updating submission draft')[0]).toBeInTheDocument()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('notifies SR users when a submission has been sent', async () => {
|
|
||||||
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
|
||||||
|
|
||||||
const {getByTestId, getByText} = render(
|
|
||||||
<MockedProvider mocks={mocks} addTypename>
|
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
|
||||||
</MockedProvider>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileInput = await waitForElement(() => getByTestId('input-file-drop'))
|
|
||||||
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
|
||||||
uploadFiles(fileInput, [file])
|
|
||||||
|
|
||||||
const submitButton = await waitForElement(() => getByTestId('submit-button'))
|
|
||||||
fireEvent.click(submitButton)
|
|
||||||
await wait(() => {
|
|
||||||
expect(getByText('Submission sent')).toBeInTheDocument()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('notifies users of error when a submission fails to send via graphql', async () => {
|
|
||||||
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
|
||||||
|
|
||||||
mocks[1].error = new Error('aw shucks')
|
|
||||||
const {getByTestId, getAllByText} = render(
|
|
||||||
<MockedProvider defaultOptions={{mutate: {errorPolicy: 'all'}}} mocks={mocks} addTypename>
|
|
||||||
<SubmissionIDQuery assignmentLid="22" />
|
|
||||||
</MockedProvider>
|
|
||||||
)
|
|
||||||
|
|
||||||
const fileInput = await waitForElement(() => getByTestId('input-file-drop'))
|
|
||||||
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
|
||||||
uploadFiles(fileInput, [file])
|
|
||||||
|
|
||||||
const submitButton = await waitForElement(() => getByTestId('submit-button'))
|
|
||||||
fireEvent.click(submitButton)
|
|
||||||
await wait(() => {
|
|
||||||
expect(getAllByText('Error sending submission')[0]).toBeInTheDocument()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('renders error', async () => {
|
it('renders error', async () => {
|
||||||
const errorMock = [
|
const mocks = await createGraphqlMocks()
|
||||||
{
|
mocks[1].error = new Error('aw shucks')
|
||||||
request: {
|
|
||||||
query: STUDENT_VIEW_QUERY,
|
|
||||||
variables: {
|
|
||||||
assignmentLid: '7'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: new Error('aw shucks')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
const {getByText} = render(
|
const {getByText} = render(
|
||||||
<MockedProvider mocks={errorMock} removeTypename addTypename>
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
<SubmissionIDQuery assignmentLid="7" />
|
<SubmissionIDQuery assignmentLid="1" />
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(await waitForElement(() => getByText('Sorry, Something Broke'))).toBeInTheDocument()
|
expect(await waitForElement(() => getByText('Sorry, Something Broke'))).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// This cannot be tested at the <AttemptTab> because the new file being
|
||||||
|
// displayed happens as a result of a cache write and these higher level
|
||||||
|
// components re-rendering
|
||||||
|
it('displays the new file after it has been uploaded', async () => {
|
||||||
|
window.URL.createObjectURL = jest.fn()
|
||||||
|
uploadFileModule.uploadFiles = jest.fn()
|
||||||
|
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
||||||
|
$('body').append('<div role="alert" id="flash_screenreader_holder" />')
|
||||||
|
|
||||||
|
const mocks = await createGraphqlMocks({
|
||||||
|
CreateSubmissionDraftPayload: () => ({
|
||||||
|
submissionDraft: () => ({attachments: [{displayName: 'test.jpg'}]})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const {container, getAllByText} = render(
|
||||||
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
|
<SubmissionIDQuery assignmentLid="1" />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const files = [new File(['foo'], 'file1.jpg', {type: 'image/jpg'})]
|
||||||
|
const fileInput = await waitForElement(() =>
|
||||||
|
container.querySelector('input[id="inputFileDrop"]')
|
||||||
|
)
|
||||||
|
fireEvent.change(fileInput, {target: {files}})
|
||||||
|
expect(await waitForElement(() => getAllByText('test.jpg')[0])).toBeInTheDocument()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default class AttemptTab extends Component {
|
||||||
|
|
||||||
cache.writeQuery({
|
cache.writeQuery({
|
||||||
query: STUDENT_VIEW_QUERY,
|
query: STUDENT_VIEW_QUERY,
|
||||||
variables: {assignmentLid: this.props.assignment._id},
|
variables: {assignmentLid: this.props.assignment._id, submissionID: this.props.submission.id},
|
||||||
data: {assignment}
|
data: {assignment}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ export default class AttemptTab extends Component {
|
||||||
|
|
||||||
if (this.state.submissionState === 'error') {
|
if (this.state.submissionState === 'error') {
|
||||||
errorMessage = I18n.t('Error sending submission')
|
errorMessage = I18n.t('Error sending submission')
|
||||||
} else if (this.state.uploadState === 'success') {
|
} else if (this.state.submissionState === 'success') {
|
||||||
successMessage = I18n.t('Submission sent')
|
successMessage = I18n.t('Submission sent')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,52 +16,72 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import $ from 'jquery'
|
||||||
|
import * as uploadFileModule from '../../../../shared/upload_file'
|
||||||
import AttemptTab from '../AttemptTab'
|
import AttemptTab from '../AttemptTab'
|
||||||
import {mockAssignment, mockSubmission, submissionGraphqlMock} from '../../test-utils'
|
import {CREATE_SUBMISSION, CREATE_SUBMISSION_DRAFT} from '../../graphqlData/Mutations'
|
||||||
|
import {createCache} from '../../../../canvas-apollo'
|
||||||
|
import {fireEvent, render, wait, waitForElement} from '@testing-library/react'
|
||||||
|
import {mockAssignmentAndSubmission, mockQuery} from '../../mocks'
|
||||||
import {MockedProvider} from 'react-apollo/test-utils'
|
import {MockedProvider} from 'react-apollo/test-utils'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {render} from '@testing-library/react'
|
import {STUDENT_VIEW_QUERY} from '../../graphqlData/Queries'
|
||||||
|
import {SubmissionMocks} from '../../graphqlData/Submission'
|
||||||
|
|
||||||
|
async function preloadCache() {
|
||||||
|
const variables = {assignmentLid: '1', submissionID: '1'}
|
||||||
|
const result = await mockQuery(STUDENT_VIEW_QUERY, {}, variables)
|
||||||
|
const cache = createCache()
|
||||||
|
cache.writeQuery({
|
||||||
|
query: STUDENT_VIEW_QUERY,
|
||||||
|
variables,
|
||||||
|
data: result.data
|
||||||
|
})
|
||||||
|
return cache
|
||||||
|
}
|
||||||
|
|
||||||
describe('ContentTabs', () => {
|
describe('ContentTabs', () => {
|
||||||
describe('the submission type is online_upload', () => {
|
describe('the submission type is online_upload', () => {
|
||||||
const mockedAssignment = mockAssignment({
|
it('renders the file upload tab when the submission is unsubmitted', async () => {
|
||||||
submissionTypes: ['online_upload']
|
const props = await mockAssignmentAndSubmission({
|
||||||
})
|
Assignment: () => ({submissionTypes: ['online_upload']})
|
||||||
|
|
||||||
it('renders the file upload tab when the submission is unsubmitted', () => {
|
|
||||||
const mockedSubmission = mockSubmission({
|
|
||||||
state: 'unsubmitted'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const {getByTestId} = render(
|
const {getByTestId} = render(
|
||||||
<MockedProvider mocks={submissionGraphqlMock()} addTypename>
|
<MockedProvider>
|
||||||
<AttemptTab assignment={mockedAssignment} submission={mockedSubmission} />
|
<AttemptTab {...props} />
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(getByTestId('upload-pane')).toBeInTheDocument()
|
expect(getByTestId('upload-pane')).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders the file preview tab when the submission is submitted', () => {
|
it('renders the file preview tab when the submission is submitted', async () => {
|
||||||
|
const props = await mockAssignmentAndSubmission({
|
||||||
|
Assignment: () => ({submissionTypes: ['online_upload']}),
|
||||||
|
Submission: () => ({
|
||||||
|
...SubmissionMocks.submitted,
|
||||||
|
attachments: [{}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const {getByTestId} = render(
|
const {getByTestId} = render(
|
||||||
<MockedProvider mocks={submissionGraphqlMock()} addTypename>
|
<MockedProvider>
|
||||||
<AttemptTab assignment={mockedAssignment} submission={mockSubmission()} />
|
<AttemptTab {...props} />
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(getByTestId('assignments_2_submission_preview')).toBeInTheDocument()
|
expect(getByTestId('assignments_2_submission_preview')).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('the submission type is online_text_entry', () => {
|
describe('the submission type is online_text_entry', () => {
|
||||||
const mockedAssignment = mockAssignment({
|
it('renders the text entry tab', async () => {
|
||||||
submissionTypes: ['online_text_entry']
|
const props = await mockAssignmentAndSubmission({
|
||||||
})
|
Assignment: () => ({submissionTypes: ['online_text_entry']})
|
||||||
|
})
|
||||||
|
|
||||||
it('renders the text entry tab', () => {
|
|
||||||
const {getByTestId} = render(
|
const {getByTestId} = render(
|
||||||
<MockedProvider mocks={submissionGraphqlMock()} addTypename>
|
<MockedProvider>
|
||||||
<AttemptTab assignment={mockedAssignment} submission={mockSubmission()} />
|
<AttemptTab {...props} />
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -69,3 +89,178 @@ describe('ContentTabs', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Submitting an assignment', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
$('body').append('<div role="alert" id="flash_screenreader_holder" />')
|
||||||
|
})
|
||||||
|
|
||||||
|
const createGraphqlMocks = async () => {
|
||||||
|
const variables = {
|
||||||
|
assignmentLid: '1',
|
||||||
|
fileIds: ['1'],
|
||||||
|
submissionID: '1',
|
||||||
|
type: 'online_upload'
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockedResults = await mockQuery(CREATE_SUBMISSION, {}, variables)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: CREATE_SUBMISSION,
|
||||||
|
variables
|
||||||
|
},
|
||||||
|
result: mockedResults
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
it('notifies SR users when an assignment is submitted', async () => {
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
|
const props = await mockAssignmentAndSubmission({
|
||||||
|
Submission: () => SubmissionMocks.draftWithAttachment,
|
||||||
|
File: () => ({_id: '1'})
|
||||||
|
})
|
||||||
|
const {getByTestId, getByText} = render(
|
||||||
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
|
<AttemptTab {...props} />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const submitButton = getByTestId('submit-button')
|
||||||
|
fireEvent.click(submitButton)
|
||||||
|
await wait(() => {
|
||||||
|
expect(getByText('Submission sent')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error when an assignment fails to be submitted', async () => {
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
|
const props = await mockAssignmentAndSubmission({
|
||||||
|
Submission: () => SubmissionMocks.draftWithAttachment,
|
||||||
|
File: () => ({_id: '1'})
|
||||||
|
})
|
||||||
|
mocks[0].error = new Error('aw shucks')
|
||||||
|
const {getByTestId, getAllByText} = render(
|
||||||
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
|
<AttemptTab {...props} />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const submitButton = getByTestId('submit-button')
|
||||||
|
fireEvent.click(submitButton)
|
||||||
|
await wait(() => {
|
||||||
|
expect(getAllByText('Error sending submission')[0]).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Uploading a file', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
$('body').append('<div role="alert" id="flash_screenreader_holder" />')
|
||||||
|
uploadFileModule.uploadFiles = jest.fn()
|
||||||
|
window.URL.createObjectURL = jest.fn()
|
||||||
|
})
|
||||||
|
|
||||||
|
const uploadFiles = (element, files) => {
|
||||||
|
fireEvent.change(element, {
|
||||||
|
target: {
|
||||||
|
files
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const createGraphqlMocks = async () => {
|
||||||
|
const variables = {id: '1', attempt: 0, fileIds: ['1']}
|
||||||
|
const mockedResults = await mockQuery(CREATE_SUBMISSION_DRAFT, {}, variables)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: CREATE_SUBMISSION_DRAFT,
|
||||||
|
variables
|
||||||
|
},
|
||||||
|
result: mockedResults
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
it('shows an error when creating a new SubmissionDraft fails', async () => {
|
||||||
|
const props = await mockAssignmentAndSubmission()
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
|
mocks[0].error = new Error('aw shucks')
|
||||||
|
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
||||||
|
|
||||||
|
const {getByTestId, getAllByText} = render(
|
||||||
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
|
<AttemptTab {...props} />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const fileInput = getByTestId('input-file-drop')
|
||||||
|
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
||||||
|
uploadFiles(fileInput, [file])
|
||||||
|
|
||||||
|
await wait(() => {
|
||||||
|
expect(getAllByText('Error updating submission draft')[0]).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows an error when uploading a file fails', async () => {
|
||||||
|
const props = await mockAssignmentAndSubmission()
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
|
uploadFileModule.uploadFiles.mock.results = [
|
||||||
|
{type: 'throw', value: 'Error uploading file to Canvas API'}
|
||||||
|
]
|
||||||
|
|
||||||
|
const {getByTestId, getAllByText} = render(
|
||||||
|
<MockedProvider mocks={mocks} cache={createCache()}>
|
||||||
|
<AttemptTab {...props} />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const fileInput = getByTestId('input-file-drop')
|
||||||
|
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
||||||
|
uploadFiles(fileInput, [file])
|
||||||
|
|
||||||
|
await wait(() => {
|
||||||
|
expect(getAllByText('Error updating submission draft')[0]).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('notifies SR users when a submission draft has been saved', async () => {
|
||||||
|
const cache = await preloadCache()
|
||||||
|
const props = await mockAssignmentAndSubmission()
|
||||||
|
const mocks = await createGraphqlMocks()
|
||||||
|
uploadFileModule.uploadFiles.mockReturnValueOnce([{id: '1', name: 'file1.jpg'}])
|
||||||
|
|
||||||
|
const {getByTestId, getByText} = render(
|
||||||
|
<MockedProvider mocks={mocks} cache={cache}>
|
||||||
|
<AttemptTab {...props} />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const fileInput = getByTestId('input-file-drop')
|
||||||
|
const file = new File(['foo'], 'file1.jpg', {type: 'image/jpg'})
|
||||||
|
uploadFiles(fileInput, [file])
|
||||||
|
|
||||||
|
await wait(() => {
|
||||||
|
expect(getByText('Submission draft updated')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows a file preview for an uploaded file', async () => {
|
||||||
|
const props = await mockAssignmentAndSubmission({
|
||||||
|
Submission: () => ({
|
||||||
|
submissionDraft: {
|
||||||
|
attachments: [{displayName: 'test.jpg'}]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const {getAllByText} = render(
|
||||||
|
<MockedProvider cache={createCache()}>
|
||||||
|
<AttemptTab {...props} />
|
||||||
|
</MockedProvider>
|
||||||
|
)
|
||||||
|
expect(await waitForElement(() => getAllByText('test.jpg')[0])).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
|
@ -15,16 +15,8 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License along
|
* You should have received a copy of the GNU Affero General Public License along
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {
|
import {CREATE_SUBMISSION_COMMENT} from './graphqlData/Mutations'
|
||||||
STUDENT_VIEW_QUERY,
|
import {SUBMISSION_COMMENT_QUERY} from './graphqlData/Queries'
|
||||||
SUBMISSION_COMMENT_QUERY,
|
|
||||||
SUBMISSION_ID_QUERY
|
|
||||||
} from './graphqlData/Queries'
|
|
||||||
import {
|
|
||||||
CREATE_SUBMISSION,
|
|
||||||
CREATE_SUBMISSION_COMMENT,
|
|
||||||
CREATE_SUBMISSION_DRAFT
|
|
||||||
} from './graphqlData/Mutations'
|
|
||||||
|
|
||||||
export function mockAssignment(overrides = {}) {
|
export function mockAssignment(overrides = {}) {
|
||||||
return {
|
return {
|
||||||
|
@ -278,102 +270,6 @@ export function mockGraphqlQueryResults(overrides = {}) {
|
||||||
return assignment
|
return assignment
|
||||||
}
|
}
|
||||||
|
|
||||||
export function submissionGraphqlMock() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
request: {
|
|
||||||
query: CREATE_SUBMISSION_DRAFT,
|
|
||||||
variables: {
|
|
||||||
id: mockSubmission().id,
|
|
||||||
attempt: 1,
|
|
||||||
fileIds: ['1']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
createSubmissionDraft: {
|
|
||||||
submissionDraft: {
|
|
||||||
__typename: 'SubmissionDraft',
|
|
||||||
_id: '22',
|
|
||||||
attachments: [singleAttachment({_id: '1'})]
|
|
||||||
},
|
|
||||||
errors: {
|
|
||||||
attribute: null,
|
|
||||||
message: null,
|
|
||||||
__typename: 'Errors'
|
|
||||||
},
|
|
||||||
__typename: 'CreateSubmissionDraftPayload'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
request: {
|
|
||||||
query: CREATE_SUBMISSION,
|
|
||||||
variables: {
|
|
||||||
assignmentLid: '22',
|
|
||||||
submissionID: mockSubmission().id,
|
|
||||||
type: 'online_upload',
|
|
||||||
fileIds: ['1']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
createSubmission: {
|
|
||||||
submission: mockSubmission(),
|
|
||||||
errors: {
|
|
||||||
attribute: null,
|
|
||||||
message: null,
|
|
||||||
__typename: 'Errors'
|
|
||||||
},
|
|
||||||
__typename: 'CreateSubmissionPayload'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
request: {
|
|
||||||
query: STUDENT_VIEW_QUERY,
|
|
||||||
variables: {
|
|
||||||
assignmentLid: '22',
|
|
||||||
submissionID: mockSubmission().id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
assignment: mockGraphqlQueryResults({
|
|
||||||
lockInfo: {isLocked: false, __typename: 'LockInfo'}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
request: {
|
|
||||||
query: SUBMISSION_ID_QUERY,
|
|
||||||
variables: {
|
|
||||||
assignmentLid: '22'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: {
|
|
||||||
assignment: {
|
|
||||||
submissionsConnection: {
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
id: mockSubmission().id,
|
|
||||||
__typename: 'Submission'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
__typename: 'SubmissionConnection'
|
|
||||||
},
|
|
||||||
__typename: 'Assignment'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mockSubmission(overrides = {}) {
|
export function mockSubmission(overrides = {}) {
|
||||||
return {
|
return {
|
||||||
attachments: mockMultipleAttachments(),
|
attachments: mockMultipleAttachments(),
|
||||||
|
|
|
@ -57,15 +57,18 @@ function createHttpLink() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function createClient(opts = {}) {
|
function createCache() {
|
||||||
const cache = new InMemoryCache({
|
return new InMemoryCache({
|
||||||
addTypename: true,
|
addTypename: true,
|
||||||
dataIdFromObject: object => object.id || null,
|
dataIdFromObject: object => object.id || null,
|
||||||
fragmentMatcher: new IntrospectionFragmentMatcher({
|
fragmentMatcher: new IntrospectionFragmentMatcher({
|
||||||
introspectionQueryResultData
|
introspectionQueryResultData
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function createClient(opts = {}) {
|
||||||
|
const cache = createCache()
|
||||||
const defaults = opts.defaults || {}
|
const defaults = opts.defaults || {}
|
||||||
const resolvers = opts.resolvers || {}
|
const resolvers = opts.resolvers || {}
|
||||||
const stateLink = withClientState({
|
const stateLink = withClientState({
|
||||||
|
@ -87,4 +90,4 @@ function createClient(opts = {}) {
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
export {createClient, gql, ApolloProvider, Query}
|
export {createClient, gql, ApolloProvider, Query, createCache}
|
||||||
|
|
Loading…
Reference in New Issue