only fetch assignments for selected grading period

Changes the assignment loading strategy for the Gradebook when Grading
Periods are being used. Now, two requests are made to get assignments;
the first requests only assignments in the current grading period, the
second requests the rest of the assignments in the course. When the
former returns, we can show the gradebook to the user. When the
latter returns, we allow the user to change the grading period in the
dropdown.

closes EVAL-1247
flag=none

Test Plan:
1. Create a course with multiple grading periods, with different
   assignments in each grading period (and a handful of assignments
   that are due in different grading periods for different students).
2. Go to the Gradebook.
3. Select "All Grading Periods" from the grading
   period dropdown. Refresh the page. When the page refreshes, verify
   in your browser dev tools that there is only a single request to
   get assignment groups + assignments.
4. Verify you can change the grading period in the dropdown and the
   expected assignments are shown.
5. Select a grading period from the grading period dropdown. Refresh
   the page. When the page refreshes, verify in your browser dev tools
   that there are two requests to get assignment groups + assignments.
   One request should have an 'assignment_ids' param that includes only
   the assignments in the current grading period. The other request
   should have an 'assignment_ids' param that includes all the rest of
   the assignment_ids for the course. if there are any assignments that
   are in both the current grading period AND and other grading period,
   you should see that assignment_id in the former call but not in the
   latter.
6. Before the call for the "rest of the assignments" returns, note that
   the menu options in the grading period dropdown are disabled. Once
   that call returns, note that the options in the menu are re-enabled.
   Once they are enabled, verify that you can change the grading period
   and the expected assignments are shown.
7. Do a quick smoke-test of using other filters in conjunction with the
   grading period filter to make sure everything works as expected.
8. Do a general smoke-test to make sure the gradebook and its filters
   work as expected for a course that does not use grading periods.
9. Verify the assignment_ids param added to the
   AssignmentGroupsAPI#index works as expected (expected behavior is
   described in the API docs for it).

Change-Id: I856810333e56de012982fb704d9cfc9a1a44b8d0
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/250580
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Kai Bjorkman <kbjorkman@instructure.com>
Product-Review: Jody Sailor
Reviewed-by: Adrian Packel <apackel@instructure.com>
Reviewed-by: Gary Mei <gmei@instructure.com>
This commit is contained in:
Spencer Olson 2020-10-12 15:47:08 -05:00
parent 7a997b350c
commit 1957ca8d20
23 changed files with 596 additions and 182 deletions

View File

@ -108,6 +108,9 @@ class AssignmentGroupsController < ApplicationController
# The "assignment_visibility" option additionally requires that the Differentiated Assignments course feature be turned on.
# 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.
#
# @argument exclude_assignment_submission_types[] [String, "online_quiz"|"discussion_topic"|"wiki_page"|"external_tool"]
# If "assignments" are included, those with the specified submission types
# will be excluded from the assignment groups.
@ -397,12 +400,13 @@ class AssignmentGroupsController < ApplicationController
def visible_assignments(context, current_user, groups)
return Assignment.none unless include_params.include?('assignments')
# TODO: possible keyword arguments refactor
assignments = AssignmentGroup.visible_assignments(
current_user,
context,
groups,
assignment_includes
includes: assignment_includes,
assignment_ids: params[:assignment_ids]
)
if params[:exclude_assignment_submission_types].present?

View File

@ -24,8 +24,6 @@ export default class AssignmentGroupsLoader {
}
loadAssignmentGroups() {
const courseId = this._gradebook.course.id
const url = `/api/v1/courses/${courseId}/assignment_groups`
const includes = [
'assignment_group_id',
'assignment_visibility',
@ -51,8 +49,57 @@ export default class AssignmentGroupsLoader {
per_page: this._performanceControls.assignmentGroupsPerPage
}
const periodId = this._gradingPeriodId()
if (periodId) {
return this._loadAssignmentGroupsForGradingPeriods(params, periodId)
}
return this._getAssignmentGroups(params)
}
// If we're filtering by grading period in Gradebook, send two requests for assignments:
// one for assignments in the selected grading period, and one for the rest.
_loadAssignmentGroupsForGradingPeriods(params, periodId) {
const assignmentIdsByGradingPeriod = this._gradingPeriodAssignmentIds(periodId)
const gotGroups = this._getAssignmentGroups(
{...params, assignment_ids: assignmentIdsByGradingPeriod.selected},
[periodId]
)
this._getAssignmentGroups(
{...params, assignment_ids: assignmentIdsByGradingPeriod.rest.ids},
assignmentIdsByGradingPeriod.rest.gradingPeriodIds
)
return gotGroups
}
_getAssignmentGroups(params, gradingPeriodIds) {
const url = `/api/v1/courses/${this._gradebook.course.id}/assignment_groups`
return this._dispatch.getDepaginated(url, params).then(assignmentGroups => {
this._gradebook.updateAssignmentGroups(assignmentGroups)
this._gradebook.updateAssignmentGroups(assignmentGroups, gradingPeriodIds)
})
}
_gradingPeriodAssignmentIds(selectedPeriodId) {
const gpAssignments = this._gradebook.courseContent.gradingPeriodAssignments
const selectedIds = this._gradebook.getGradingPeriodAssignments(selectedPeriodId)
const restIds = Object.values(gpAssignments)
.flat()
.filter(id => !selectedIds.includes(id))
return {
selected: selectedIds,
rest: {
ids: [...new Set(restIds)],
gradingPeriodIds: Object.keys(gpAssignments).filter(gpId => gpId !== selectedPeriodId)
}
}
}
_gradingPeriodId() {
const periodId = this._gradebook.gradingPeriodId
return periodId === '0' ? null : periodId
}
}

View File

@ -58,7 +58,6 @@ export default class DataLoader {
this.__loadGradebookData({
dataLoader: this,
gradebook,
getAssignmentGroups: true,
getModules: gradebook.options.has_modules,
getCustomColumns: true,
@ -118,12 +117,20 @@ export default class DataLoader {
// Begin loading Student IDs before any other data.
const gotStudentIds = dataLoader.studentIdsLoader.loadStudentIds()
if (options.getAssignmentGroups) {
dataLoader.assignmentGroupsLoader.loadAssignmentGroups()
let gotGradingPeriodAssignments
if (options.getGradingPeriodAssignments) {
gotGradingPeriodAssignments = dataLoader.gradingPeriodAssignmentsLoader.loadGradingPeriodAssignments()
}
if (options.getGradingPeriodAssignments) {
dataLoader.gradingPeriodAssignmentsLoader.loadGradingPeriodAssignments()
if (options.getAssignmentGroups) {
if (gotGradingPeriodAssignments && gradebook.gradingPeriodId !== '0') {
// eslint-disable-next-line promise/catch-or-return
gotGradingPeriodAssignments.then(() => {
dataLoader.assignmentGroupsLoader.loadAssignmentGroups()
})
} else {
dataLoader.assignmentGroupsLoader.loadAssignmentGroups()
}
}
if (options.getCustomColumns) {

View File

@ -45,7 +45,7 @@ describe('Gradebook FinalGradeOverrides', () => {
id: '1201'
},
getGradingPeriodToShow: sinon.stub().returns('1501'),
gradingPeriodId: '1501',
gradebookGrid: {
updateRowCell: sinon.stub()

View File

@ -31,7 +31,7 @@ export default class FinalGradeOverrides {
getGradeForUser(userId) {
let gradingPeriodId = null
if (this._gradebook.isFilteringColumnsByGradingPeriod()) {
gradingPeriodId = this._gradebook.getGradingPeriodToShow()
gradingPeriodId = this._gradebook.gradingPeriodId
}
return this._datastore.getGrade(userId, gradingPeriodId)
@ -40,7 +40,7 @@ export default class FinalGradeOverrides {
getPendingGradeInfoForUser(userId) {
let gradingPeriodId = null
if (this._gradebook.isFilteringColumnsByGradingPeriod()) {
gradingPeriodId = this._gradebook.getGradingPeriodToShow()
gradingPeriodId = this._gradebook.gradingPeriodId
}
return this._datastore.getPendingGradeInfo(userId, gradingPeriodId)
@ -59,7 +59,7 @@ export default class FinalGradeOverrides {
let gradingPeriodId = null
if (this._gradebook.isFilteringColumnsByGradingPeriod()) {
gradingPeriodId = this._gradebook.getGradingPeriodToShow()
gradingPeriodId = this._gradebook.gradingPeriodId
}
this._datastore.addPendingGradeInfo(userId, gradingPeriodId, gradeOverrideInfo)

View File

@ -145,6 +145,7 @@ class Gradebook {
this.gotAllAssignmentGroups = this.gotAllAssignmentGroups.bind(this)
// Grading Period Assignment Data & Lifecycle Methods
this.assignmentsLoadedForCurrentView = this.assignmentsLoadedForCurrentView.bind(this)
this.updateGradingPeriodAssignments = this.updateGradingPeriodAssignments.bind(this)
this.gotGradingPeriodAssignments = this.gotGradingPeriodAssignments.bind(this)
this.gotSections = this.gotSections.bind(this)
@ -255,6 +256,7 @@ class Gradebook {
this.gradeSort = this.gradeSort.bind(this)
this.missingSort = this.missingSort.bind(this)
this.lateSort = this.lateSort.bind(this)
this.setCurrentGradingPeriod = this.setCurrentGradingPeriod.bind(this)
this.sortByStudentColumn = this.sortByStudentColumn.bind(this)
this.sortByCustomColumn = this.sortByCustomColumn.bind(this)
this.sortByAssignmentColumn = this.sortByAssignmentColumn.bind(this)
@ -274,6 +276,7 @@ class Gradebook {
this.showNotesColumn = this.showNotesColumn.bind(this)
this.hideNotesColumn = this.hideNotesColumn.bind(this)
// # Grid DOM Access/Reference Methods
this.addAssignmentColumnDefinition = this.addAssignmentColumnDefinition.bind(this)
this.getCustomColumnId = this.getCustomColumnId.bind(this)
this.getAssignmentColumnId = this.getAssignmentColumnId.bind(this)
this.getAssignmentGroupColumnId = this.getAssignmentGroupColumnId.bind(this)
@ -365,7 +368,7 @@ class Gradebook {
this.getAssignmentGroupToShow = this.getAssignmentGroupToShow.bind(this)
this.isFilteringColumnsByGradingPeriod = this.isFilteringColumnsByGradingPeriod.bind(this)
this.isFilteringRowsBySearchTerm = this.isFilteringRowsBySearchTerm.bind(this)
this.getGradingPeriodToShow = this.getGradingPeriodToShow.bind(this)
this.getGradingPeriodAssignments = this.getGradingPeriodAssignments.bind(this)
this.getGradingPeriod = this.getGradingPeriod.bind(this)
this.setSelectedPrimaryInfo = this.setSelectedPrimaryInfo.bind(this)
this.toggleDefaultSort = this.toggleDefaultSort.bind(this)
@ -524,6 +527,7 @@ class Gradebook {
} else {
this.gradingPeriodSet = null
}
this.setCurrentGradingPeriod()
this.show_attendance = !!UserSettings.contextGet('show_attendance')
// preferences serialization causes these to always come
// from the database as strings
@ -758,46 +762,46 @@ class Gradebook {
return this.invalidateRowsForStudentIds(_.uniq(studentIds))
}
updateAssignmentGroups(assigmentGroups) {
this.gotAllAssignmentGroups(assigmentGroups)
this.contentLoadStates.assignmentsLoaded = true
updateAssignmentGroups(assignmentGroups, gradingPeriodIds) {
this.gotAllAssignmentGroups(assignmentGroups)
this.setAssignmentsLoaded(gradingPeriodIds)
this.renderViewOptionsMenu()
this.renderFilters()
this.updateColumnHeaders()
return this._updateEssentialDataLoaded()
}
gotAllAssignmentGroups(assignmentGroups) {
let assignment, group, j, len
this.setAssignmentGroupsLoaded(true)
// purposely passing the @options and assignmentGroups by reference so it can update
// an assigmentGroup's .group_weight and @options.group_weighting_scheme
const results = []
for (j = 0, len = assignmentGroups.length; j < len; j++) {
group = assignmentGroups[j]
this.assignmentGroups[group.id] = group
results.push(
function() {
let k, len1
const ref1 = group.assignments
const results1 = []
for (k = 0, len1 = ref1.length; k < len1; k++) {
assignment = ref1[k]
assignment.assignment_group = group
assignment.due_at = tz.parse(assignment.due_at)
this.updateAssignmentEffectiveDueDates(assignment)
results1.push((this.assignments[assignment.id] = assignment))
}
return results1
}.call(this)
)
}
return results
assignmentGroups.forEach(assignmentGroup => {
let group = this.assignmentGroups[assignmentGroup.id]
if (!group) {
group = assignmentGroup
this.assignmentGroups[group.id] = group
}
assignmentGroup.assignments.forEach(assignment => {
assignment.assignment_group = group
assignment.due_at = tz.parse(assignment.due_at)
this.updateAssignmentEffectiveDueDates(assignment)
this.addAssignmentColumnDefinition(assignment)
this.assignments[assignment.id] = assignment
})
})
}
updateGradingPeriodAssignments(gradingPeriodAssignments) {
this.gotGradingPeriodAssignments({
grading_period_assignments: gradingPeriodAssignments
})
Object.keys(gradingPeriodAssignments).forEach(periodId => {
this.contentLoadStates.assignmentsLoaded.gradingPeriod[
periodId
] = this.contentLoadStates.assignmentsLoaded.all
})
this.setGradingPeriodAssignmentsLoaded(true)
if (this._gridHasRendered()) {
this.updateColumns()
@ -805,6 +809,10 @@ class Gradebook {
return this._updateEssentialDataLoaded()
}
getGradingPeriodAssignments(gradingPeriodId) {
return this.courseContent.gradingPeriodAssignments[gradingPeriodId] || []
}
gotGradingPeriodAssignments({grading_period_assignments: gradingPeriodAssignments}) {
return (this.courseContent.gradingPeriodAssignments = gradingPeriodAssignments)
}
@ -1238,17 +1246,10 @@ class Gradebook {
}
filterAssignmentByGradingPeriod(assignment) {
let ref1
if (!this.isFilteringColumnsByGradingPeriod()) {
return true
}
return (
(ref1 = assignment.id),
indexOf.call(
this.courseContent.gradingPeriodAssignments[this.getGradingPeriodToShow()] || [],
ref1
) >= 0
)
if (!this.isFilteringColumnsByGradingPeriod()) return true
const assignmentsForPeriod = this.getGradingPeriodAssignments(this.gradingPeriodId)
return assignmentsForPeriod.includes(assignment.id)
}
filterAssignmentByModule(assignment) {
@ -1443,9 +1444,7 @@ class Gradebook {
const studentPeriodInfo = this.effectiveDueDates[submission.assignment_id]?.[
submission.user_id
]
return (
studentPeriodInfo && studentPeriodInfo.grading_period_id === this.getGradingPeriodToShow()
)
return studentPeriodInfo && studentPeriodInfo.grading_period_id === this.gradingPeriodId
})
}
@ -1476,7 +1475,7 @@ class Gradebook {
let grades = this.getStudentGrades(student, preferCachedGrades)
if (this.isFilteringColumnsByGradingPeriod()) {
grades = grades.gradingPeriods[this.getGradingPeriodToShow()]
grades = grades.gradingPeriods[this.gradingPeriodId]
}
const scoreType = this.viewUngradedAsZero() ? 'final' : 'current'
@ -1692,10 +1691,10 @@ class Gradebook {
indexOf.call(this.gridDisplaySettings.selectedViewOptionsFilters, 'gradingPeriods') >= 0
) {
props = {
disabled: false,
disabled: !this.contentLoadStates.assignmentsLoaded.all,
gradingPeriods: this.gradingPeriodList(),
onSelect: this.updateCurrentGradingPeriod,
selectedGradingPeriodId: this.getGradingPeriodToShow()
selectedGradingPeriodId: this.gradingPeriodId
}
return renderComponent(GradingPeriodFilter, mountPoint, props)
} else if (mountPoint != null) {
@ -1707,6 +1706,7 @@ class Gradebook {
updateCurrentGradingPeriod(period) {
if (this.getFilterColumnsBySetting('gradingPeriodId') !== period) {
this.setFilterColumnsBySetting('gradingPeriodId', period)
this.setCurrentGradingPeriod()
this.saveSettings()
this.resetGrading()
this.sortGridRows()
@ -1756,7 +1756,7 @@ class Gradebook {
initSubmissionStateMap() {
return (this.submissionStateMap = new SubmissionStateMap({
hasGradingPeriods: this.gradingPeriodSet != null,
selectedGradingPeriodID: this.getGradingPeriodToShow(),
selectedGradingPeriodID: this.gradingPeriodId,
isAdmin: isAdmin()
}))
}
@ -1878,7 +1878,7 @@ class Gradebook {
return {
criterion,
direction: storedSortOrder.direction || 'ascending',
disabled: !this.contentLoadStates.assignmentsLoaded,
disabled: !this.assignmentsLoadedForCurrentView(),
modulesEnabled: this.listContextModules().length > 0,
onSortByDefault: () => {
return this.arrangeColumnsBy(
@ -2024,7 +2024,7 @@ class Gradebook {
isEnabled: this.options.publish_to_sis_enabled,
publishToSisUrl: this.options.publish_to_sis_url
},
gradingPeriodId: this.getGradingPeriodToShow()
gradingPeriodId: this.gradingPeriodId
}
const progressData = this.options.gradebook_csv_progress
if (this.options.gradebook_csv_progress) {
@ -2409,17 +2409,11 @@ class Gradebook {
}
initGrid() {
let assignment, assignmentColumn, assignmentGroup, assignmentGroupColumn, id
let assignmentGroup, assignmentGroupColumn, id
this.updateFilteredContentInfo()
const studentColumn = this.buildStudentColumn()
this.gridData.columns.definitions[studentColumn.id] = studentColumn
this.gridData.columns.frozen.push(studentColumn.id)
const ref1 = this.assignments
for (id in ref1) {
assignment = ref1[id]
assignmentColumn = this.buildAssignmentColumn(assignment)
this.gridData.columns.definitions[assignmentColumn.id] = assignmentColumn
}
const ref2 = this.assignmentGroups
for (id in ref2) {
assignmentGroup = ref2[id]
@ -2434,6 +2428,13 @@ class Gradebook {
return this.createGrid()
}
addAssignmentColumnDefinition(assignment) {
const assignmentColumn = this.buildAssignmentColumn(assignment)
if (!this.gridData.columns.definitions[assignmentColumn.id]) {
this.gridData.columns.definitions[assignmentColumn.id] = assignmentColumn
}
}
createGrid() {
this.setVisibleGridColumns()
this.gradebookGrid.initialize()
@ -2882,7 +2883,7 @@ class Gradebook {
listHiddenAssignments(studentId) {
if (this.options.post_policies_enabled) {
if (!(this.contentLoadStates.submissionsLoaded && this.contentLoadStates.assignmentsLoaded)) {
if (!(this.contentLoadStates.submissionsLoaded && this.assignmentsLoadedForCurrentView())) {
return []
}
return Object.values(this.assignments).filter(assignment => {
@ -3530,8 +3531,30 @@ class Gradebook {
) // on success, do nothing since the render happened earlier
}
setAssignmentsLoaded(loaded) {
return (this.contentLoadStates.assignmentsLoaded = loaded)
assignmentsLoadedForCurrentView() {
const gradingPeriodId = this.gradingPeriodId
const loadStates = this.contentLoadStates.assignmentsLoaded
if (loadStates.all || gradingPeriodId === '0') {
return loadStates.all
}
return loadStates.gradingPeriod[gradingPeriodId]
}
setAssignmentsLoaded(gradingPeriodIds) {
const {assignmentsLoaded} = this.contentLoadStates
if (!gradingPeriodIds) {
assignmentsLoaded.all = true
Object.keys(assignmentsLoaded.gradingPeriod).forEach(periodId => {
assignmentsLoaded.gradingPeriod[periodId] = true
})
return
}
gradingPeriodIds.forEach(id => (assignmentsLoaded.gradingPeriod[id] = true))
if (Object.values(assignmentsLoaded.gradingPeriod).every(loaded => loaded)) {
assignmentsLoaded.all = true
}
}
setAssignmentGroupsLoaded(loaded) {
@ -3673,23 +3696,26 @@ class Gradebook {
}
isFilteringColumnsByGradingPeriod() {
return this.getGradingPeriodToShow() !== '0'
return this.gradingPeriodId !== '0'
}
isFilteringRowsBySearchTerm() {
return this.userFilterTerm != null && this.userFilterTerm !== ''
}
getGradingPeriodToShow() {
setCurrentGradingPeriod() {
if (this.gradingPeriodSet == null) {
return '0'
this.gradingPeriodId = '0'
return
}
const periodId =
this.getFilterColumnsBySetting('gradingPeriodId') || this.options.current_grading_period_id
if (indexOf.call(_.pluck(this.gradingPeriodSet.gradingPeriods, 'id'), periodId) >= 0) {
return periodId
if (this.gradingPeriodSet.gradingPeriods.some(period => period.id === periodId)) {
this.gradingPeriodId = periodId
} else {
return '0'
this.gradingPeriodId = '0'
}
}
@ -4294,6 +4320,7 @@ class Gradebook {
this.contentLoadStates.contextModulesLoaded &&
this.contentLoadStates.customColumnsLoaded &&
this.contentLoadStates.assignmentGroupsLoaded &&
this.assignmentsLoadedForCurrentView() &&
(!this.gradingPeriodSet || this.contentLoadStates.gradingPeriodAssignmentsLoaded)
) {
return this._essentialDataLoaded.resolve()

View File

@ -54,7 +54,7 @@ function getProps(column, gradebook, options) {
const assignment = gradebook.getAssignment(column.assignmentId)
const gradeSortDataLoaded =
gradebook.contentLoadStates.assignmentsLoaded &&
gradebook.assignmentsLoadedForCurrentView() &&
gradebook.contentLoadStates.studentsLoaded &&
gradebook.contentLoadStates.submissionsLoaded

View File

@ -26,7 +26,7 @@ function getProps(column, gradebook, options) {
const assignmentGroup = gradebook.getAssignmentGroup(column.assignmentGroupId)
const gradeSortDataLoaded =
gradebook.contentLoadStates.assignmentsLoaded &&
gradebook.assignmentsLoadedForCurrentView() &&
gradebook.contentLoadStates.studentsLoaded &&
gradebook.contentLoadStates.submissionsLoaded

View File

@ -25,7 +25,7 @@ function getProps(column, gradebook, gridSupport, options) {
const sortRowsBySetting = gradebook.getSortRowsBySetting()
const gradeSortDataLoaded =
gradebook.contentLoadStates.assignmentsLoaded &&
gradebook.assignmentsLoadedForCurrentView() &&
gradebook.contentLoadStates.studentsLoaded &&
gradebook.contentLoadStates.submissionsLoaded

View File

@ -83,8 +83,8 @@ export function getInitialGridDisplaySettings(settings, colors) {
export function getInitialContentLoadStates(options) {
return {
assignmentGroupsLoaded: false,
assignmentsLoaded: false,
contextModulesLoaded: !options.has_modules,
assignmentsLoaded: {all: false, gradingPeriod: {}},
customColumnsLoaded: false,
gradingPeriodAssignmentsLoaded: false,
overridesColumnUpdating: false,

View File

@ -226,19 +226,30 @@ class AssignmentGroup < ActiveRecord::Base
effective_due_dates.any_in_closed_grading_period?
end
def visible_assignments(user, includes=[])
self.class.visible_assignments(user, self.context, [self], includes)
def visible_assignments(user, includes: [], assignment_ids: [])
self.class.visible_assignments(
user,
self.context,
[self],
includes: includes,
assignment_ids: assignment_ids
)
end
def self.visible_assignments(user, context, assignment_groups, includes = [])
if context.grants_any_right?(user, :manage_grades, :read_as_admin, :manage_assignments)
scope = context.active_assignments.where(:assignment_group_id => assignment_groups)
def self.visible_assignments(user, context, assignment_groups, includes: [], assignment_ids: [])
scope = if context.grants_any_right?(user, :manage_grades, :read_as_admin, :manage_assignments)
context.active_assignments.where(:assignment_group_id => assignment_groups)
elsif user.nil?
scope = context.active_assignments.published.where(:assignment_group_id => assignment_groups)
context.active_assignments.published.where(:assignment_group_id => assignment_groups)
else
scope = user.assignments_visible_in_course(context).
where(:assignment_group_id => assignment_groups).published
user.assignments_visible_in_course(context).
where(:assignment_group_id => assignment_groups).published
end
if assignment_ids&.any?
scope = scope.where(id: assignment_ids)
end
includes.any? ? scope.preload(includes) : scope
end

View File

@ -145,7 +145,7 @@ class GradeSummaryPresenter
includes = [:assignment_overrides, :post_policy]
includes << :assignment_group if @assignment_order == :assignment_group
AssignmentGroup.
visible_assignments(student, @context, all_groups, includes).
visible_assignments(student, @context, all_groups, includes: includes).
where.not(submission_types: %w(not_graded wiki_page)).
except(:order)
end

View File

@ -213,6 +213,43 @@ describe AssignmentGroupsController do
end
end
describe 'filtering assignments by ID' do
before(:once) do
course_with_teacher(active_all: true)
@first_assignment = @course.assignments.create!(name: "Assignment 1")
@second_assignment = @course.assignments.create!(name: "Assignment 2")
end
it 'optionally filters assignments by ID' do
user_session(@teacher)
get :index, {
params: {
course_id: @course.id,
include: ['assignments'],
assignment_ids: [@second_assignment.id]
},
format: :json
}
expect(assignments_ids).to match_array [@second_assignment.id]
end
it 'does not return assignments outside the scope of the original result set' do
new_course = Course.create!
new_assignment = new_course.assignments.create!(name: "New Assignment")
user_session(@teacher)
get :index, {
params: {
course_id: @course.id,
include: ['assignments'],
assignment_ids: [@second_assignment.id, new_assignment.id]
},
format: :json
}
expect(assignments_ids).to match_array [@second_assignment.id]
end
end
context 'given a course with a teacher and a student' do
before :once do
course_with_teacher(active_all: true)

View File

@ -147,12 +147,16 @@ test('sets the submission state map .hasGradingPeriods to true when a grading pe
strictEqual(gradebook.submissionStateMap.hasGradingPeriods, true)
})
test('sets the submission state map .selectedGradingPeriodID to the "grading period to show"', () => {
const gradebook = createGradebook()
strictEqual(
gradebook.submissionStateMap.selectedGradingPeriodID,
gradebook.getGradingPeriodToShow()
)
test('sets the submission state map .selectedGradingPeriodID to the current grading period', () => {
const grading_period_set = {
id: '1501',
grading_periods: [
{id: '701', title: 'Grading Period 1', startDate: new Date(1)},
{id: '702', title: 'Grading Period 2', startDate: new Date(2)}
]
}
const gradebook = createGradebook({current_grading_period_id: '701', grading_period_set})
strictEqual(gradebook.submissionStateMap.selectedGradingPeriodID, '701')
})
test('adds teacher notes to custom columns when provided', () => {
@ -446,6 +450,7 @@ test('stores the final grade on the student if viewing ungraded as zero', functi
test('stores the current grade from the selected grading period if not viewing ungraded as zero', function() {
const gradebook = this.createGradebook()
gradebook.gradingPeriodId = '701'
gradebook.setFilterColumnsBySetting('gradingPeriodId', '701')
sandbox.stub(CourseGradeCalculator, 'calculate').returns(this.exampleGrades)
const student = {
@ -459,6 +464,7 @@ test('stores the current grade from the selected grading period if not viewing u
test('stores the final grade from the selected grading period if viewing ungraded as zero', function() {
const gradebook = this.createGradebook()
gradebook.gradingPeriodId = '701'
gradebook.courseFeatures.allowViewUngradedAsZero = true
gradebook.gridDisplaySettings.viewUngradedAsZero = true
gradebook.setFilterColumnsBySetting('gradingPeriodId', '701')
@ -730,6 +736,7 @@ test('returns false if there are no grading periods, even if isAllGradingPeriods
test('returns false if "All Grading Periods" is not selected', function() {
const gradebook = this.createGradebook()
gradebook.gradingPeriodId = '701'
gradebook.setFilterColumnsBySetting('gradingPeriodId', '701')
notOk(gradebook.hideAggregateColumns())
})
@ -2049,7 +2056,7 @@ QUnit.module('#listHiddenAssignments', hooks => {
}
}
gradebook.gotSubmissionsChunk(submissionsChunk)
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setSubmissionsLoaded(true)
})
@ -2243,13 +2250,11 @@ test('sets the direction', function() {
})
test('sets disabled to true when assignments have not been loaded yet', function() {
this.gradebook.setAssignmentsLoaded(false)
strictEqual(this.getProps().disabled, true)
})
test('sets disabled to false when assignments have been loaded', function() {
this.gradebook.setAssignmentsLoaded(true)
this.gradebook.setAssignmentsLoaded()
strictEqual(this.getProps().disabled, false)
})
@ -2988,6 +2993,23 @@ test('reloads student data after saving settings', function() {
strictEqual(this.gradebook.dataLoader.reloadStudentDataForSectionFilterChange.callCount, 1)
})
QUnit.module('Gradebook#getGradingPeriodAssignments', hooks => {
let gradebook
hooks.beforeEach(() => {
gradebook = createGradebook()
gradebook.gotGradingPeriodAssignments({grading_period_assignments: {14: ['3', '92', '11']}})
})
test('returns the assignments for the given grading period', () => {
deepEqual(gradebook.getGradingPeriodAssignments(14), ['3', '92', '11'])
})
test('returns an empty array if there are no assignments in the given period', () => {
deepEqual(gradebook.getGradingPeriodAssignments(23), [])
})
})
QUnit.module('Gradebook#updateGradingPeriodFilterVisibility', {
setup() {
const sectionsFilterContainerSelector = 'grading-periods-filter-container'
@ -3036,6 +3058,7 @@ test('renders the filter with a list of grading periods', function() {
test('sets the filter to show the selected grading period', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '702')
this.gradebook.setCurrentGradingPeriod()
this.gradebook.updateGradingPeriodFilterVisibility()
const filter = ContentFilterDriver.findWithLabelText('Grading Period Filter', this.container)
filter.clickToExpand()
@ -3924,6 +3947,7 @@ test('includes assignments from all grading periods when not filtering by gradin
test('excludes assignments from other grading periods when filtering by a grading period', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '1401')
this.gradebook.setCurrentGradingPeriod()
const assignments = this.gradebook.filterAssignments(this.assignments)
deepEqual(_.map(assignments, 'id'), ['2301'])
})
@ -5909,7 +5933,7 @@ test('sets the submission state map .hasGradingPeriods to false when no grading
test('sets the submission state map .selectedGradingPeriodID to the "grading period to show"', () => {
const gradebook = createGradebook()
sandbox.stub(gradebook, 'getGradingPeriodToShow').returns('1401')
gradebook.gradingPeriodId = '1401'
gradebook.initSubmissionStateMap()
strictEqual(gradebook.submissionStateMap.selectedGradingPeriodID, '1401')
})
@ -6253,6 +6277,7 @@ QUnit.module('Gradebook#isFilteringColumnsByGradingPeriod', {
this.gradebook = createGradebook()
this.gradebook.gradingPeriodSet = {id: '1501', gradingPeriods: [{id: '701'}, {id: '702'}]}
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '702')
this.gradebook.setCurrentGradingPeriod()
}
})
@ -6262,68 +6287,35 @@ test('returns true when the "filter columns by" setting includes a grading perio
test('returns false when the "filter columns by" setting includes the "all grading periods" value ("0")', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '0')
this.gradebook.setCurrentGradingPeriod()
strictEqual(this.gradebook.isFilteringColumnsByGradingPeriod(), false)
})
test('returns false when the "filter columns by" setting does not include a grading period', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', null)
this.gradebook.setCurrentGradingPeriod()
strictEqual(this.gradebook.isFilteringColumnsByGradingPeriod(), false)
})
test('returns false when the "filter columns by" setting does not include a valid grading period', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '799')
this.gradebook.setCurrentGradingPeriod()
strictEqual(this.gradebook.isFilteringColumnsByGradingPeriod(), false)
})
test('returns false when no grading period set exists', function() {
this.gradebook.gradingPeriodSet = null
this.gradebook.setCurrentGradingPeriod()
strictEqual(this.gradebook.isFilteringColumnsByGradingPeriod(), false)
})
test('returns true when the "filter columns by" setting is null and the current_grading_period_id is set', function() {
this.gradebook.options.current_grading_period_id = '701'
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', null)
this.gradebook.setCurrentGradingPeriod()
strictEqual(this.gradebook.isFilteringColumnsByGradingPeriod(), true)
})
QUnit.module('Gradebook#getGradingPeriodToShow', {
setup() {
this.gradebook = createGradebook()
this.gradebook.gradingPeriodSet = {id: '1501', gradingPeriods: [{id: '701'}, {id: '702'}]}
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '702')
}
})
test('returns the "filter columns by" setting when it includes a grading period', function() {
strictEqual(this.gradebook.getGradingPeriodToShow(), '702')
})
test('returns "0" when the "filter columns by" setting includes the "all grading periods" value ("0")', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '0')
strictEqual(this.gradebook.getGradingPeriodToShow(), '0')
})
test('returns "0" when the "filter columns by" setting does not include a grading period', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', null)
strictEqual(this.gradebook.getGradingPeriodToShow(), '0')
})
test('returns "0" when the "filter columns by" setting does not include a valid grading period', function() {
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', '799')
strictEqual(this.gradebook.getGradingPeriodToShow(), '0')
})
test('returns "0" when no grading period set exists', function() {
this.gradebook.gradingPeriodSet = null
strictEqual(this.gradebook.getGradingPeriodToShow(), '0')
})
test('returns the current_grading_period_id when set and the "filter columns by" setting is null', function() {
this.gradebook.options.current_grading_period_id = '701'
this.gradebook.setFilterColumnsBySetting('gradingPeriodId', null)
strictEqual(this.gradebook.getGradingPeriodToShow(), '701')
})
QUnit.module('Gradebook#setSelectedPrimaryInfo', {
setup() {
this.gradebook = createGradebook()
@ -9515,6 +9507,163 @@ QUnit.module('Gradebook#getSubmission', hooks => {
})
})
QUnit.module('Gradebook#addAssignmentColumnDefinition', hooks => {
let gradebook
hooks.beforeEach(() => {
gradebook = createGradebook()
})
test('adds a column definition for the given assignment', () => {
const assignment = {id: 12, name: 'Some Assignment'}
gradebook.addAssignmentColumnDefinition(assignment)
const definitions = gradebook.gridData.columns.definitions
ok(definitions.assignment_12)
})
test('ignores the assignment if a column definition already exists for it', () => {
const assignment = {id: 12, name: 'Some Assignment'}
gradebook.addAssignmentColumnDefinition(assignment)
gradebook.addAssignmentColumnDefinition(assignment)
const definitions = gradebook.gridData.columns.definitions
strictEqual(Object.keys(definitions).length, 1)
})
})
QUnit.module('Gradebook#assignmentsLoadedForCurrentView', hooks => {
let gradebook
hooks.beforeEach(() => {
gradebook = createGradebook()
})
test('returns false when assignments are not loaded', () => {
strictEqual(gradebook.assignmentsLoadedForCurrentView(), false)
})
test('returns true when assignments are loaded', () => {
gradebook.setAssignmentsLoaded()
strictEqual(gradebook.assignmentsLoadedForCurrentView(), true)
})
QUnit.module('when grading periods are used', contextHooks => {
contextHooks.beforeEach(() => {
gradebook.contentLoadStates.assignmentsLoaded = {
all: false,
gradingPeriod: {2: false, 14: false}
}
gradebook.gradingPeriodId = '14'
})
test('returns true when assignments are loaded for the current grading period', () => {
gradebook.setAssignmentsLoaded(['14'])
strictEqual(gradebook.assignmentsLoadedForCurrentView(), true)
})
test('returns false when assignments are not loaded', () => {
strictEqual(gradebook.assignmentsLoadedForCurrentView(), false)
})
test('returns false when assignments are loaded, but not for the current grading period', () => {
gradebook.setAssignmentsLoaded(['2'])
strictEqual(gradebook.assignmentsLoadedForCurrentView(), false)
})
})
})
QUnit.module('Gradebook#setAssignmentsLoaded', hooks => {
let gradebook
hooks.beforeEach(() => {
gradebook = createGradebook()
gradebook.contentLoadStates.assignmentsLoaded.gradingPeriod = {2: false, 59: false}
})
test('sets all assignments as loaded', () => {
gradebook.setAssignmentsLoaded()
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.all, true)
})
test('sets all grading periods as loaded', () => {
gradebook.setAssignmentsLoaded()
const gpLoadStates = Object.values(gradebook.contentLoadStates.assignmentsLoaded.gradingPeriod)
strictEqual(
gpLoadStates.every(loaded => loaded),
true
)
})
QUnit.module('when assignments are loaded for particular grading periods', () => {
test('sets assignments loaded for the expected grading period', () => {
gradebook.setAssignmentsLoaded(['59'])
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.gradingPeriod[59], true)
})
test('does not set assignments loaded for excluded grading periods', () => {
gradebook.setAssignmentsLoaded(['59'])
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.gradingPeriod[2], false)
})
test('sets all assignments loaded if all grading periods are loaded', () => {
gradebook.setAssignmentsLoaded(['59', '2'])
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.all, true)
})
test('does not set all assignments loaded if not all grading periods are loaded', () => {
gradebook.setAssignmentsLoaded(['59'])
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.all, false)
})
})
})
QUnit.module('Gradebook#setCurrentGradingPeriod', hooks => {
let gradebook
hooks.beforeEach(() => {
gradebook = createGradebook({
grading_period_set: {
id: '1501',
grading_periods: [
{id: '701', weight: 50},
{id: '702', weight: 50}
],
weighted: true
}
})
})
test('sets grading period id to "0" if no grading period set exists', () => {
gradebook.setFilterColumnsBySetting('gradingPeriodId', '702')
gradebook.gradingPeriodSet = null
gradebook.setCurrentGradingPeriod()
strictEqual(gradebook.gradingPeriodId, '0')
})
test('sets grading period id to "0" if "All Grading Periods" is selected', () => {
gradebook.setFilterColumnsBySetting('gradingPeriodId', '0')
gradebook.setCurrentGradingPeriod()
strictEqual(gradebook.gradingPeriodId, '0')
})
test('sets grading period id to the grading period being filtered by', () => {
gradebook.setFilterColumnsBySetting('gradingPeriodId', '702')
gradebook.setCurrentGradingPeriod()
strictEqual(gradebook.gradingPeriodId, '702')
})
test('if not filtered, sets grading period id to the current_grading_period_id', () => {
gradebook.options.current_grading_period_id = '702'
gradebook.setCurrentGradingPeriod()
strictEqual(gradebook.gradingPeriodId, '702')
})
test('if the saved grading period id is not in the set, sets period id to "0"', () => {
gradebook.options.current_grading_period_id = '1000'
gradebook.setCurrentGradingPeriod()
strictEqual(gradebook.gradingPeriodId, '0')
})
})
QUnit.module('Gradebook#toggleViewUngradedAsZero', hooks => {
let gradebook
@ -9627,6 +9776,7 @@ QUnit.module('Gradebook', suiteHooks => {
gradebook.setStudentIdsLoaded(true)
gradebook.setAssignmentGroupsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setContextModulesLoaded(true)
gradebook.setCustomColumnsLoaded(true)
}

View File

@ -130,6 +130,76 @@ QUnit.module('Gradebook > DataLoader > AssignmentGroupsLoader', suiteHooks => {
notOk(params.include.includes('module_ids'))
})
QUnit.module('when grading periods are in use', contextHooks => {
contextHooks.beforeEach(() => {
gradebook.gradingPeriodId = '3'
gradebook.gotGradingPeriodAssignments({
grading_period_assignments: {
3: ['1', '8', '12'],
19: ['4', '77', '99'],
66: ['3']
}
})
})
test('makes a single request if "All Grading Periods" is selected', async () => {
gradebook.gradingPeriodId = '0'
loadAssignmentGroups()
await network.allRequestsReady()
const requests = getRequests()
strictEqual(requests.length, 1)
})
test('makes two requests if a specific grading period is selected', async () => {
loadAssignmentGroups()
await network.allRequestsReady()
const requests = getRequests()
strictEqual(requests.length, 2)
})
test('makes one request to get assignments for the current grading period', async () => {
loadAssignmentGroups()
await network.allRequestsReady()
const {params} = getRequests()[0]
deepEqual(params.assignment_ids, ['1', '8', '12'])
})
test('makes another request to get assignments for all other grading periods', async () => {
loadAssignmentGroups()
await network.allRequestsReady()
const {params} = getRequests()[1]
deepEqual(params.assignment_ids, ['4', '77', '99', '3'])
})
test('excludes assignments in the second request that were present in the first', async () => {
gradebook.gotGradingPeriodAssignments({
grading_period_assignments: {
3: ['1', '2'],
19: ['2', '3']
}
})
loadAssignmentGroups()
await network.allRequestsReady()
const {params} = getRequests()[1]
deepEqual(params.assignment_ids, ['3'])
})
test('does not include duplicates in requested assignment ids', async () => {
gradebook.gotGradingPeriodAssignments({
grading_period_assignments: {
3: ['1', '2'],
19: ['3', '4'],
22: ['4', '5'],
89: ['5', '6', '7']
}
})
loadAssignmentGroups()
await network.allRequestsReady()
const {params} = getRequests()[1]
deepEqual(params.assignment_ids, ['3', '4', '5', '6', '7'])
})
})
QUnit.module('when sending the initial request', () => {
test('sets the `per_page` parameter to the configured per page maximum', async () => {
performanceControls = new PerformanceControls({assignmentGroupsPerPage: 45})

View File

@ -490,7 +490,10 @@ QUnit.module('Gradebook Grid Column Filtering', suiteHooks => {
grading_period_set: {
id: '1501',
display_totals_for_all_grading_periods: true,
grading_periods: [{id: '1401', title: 'GP1'}, {id: '1402', title: 'GP2'}]
grading_periods: [
{id: '1401', title: 'GP1'},
{id: '1402', title: 'GP2'}
]
}
})
})
@ -512,6 +515,7 @@ QUnit.module('Gradebook Grid Column Filtering', suiteHooks => {
test('optionally shows only assignment columns for the selected grading period at initial render', () => {
gradebook.setFilterColumnsBySetting('gradingPeriodId', '1401')
gradebook.setCurrentGradingPeriod()
addDataAndInitialize()
const expectedColumns = [
'assignment_2301',

View File

@ -51,7 +51,7 @@ QUnit.module('GradebookGrid TotalGradeOverrideCellFormatter', suiteHooks => {
}
}
sinon.stub(gradebook, 'isFilteringColumnsByGradingPeriod').returns(false)
sinon.stub(gradebook, 'getGradingPeriodToShow').returns('1501')
gradebook.gradingPeriodId = '1501'
})
suiteHooks.afterEach(() => {
@ -152,7 +152,7 @@ QUnit.module('GradebookGrid TotalGradeOverrideCellFormatter', suiteHooks => {
})
test('renders "" (en dash) when the student has no grade override for the selected grading period', () => {
gradebook.getGradingPeriodToShow.returns('1502')
gradebook.gradingPeriodId = '1502'
equal(getGrade(), '')
})
})
@ -182,7 +182,7 @@ QUnit.module('GradebookGrid TotalGradeOverrideCellFormatter', suiteHooks => {
})
test('renders "" (en dash) when the student has no grade override for the selected grading period', () => {
gradebook.getGradingPeriodToShow.returns('1502')
gradebook.gradingPeriodId = '1502'
equal(getGrade(), '')
})
})

View File

@ -734,18 +734,21 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => {
equal(component.props.sortBySetting.direction, 'ascending')
})
test('sets the "Sort by" disabled setting to true when assignments are not loaded', () => {
buildGradebook()
gradebook.setAssignmentsLoaded(false)
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()
strictEqual(component.props.sortBySetting.disabled, true)
})
QUnit.test(
'sets the "Sort by" disabled setting to true when assignments are not loaded',
() => {
buildGradebook()
gradebook.contentLoadStates.assignmentsLoaded.all = false
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()
strictEqual(component.props.sortBySetting.disabled, true)
}
)
test('sets the "Sort by" disabled setting to true when anonymize_students is true', () => {
buildGradebook()
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
assignment.anonymize_students = true
@ -755,7 +758,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => {
test('sets the "Sort by" disabled setting to true when students are not loaded', () => {
buildGradebook()
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(false)
gradebook.setSubmissionsLoaded(true)
render()
@ -764,7 +767,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => {
test('sets the "Sort by" disabled setting to true when submissions are not loaded', () => {
buildGradebook()
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(false)
render()
@ -773,7 +776,7 @@ QUnit.module('GradebookGrid AssignmentColumnHeaderRenderer', suiteHooks => {
test('sets the "Sort by" disabled setting to false when necessary data are loaded', () => {
buildGradebook()
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()

View File

@ -170,7 +170,7 @@ QUnit.module('GradebookGrid AssignmentGroupColumnHeaderRenderer', suiteHooks =>
})
test('sets the "Sort by" disabled setting to true when assignments are not loaded', () => {
gradebook.setAssignmentsLoaded(false)
gradebook.contentLoadStates.assignmentsLoaded.all = false
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()
@ -178,7 +178,7 @@ QUnit.module('GradebookGrid AssignmentGroupColumnHeaderRenderer', suiteHooks =>
})
test('sets the "Sort by" disabled setting to true when students are not loaded', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(false)
gradebook.setSubmissionsLoaded(true)
render()
@ -186,7 +186,7 @@ QUnit.module('GradebookGrid AssignmentGroupColumnHeaderRenderer', suiteHooks =>
})
test('sets the "Sort by" disabled setting to true when submissions are not loaded', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(false)
render()
@ -194,7 +194,7 @@ QUnit.module('GradebookGrid AssignmentGroupColumnHeaderRenderer', suiteHooks =>
})
test('sets the "Sort by" disabled setting to false when necessary data are loaded', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()

View File

@ -244,7 +244,7 @@ QUnit.module('GradebookGrid TotalGradeColumnHeaderRenderer', suiteHooks => {
})
test('sets the "Sort by" disabled setting to true when assignments are not loaded', () => {
gradebook.setAssignmentsLoaded(false)
gradebook.contentLoadStates.assignmentsLoaded.all = false
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()
@ -252,7 +252,7 @@ QUnit.module('GradebookGrid TotalGradeColumnHeaderRenderer', suiteHooks => {
})
test('sets the "Sort by" disabled setting to true when students are not loaded', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(false)
gradebook.setSubmissionsLoaded(true)
render()
@ -260,7 +260,7 @@ QUnit.module('GradebookGrid TotalGradeColumnHeaderRenderer', suiteHooks => {
})
test('sets the "Sort by" disabled setting to true when submissions are not loaded', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(false)
render()
@ -268,7 +268,7 @@ QUnit.module('GradebookGrid TotalGradeColumnHeaderRenderer', suiteHooks => {
})
test('sets the "Sort by" disabled setting to false when necessary data are loaded', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded()
gradebook.setStudentsLoaded(true)
gradebook.setSubmissionsLoaded(true)
render()

View File

@ -43,7 +43,7 @@ QUnit.module('Gradebook Data Loading: Content Load States', suiteHooks => {
})
test('sets assignments as "not loaded"', () => {
strictEqual(gradebook.contentLoadStates.assignmentsLoaded, false)
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.all, false)
})
test('sets assignment groups as "not loaded"', () => {
@ -77,14 +77,8 @@ QUnit.module('Gradebook Data Loading: Content Load States', suiteHooks => {
QUnit.module('#setAssignmentsLoaded()', () => {
test('optionally sets assignments as "loaded"', () => {
gradebook.setAssignmentsLoaded(true)
strictEqual(gradebook.contentLoadStates.assignmentsLoaded, true)
})
test('optionally sets assignments as "not loaded"', () => {
gradebook.setAssignmentsLoaded(true)
gradebook.setAssignmentsLoaded(false)
strictEqual(gradebook.contentLoadStates.assignmentsLoaded, false)
gradebook.setAssignmentsLoaded()
strictEqual(gradebook.contentLoadStates.assignmentsLoaded.all, true)
})
})

View File

@ -371,6 +371,7 @@ QUnit.module('Gradebook > Submissions', suiteHooks => {
createGradebookAndLoadData()
// Select "All Grading Periods"
gradebook.setFilterColumnsBySetting('gradingPeriodId', '0')
gradebook.setCurrentGradingPeriod()
deepEqual(getSubmissionIds().sort(), ['2501', '2502'])
})
@ -380,6 +381,7 @@ QUnit.module('Gradebook > Submissions', suiteHooks => {
createGradebookAndLoadData()
// Select "Q2"
gradebook.setFilterColumnsBySetting('gradingPeriodId', '1502')
gradebook.setCurrentGradingPeriod()
deepEqual(getSubmissionIds(), ['2502'])
})
})

View File

@ -51,23 +51,81 @@ describe AssignmentGroup do
expect(score.assignment_group_id).to be ag.id
end
context "visible assignments" do
context "visible_assignments" do
before(:each) do
@ag = @course.assignment_groups.create!(@valid_attributes)
@s = @course.course_sections.create!(name: "test section")
student_in_section(@s, user: @student)
assignments = (0...4).map { @course.assignments.create!({:title => "test_foo",
:assignment_group => @ag,
:points_possible => 10,
:only_visible_to_overrides => true})}
assignments.first.destroy
assignments.second.grade_student(@student, grade: 10, grader: @teacher)
assignment_to_override = assignments.last
create_section_override_for_assignment(assignment_to_override, course_section: @s)
assignments = (0...4).map do
@course.assignments.create!(
title: "test_foo",
assignment_group: @ag,
points_possible: 10,
only_visible_to_overrides: true
)
end
@destroyed_assignment = assignments.first
@destroyed_assignment.destroy
@assignment = assignments.second
@assignment.grade_student(@student, grade: 10, grader: @teacher)
@overridden_assignment = assignments.last
create_section_override_for_assignment(@overridden_assignment, course_section: @s)
@course.reload
@ag.reload
end
describe "class method" do
it "optionally scopes results to specific assignment IDs" do
assignment_ids = AssignmentGroup.visible_assignments(
@student,
@course,
[@ag],
assignment_ids: [@assignment.id]
).pluck(:id)
expect(assignment_ids).to match_array [@assignment.id]
end
it "does not include requested assignments that would otherwise not be returned" do
assignment_ids = AssignmentGroup.visible_assignments(
@student,
@course,
[@ag],
assignment_ids: [@assignment.id, @destroyed_assignment.id]
).pluck(:id)
expect(assignment_ids).to match_array [@assignment.id]
end
it "gracefully ignores assignment_ids if passed nil" do
assignment_ids = AssignmentGroup.visible_assignments(
@student,
@course,
[@ag],
assignment_ids: nil
).pluck(:id)
expect(assignment_ids).to match_array [@assignment.id, @overridden_assignment.id]
end
end
describe "instance method" do
it "optionally scopes results to specific assignment IDs" do
assignment_ids = @ag.visible_assignments(@student, assignment_ids: [@assignment.id]).pluck(:id)
expect(assignment_ids).to match_array [@assignment.id]
end
it "does not include requested assignments that would otherwise not be returned" do
assignment_ids = @ag.visible_assignments(
@student,
assignment_ids: [@assignment.id, @destroyed_assignment.id]
).pluck(:id)
expect(assignment_ids).to match_array [@assignment.id]
end
it "gracefully ignores assignment_ids if passed nil" do
assignment_ids = @ag.visible_assignments(@student, assignment_ids: nil).pluck(:id)
expect(assignment_ids).to match_array [@assignment.id, @overridden_assignment.id]
end
end
context "with differentiated assignments and draft state on" do
it "should return only active assignments with overrides or grades for the user" do
expect(@ag.active_assignments.count).to eq 3