add pending_review to ungraded list

when modal "Message students who" is
opened and "Have not been graded" is
selected it should show quizzes where
workflow state is "pending_review"

fixes EVAL-3968
flag=message_observers_of_students_who

test plan:
- create a quiz with manual grading
- submit the quiz with an student
- cutoff the quiz
- go to the individual and classic gradebook
- open "Message students who" modal
- validate "Have not been graded" option
is showing the student

Change-Id: Ibb7a43a38a2e934bf2aa17c0ceac924a415e6061
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/345650
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Spencer Olson <solson@instructure.com>
QA-Review: Spencer Olson <solson@instructure.com>
Product-Review: Cameron Ray <cameron.ray@instructure.com>
This commit is contained in:
Sleyder Zuleta 2024-04-19 01:47:15 -05:00
parent 1dd2e5806c
commit 7ae1b2dac1
5 changed files with 94 additions and 4 deletions

View File

@ -80,6 +80,7 @@ export default function MessageStudentsWhoModal({
redoRequest: submission?.redoRequest,
score: submission?.score,
excused: submission?.excused,
workflowState: submission?.state,
})
return filteredStudents

View File

@ -113,6 +113,7 @@ export type SubmissionConnection = {
userId: string
gradingPeriodId?: string
excused?: boolean
state: string
}
export type Attachment = {

View File

@ -261,7 +261,8 @@ export default class AssignmentColumnHeader extends ColumnHeader<
.filter(student => !student.isInactive && !student.isTestStudent)
return activeStudents.map(student => {
const {excused, grade, latePolicyStatus, score, submittedAt, redoRequest} = student.submission
const {excused, grade, latePolicyStatus, score, submittedAt, redoRequest, workflowState} =
student.submission
return {
excused,
grade,
@ -272,6 +273,7 @@ export default class AssignmentColumnHeader extends ColumnHeader<
score,
sortableName: student.sortableName,
submittedAt,
workflowState,
}
})
}

View File

@ -90,6 +90,7 @@ export type Student = {
sortableName: string
submittedAt: null | Date
excused?: boolean
workflowState: string
}
export type Props = {
@ -242,12 +243,12 @@ function filterStudents(criterion, students, cutoff) {
}
break
case 'submitted_and_graded':
if (student.submittedAt && student.grade) {
if (student.submittedAt && student.grade && student.workflowState !== 'pending_review') {
newfilteredStudents.push(student)
}
break
case 'submitted_and_not_graded':
if (student.submittedAt && !student.grade) {
if (student.submittedAt && (!student.grade || student.workflowState === 'pending_review')) {
newfilteredStudents.push(student)
}
break
@ -262,7 +263,7 @@ function filterStudents(criterion, students, cutoff) {
}
break
case 'ungraded':
if (!student.grade && !student.excused) {
if ((!student.grade && !student.excused) || student.workflowState === 'pending_review') {
newfilteredStudents.push(student)
}
break

View File

@ -533,6 +533,91 @@ describe.skip('MessageStudentsWhoDialog', () => {
})
describe('"Have submitted"', () => {
it('renders a student cell if the student has workflowState pending_review and submittedAt', async () => {
const mocks = await makeMocks()
students[0].workflowState = 'pending_review'
students[0].submittedAt = new Date()
const {getByTestId, findByLabelText, getByText, getAllByRole, getByRole} = render(
<MockedProvider mocks={mocks} cache={createCache()}>
<MessageStudentsWhoDialog {...makeProps()} />
</MockedProvider>
)
const button = await findByLabelText(/For students who/)
fireEvent.click(button)
fireEvent.click(getByText(/Have submitted/))
// Select "All" radio button
fireEvent.click(getByTestId('all-students-radio-button'))
fireEvent.click(getByRole('button', {name: 'Show all recipients'}))
expect(getByRole('table')).toBeInTheDocument()
const tableRows = getAllByRole('row') as HTMLTableRowElement[]
const studentCells = tableRows.map(row => row.cells[0])
expect(studentCells).toHaveLength(2) // Header + 1 student
expect(studentCells[1]).toHaveTextContent('Betty Ford')
})
it('renders a student cell with workflowState pending_review when "Not Graded" radio button is selected', async () => {
const mocks = await makeMocks()
students[0].workflowState = 'pending_review'
students[0].submittedAt = new Date()
const {findByLabelText, getByText, getAllByRole, getByRole, getByTestId} = render(
<MockedProvider mocks={mocks} cache={createCache()}>
<MessageStudentsWhoDialog {...makeProps()} />
</MockedProvider>
)
const button = await findByLabelText(/For students who/)
fireEvent.click(button)
fireEvent.click(getByText(/Have submitted/))
// Select "Not Graded" radio button
fireEvent.click(getByTestId('not-graded-students-radio-button'))
fireEvent.click(getByRole('button', {name: 'Show all recipients'}))
expect(getByRole('table')).toBeInTheDocument()
const tableRows = getAllByRole('row') as HTMLTableRowElement[]
const studentCells = tableRows.map(row => row.cells[0])
expect(studentCells).toHaveLength(2) // Header + 1 student
expect(studentCells[1]).toHaveTextContent('Betty Ford')
})
it('renders a student cell if the student does not have workflowState pending_review and has a grade defined when "Graded" radio button is selected', async () => {
const mocks = await makeMocks()
students[0].workflowState = 'graded'
students[0].submittedAt = new Date()
students[0].grade = 'A'
const {findByLabelText, getByText, getAllByRole, getByRole, getByTestId} = render(
<MockedProvider mocks={mocks} cache={createCache()}>
<MessageStudentsWhoDialog {...makeProps()} />
</MockedProvider>
)
const button = await findByLabelText(/For students who/)
fireEvent.click(button)
fireEvent.click(getByText(/Have submitted/))
// Select "Graded" radio button
fireEvent.click(getByTestId('graded-students-radio-button'))
fireEvent.click(getByRole('button', {name: 'Show all recipients'}))
expect(getByRole('table')).toBeInTheDocument()
const tableRows = getAllByRole('row') as HTMLTableRowElement[]
const studentCells = tableRows.map(row => row.cells[0])
expect(studentCells).toHaveLength(2) // Header + 1 student
expect(studentCells[1]).toHaveTextContent('Betty Ford')
})
it('student radio buttons render when "Have submitted" option is selected', async () => {
const mocks = await makeMocks()