From 209719210c24fcfbfa00880caa97fe72dbbc047a Mon Sep 17 00:00:00 2001 From: Gary Mei Date: Wed, 22 May 2019 17:03:03 -0500 Subject: [PATCH] check graded status when determining hidden status The hidden count in the PostAssignmentGradesTray checks for lack of posted, but the rules for whether a grade is hidden should be if it has a grade, but is not posted. closes GRADE-2177 Test Plan - Create an assignment with a manual post policy. - Create an assignment with an automatic post policy. - For the manual assignment: - Grade a number of students. - Submit for a number of students. - Verify that the hidden count in the Post tray is the number of students that have grades. - Verify that those submissions have a Hidden pill in the Submission Tray and SpeedGrader. - Post all grades. - Verify that the hidden count is gone, the eye indicator in the column header is no longer orange, that the Submission Tray no longer contains the Hidden pill, and that SpeedGrader no longer contains the Hidden pill. - For the automatic assignment: - Grade a number of students. - Submit for a number of students. - Verify that nothing is currently hidden. - Hide grades for a subset of the students. - Verify that the hidden count in the Post tray is the number of students that were hidden for, that also had a grade. - Verify that those submissions have a Hidden pill in the Submission Tray and SpeedGrader. Change-Id: Iccc45b11fc356933db8082a739766b53b7c52494 Reviewed-on: https://gerrit.instructure.com/194836 Tested-by: Jenkins Product-Review: Jonathan Fenton Reviewed-by: Adrian Packel Reviewed-by: Derek Bender QA-Review: James Butters --- .../formatters/AssignmentCellFormatter.js | 7 +- .../headers/AssignmentColumnHeader.js | 6 +- .../headers/AssignmentColumnHeaderRenderer.js | 6 +- .../default_gradebook/PostPolicies/index.js | 13 ++- .../components/SubmissionStatus.js | 19 ++--- .../grading/PostAssignmentGradesTray/index.js | 4 +- app/jsx/grading/helpers/SubmissionHelper.js | 29 +++++++ app/jsx/speed_grader/PostPolicies/index.js | 8 +- public/javascripts/speed_grader.js | 16 ++-- .../formatters/AssignmentCellFormatterSpec.js | 6 ++ .../AssignmentColumnHeaderRendererSpec.js | 8 +- .../headers/AssignmentColumnHeaderSpec.js | 20 +++-- .../PostPolicies/PostPoliciesSpec.js | 8 +- .../components/SubmissionStatusSpec.js | 81 ++++++++----------- .../components/SubmissionTraySpec.js | 2 +- .../PostAssignmentGradesTraySpec.js | 17 ++-- .../grading/helpers/SubmissionHelperSpec.js | 61 ++++++++++++++ .../PostPolicies/PostPoliciesSpec.js | 8 +- spec/javascripts/jsx/speed_graderSpec.js | 20 ++++- 19 files changed, 232 insertions(+), 107 deletions(-) create mode 100644 app/jsx/grading/helpers/SubmissionHelper.js create mode 100644 spec/javascripts/jsx/grading/helpers/SubmissionHelperSpec.js diff --git a/app/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatter.js b/app/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatter.js index ca60290fa57..f35de9fab53 100644 --- a/app/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatter.js +++ b/app/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatter.js @@ -22,6 +22,7 @@ import I18n from 'i18n!gradezilla' import htmlEscape from 'str/htmlEscape' import {extractDataTurnitin} from 'compiled/gradezilla/Turnitin' import GradeFormatHelper from '../../../../gradebook/shared/helpers/GradeFormatHelper' +import {isHidden} from '../../../../grading/helpers/SubmissionHelper' import {classNamesForAssignmentCell} from './CellStyles' function getTurnitinState(submission) { @@ -134,7 +135,7 @@ export default class AssignmentCellFormatter { this.postPoliciesEnabled = gradebook.options.post_policies_enabled } - render = (row, cell, submission /* value */, columnDef, student /* dataContext */) => { + render = (_row, _cell, submission /* value */, columnDef, student /* dataContext */) => { let submissionState if (submission) { submissionState = this.options.getSubmissionState(submission) @@ -182,9 +183,7 @@ export default class AssignmentCellFormatter { } const showUnpostedIndicator = - columnDef.postAssignmentGradesTrayOpenForAssignmentId && - submission.workflow_state === 'graded' && - !submission.posted_at + columnDef.postAssignmentGradesTrayOpenForAssignmentId && isHidden(submission) const options = { classNames: classNamesForAssignmentCell(assignmentData, submissionData), diff --git a/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeader.js b/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeader.js index 61b79dffd70..43aaba1ee78 100644 --- a/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeader.js +++ b/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeader.js @@ -33,6 +33,7 @@ import Text from '@instructure/ui-elements/lib/components/Text' import 'message_students' import I18n from 'i18n!gradezilla' import ScreenReaderContent from '@instructure/ui-a11y/lib/components/ScreenReaderContent' +import {isHidden} from '../../../../grading/helpers/SubmissionHelper' import MessageStudentsWhoHelper from '../../../shared/helpers/messageStudentsWhoHelper' import ColumnHeader from './ColumnHeader' @@ -142,7 +143,8 @@ export default class AssignmentColumnHeader extends ColumnHeader { latePolicyStatus: string, postedAt: instanceOf(Date), score: number, - submittedAt: instanceOf(Date) + submittedAt: instanceOf(Date), + workflowState: string.isRequired }).isRequired }) ).isRequired, @@ -473,7 +475,7 @@ export default class AssignmentColumnHeader extends ColumnHeader { const submissions = this.props.students.map(student => student.submission) const postableSubmissionsPresent = submissions.some( - submission => submission.score != null && submission.postedAt == null + submission => isHidden(submission) ) // Assignment is manually-posted and has no graded-but-unposted submissions diff --git a/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer.js b/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer.js index cd16bae1ae4..a8a10d904ba 100644 --- a/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer.js +++ b/app/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer.js @@ -18,6 +18,7 @@ import React from 'react' import ReactDOM from 'react-dom' +import {isHidden} from '../../../../grading/helpers/SubmissionHelper' import {optionsForGradingType} from '../../../shared/EnterGradesAsSetting' import AssignmentColumnHeader from './AssignmentColumnHeader' @@ -33,7 +34,8 @@ function getSubmission(student, assignmentId) { latePolicyStatus: submission.late_policy_status, postedAt: submission.posted_at, score: submission.score, - submittedAt: submission.submitted_at + submittedAt: submission.submitted_at, + workflowState: submission.workflow_state } } @@ -109,7 +111,7 @@ function getProps(column, gradebook, options) { postGradesAction: { featureEnabled: gradebook.postPolicies != null, - hasGradesToPost: students.some(student => student.submission.postedAt == null), + hasGradesToPost: students.some(student => isHidden(student.submission)), onSelect(onExited) { if (gradebook.postPolicies) { gradebook.postPolicies.showPostAssignmentGradesTray({assignmentId, onExited}) diff --git a/app/jsx/gradezilla/default_gradebook/PostPolicies/index.js b/app/jsx/gradezilla/default_gradebook/PostPolicies/index.js index 9bba063e47b..bdc21166fab 100644 --- a/app/jsx/gradezilla/default_gradebook/PostPolicies/index.js +++ b/app/jsx/gradezilla/default_gradebook/PostPolicies/index.js @@ -25,8 +25,17 @@ import HideAssignmentGradesTray from '../../../grading/HideAssignmentGradesTray' import PostAssignmentGradesTray from '../../../grading/PostAssignmentGradesTray' function getSubmission(student, assignmentId) { - const submission = student[`assignment_${assignmentId}`] || {posted_at: null} - return {postedAt: submission.posted_at} + const submission = student[`assignment_${assignmentId}`] || { + posted_at: null, + score: null, + workflow_state: null + } + + return { + postedAt: submission.posted_at, + score: submission.score, + workflowState: submission.workflow_state + } } export default class PostPolicies { diff --git a/app/jsx/gradezilla/default_gradebook/components/SubmissionStatus.js b/app/jsx/gradezilla/default_gradebook/components/SubmissionStatus.js index 45f0ee4768b..0c68f746108 100644 --- a/app/jsx/gradezilla/default_gradebook/components/SubmissionStatus.js +++ b/app/jsx/gradezilla/default_gradebook/components/SubmissionStatus.js @@ -17,11 +17,12 @@ */ import React from 'react' -import {bool, shape, string} from 'prop-types' +import {bool, instanceOf, number, shape, string} from 'prop-types' import I18n from 'i18n!gradezilla' import View from '@instructure/ui-layout/lib/components/View' import Pill from '@instructure/ui-elements/lib/components/Pill' import Message from './SubmissionStatus/Message' +import {isHidden} from '../../../grading/helpers/SubmissionHelper' export default class SubmissionStatus extends React.Component { static defaultProps = { @@ -44,9 +45,10 @@ export default class SubmissionStatus extends React.Component { postPoliciesEnabled: bool.isRequired, submission: shape({ drop: bool, - gradedAt: string, excused: bool, - postedAt: string + postedAt: instanceOf(Date), + score: number, + workflowState: string.isRequired }).isRequired } @@ -55,16 +57,7 @@ export default class SubmissionStatus extends React.Component { const statusPillComponents = [] if (postPoliciesEnabled) { - // Show the "hidden" pill if: - // - Manual posting is enabled and the submission is not posted (graded or not) - // - Auto-posting is enabled and the submission is graded but not posted - // (this means it's been manually hidden) - const showPill = - submission && - !submission.postedAt && - (assignment.postManually || submission.gradedAt != null) - - if (showPill) { + if (isHidden(submission)) { statusPillComponents.push( submission.postedAt == null).length if (!assignment) { return null } + const unpostedCount = submissions.filter(submission => isHidden(submission)).length + return ( . + */ + +import {camelize} from 'convert_case' + +function isGraded(submission) { + const sub = camelize(submission) + return (sub.score != null && sub.workflowState === 'graded') || sub.excused +} + +export function isHidden(submission) { + const sub = camelize(submission) + return isGraded(sub) && !sub.postedAt +} diff --git a/app/jsx/speed_grader/PostPolicies/index.js b/app/jsx/speed_grader/PostPolicies/index.js index 40154c49b23..79707bca416 100644 --- a/app/jsx/speed_grader/PostPolicies/index.js +++ b/app/jsx/speed_grader/PostPolicies/index.js @@ -79,7 +79,7 @@ export default class PostPolicies { }) } - showPostAssignmentGradesTray({submissionsMap, submissions}) { + showPostAssignmentGradesTray({submissionsMap, submissions = []}) { const onPosted = submissionsPostedAtUpdater({ afterUpdateSubmission: this._afterUpdateSubmission, submissionsMap, @@ -89,7 +89,11 @@ export default class PostPolicies { assignment: this._assignment, onPosted, sections: this._sections, - submissions + submissions: submissions.map(submission => ({ + postedAt: submission.posted_at, + score: submission.score, + workflowState: submission.workflow_state + })) }) } } diff --git a/public/javascripts/speed_grader.js b/public/javascripts/speed_grader.js index 6f239cd107d..03cd5cda9bc 100644 --- a/public/javascripts/speed_grader.js +++ b/public/javascripts/speed_grader.js @@ -35,6 +35,7 @@ import PostPolicies from 'jsx/speed_grader/PostPolicies' import SpeedGraderProvisionalGradeSelector from 'jsx/speed_grader/SpeedGraderProvisionalGradeSelector' import SpeedGraderPostGradesMenu from 'jsx/speed_grader/SpeedGraderPostGradesMenu' import SpeedGraderSettingsMenu from 'jsx/speed_grader/SpeedGraderSettingsMenu' +import {isHidden} from 'jsx/grading/helpers/SubmissionHelper' import studentViewedAtTemplate from 'jst/speed_grader/student_viewed_at' import submissionsDropdownTemplate from 'jst/speed_grader/submissions_dropdown' import speechRecognitionTemplate from 'jst/speed_grader/speech_recognition' @@ -748,17 +749,12 @@ function renderProgressIcon(attachment) { } } -function renderHiddenSubmissionPill({submission, postManually}) { +function renderHiddenSubmissionPill(submission) { const mountPoint = document.getElementById(SPEED_GRADER_HIDDEN_SUBMISSION_PILL_MOUNT_POINT) - // Show the "hidden" pill if: - // - Manual posting is enabled and the submission is not posted (graded or not) - // - Auto-posting is enabled and the submission is graded but not posted - // (this means it's been manually hidden) - const showPill = - submission && submission.posted_at == null && (postManually || submission.graded_at != null) - if (showPill) { + + if (isHidden(submission)) { ReactDOM.render( - , + , mountPoint ) } else { @@ -3129,7 +3125,7 @@ EG = { } if (ENV.post_policies_enabled) { - renderHiddenSubmissionPill({submission, postManually: jsonData.post_manually}) + renderHiddenSubmissionPill(submission) } EG.updateStatsInHeader() }, diff --git a/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatterSpec.js b/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatterSpec.js index 7df5d26b958..5fcb7be63ac 100644 --- a/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatterSpec.js +++ b/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/formatters/AssignmentCellFormatterSpec.js @@ -337,6 +337,12 @@ QUnit.module('GradebookGrid AssignmentCellFormatter', suiteHooks => { submission.workflow_state = 'unsubmitted' strictEqual(renderCell().querySelectorAll('.Grid__GradeCell__UnpostedGrade').length, 0) }) + + test('does not display an unposted grade indicator when submission does not have a score', () => { + submission.workflow_state = 'graded' + submission.score = null + strictEqual(renderCell().querySelectorAll('.Grid__GradeCell__UnpostedGrade').length, 0) + }) }) QUnit.module('when a grade is pending', contextHooks => { diff --git a/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRendererSpec.js b/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRendererSpec.js index bcf5685302e..e4b43d2a03e 100644 --- a/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRendererSpec.js +++ b/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRendererSpec.js @@ -74,6 +74,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => { name: 'Math Assignment', omit_from_final_grade: false, only_visible_to_overrides: false, + post_manually: false, published: true, submission_types: ['online_text_entry'] } @@ -86,7 +87,8 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => { posted_at: null, score: null, submitted_at: null, - user_id: '441' + user_id: '441', + workflow_state: 'unsubmitted' } student = { @@ -360,7 +362,9 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => { strictEqual(component.props.postGradesAction.featureEnabled, true) }) - test('sets hasGradesToPost to true if at least one submission has no posted_at date', () => { + test('sets hasGradesToPost to true if at least one graded submission has no posted_at date', () => { + submission.workflow_state = 'graded' + submission.score = 1 gradebook.gotChunkOfStudents([student]) render() strictEqual(component.props.postGradesAction.hasGradesToPost, true) diff --git a/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderSpec.js b/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderSpec.js index e7730a46dcc..4f7e469565f 100644 --- a/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderSpec.js +++ b/spec/javascripts/jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderSpec.js @@ -77,6 +77,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { }, hideGradesAction: { + hasGradesToHide: true, onSelect() {} }, @@ -88,6 +89,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { postGradesAction: { enabled: false, featureEnabled: false, + hasGradesToPost: true, onSelect() {} }, @@ -130,11 +132,13 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { id: '1001', isInactive: false, name: 'Adam Jones', + sortableName: 'Jones, Adam', submission: { excused: false, postedAt: null, score: 7, - submittedAt: null + submittedAt: null, + workflowState: 'graded' } }, @@ -142,11 +146,13 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { id: '1002', isInactive: false, name: 'Betty Ford', + sortableName: 'Ford, Betty', submission: { excused: false, postedAt: null, score: 8, - submittedAt: new Date('Thu Feb 02 2017 16:33:19 GMT-0500 (EST)') + submittedAt: new Date('Thu Feb 02 2017 16:33:19 GMT-0500 (EST)'), + workflowState: 'graded' } }, @@ -154,11 +160,13 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { id: '1003', isInactive: false, name: 'Charlie Xi', + sortableName: 'Xi, Charlie', submission: { excused: false, postedAt: null, score: null, - submittedAt: null + submittedAt: null, + workflowState: 'unsubmitted' } } ], @@ -249,7 +257,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { QUnit.module('when the assignment is manually-posted', () => { test('displays an "eye" icon when no submissions are graded but unposted', () => { props.students.forEach(student => { - if (student.submission.score != null) { + if (student.submission.workflowState === 'graded') { student.submission.postedAt = new Date() } }) @@ -1087,10 +1095,10 @@ QUnit.module('GradebookGrid AssignmentColumnHeader', suiteHooks => { strictEqual(getMenuItem($menuContent, 'Hide grades').getAttribute('aria-disabled'), null) }) - test('has the text "All grades posted" when no submissions can be hidden', () => { + test('has the text "All grades hidden" when no submissions can be hidden', () => { props.hideGradesAction.hasGradesToHide = false mountAndOpenOptionsMenu() - ok(getMenuItem($menuContent, 'All grades posted')) + ok(getMenuItem($menuContent, 'All grades hidden')) }) test('is disabled when no submissions can be hidden', () => { diff --git a/spec/javascripts/jsx/gradezilla/default_gradebook/PostPolicies/PostPoliciesSpec.js b/spec/javascripts/jsx/gradezilla/default_gradebook/PostPolicies/PostPoliciesSpec.js index 0b5de988b6e..4ed4de7d4d0 100644 --- a/spec/javascripts/jsx/gradezilla/default_gradebook/PostPolicies/PostPoliciesSpec.js +++ b/spec/javascripts/jsx/gradezilla/default_gradebook/PostPolicies/PostPoliciesSpec.js @@ -245,7 +245,9 @@ QUnit.module('Gradebook PostPolicies', suiteHooks => { } submission = { assignment_id: '2301', - posted_at: new Date().toISOString() + posted_at: new Date().toISOString(), + score: 1.0, + workflow_state: 'graded' } const student = { assignment_2301: submission, @@ -298,7 +300,9 @@ QUnit.module('Gradebook PostPolicies', suiteHooks => { test('includes the submissions', () => { postPolicies.showPostAssignmentGradesTray({assignmentId: '2301'}) const [{submissions}] = postPolicies._postAssignmentGradesTray.show.lastCall.args - deepEqual(submissions, [{postedAt: submission.posted_at}]) + deepEqual(submissions, [ + {postedAt: submission.posted_at, score: 1.0, workflowState: 'graded'} + ]) }) test('the `onExited` callback is passed in onExited', () => { diff --git a/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionStatusSpec.js b/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionStatusSpec.js index b77aa3a24b7..34f04202ca9 100644 --- a/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionStatusSpec.js +++ b/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionStatusSpec.js @@ -40,11 +40,11 @@ QUnit.module('SubmissionStatus - Pills', function(hooks) { submission: { assignmentId: '1', excused: false, - gradedAt: null, late: false, missing: false, postedAt: null, - secondsLate: 0 + secondsLate: 0, + workflowState: 'unsubmitted' } } }) @@ -168,50 +168,32 @@ QUnit.module('SubmissionStatus - Pills', function(hooks) { strictEqual(mutedPills.length, 0) }) - QUnit.module('post manually', postManuallyHooks => { - postManuallyHooks.beforeEach(() => { - props.assignment.postManually = true - }) - - test('shows the "Hidden" pill when the submission is not posted', function() { - props.submission.gradedAt = new Date().toISOString() - wrapper = mountComponent() - const hiddenPills = getHiddenPills() - strictEqual(hiddenPills.length, 1) - }) - - test('does not show the "Hidden" pill when the submission is posted', function() { - props.submission.postedAt = new Date().toISOString() - wrapper = mountComponent() - const hiddenPills = getHiddenPills() - strictEqual(hiddenPills.length, 0) - }) + test('shows the "Hidden" pill when the submission is graded and not posted', function() { + props.submission.score = 1 + props.submission.workflowState = 'graded' + wrapper = mountComponent() + const hiddenPills = getHiddenPills() + strictEqual(hiddenPills.length, 1) }) - QUnit.module('post automatically', postManuallyHooks => { - postManuallyHooks.beforeEach(() => { - props.assignment.postManually = false - }) + test('does not show the "Hidden" pill when the submission is not graded', function() { + props.submission.workflowState = 'unsubmitted' + wrapper = mountComponent() + const hiddenPills = getHiddenPills() + strictEqual(hiddenPills.length, 0) + }) - test('shows the "Hidden" pill when the submission is graded and not posted', function() { - props.submission.gradedAt = new Date().toISOString() - wrapper = mountComponent() - const hiddenPills = getHiddenPills() - strictEqual(hiddenPills.length, 1) - }) + test('does not show the "Hidden" pill when the submission is posted', function() { + props.submission.postedAt = new Date() + wrapper = mountComponent() + const hiddenPills = getHiddenPills() + strictEqual(hiddenPills.length, 0) + }) - test('does not show the "Hidden" pill when the submission is posted', function() { - props.submission.postedAt = new Date().toISOString() - wrapper = mountComponent() - const hiddenPills = getHiddenPills() - strictEqual(hiddenPills.length, 0) - }) - - test('does not show the "Hidden" pill when the submission is not graded nor posted', function() { - wrapper = mountComponent() - const hiddenPills = getHiddenPills() - strictEqual(hiddenPills.length, 0) - }) + test('does not show the "Hidden" pill when the submission is not graded nor posted', function() { + wrapper = mountComponent() + const hiddenPills = getHiddenPills() + strictEqual(hiddenPills.length, 0) }) }) }) @@ -239,7 +221,8 @@ QUnit.module('SubmissionStatus - Grading Period not in any grading period warnin late: false, missing: false, secondsLate: 0, - assignmentId: '1' + assignmentId: '1', + workflowState: 'unsubmitted' } } }) @@ -298,7 +281,8 @@ QUnit.module('SubmissionStatus - Grading Period is a closed warning', hooks => { late: false, missing: false, secondsLate: 0, - assignmentId: '1' + assignmentId: '1', + workflowState: 'unsubmitted' } } }) @@ -357,7 +341,8 @@ QUnit.module('SubmissionStatus - Grading Period is in another period warning', h late: false, missing: false, secondsLate: 0, - assignmentId: '1' + assignmentId: '1', + workflowState: 'unsubmitted' } } }) @@ -416,7 +401,8 @@ QUnit.module('SubmissionStatus - Concluded Enrollment Warning', function(hooks) late: false, missing: false, secondsLate: 0, - assignmentId: '1' + assignmentId: '1', + workflowState: 'unsubmitted' } } }) @@ -475,7 +461,8 @@ QUnit.module('SubmissionStatus - Not calculated in final grade', hooks => { late: false, missing: false, secondsLate: 0, - assignmentId: '1' + assignmentId: '1', + workflowState: 'unsubmitted' } } }) diff --git a/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionTraySpec.js b/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionTraySpec.js index 8ecf14b2136..711b0672bb2 100644 --- a/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionTraySpec.js +++ b/spec/javascripts/jsx/gradezilla/default_gradebook/components/SubmissionTraySpec.js @@ -314,7 +314,7 @@ QUnit.module('SubmissionTray', function(hooks) { test('passes along postPoliciesEnabled prop to SubmissionStatus', function() { defaultProps.postPoliciesEnabled = true - defaultProps.submission.gradedAt = new Date().toISOString() + defaultProps.submission.workflowState = 'graded' mountComponent() ok(content.textContent.includes('Hidden')) }) diff --git a/spec/javascripts/jsx/grading/PostAssignmentGradesTray/PostAssignmentGradesTraySpec.js b/spec/javascripts/jsx/grading/PostAssignmentGradesTray/PostAssignmentGradesTraySpec.js index 518bda57a9a..095dda85224 100644 --- a/spec/javascripts/jsx/grading/PostAssignmentGradesTray/PostAssignmentGradesTraySpec.js +++ b/spec/javascripts/jsx/grading/PostAssignmentGradesTray/PostAssignmentGradesTraySpec.js @@ -37,7 +37,8 @@ QUnit.module('PostAssignmentGradesTray', suiteHooks => { anonymousGrading: false, gradesPublished: true, id: '2301', - name: 'Math 1.1' + name: 'Math 1.1', + postManually: false }, onExited: sinon.spy(), onPosted: sinon.spy(), @@ -236,22 +237,22 @@ QUnit.module('PostAssignmentGradesTray', suiteHooks => { QUnit.module('unposted summary', () => { QUnit.module('with unposted submissions', () => { - test('the number of unposted submissions is displayed', async () => { + test('graded submissions without a postedAt are counted', async () => { context.submissions = [ - {postedAt: new Date().toISOString()}, - {postedAt: null}, - {postedAt: null} + {postedAt: new Date().toISOString(), score: 1, workflowState: 'graded'}, + {postedAt: null, score: 1, workflowState: 'graded'}, + {postedAt: null, score: null, workflowState: 'unsubmitted'} ] await show() - strictEqual(getUnpostedCount().textContent, '2') + strictEqual(getUnpostedCount().textContent, '1') }) }) QUnit.module('with no unposted submissions', unpostedSubmissionsHooks => { unpostedSubmissionsHooks.beforeEach(async () => { context.submissions = [ - {postedAt: new Date().toISOString()}, - {postedAt: new Date().toISOString()} + {postedAt: new Date().toISOString(), score: 1, workflowState: 'graded'}, + {postedAt: new Date().toISOString(), score: 1, workflowState: 'graded'} ] await show() diff --git a/spec/javascripts/jsx/grading/helpers/SubmissionHelperSpec.js b/spec/javascripts/jsx/grading/helpers/SubmissionHelperSpec.js new file mode 100644 index 00000000000..afc67d68162 --- /dev/null +++ b/spec/javascripts/jsx/grading/helpers/SubmissionHelperSpec.js @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import {isHidden} from 'jsx/grading/helpers/SubmissionHelper' + +QUnit.module('SubmissionHelper', suiteHooks => { + let submission + + suiteHooks.beforeEach(() => { + submission = { + excused: false, + score: null, + workflowState: 'unsubmitted' + } + }) + + QUnit.module('.isHidden', () => { + QUnit.module('when submission is excused', excusedHooks => { + excusedHooks.beforeEach(() => { + submission.excused = true + }) + + test('returns true', () => { + strictEqual(isHidden(submission), true) + }) + }) + + QUnit.module('when submission is not excused', () => { + test('is true when submission workflow state is graded and score is present', () => { + submission.score = 1 + submission.workflowState = 'graded' + strictEqual(isHidden(submission), true) + }) + + test('is false when workflow state is not graded', () => { + submission.score = 1 + strictEqual(isHidden(submission), false) + }) + + test('is false when score is not present', () => { + submission.workflowState = 'graded' + strictEqual(isHidden(submission), false) + }) + }) + }) +}) diff --git a/spec/javascripts/jsx/speed_grader/PostPolicies/PostPoliciesSpec.js b/spec/javascripts/jsx/speed_grader/PostPolicies/PostPoliciesSpec.js index e487a11c90a..c9a4742d05a 100644 --- a/spec/javascripts/jsx/speed_grader/PostPolicies/PostPoliciesSpec.js +++ b/spec/javascripts/jsx/speed_grader/PostPolicies/PostPoliciesSpec.js @@ -177,11 +177,15 @@ QUnit.module('SpeedGrader PostPolicies', suiteHooks => { id: '93', assignment_id: '2301', posted_at: new Date().toISOString(), - user_id: '441' + score: 1.0, + user_id: '441', + workflow_state: 'graded' } postPolicies.showPostAssignmentGradesTray({submissions: [submission]}) const {submissions} = postGradesShowArgs() - deepEqual(submissions, [submission]) + deepEqual(submissions, [ + {postedAt: submission.posted_at, score: 1.0, workflowState: submission.workflow_state} + ]) }) test('passes updateSubmission to "show"', () => { diff --git a/spec/javascripts/jsx/speed_graderSpec.js b/spec/javascripts/jsx/speed_graderSpec.js index 40fb2fbec87..0be7fe2ab82 100644 --- a/spec/javascripts/jsx/speed_graderSpec.js +++ b/spec/javascripts/jsx/speed_graderSpec.js @@ -6095,13 +6095,20 @@ QUnit.module('SpeedGrader', function(suiteHooks) { /* eslint-disable-line qunit/ delete window.jsonData.post_manually }) - test('is shown if the selected submission is not posted', () => { - SpeedGrader.EG.currentStudent.submission.graded_at = new Date('Jan 1, 2020') + test('is shown if the selected submission is graded but not posted', () => { + SpeedGrader.EG.currentStudent.submission.workflow_state = 'graded' SpeedGrader.EG.showGrade() ok(mountPoint.innerText.includes('HIDDEN')) }) + test('is not shown if the selected submission is unsubmitted', () => { + SpeedGrader.EG.currentStudent.submission.workflow_state = 'unsubmitted' + SpeedGrader.EG.showGrade() + + notOk(mountPoint.innerText.includes('HIDDEN')) + }) + test('is not shown if the selected submission is posted', () => { SpeedGrader.EG.currentStudent.submission.graded_at = new Date('Jan 1, 2020') SpeedGrader.EG.currentStudent.submission.posted_at = new Date('Jan 1, 2020') @@ -6113,11 +6120,18 @@ QUnit.module('SpeedGrader', function(suiteHooks) { /* eslint-disable-line qunit/ QUnit.module('when the assignment is auto-posted', () => { test('is shown if the selected submission is graded but not posted', () => { - SpeedGrader.EG.currentStudent.submission.graded_at = new Date('Jan 1, 2020') + SpeedGrader.EG.currentStudent.submission.workflow_state = 'graded' SpeedGrader.EG.showGrade() ok(mountPoint.innerText.includes('HIDDEN')) }) + test('is not shown if the selected submission is unsubmitted', () => { + SpeedGrader.EG.currentStudent.submission.workflow_state = 'unsubmitted' + SpeedGrader.EG.showGrade() + + notOk(mountPoint.innerText.includes('HIDDEN')) + }) + test('is not shown if the selected submission is graded and posted', () => { SpeedGrader.EG.currentStudent.submission.graded_at = new Date('Jan 1, 2020') SpeedGrader.EG.currentStudent.submission.posted_at = new Date('Jan 1, 2020')