gradebook: include assignments not in any grading period

Fixes a bug where assignments due outside of any grading period were
not shown in the Gradebook when "All Grading Periods" was selected.
Also, fixes a documentation indentation error that was causing docs to
not get generated.

closes EVAL-1306
flag=none

Test Plan 1:
1. Create a course that uses grading periods, and create 2 grading
   periods: one that spans all of 2019 and one that spans all of 2020.
2. Create an assignment due in 2019, an assignment due in 2020, and
   an assignment due in 2021.
3. Go to the Gradebook. Filter by the 2020 Grading Period and then
   refresh the page. After page refresh, verify:
   - The assignment due in the 2020 Grading Period is shown.
   - Select the 2019 Grading Period from the dropdown. Verify the
     assignment due in 2019 is shown.
   - Select "All Grading Periods" from the dropdown. Verify the
     assignment due in 2021 is shown (along with the other two
     assignments).

Test Plan 2:
1. Generate API documentation:

   bundle exec rake doc:api

2. Go to /doc/api/assignment_groups.html#method.assignment_groups.index
   and verify there is documentation for an "assignment_ids[]" param
   that reads, 'If “assignments” are included, optionally return only
   assignments having their ID in this array.'

Change-Id: Ie0c87674f7816e5a68558926646c8baa521c1a52
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/252594
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Syed Hussain <shussain@instructure.com>
Product-Review: Syed Hussain <shussain@instructure.com>
Reviewed-by: Adrian Packel <apackel@instructure.com>
Reviewed-by: Kai Bjorkman <kbjorkman@instructure.com>
This commit is contained in:
Spencer Olson 2020-11-11 15:56:46 -06:00
parent 4a59772e65
commit 6bfa6278df
4 changed files with 28 additions and 10 deletions

View File

@ -109,7 +109,7 @@ class AssignmentGroupsController < ApplicationController
# If "observed_users" is passed along with "assignments" and "submission", submissions for observed users will also be included as an array.
#
# @argument assignment_ids[] [String]
# If "assignments" are included, optionally return only assignments having their ID in this array.
# If "assignments" are included, optionally return only assignments having their ID in this array.
#
# @argument exclude_assignment_submission_types[] [String, "online_quiz"|"discussion_topic"|"wiki_page"|"external_tool"]
# If "assignments" are included, those with the specified submission types

View File

@ -32,7 +32,10 @@ class GradebookGradingPeriodAssignments
def to_h
return {} unless @course.grading_periods?
the_query.transform_values {|list| list.map(&:to_s)}
the_query.each_with_object({}) do |(period_id, list), hash|
hash[period_id || :none] = list.map(&:to_s)
end
end
private
@ -53,7 +56,7 @@ class GradebookGradingPeriodAssignments
joins("INNER JOIN #{Enrollment.quoted_table_name} enrollments ON enrollments.user_id = submissions.user_id").
merge(Assignment.for_course(@course).active).
where(enrollments: { course_id: @course, type: ['StudentEnrollment', 'StudentViewEnrollment'] }).
where.not(grading_period_id: nil).where.not(enrollments: { workflow_state: excluded_workflow_states })
where.not(enrollments: { workflow_state: excluded_workflow_states })
scope = scope.where(user: @student) if @student
scope.

View File

@ -1625,6 +1625,7 @@ describe GradebooksController do
@period1, @period2 = Factories::GradingPeriodHelper.new.create_presets_for_group(@group, :past, :current)
@assignment1_in_gp1 = @course.assignments.create!(due_at: 3.months.ago)
@assignment2_in_gp2 = @course.assignments.create!(due_at: 1.day.from_now)
@assignment_not_in_gp = @course.assignments.create!(due_at: 9.months.from_now)
end
it "returns unauthorized if there is no current user" do
@ -1657,7 +1658,8 @@ describe GradebooksController do
json = json_parse(response.body)["grading_period_assignments"]
expect(json).to eq({
@period1.id.to_s => [@assignment1_in_gp1.id.to_s],
@period2.id.to_s => [@assignment2_in_gp2.id.to_s]
@period2.id.to_s => [@assignment2_in_gp2.id.to_s],
"none" => [@assignment_not_in_gp.id.to_s]
})
end
end

View File

@ -31,7 +31,7 @@ describe GradebookGradingPeriodAssignments do
@assignment1_in_gp1 = @example_course.assignments.create!(due_at: 3.months.ago)
@assignment2_in_gp2 = @example_course.assignments.create!(due_at: 1.day.from_now)
@assignment3_in_gp2 = @example_course.assignments.create!(due_at: 2.days.from_now)
@assignment4 = @example_course.assignments.create!(due_at: 6.months.from_now)
@assignment_not_in_gp = @example_course.assignments.create!(due_at: 6.months.from_now)
end
let(:hash) { GradebookGradingPeriodAssignments.new(@example_course).to_h }
@ -43,14 +43,14 @@ describe GradebookGradingPeriodAssignments do
@period1, @period2, @period3 = Factories::GradingPeriodHelper.new.create_presets_for_group(
@group, :past, :current, :future
)
[@assignment1_in_gp1, @assignment2_in_gp2, @assignment3_in_gp2, @assignment4].each do |assignment|
[@assignment1_in_gp1, @assignment2_in_gp2, @assignment3_in_gp2, @assignment_not_in_gp].each do |assignment|
DueDateCacher.recompute(assignment)
end
end
it "includes the grading period ids as keys on the hash" do
it "includes the grading period ids as keys on the hash, and a 'none' key to indicate no grading period" do
@example_course.assignments.create!(due_at: 3.months.from_now)
expect(hash.keys).to match_array([@period1.id, @period2.id, @period3.id])
expect(hash.keys).to match_array([@period1.id, @period2.id, @period3.id, :none])
end
it "lists the related assignment ids as strings for the grading periods" do
@ -62,6 +62,12 @@ describe GradebookGradingPeriodAssignments do
expect(hash[@period2.id]).to include(@assignment3_in_gp2.id.to_s)
end
it "includes all assignments due outside of any grading period" do
assignment = @example_course.assignments.create!(due_at: 9.months.from_now)
expect(hash[:none]).to include(@assignment_not_in_gp.id.to_s)
expect(hash[:none]).to include(assignment.id.to_s)
end
it "includes assignments with due dates in multiple grading periods" do
override = @assignment1_in_gp1.assignment_overrides.create!(due_at: 1.day.ago, due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
@ -69,6 +75,13 @@ describe GradebookGradingPeriodAssignments do
expect(hash[@period2.id]).to include(@assignment1_in_gp1.id.to_s)
end
it "includes assignments with due dates in a grading period and outside of a grading period" do
override = @assignment1_in_gp1.assignment_overrides.create!(due_at: 9.months.from_now, due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
expect(hash[@period1.id]).to include(@assignment1_in_gp1.id.to_s)
expect(hash[:none]).to include(@assignment1_in_gp1.id.to_s)
end
it "optionally returns results for a specific student" do
override = @assignment1_in_gp1.assignment_overrides.create!(due_at: 1.day.ago, due_at_overridden: true)
override.assignment_override_students.create!(user: @student2)
@ -78,8 +91,8 @@ describe GradebookGradingPeriodAssignments do
end
it "excludes assignments due outside of any grading period" do
expect(hash[@period1.id]).not_to include(@assignment4.id.to_s)
expect(hash[@period2.id]).not_to include(@assignment4.id.to_s)
expect(hash[@period1.id]).not_to include(@assignment_not_in_gp.id.to_s)
expect(hash[@period2.id]).not_to include(@assignment_not_in_gp.id.to_s)
end
it "excludes grading periods without assignments" do