filter assignments by overrides when necessary
build query that search for overrides but delegates to assignment if none exist fixes CNVS-20435 Change-Id: I0b88ccb78027e43a7d82c392a11b9980fff52174 Reviewed-on: https://gerrit.instructure.com/57176 Tested-by: Jenkins Reviewed-by: Strand McCutchen <smccutchen@instructure.com> QA-Review: Adrian Foong <afoong@instructure.com> Product-Review: Matt Fairbourn <mfairbourn@instructure.com>
This commit is contained in:
parent
153be42401
commit
570e6d3165
|
@ -106,89 +106,12 @@ class AssignmentGroupsController < ApplicationController
|
|||
# @returns [AssignmentGroup]
|
||||
def index
|
||||
if authorized_action(@context.assignment_groups.scoped.new, @current_user, :read)
|
||||
@groups = @context.assignment_groups.active
|
||||
|
||||
params[:include] = Array(params[:include])
|
||||
assignments_by_group = {}
|
||||
if params[:include].include? 'assignments'
|
||||
assignment_includes = [:rubric, :quiz, :external_tool_tag, :rubric_association]
|
||||
assignment_includes.concat(params[:include] & ["discussion_topic"])
|
||||
assignment_includes.concat([:assignment_overrides]) if params[:include].include?("all_dates")
|
||||
|
||||
all_visible_assignments = AssignmentGroup.visible_assignments(@current_user, @context, @groups, assignment_includes)
|
||||
.with_student_submission_count
|
||||
|
||||
if params[:grading_period_id].present? && multiple_grading_periods?
|
||||
all_visible_assignments = GradingPeriod
|
||||
.active
|
||||
.find(params[:grading_period_id])
|
||||
.assignments(all_visible_assignments)
|
||||
end
|
||||
|
||||
da_enabled = @context.feature_enabled?(:differentiated_assignments)
|
||||
include_visibility = Array(params[:include]).include?('assignment_visibility') && @context.grants_any_right?(@current_user, :read_as_admin, :manage_grades, :manage_assignments)
|
||||
if include_visibility && da_enabled
|
||||
assignment_visibilities = AssignmentStudentVisibility.users_with_visibility_by_assignment(course_id: @context.id, assignment_id: all_visible_assignments.map(&:id))
|
||||
else
|
||||
params[:include].delete('assignment_visibility')
|
||||
end
|
||||
|
||||
# because of a bug with including content_tags, we are preloading here rather than in
|
||||
# visible_assignments with multiple associations referencing content_tags table and therefore
|
||||
# aliased table names the conditons on has_many :context_module_tags will break
|
||||
if params[:include].include? "module_ids"
|
||||
module_includes = [:context_module_tags,{:discussion_topic => :context_module_tags},{:quiz => :context_module_tags}]
|
||||
ActiveRecord::Associations::Preloader.new(all_visible_assignments, module_includes).run
|
||||
end
|
||||
|
||||
assignments_by_group = all_visible_assignments.group_by(&:assignment_group_id)
|
||||
|
||||
unless params[:exclude_descriptions]
|
||||
assignment_descriptions = all_visible_assignments.map(&:description)
|
||||
user_content_attachments = api_bulk_load_user_content_attachments(
|
||||
assignment_descriptions, @context, @current_user
|
||||
)
|
||||
end
|
||||
|
||||
override_param = params[:override_assignment_dates] || true
|
||||
override_dates = value_to_boolean(override_param)
|
||||
if override_dates
|
||||
assignments_with_overrides = @context.assignments.active.except(:order)
|
||||
.joins(:assignment_overrides)
|
||||
.select("assignments.id")
|
||||
.uniq
|
||||
assignments_without_overrides = all_visible_assignments - assignments_with_overrides
|
||||
assignments_without_overrides.each { |a| a.has_no_overrides = true }
|
||||
end
|
||||
end
|
||||
|
||||
include_overrides = params[:include].include? 'overrides'
|
||||
assignments = visible_assignments(@context, @current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
json = @groups.map { |g|
|
||||
g.context = @context
|
||||
assignments = assignments_by_group[g.id] || []
|
||||
overrides = []
|
||||
if include_overrides
|
||||
ActiveRecord::Associations::Preloader.new(assignments, :assignment_overrides).run
|
||||
assignments.select{ |a| a.assignment_overrides.size == 0 }.
|
||||
each { |a| a.has_no_overrides = true }
|
||||
overrides = assignments.map{|assignment| assignment.assignment_overrides.active}
|
||||
end
|
||||
assignment_group_json(g, @current_user, session, params[:include],
|
||||
stringify_json_ids: stringify_json_ids?,
|
||||
override_assignment_dates: override_dates,
|
||||
preloaded_user_content_attachments: user_content_attachments,
|
||||
assignments: assignments,
|
||||
assignment_visibilities: assignment_visibilities,
|
||||
differentiated_assignments_enabled: da_enabled,
|
||||
exclude_descriptions: !!params[:exclude_descriptions],
|
||||
overrides: overrides.flatten
|
||||
)
|
||||
}
|
||||
render :json => json
|
||||
}
|
||||
format.json do
|
||||
render json: index_groups_json(@context, @current_user, assignments)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -294,4 +217,150 @@ class AssignmentGroupsController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assignments_by_group(visible_assignments)
|
||||
visible_assignments.group_by(&:assignment_group_id)
|
||||
end
|
||||
|
||||
def assignment_includes
|
||||
includes = [:rubric, :quiz, :external_tool_tag, :rubric_association]
|
||||
includes << "discussion_topic" if params[:include].include?("discussion_topic")
|
||||
includes << :assignment_overrides if params[:include].include?('all_dates')
|
||||
includes
|
||||
end
|
||||
|
||||
def assignment_visibilities(course)
|
||||
if include_visibility? && differentiated_assignments?
|
||||
AssignmentStudentVisibility.users_with_visibility_by_assignment(
|
||||
course_id: course.id,
|
||||
assignment_id: visible_assignment_ids
|
||||
)
|
||||
else
|
||||
params.fetch(:include, []).delete('assignment_visibility')
|
||||
AssignmentStudentVisibility.none
|
||||
end
|
||||
end
|
||||
|
||||
def differentiated_assignments?
|
||||
@context.feature_enabled?(:differentiated_assignments)
|
||||
end
|
||||
|
||||
def index_groups_json(context, current_user, visible_assignments)
|
||||
include_overrides = params.fetch(:include, []).include? 'overrides'
|
||||
|
||||
context.assignment_groups.active.map do |group|
|
||||
group.context = context
|
||||
assignments = assignments_by_group(visible_assignments)[group.id] || []
|
||||
overrides = []
|
||||
if include_overrides
|
||||
# TODO: use above?
|
||||
ActiveRecord::Associations::Preloader.new(assignments, :assignment_overrides).run
|
||||
|
||||
assignments.select{ |a| a.assignment_overrides.size == 0 }.
|
||||
each { |a| a.has_no_overrides = true }
|
||||
overrides = assignments.map{|assignment| assignment.assignment_overrides.active}
|
||||
end
|
||||
|
||||
assignment_group_json(
|
||||
group,
|
||||
current_user,
|
||||
session,
|
||||
params[:include],
|
||||
{
|
||||
stringify_json_ids: stringify_json_ids?,
|
||||
override_assignment_dates: override_dates?,
|
||||
preloaded_user_content_attachments: user_content_attachments(context, current_user),
|
||||
assignments: assignments,
|
||||
assignment_visibilities: assignment_visibilities(context),
|
||||
differentiated_assignments_enabled: differentiated_assignments?,
|
||||
exclude_descriptions: !!params[:exclude_descriptions],
|
||||
overrides: overrides.flatten
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def include_visibility?
|
||||
if Array(params[:include]).include?('assignment_visibility')
|
||||
@context.grants_any_right?(@current_user, :read_as_admin, :manage_grades, :manage_assignments)
|
||||
end
|
||||
end
|
||||
|
||||
def override_dates?
|
||||
value_to_boolean(params.fetch(:override_assignment_dates, true))
|
||||
end
|
||||
|
||||
def user_content_attachments(context, current_user)
|
||||
unless params[:exclude_descriptions]
|
||||
api_bulk_load_user_content_attachments(
|
||||
visible_assignment_descriptions, context, current_user
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def visible_assignment_descriptions
|
||||
visible_assignments(@context, @current_user).map(&:description)
|
||||
end
|
||||
|
||||
def visible_assignment_ids
|
||||
visible_assignments(@context, @current_user).map(&:id)
|
||||
end
|
||||
|
||||
def visible_assignments(context, current_user)
|
||||
if params[:include] && params[:include].include?('assignments')
|
||||
# TODO: possible keyword arguments refactor
|
||||
assignments = AssignmentGroup.visible_assignments(
|
||||
current_user,
|
||||
context,
|
||||
context.assignment_groups.active,
|
||||
assignment_includes
|
||||
).with_student_submission_count
|
||||
|
||||
if params[:grading_period_id].present? && multiple_grading_periods?
|
||||
grading_period = GradingPeriod.context_find(
|
||||
context,
|
||||
params.fetch(:grading_period_id)
|
||||
)
|
||||
|
||||
assignments = Assignment::FilterWithOverridesByDueAt.new(
|
||||
assignments: assignments,
|
||||
grading_period: grading_period,
|
||||
differentiated_assignments: differentiated_assignments?
|
||||
).filter_assignments
|
||||
end
|
||||
|
||||
# because of a bug with including content_tags, we are preloading
|
||||
# here rather than in assignments with multiple associations
|
||||
# referencing content_tags table and therefore aliased table names
|
||||
# the conditions on has_many :context_module_tags will break
|
||||
if params[:include].include? "module_ids"
|
||||
module_includes = [
|
||||
:context_module_tags,
|
||||
{ :discussion_topic => :context_module_tags },
|
||||
{ :quiz => :context_module_tags }
|
||||
]
|
||||
ActiveRecord::Associations::Preloader.new(assignments, module_includes).run
|
||||
end
|
||||
|
||||
# FIXME: determine if this code is necessary as it is potentially
|
||||
# dead code
|
||||
if override_dates?
|
||||
assignments_with_overrides = context
|
||||
.assignments
|
||||
.active
|
||||
.except(:order)
|
||||
.joins(:assignment_overrides)
|
||||
.select("assignments.id")
|
||||
.uniq
|
||||
assignments_without_overrides = assignments - assignments_with_overrides
|
||||
assignments_without_overrides.each { |a| a.has_no_overrides = true }
|
||||
end
|
||||
|
||||
assignments
|
||||
else
|
||||
Assignment.none
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
# API Filter Assignments by due_at and respect overrides
|
||||
#
|
||||
# Returns a list of assignments that have been filtered by assignment
|
||||
# due_at and assignment_overrides due_at fields. For example: if any
|
||||
# due_at fields fall within the date range then then corresponding
|
||||
# assignment is included.
|
||||
#
|
||||
# @argument assignments [ActiveRecord::Relation]
|
||||
#
|
||||
# @argument start_date [DateTime]
|
||||
|
||||
# @argument end_date [DateTime]
|
||||
#
|
||||
# @argument differentiated_assignments [Boolean]
|
||||
#
|
||||
# @public assignments
|
||||
#
|
||||
# @return [ Assignment ] assignments An array of assignments
|
||||
#
|
||||
# @example
|
||||
# Assignment::FilterWithoutOverridesByDueAt.new(
|
||||
# assignments: @context.assignments,
|
||||
# grading_period: grading_period
|
||||
# differentiated_assignments: @context.feature_enabled?(:differentiated_assignments)
|
||||
# )
|
||||
#
|
||||
|
||||
class Assignment::FilterWithOverridesByDueAt
|
||||
def initialize(assignments:, grading_period:, differentiated_assignments:)
|
||||
@assignments = assignments
|
||||
@differentiated_assignments = differentiated_assignments
|
||||
@grading_period = grading_period
|
||||
end
|
||||
|
||||
# @returns [Assignments]
|
||||
def filter_assignments
|
||||
assignments.select do |assignment|
|
||||
filter_criteria(assignment).any?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :assignments, :grading_period
|
||||
|
||||
def filter_criteria(assignment)
|
||||
[
|
||||
differentiated_assignments_and_any_assignment_overrides?(assignment) &&
|
||||
last_grading_period_and_any_overrides_with_due_at_nil?(assignment),
|
||||
|
||||
differentiated_assignments_and_any_assignment_overrides?(assignment) &&
|
||||
any_overrides_in_date_range?(assignment),
|
||||
|
||||
last_grading_period_and_assignment_due_at_nil?(assignment),
|
||||
|
||||
in_date_range_end_inclusive?(assignment)
|
||||
]
|
||||
end
|
||||
|
||||
def differentiated_assignments_and_any_assignment_overrides?(assignment)
|
||||
differentiated_assignments? && assignment.assignment_overrides.any?
|
||||
end
|
||||
|
||||
def last_grading_period_and_any_overrides_with_due_at_nil?(assignment)
|
||||
last_grading_period? && any_overrides_with_due_at_nil?(assignment)
|
||||
end
|
||||
|
||||
def last_grading_period_and_assignment_due_at_nil?(assignment)
|
||||
last_grading_period? && assignment.due_at.nil?
|
||||
end
|
||||
|
||||
def in_date_range_end_inclusive?(assignment_or_override)
|
||||
return false if assignment_or_override.due_at.nil?
|
||||
|
||||
grading_period.start_date < assignment_or_override.due_at &&
|
||||
assignment_or_override.due_at <= grading_period.end_date
|
||||
end
|
||||
|
||||
def differentiated_assignments?
|
||||
@differentiated_assignments
|
||||
end
|
||||
|
||||
def last_grading_period?
|
||||
@grading_period.last?
|
||||
end
|
||||
|
||||
def any_overrides_in_date_range?(assignment)
|
||||
assignment.assignment_overrides.any? do |override|
|
||||
in_date_range_end_inclusive?(override)
|
||||
end
|
||||
end
|
||||
|
||||
def any_overrides_with_due_at_nil?(assignment)
|
||||
assignment.assignment_overrides.any? do |override|
|
||||
override.due_at.nil?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -202,7 +202,7 @@ class AssignmentGroup < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def visible_assignments(user, includes=[])
|
||||
AssignmentGroup.visible_assignments(user, self.context, [self], includes)
|
||||
self.class.visible_assignments(user, self.context, [self], includes)
|
||||
end
|
||||
|
||||
def self.visible_assignments(user, context, assignment_groups, includes = [])
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
#
|
||||
# Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class GradingPeriod < ActiveRecord::Base
|
||||
include Canvas::SoftDeletable
|
||||
|
||||
|
@ -35,8 +53,13 @@ class GradingPeriod < ActiveRecord::Base
|
|||
.grading_periods
|
||||
end
|
||||
|
||||
def self.context_find(context, id)
|
||||
self.for(context).detect { |grading_period| grading_period.id == id.to_i }
|
||||
# Takes a context and a grading_period_id and returns a grading period
|
||||
# if it is in the for collection. Uses Enumberable#find to query
|
||||
# collection.
|
||||
def self.context_find(context, grading_period_id)
|
||||
self.for(context).find do |grading_period|
|
||||
grading_period.id == grading_period_id.to_i
|
||||
end
|
||||
end
|
||||
|
||||
def assignments(assignment_scope)
|
||||
|
|
|
@ -24,10 +24,12 @@ class GradingPeriod
|
|||
end
|
||||
|
||||
def grading_periods
|
||||
course_gps = GradingPeriod.active.grading_periods_by(course_id: course.id)
|
||||
course_gps.present? ?
|
||||
course_gps :
|
||||
periods = GradingPeriod.active.grading_periods_by(course_id: course.id)
|
||||
if periods.present?
|
||||
periods
|
||||
else
|
||||
AccountGradingPeriodFinder.new(course.account).grading_periods
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -63,7 +63,7 @@ describe AssignmentGroupsController, type: :request do
|
|||
course_with_teacher(:active_all => true)
|
||||
end
|
||||
|
||||
it "should sort the returned list of assignment groups" do
|
||||
it "sorts the returned list of assignment groups" do
|
||||
# the API returns the assignments sorted by
|
||||
# assignment_groups.position
|
||||
group1 = @course.assignment_groups.create!(:name => 'group1')
|
||||
|
|
|
@ -16,125 +16,174 @@
|
|||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
require_relative '../spec_helper'
|
||||
|
||||
describe AssignmentGroupsController do
|
||||
def course_assignment
|
||||
@assignment = @course.assignments.create(:title => "some assignment")
|
||||
end
|
||||
|
||||
def course_group
|
||||
@group = @course.assignment_groups.create(:name => "some group")
|
||||
@group = @course.assignment_groups.create(:name => 'some group')
|
||||
end
|
||||
|
||||
def group_assignment
|
||||
@assignment = @group.assignments.create(:name => "some group assignment")
|
||||
end
|
||||
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
end
|
||||
|
||||
describe "GET 'index'" do
|
||||
it "should require authorization" do
|
||||
get 'index', :course_id => @course.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should assign variables" do
|
||||
user_session(@student)
|
||||
get 'index', :course_id => @course.id, :format => :json
|
||||
expect(assigns[:groups]).not_to be_nil
|
||||
end
|
||||
|
||||
it "should retrieve course groups if they exist" do
|
||||
user_session(@student)
|
||||
course_group
|
||||
@group = course_group
|
||||
|
||||
get 'index', :course_id => @course.id, :format => :json
|
||||
|
||||
expect(assigns[:groups]).not_to be_nil
|
||||
expect(assigns[:groups]).not_to be_empty
|
||||
expect(assigns[:groups][1]).to eql(@group)
|
||||
end
|
||||
|
||||
context "differentiated assignments" do
|
||||
before do
|
||||
user_session(@teacher)
|
||||
course_group
|
||||
@group = course_group
|
||||
@course.enable_feature!(:differentiated_assignments)
|
||||
@assignment = @course.assignments.create!(title: "assignment",
|
||||
assignment_group: @group,
|
||||
only_visible_to_overrides: true,
|
||||
workflow_state: 'published')
|
||||
describe 'GET index' do
|
||||
describe 'filteing by grading period and overrides' do
|
||||
let!(:assignment) { course.assignments.create!(due_at: Date.new(2015, 1, 15)) }
|
||||
let!(:assignment_with_override) { course.assignments.create!(due_at: Date.new(2015, 1, 15)) }
|
||||
let!(:feb_override) do
|
||||
# mass assignment is disabled for AssigmentOverride
|
||||
assignment_with_override.assignment_overrides.new.tap do |override|
|
||||
override.title = 'feb override'
|
||||
override.due_at = Time.zone.local(2015, 2, 15)
|
||||
end.save!
|
||||
end
|
||||
it "should not check visibilities on individual assignemnts" do
|
||||
# ensures that check is not an N+1 from the gradebook
|
||||
Assignment.any_instance.expects(:students_with_visibility).never
|
||||
get 'index', :course_id => @course.id, :include => ["assignments","assignment_visibility"], :format => :json
|
||||
expect(response).to be_success
|
||||
|
||||
let(:jan_grading_period) do
|
||||
grading_period_group.grading_periods.create!(
|
||||
start_date: Date.new(2015, 1, 1),
|
||||
end_date: Date.new(2015, 1, 31),
|
||||
title: 'Jan Period'
|
||||
)
|
||||
end
|
||||
|
||||
let(:feb_grading_period) do
|
||||
grading_period_group.grading_periods.create!(
|
||||
start_date: Date.new(2015, 2, 1),
|
||||
end_date: Date.new(2015, 2, 28),
|
||||
title: 'Feb Period'
|
||||
)
|
||||
end
|
||||
|
||||
let(:grading_period_group) { course.grading_period_groups.create! }
|
||||
let(:course) { Course.create! }
|
||||
let(:root_account) { Account.default }
|
||||
let(:sub_account) { root_account.sub_accounts.create! }
|
||||
|
||||
context 'given a root account with a grading period and a sub account with a grading period' do
|
||||
before do
|
||||
root_account.allow_feature!(:multiple_grading_periods)
|
||||
root_account.enable_feature!(:multiple_grading_periods)
|
||||
root_account.enable_feature!(:differentiated_assignments)
|
||||
|
||||
account_admin_user(account: root_account)
|
||||
user_session(@admin)
|
||||
end
|
||||
|
||||
it 'when there is an assignment with overrides, filter grading periods by overrides due_at' do
|
||||
get :index,
|
||||
course_id: course.id,
|
||||
include: ['assignments', 'assignment_visibility', 'overrides'],
|
||||
override_assignment_dates: false,
|
||||
exclude_descriptions: true,
|
||||
grading_period_id: feb_grading_period.id,
|
||||
format: :json
|
||||
|
||||
json = JSON.parse(response.body[9..-1])
|
||||
assignments_ids = json.first['assignments'].map{|a| a['id']}
|
||||
expect(assignments_ids).to include assignment_with_override.id
|
||||
expect(assignments_ids).to_not include assignment.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "multiple grading periods feature enabled" do
|
||||
it "should not throw an error when grading_period_id is passed in as empty string" do
|
||||
@course.root_account.enable_feature!(:multiple_grading_periods)
|
||||
user_session(@teacher)
|
||||
get 'index', :course_id => @course.id, :include => ["assignments", "assignment_visibility"], :grading_period_id => "", :format => :json
|
||||
expect(response).to be_success
|
||||
context 'given a course with teach and a student in course' do
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
end
|
||||
|
||||
it 'requires authorization' do
|
||||
get 'index', :course_id => @course.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
context 'differentiated assignments' do
|
||||
before do
|
||||
user_session(@teacher)
|
||||
course_group
|
||||
@group = course_group
|
||||
@course.enable_feature!(:differentiated_assignments)
|
||||
@assignment = @course.assignments.create!(
|
||||
title: 'assignment',
|
||||
assignment_group: @group,
|
||||
only_visible_to_overrides: true,
|
||||
workflow_state: 'published'
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not check visibilities on individual assignemnts' do
|
||||
# ensures that check is not an N+1 from the gradebook
|
||||
Assignment.any_instance.expects(:students_with_visibility).never
|
||||
get 'index', :course_id => @course.id, :include => ['assignments','assignment_visibility'], :format => :json
|
||||
expect(response).to be_success
|
||||
end
|
||||
end
|
||||
|
||||
context 'multiple grading periods feature enabled' do
|
||||
before do
|
||||
@course.root_account.enable_feature!(:multiple_grading_periods)
|
||||
user_session(@teacher)
|
||||
end
|
||||
|
||||
it 'does not throw an error when grading_period_id is passed in as empty string' do
|
||||
get 'index', :course_id => @course.id, :include => ['assignments', 'assignment_visibility'], :grading_period_id => '', :format => :json
|
||||
expect(response).to be_success
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST 'reorder'" do
|
||||
it "should require authorization" do
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
end
|
||||
|
||||
it 'requires authorization' do
|
||||
post 'reorder', :course_id => @course.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should not allowe students to reorder" do
|
||||
it 'does not allow students to reorder' do
|
||||
user_session(@student)
|
||||
post 'reorder', :course_id => @course.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should reorder assignment groups" do
|
||||
it 'reorders assignment groups' do
|
||||
user_session(@teacher)
|
||||
groups = 3.times.map { course_group }
|
||||
expect(groups.map(&:position)).to eq [1, 2, 3]
|
||||
g1, g2, _ = groups
|
||||
post 'reorder', :course_id => @course.id, :order => "#{g2.id},#{g1.id}"
|
||||
expect(response).to be_success
|
||||
groups.each &:reload
|
||||
groups.each(&:reload)
|
||||
expect(groups.map(&:position)).to eq [2, 1, 3]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "POST 'reorder_assignments'"do
|
||||
before(:once) do
|
||||
@group1 = @course.assignment_groups.create!(:name => "group 1")
|
||||
@group2 = @course.assignment_groups.create!(:name => "group 2")
|
||||
@assignment1 = @course.assignments.create!(:title => "assignment 1", :assignment_group => @group1)
|
||||
@assignment2 = @course.assignments.create!(:title => "assignment 2", :assignment_group => @group1)
|
||||
@assignment3 = @course.assignments.create!(:title => "assignment 3", :assignment_group => @group2)
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
@group1 = @course.assignment_groups.create!(:name => 'group 1')
|
||||
@group2 = @course.assignment_groups.create!(:name => 'group 2')
|
||||
@assignment1 = @course.assignments.create!(:title => 'assignment 1', :assignment_group => @group1)
|
||||
@assignment2 = @course.assignments.create!(:title => 'assignment 2', :assignment_group => @group1)
|
||||
@assignment3 = @course.assignments.create!(:title => 'assignment 3', :assignment_group => @group2)
|
||||
@order = "#{@assignment1.id},#{@assignment2.id},#{@assignment3.id}"
|
||||
end
|
||||
it "should require authorization" do
|
||||
|
||||
it 'requires authorization' do
|
||||
post :reorder_assignments, :course_id => @course.id, :assignment_group_id => @assignment1.assignment_group.id, :order => @order
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should not allow students to reorder" do
|
||||
it 'does not allow students to reorder' do
|
||||
user_session(@student)
|
||||
post :reorder_assignments, :course_id => @course.id, :assignment_group_id => @assignment1.assignment_group.id, :order => @order
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should move the assingment from its current assignment group to another assignment group" do
|
||||
it 'moves the assingment from its current assignment group to another assignment group' do
|
||||
user_session(@teacher)
|
||||
expect(response).to be_success
|
||||
post :reorder_assignments, :course_id => @course.id, :assignment_group_id => @assignment1.assignment_group.id, :order => @order
|
||||
|
@ -146,95 +195,107 @@ describe AssignmentGroupsController do
|
|||
end
|
||||
|
||||
describe "GET 'show'" do
|
||||
before(:once) { course_group }
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
course_group
|
||||
end
|
||||
|
||||
it "should require authorization" do
|
||||
it 'requires authorization' do
|
||||
get 'show', :course_id => @course.id, :id => @group.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should assign variables" do
|
||||
it 'assigns variables' do
|
||||
user_session(@student)
|
||||
get 'show', :course_id => @course.id, :id => @group.id, :format => :json
|
||||
# response.should be_success
|
||||
expect(assigns[:assignment_group]).not_to be_nil
|
||||
expect(assigns[:assignment_group]).to eql(@group)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST 'create'" do
|
||||
it "should require authorization" do
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
end
|
||||
|
||||
it 'requires authorization' do
|
||||
post 'create', :course_id => @course.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should not allow students to create" do
|
||||
it 'does not allow students to create' do
|
||||
user_session(@student)
|
||||
post 'create', :course_id => @course.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should create a new group" do
|
||||
it 'creates a new group' do
|
||||
user_session(@teacher)
|
||||
post 'create', :course_id => @course.id, :assignment_group => {:name => "some test group"}
|
||||
post 'create', :course_id => @course.id, :assignment_group => {:name => 'some test group'}
|
||||
expect(response).to be_redirect
|
||||
expect(assigns[:assignment_group]).not_to be_nil
|
||||
expect(assigns[:assignment_group].name).to eql("some test group")
|
||||
expect(assigns[:assignment_group].name).to eql('some test group')
|
||||
expect(assigns[:assignment_group].position).to eql(1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "PUT 'update'" do
|
||||
before(:once) { course_group }
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
course_group
|
||||
end
|
||||
|
||||
it "should require authorization" do
|
||||
it 'requires authorization' do
|
||||
put 'update', :course_id => @course.id, :id => @group.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should not allow students to update" do
|
||||
it 'does not allow students to update' do
|
||||
user_session(@student)
|
||||
put 'update', :course_id => @course.id, :id => @group.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should update group" do
|
||||
it 'updates group' do
|
||||
user_session(@teacher)
|
||||
put 'update', :course_id => @course.id, :id => @group.id, :assignment_group => {:name => "new group name"}
|
||||
expect(assigns[:assignment_group]).not_to be_nil
|
||||
put 'update', :course_id => @course.id, :id => @group.id, :assignment_group => {:name => 'new group name'}
|
||||
expect(assigns[:assignment_group]).to eql(@group)
|
||||
expect(assigns[:assignment_group].name).to eql("new group name")
|
||||
expect(assigns[:assignment_group].name).to eql('new group name')
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE 'destroy'" do
|
||||
before(:once) { course_group }
|
||||
before :once do
|
||||
course_with_teacher(active_all: true)
|
||||
student_in_course(active_all: true)
|
||||
course_group
|
||||
end
|
||||
|
||||
it "should require authorization" do
|
||||
it 'requires authorization' do
|
||||
delete 'destroy', :course_id => @course.id, :id => @group.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should not allow students to delete" do
|
||||
it 'does not allow students to delete' do
|
||||
user_session(@student)
|
||||
delete 'destroy', :course_id => @course.id, :id => @group.id
|
||||
assert_unauthorized
|
||||
end
|
||||
|
||||
it "should delete group" do
|
||||
it 'deletes group' do
|
||||
user_session(@teacher)
|
||||
delete 'destroy', :course_id => @course.id, :id => @group.id
|
||||
expect(assigns[:assignment_group]).not_to be_nil
|
||||
expect(assigns[:assignment_group]).to eql(@group)
|
||||
expect(assigns[:assignment_group]).not_to be_frozen
|
||||
expect(assigns[:assignment_group]).to be_deleted
|
||||
end
|
||||
|
||||
it "should delete assignments in the group" do
|
||||
it 'delete assignments in the group' do
|
||||
user_session(@teacher)
|
||||
@group1 = @course.assignment_groups.create!(:name => "group 1")
|
||||
@assignment1 = @course.assignments.create!(:title => "assignment 1", :assignment_group => @group1)
|
||||
@group1 = @course.assignment_groups.create!(:name => 'group 1')
|
||||
@assignment1 = @course.assignments.create!(:title => 'assignment 1', :assignment_group => @group1)
|
||||
delete 'destroy', :course_id => @course.id, :id => @group1.id
|
||||
expect(assigns[:assignment_group]).to eql(@group1)
|
||||
expect(assigns[:assignment_group]).to be_deleted
|
||||
|
@ -243,12 +304,12 @@ describe AssignmentGroupsController do
|
|||
expect(@group1.assignments.active.length).to eql(0)
|
||||
end
|
||||
|
||||
it "should move assignments to a different group if specified" do
|
||||
it 'moves assignments to a different group if specified' do
|
||||
user_session(@teacher)
|
||||
@group1 = @course.assignment_groups.create!(:name => "group 1")
|
||||
@assignment1 = @course.assignments.create!(:title => "assignment 1", :assignment_group => @group1)
|
||||
@group2 = @course.assignment_groups.create!(:name => "group 2")
|
||||
@assignment2 = @course.assignments.create!(:title => "assignment 2", :assignment_group => @group2)
|
||||
@group1 = @course.assignment_groups.create!(:name => 'group 1')
|
||||
@assignment1 = @course.assignments.create!(:title => 'assignment 1', :assignment_group => @group1)
|
||||
@group2 = @course.assignment_groups.create!(:name => 'group 2')
|
||||
@assignment2 = @course.assignments.create!(:title => 'assignment 2', :assignment_group => @group2)
|
||||
expect(@assignment1.position).to eql(1)
|
||||
expect(@assignment1.assignment_group_id).to eql(@group1.id)
|
||||
expect(@assignment2.position).to eql(1)
|
||||
|
@ -267,13 +328,15 @@ describe AssignmentGroupsController do
|
|||
expect(@assignment2.assignment_group_id).to eql(@group1.id)
|
||||
end
|
||||
|
||||
it "does not allow users to delete assignment groups with frozen assignments" do
|
||||
it 'does not allow users to delete assignment groups with frozen assignments' do
|
||||
PluginSetting.stubs(:settings_for_plugin).returns(title: 'yes')
|
||||
user_session(@teacher)
|
||||
group = @course.assignment_groups.create!(name: "group 1")
|
||||
assignment = @course.assignments.create!(title: "assignment",
|
||||
assignment_group: group,
|
||||
freeze_on_copy: true)
|
||||
group = @course.assignment_groups.create!(name: 'group 1')
|
||||
assignment = @course.assignments.create!(
|
||||
title: 'assignment',
|
||||
assignment_group: group,
|
||||
freeze_on_copy: true
|
||||
)
|
||||
expect(assignment.position).to eq 1
|
||||
assignment.copied = true
|
||||
assignment.save!
|
||||
|
@ -281,9 +344,9 @@ describe AssignmentGroupsController do
|
|||
expect(response).not_to be_success
|
||||
end
|
||||
|
||||
it "should return JSON if requested" do
|
||||
it 'returns JSON if requested' do
|
||||
user_session(@teacher)
|
||||
delete 'destroy', :format => "json", :course_id => @course.id, :id => @group.id
|
||||
delete 'destroy', :format => 'json', :course_id => @course.id, :id => @group.id
|
||||
expect(response).to be_success
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,6 @@ def assignment_model(opts={})
|
|||
@group_category = course.group_categories.create(:name => group_category) if group_category
|
||||
opts[:group_category] = @group_category if @group_category
|
||||
@assignment = factory_with_protected_attributes(course.assignments, assignment_valid_attributes.merge(opts))
|
||||
expect(@assignment.context).to eq course
|
||||
@a = @assignment
|
||||
@c = course
|
||||
@a
|
||||
|
@ -33,7 +32,7 @@ def assignment_valid_attributes
|
|||
{
|
||||
:title => "value for title",
|
||||
:description => "value for description",
|
||||
:due_at => Time.now,
|
||||
:due_at => Time.zone.now,
|
||||
:points_possible => "1.5"
|
||||
}
|
||||
end
|
||||
|
|
|
@ -0,0 +1,431 @@
|
|||
require_relative '../../../app/models/assignment/filter_with_overrides_by_due_at'
|
||||
|
||||
describe Assignment::FilterWithOverridesByDueAt do
|
||||
describe '#filter_assignments' do
|
||||
subject(:assignments) do
|
||||
Assignment::FilterWithOverridesByDueAt.new(params).filter_assignments
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
assignments: course.assignments,
|
||||
grading_period: period,
|
||||
differentiated_assignments: differentiated_assignments
|
||||
}
|
||||
end
|
||||
|
||||
let!(:first_period) do
|
||||
group.grading_periods.create!(
|
||||
start_date: Time.zone.local(2015, 1, 1),
|
||||
end_date: Time.zone.local(2015, 1, 31),
|
||||
title: 'first period'
|
||||
)
|
||||
end
|
||||
|
||||
let!(:last_period) do
|
||||
group.grading_periods.create!(
|
||||
start_date: Time.zone.local(2015, 2, 1),
|
||||
end_date: Time.zone.local(2015, 2, 28),
|
||||
title: 'last period'
|
||||
)
|
||||
end
|
||||
|
||||
let(:group) { course.grading_period_groups.create! }
|
||||
let(:date_inside_first_range) { Time.zone.local(2015, 1, 15) }
|
||||
let(:date_inside_last_range) { Time.zone.local(2015, 2, 15) }
|
||||
let(:date_outside_range) { Time.zone.local(2999, 12, 31) }
|
||||
|
||||
let(:course) { account.courses.create! }
|
||||
let(:account) { Account.create! }
|
||||
|
||||
let(:assignment_graph_builder) do
|
||||
-> (assignment_property:, override_property:, period:) do
|
||||
date_inside_range = date_range_selector.call(period)
|
||||
|
||||
assignment = assignment_builder.call(
|
||||
assignment_property,
|
||||
date_inside_range
|
||||
)
|
||||
|
||||
assignment = override_builder.call(
|
||||
assignment,
|
||||
override_property,
|
||||
date_inside_range
|
||||
)
|
||||
|
||||
assignment
|
||||
end
|
||||
end
|
||||
|
||||
let(:date_range_selector) do
|
||||
-> (period) do
|
||||
if period.last?
|
||||
date_inside_last_range
|
||||
else
|
||||
date_inside_first_range
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:assignment_builder) do
|
||||
-> (assignment_property, date_inside_range) do
|
||||
case assignment_property
|
||||
when :in
|
||||
course.assignments.create!(
|
||||
due_at: date_inside_range,
|
||||
workflow_state: 'active'
|
||||
)
|
||||
when nil
|
||||
course.assignments.create!(
|
||||
due_at: nil,
|
||||
workflow_state: 'active'
|
||||
)
|
||||
when :out
|
||||
course.assignments.create!(
|
||||
due_at: date_outside_range,
|
||||
workflow_state: 'active'
|
||||
)
|
||||
else
|
||||
raise AssignmentCaseNotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:override_builder) do
|
||||
-> (assignment, override_property, date_inside_range) do
|
||||
case override_property
|
||||
when :in
|
||||
assignment.assignment_overrides.build do |override|
|
||||
override.due_at = date_inside_range
|
||||
override.workflow_state = 'active'
|
||||
override.title = 'override inside range'
|
||||
end.save!
|
||||
assignment
|
||||
when nil
|
||||
assignment.assignment_overrides.build do |override|
|
||||
override.due_at = nil
|
||||
override.workflow_state = 'active'
|
||||
override.title = 'override with nil due_at'
|
||||
end.save!
|
||||
assignment
|
||||
when :none
|
||||
assignment
|
||||
when :out
|
||||
assignment.assignment_overrides.build do |override|
|
||||
override.due_at = date_outside_range
|
||||
override.workflow_state = 'active'
|
||||
override.title = 'override with nil due_at'
|
||||
end.save!
|
||||
assignment
|
||||
else
|
||||
raise OverrideCaseNotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:builder_params) do
|
||||
{
|
||||
assignment_property: assignment_property,
|
||||
override_property: override_property,
|
||||
period: period
|
||||
}
|
||||
end
|
||||
|
||||
context 'differentiated assignments is false' do
|
||||
# differentiated assignments implies :none for override_property
|
||||
let(:differentiated_assignments) { false }
|
||||
let(:override_property) { :none }
|
||||
|
||||
context 'not the last grading period' do
|
||||
let(:period) { first_period }
|
||||
|
||||
context 'given an assignment with no due at' do
|
||||
let(:assignment_property) { nil }
|
||||
it 'does not select assignments' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment with a due at in range' do
|
||||
let(:assignment_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment = assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to eql [assignment]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment with a due at outside the range' do
|
||||
let(:assignment_property) { :out }
|
||||
it 'does not select the assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'last grading period' do
|
||||
let(:period) { last_period }
|
||||
|
||||
context 'given an assignment with no due at' do
|
||||
let(:assignment_property) { nil }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_nil_due_at = assignment_graph_builder
|
||||
.call(builder_params)
|
||||
expect(assignments).to eql [assignment_with_nil_due_at]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment with a due at in range' do
|
||||
let(:assignment_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_in_range = assignment_graph_builder
|
||||
.call(builder_params)
|
||||
expect(assignments).to eql [assignment_in_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment with a due at outside the range' do
|
||||
let(:assignment_property) { :out }
|
||||
it 'selects the assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to eql []
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'differentiated assignments is true' do
|
||||
let(:differentiated_assignments) { true }
|
||||
|
||||
context 'not the last grading period' do
|
||||
let(:period) { first_period }
|
||||
|
||||
context 'given an assignment with no due at' do
|
||||
let(:assignment_property) { nil }
|
||||
|
||||
context 'given an override with no due at' do
|
||||
let(:override_property) { nil }
|
||||
it 'does not select assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to eql []
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override in range' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_no_due_at_and_an_override_in_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_no_due_at_and_an_override_in_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override outside the range' do
|
||||
let(:override_property) { :out }
|
||||
it 'does not select the assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to eql []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment in range' do
|
||||
let(:assignment_property) { :in }
|
||||
context 'given an override with no due at' do
|
||||
let(:override_property) { nil }
|
||||
it 'selects the assignment' do
|
||||
assignment_in_range = assignment_graph_builder
|
||||
.call(builder_params)
|
||||
expect(assignments).to eql [assignment_in_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override in range' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_in_range_with_an_override_in_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_in_range_with_an_override_in_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override outside the range' do
|
||||
let(:override_property) { :out }
|
||||
it 'selects the assignment' do
|
||||
assignment_in_range_and_override_outside_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_in_range_and_override_outside_range]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment outside the range' do
|
||||
let(:assignment_property) { :out }
|
||||
|
||||
context 'given an override with no due at' do
|
||||
let(:override_property) { nil }
|
||||
it 'does not select assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to eql []
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override in the range' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_override_in_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_override_in_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override outside the range' do
|
||||
let(:override_property) { :out }
|
||||
it 'does not select the assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the grading period is the last in the group' do
|
||||
let(:period) { last_period }
|
||||
|
||||
context 'given an assignment with no due at' do
|
||||
let(:assignment_property) { nil }
|
||||
|
||||
context 'given an override with no due at' do
|
||||
let(:override_property) { nil }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_override_and_no_due_ats =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_override_and_no_due_ats]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override in range' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_no_due_at_and_override_in_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_no_due_at_and_override_in_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override outside the range' do
|
||||
let(:override_property) { :out }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_no_due_at_and_override_outside_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_no_due_at_and_override_outside_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given no override' do
|
||||
let(:override_property) { :none }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_no_due_at_and_no_override =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_no_due_at_and_no_override]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment in the date range' do
|
||||
let(:assignment_property) { :in }
|
||||
|
||||
context 'given an override with no due at' do
|
||||
let(:override_property) { nil }
|
||||
it 'selects the assignment' do
|
||||
assignment_in_date_range_and_override_with_no_due_at =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_in_date_range_and_override_with_no_due_at]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override in range' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_with_override_both_inside_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_with_override_both_inside_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override outside the range' do
|
||||
let(:override_property) { :out }
|
||||
it 'selects the assignment' do
|
||||
assignment_inside_range_and_override_outside_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_inside_range_and_override_outside_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given no override' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_in_range_and_no_override =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_in_range_and_no_override]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an assignment outside the date range' do
|
||||
let(:assignment_property) { :out }
|
||||
|
||||
context 'given an override with no due at' do
|
||||
let(:override_property) { nil }
|
||||
it 'selects the assignment' do
|
||||
assignment_outside_date_range_and_override_with_no_due_at =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_outside_date_range_and_override_with_no_due_at]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given no override' do
|
||||
let(:override_property) { :none }
|
||||
it 'selects the assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override in range' do
|
||||
let(:override_property) { :in }
|
||||
it 'selects the assignment' do
|
||||
assignment_outside_and_override_inside_range =
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments)
|
||||
.to eql [assignment_outside_and_override_inside_range]
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an override outside the range' do
|
||||
let(:override_property) { :out }
|
||||
it 'does not select the assignment' do
|
||||
assignment_graph_builder.call(builder_params)
|
||||
expect(assignments).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,82 +4,93 @@ require File.expand_path(File.dirname(__FILE__) + '/helpers/groups_common')
|
|||
describe "gradebook2" do
|
||||
include_context "in-process server selenium tests"
|
||||
|
||||
context "multiple grading periods" do
|
||||
let!(:enable_mgp_and_navigate_to_gradebook) do
|
||||
describe "multiple grading periods" do
|
||||
let!(:enable_mgp) do
|
||||
course_with_admin_logged_in
|
||||
student_in_course
|
||||
@course.root_account.enable_feature!(:multiple_grading_periods)
|
||||
group = @course.root_account.grading_period_groups.create
|
||||
group.grading_periods.create start_date: 4.months.ago,
|
||||
end_date: 2.months.ago,
|
||||
title: "Period in the Past"
|
||||
group.grading_periods.create start_date: 1.month.ago,
|
||||
end_date: 2.months.from_now,
|
||||
title: "Current Period"
|
||||
end
|
||||
|
||||
let(:select_period_in_the_past) do
|
||||
f(".grading-period-select-button").click
|
||||
f("#ui-id-4").click # The id of the Period in the Past
|
||||
end
|
||||
|
||||
let(:sign_in_as_a_teacher) do
|
||||
teacher_in_course
|
||||
user_session(@teacher)
|
||||
end
|
||||
|
||||
let(:uneditable_cells) { f('.cannot_edit') }
|
||||
let(:gradebook_header) { f('#gradebook_grid .container_1 .slick-header') }
|
||||
|
||||
it "should load gradebook when no grading periods have been created", priority: "1", test_id: 210011 do
|
||||
it "loads gradebook when no grading periods have been created", priority: "1", test_id: 210011 do
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
expect(f('#gradebook-grid-wrapper')).to be_displayed
|
||||
end
|
||||
|
||||
context "assignments in past grading periods" do
|
||||
let!(:assignment_in_the_past) do
|
||||
@course.assignments.create! due_at: 3.months.ago,
|
||||
title: "past-due assignment"
|
||||
describe 'with a current and past grading period' do
|
||||
let!(:create_period_group_and_default_periods) do
|
||||
group = @course.root_account.grading_period_groups.create
|
||||
group.grading_periods.create(
|
||||
start_date: 4.months.ago,
|
||||
end_date: 2.months.ago,
|
||||
title: "Period in the Past"
|
||||
)
|
||||
group.grading_periods.create(
|
||||
start_date: 1.month.ago,
|
||||
end_date: 2.months.from_now,
|
||||
title: "Current Period"
|
||||
)
|
||||
end
|
||||
|
||||
it "admins should be able to edit", priority: "1", test_id: 210012 do
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
|
||||
select_period_in_the_past
|
||||
expect(gradebook_header).to include_text("past-due assignment")
|
||||
expect(uneditable_cells).to_not be_present
|
||||
let(:select_period_in_the_past) do
|
||||
f(".grading-period-select-button").click
|
||||
f("#ui-id-4").click # The id of the Period in the Past
|
||||
end
|
||||
|
||||
it "teachers should not be able to edit", priority: "1", test_id: 210023 do
|
||||
sign_in_as_a_teacher
|
||||
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
|
||||
select_period_in_the_past
|
||||
expect(gradebook_header).to include_text("past-due assignment")
|
||||
expect(uneditable_cells).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context "assignments with no due_at" do
|
||||
let!(:assignment_without_due_at) do
|
||||
@course.assignments.create! title: "No Due Date"
|
||||
let(:sign_in_as_a_teacher) do
|
||||
teacher_in_course
|
||||
user_session(@teacher)
|
||||
end
|
||||
|
||||
it "admins should be able to edit", priority: "1", test_id: 210014 do
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
let(:uneditable_cells) { f('.cannot_edit') }
|
||||
let(:gradebook_header) { f('#gradebook_grid .container_1 .slick-header') }
|
||||
|
||||
expect(gradebook_header).to include_text("No Due Date")
|
||||
expect(uneditable_cells).to_not be_present
|
||||
context "assignments in past grading periods" do
|
||||
let!(:assignment_in_the_past) do
|
||||
@course.assignments.create!(
|
||||
due_at: 3.months.ago,
|
||||
title: "past-due assignment"
|
||||
)
|
||||
end
|
||||
|
||||
it "admins should be able to edit", priority: "1", test_id: 210012 do
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
|
||||
select_period_in_the_past
|
||||
expect(gradebook_header).to include_text("past-due assignment")
|
||||
expect(uneditable_cells).to_not be_present
|
||||
end
|
||||
|
||||
it "teachers should not be able to edit", priority: "1", test_id: 210023 do
|
||||
sign_in_as_a_teacher
|
||||
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
|
||||
select_period_in_the_past
|
||||
expect(gradebook_header).to include_text("past-due assignment")
|
||||
expect(uneditable_cells).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
it "teachers should be able to edit", priority: "1", test_id: 210015 do
|
||||
sign_in_as_a_teacher
|
||||
context "assignments with no due_at" do
|
||||
let!(:assignment_without_due_at) do
|
||||
@course.assignments.create! title: "No Due Date"
|
||||
end
|
||||
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
it "admins should be able to edit", priority: "1", test_id: 210014 do
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
|
||||
expect(gradebook_header).to include_text("No Due Date")
|
||||
expect(uneditable_cells).to_not be_present
|
||||
expect(gradebook_header).to include_text("No Due Date")
|
||||
expect(uneditable_cells).to_not be_present
|
||||
end
|
||||
|
||||
it "teachers should be able to edit", priority: "1", test_id: 210015 do
|
||||
sign_in_as_a_teacher
|
||||
|
||||
get "/courses/#{@course.id}/gradebook2"
|
||||
|
||||
expect(gradebook_header).to include_text("No Due Date")
|
||||
expect(uneditable_cells).to_not be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue