blueprint: prevent changing [not-]graded when locked-by-points
test plan: - configure a blueprint course to lock points (and not content) for assignments - create two assignments in the blueprint, one graded, and one not graded, and lock both - sync to associated courses - in an associated course, confirm that: 1. the graded assignment can't be changed to "Not Graded" 2. the non-graded assignment can't be changed away from "Not Graded" 2a. a screenreader sees "Display Grade as" label linked to a read-only input containing "Not Graded" 3. the content in both assignments can still be edited and the assignment can be saved in the associated course 4. for an assignment in a closed grading period, "Display Grade as" should be read-only as in step 2 fixes ADMIN-789 Change-Id: I76e0fba272df1a43e2cf12cfa38ecbf6896b54b6 Reviewed-on: https://gerrit.instructure.com/141797 Reviewed-by: Mysti Sadler <mysti@instructure.com> Reviewed-by: Ed Schiebel <eschiebel@instructure.com> QA-Review: Ed Schiebel <eschiebel@instructure.com> Tested-by: Jenkins Product-Review: Jeremy Stanley <jeremy@instructure.com>
This commit is contained in:
parent
ec511dbf16
commit
1b745794b3
|
@ -595,6 +595,11 @@ define [
|
|||
|
||||
nf:(number, {hash: {format}}) ->
|
||||
numberFormat[format](number)
|
||||
|
||||
# Public: look up an element of a hash or array
|
||||
#
|
||||
lookup: (obj, key) ->
|
||||
obj && obj[key]
|
||||
}
|
||||
|
||||
return Handlebars
|
||||
|
|
|
@ -50,6 +50,7 @@ define [
|
|||
@optionProperty 'parentModel'
|
||||
@optionProperty 'nested'
|
||||
@optionProperty 'preventNotGraded'
|
||||
@optionProperty 'lockedItems'
|
||||
|
||||
handleGradingTypeChange: (ev) =>
|
||||
gradingType = @$gradingType.val()
|
||||
|
@ -80,6 +81,14 @@ define [
|
|||
close: -> $(ev.target).focus()
|
||||
).fixDialogButtons()
|
||||
|
||||
gradingTypeMap: () ->
|
||||
percent: I18n.t 'grading_type_options.percent', 'Percentage'
|
||||
pass_fail: I18n.t 'grading_type_options.pass_fail', 'Complete/Incomplete'
|
||||
points: I18n.t 'grading_type_options.points', 'Points'
|
||||
letter_grade: I18n.t 'grading_type_options.letter_grade', 'Letter Grade'
|
||||
gpa_scale: I18n.t 'grading_type_options.gpa_scale', 'GPA Scale'
|
||||
not_graded: I18n.t 'grading_type_options.not_graded', 'Not Graded'
|
||||
|
||||
toJSON: =>
|
||||
gradingType: @parentModel.gradingType()
|
||||
isNotGraded: @parentModel.isNotGraded()
|
||||
|
@ -87,7 +96,8 @@ define [
|
|||
gpaScaleQuestionLabel: I18n.t('gpa_scale_explainer', "What is GPA Scale Grading?")
|
||||
isGpaScaled: @parentModel.isGpaScaled()
|
||||
gradingStandardId: @parentModel.gradingStandardId()
|
||||
frozenAttributes: @parentModel.frozenAttributes()
|
||||
nested: @nested
|
||||
preventNotGraded: @preventNotGraded
|
||||
inClosedGradingPeriod: @parentModel.inClosedGradingPeriod
|
||||
preventNotGraded: @preventNotGraded || (@lockedItems?.points && !@parentModel.isNotGraded())
|
||||
freezeGradingType: _.include(@parentModel.frozenAttributes(), 'grading_type') ||
|
||||
@parentModel.inClosedGradingPeriod() || (@lockedItems?.points && @parentModel.isNotGraded())
|
||||
gradingTypeMap: @gradingTypeMap()
|
||||
|
|
|
@ -32,6 +32,7 @@ import LockManager from '../blueprint_courses/apps/LockManager'
|
|||
|
||||
const lockManager = new LockManager()
|
||||
lockManager.init({ itemType: 'assignment', page: 'edit' })
|
||||
const lockedItems = lockManager.isChildContent() ? lockManager.getItemLocks() : {}
|
||||
|
||||
ENV.ASSIGNMENT.assignment_overrides = ENV.ASSIGNMENT_OVERRIDES
|
||||
|
||||
|
@ -49,7 +50,8 @@ const assignmentGroupSelector = new AssignmentGroupSelector({
|
|||
})
|
||||
const gradingTypeSelector = new GradingTypeSelector({
|
||||
parentModel: assignment,
|
||||
preventNotGraded: assignment.submissionTypesFrozen()
|
||||
preventNotGraded: assignment.submissionTypesFrozen(),
|
||||
lockedItems
|
||||
})
|
||||
const groupCategorySelector = new GroupCategorySelector({
|
||||
parentModel: assignment,
|
||||
|
@ -62,8 +64,6 @@ const peerReviewsSelector = new PeerReviewsSelector({
|
|||
|
||||
const headerEl = ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED ? '#edit_assignment_header-cr' : '#edit_assignment_header'
|
||||
|
||||
const lockedItems = lockManager.isChildContent() ? lockManager.getItemLocks() : {}
|
||||
|
||||
const editView = new EditView({
|
||||
el: '#edit_assignment_form',
|
||||
model: assignment,
|
||||
|
|
|
@ -5,35 +5,35 @@
|
|||
</div>
|
||||
|
||||
<div class="form-column-right">
|
||||
{{#if freezeGradingType}}
|
||||
<input type="text" id="assignment_grading_type" readonly value="{{lookup gradingTypeMap gradingType}}"/>
|
||||
<input type="hidden" name="{{#if nested}}assignment[grading_type]{{else}}grading_type{{/if}}" value="{{gradingType}}"/>
|
||||
{{else}}
|
||||
<select id="assignment_grading_type"
|
||||
name="{{#if nested}}assignment[grading_type]{{else}}grading_type{{/if}}"
|
||||
{{#if inClosedGradingPeriod}}
|
||||
readonly
|
||||
aria-readonly="true"
|
||||
{{/if}}
|
||||
aria-controls="graded_assignment_fields view-grading-levels"
|
||||
{{disabledIfIncludes frozenAttributes "grading_type"}}>
|
||||
aria-controls="graded_assignment_fields view-grading-levels">
|
||||
<option value="percent" {{selectedIf gradingType "percent"}}>
|
||||
{{#t "grading_type_options.percent"}}Percentage{{/t}}
|
||||
{{gradingTypeMap.percent}}
|
||||
</option>
|
||||
<option value="pass_fail" {{selectedIf gradingType "pass_fail" }}>
|
||||
{{#t "grading_type_options.pass_fail"}}Complete/Incomplete{{/t}}
|
||||
{{gradingTypeMap.pass_fail}}
|
||||
</option>
|
||||
<option value="points" {{selectedIf gradingType "points"}}>
|
||||
{{#t "grading_type_options.points"}}Points{{/t}}
|
||||
{{gradingTypeMap.points}}
|
||||
</option>
|
||||
<option value="letter_grade" {{selectedIf gradingType "letter_grade"}}>
|
||||
{{#t "grading_type_options.letter_grade"}}Letter Grade{{/t}}
|
||||
{{gradingTypeMap.letter_grade}}
|
||||
</option>
|
||||
<option value="gpa_scale" {{selectedIf gradingType "gpa_scale"}}>
|
||||
{{#t "grading_type_options.gpa_scale"}}GPA Scale{{/t}}
|
||||
{{gradingTypeMap.gpa_scale}}
|
||||
</option>
|
||||
{{#unless preventNotGraded}}
|
||||
<option value="not_graded" {{selectedIf isNotGraded}}>
|
||||
{{#t "grading_type_options.not_graded"}}Not Graded{{/t}}
|
||||
{{gradingTypeMap.not_graded}}
|
||||
</option>
|
||||
{{/unless}}
|
||||
</select>
|
||||
{{/if}}
|
||||
<a id=gpa-scale-question
|
||||
href="#"
|
||||
aria-label="{{gpaScaleQuestionLabel}}"
|
||||
|
|
|
@ -353,11 +353,19 @@ test('disables fields when inClosedGradingPeriod', function() {
|
|||
ok(view.$el.find('#assignment_group_id').attr('readonly'))
|
||||
equal(view.$el.find('#assignment_group_id').attr('aria-readonly'), 'true')
|
||||
ok(view.$el.find('#assignment_grading_type').attr('readonly'))
|
||||
equal(view.$el.find('#assignment_grading_type').attr('aria-readonly'), 'true')
|
||||
equal(view.$el.find('input[name="grading_type"]').attr('type'), 'hidden')
|
||||
ok(view.$el.find('#has_group_category').attr('readonly'))
|
||||
equal(view.$el.find('#has_group_category').attr('aria-readonly'), 'true')
|
||||
})
|
||||
|
||||
test('disables grading type field when frozen', function() {
|
||||
const view = this.editView({frozen_attributes: ['grading_type']})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
|
||||
ok(view.$el.find('#assignment_grading_type').attr('readonly'))
|
||||
equal(view.$el.find('input[name="grading_type"]').attr('type'), 'hidden')
|
||||
})
|
||||
|
||||
test('does not disable post to sis when inClosedGradingPeriod', function() {
|
||||
ENV.POST_TO_SIS = true
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
|
|
|
@ -160,6 +160,31 @@ describe "blueprint courses assignments" do
|
|||
expect(f("#due_at").attribute("readonly")).to eq "true"
|
||||
expect(f("#unlock_at").attribute("readonly")).to eq "true"
|
||||
expect(f("#lock_at").attribute("readonly")).to eq "true"
|
||||
expect(f('#assignment_grading_type')).to contain_css('option[value="points"]')
|
||||
expect(f('#assignment_grading_type')).not_to contain_css('option[value="not_graded"]')
|
||||
end
|
||||
|
||||
it "should not allow making a non-graded assignment graded when points are locked" do
|
||||
not_graded_assignment = @copy_from.assignments.create!(
|
||||
title: "eh", description: "meh", submission_types: "not_graded", grading_type: 'not_graded'
|
||||
)
|
||||
nga_tag = @template.create_content_tag_for!(not_graded_assignment)
|
||||
|
||||
# fake the copy instead of doing a full migration
|
||||
nga_copy = @copy_to.assignments.create(
|
||||
title: "eh", description: "meh", submission_types: "not_graded", grading_type: 'not_graded'
|
||||
)
|
||||
nga_copy.migration_id = nga_tag.migration_id
|
||||
nga_copy.save!
|
||||
|
||||
nga_tag.update(restrictions: {content: true, points: true, due_dates: true, availability_dates: true})
|
||||
|
||||
get "/courses/#{@copy_to.id}/assignments/#{nga_copy.id}/edit"
|
||||
|
||||
node = f "#assignment_grading_type"
|
||||
expect(node.tag_name).to eq 'input'
|
||||
expect(node.attribute('readonly')).to eq 'true'
|
||||
expect(f('input[name="grading_type"][type="hidden"]').attribute('value')).to eq 'not_graded'
|
||||
end
|
||||
|
||||
it "should not allow popup editing of restricted items" do
|
||||
|
|
Loading…
Reference in New Issue