DA - gb2 visibility data

fixes CNVS-9872
refs CNVS-14074

test plan:
 * turn on the differentiated assignments feature flag
 * edit an assignment so that not all sections can see it
 * using assignment groups API
 - in the request make sure to include "assignments" and "assignment_visibility"
 > there should be an assignment_visibility object within each assignment object
 > the assignment_visibility object should be an array of unique ids
 > the ids should only be students in sections that can see the assignment
   or students whose submissions were graded
 * using the assignments API
 - in the request make sure to include "assignment_visibility"
 > there should be an assignment_visibility object
 > it should be an array of unique ids
 > the ids should only be students in sections that can see the assignment
   or students whose submissions were graded

Change-Id: I68e832c3dc1859e398f656fa77804b2733f0dcd3
Reviewed-on: https://gerrit.instructure.com/36811
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
QA-Review: Amber Taniuchi <amber@instructure.com>
Product-Review: Simon Williams <simon@instructure.com>
This commit is contained in:
Cameron Sutter 2014-06-24 14:16:34 -06:00
parent 88afac883e
commit 228306d922
7 changed files with 156 additions and 38 deletions

View File

@ -27,9 +27,10 @@ class AssignmentGroupsApiController < ApplicationController
#
# Returns the assignment group with the given id.
#
# @argument include[] ["assignments"|"discussion_topic"]
# Associations to include with the group. "discussion_topic" is only valid
# if "assignments" is also included.
# @argument include[] ["assignments"|"discussion_topic"|"assignment_visibility"]
# Associations to include with the group. "discussion_topic" and "assignment_visibility"
# are only valid if "assignments" is also included. The "assignment_visibility" option additionally
# requires that the Differentiated Assignments course feature be turned on.
#
# @argument override_assignment_dates [Optional, Boolean]
# Apply assignment overrides for each assignment, defaults to true.

View File

@ -91,9 +91,10 @@ class AssignmentGroupsController < ApplicationController
# Returns the list of assignment groups for the current context. The returned
# groups are sorted by their position field.
#
# @argument include[] [String, "assignments"|"discussion_topic"|"all_dates"]
# Associations to include with the group. both "discussion_topic" and
# "all_dates" is only valid are only valid if "assignments" is also included.
# @argument include[] [String, "assignments"|"discussion_topic"|"all_dates"|"assignment_visibility"]
# Associations to include with the group. "discussion_topic", "all_dates"
# "assignment_visibility" are only valid are only valid if "assignments" is also included.
# The "assignment_visibility" option additionally requires that the Differentiated Assignments course feature be turned on.
#
# @argument override_assignment_dates [Optional, Boolean]
# Apply assignment overrides for each assignment, defaults to true.

View File

@ -389,7 +389,7 @@
# "type": "boolean"
# },
# "only_visible_to_overrides": {
# "description": "(Only visible if 'differentiated assignments' account setting is on) Whether the assignment is only visible to overrides.",
# "description": "(Only visible if the Differentiated Assignments course feature is turned on) Whether the assignment is only visible to overrides.",
# "example": false,
# "type": "boolean"
# },
@ -455,6 +455,11 @@
# "rubric": {
# "description": "(Optional) A list of scoring criteria and ratings for each rubric criterion. Included if there is an associated rubric.",
# "$ref": "RubricCriteria"
# },
# "assignment_visibility": {
# "description": "(Optional) If 'assignment_visibility' is included in the 'include' parameter, includes an array of student IDs who can see this assignment.",
# "example": "[137,381,572]",
# "type": "array"
# }
# }
# }
@ -466,8 +471,9 @@ class AssignmentsApiController < ApplicationController
# @API List assignments
# Returns the list of assignments for the current context.
# @argument include[] [String, "submission"]
# Associations to include with the assignment.
# @argument include[] [String, "submission"|"assignment_visibility"]
# Associations to include with the assignment. The "assignment_visibility" option
# requires that the Differentiated Assignments course feature be turned on.
# @argument search_term [Optional, String]
# The partial title of the assignments to match and return.
# @argument override_assignment_dates [Optional, Boolean]
@ -513,10 +519,13 @@ class AssignmentsApiController < ApplicationController
each { |a| a.has_no_overrides = true }
end
include_visibility = Array(params[:include]).include?('assignment_visibility')
hashes = assignments.map do |assignment|
submission = submissions[assignment.id]
assignment_json(assignment, @current_user, session,
submission: submission, override_dates: override_dates)
submission: submission, override_dates: override_dates,
include_visibility: include_visibility)
end
render :json => hashes
@ -525,8 +534,9 @@ class AssignmentsApiController < ApplicationController
# @API Get a single assignment
# Returns the assignment with the given id.
# @argument include[] [String, "submission"]
# Associations to include with the assignment.
# @argument include[] [String, "submission"|"assignment_visibility"]
# Associations to include with the assignment. The "assignment_visibility" option
# requires that the Differentiated Assignments course feature be turned on.
# @argument override_assignment_dates [Optional, Boolean]
# Apply assignment overrides to the assignment, defaults to true.
# @returns Assignment
@ -538,13 +548,16 @@ class AssignmentsApiController < ApplicationController
submission = @assignment.submissions.for_user(@current_user).first
end
include_visibility = Array(params[:include]).include?('assignment_visibility')
override_param = params[:override_assignment_dates] || true
override_dates = value_to_boolean(override_param)
@assignment.context_module_action(@current_user, :read) unless @assignment.locked_for?(@current_user, :check_policies => true)
render :json => assignment_json(@assignment, @current_user, session,
submission: submission,
override_dates: override_dates)
override_dates: override_dates,
include_visibility: include_visibility)
end
end

View File

@ -190,6 +190,10 @@ module Api::V1::Assignment
if assignment.context.feature_enabled?(:differentiated_assignments)
hash['only_visible_to_overrides'] = value_to_boolean(assignment.only_visible_to_overrides)
if opts[:include_visibility]
hash['assignment_visibility'] = assignment.students_with_visibility.pluck(:id).uniq
end
end
if submission = opts[:submission]

View File

@ -50,7 +50,8 @@ module Api::V1::AssignmentGroup
include_all_dates: includes.include?('all_dates'),
include_module_ids: includes.include?('module_ids'),
override_dates: opts[:override_assignment_dates],
preloaded_user_content_attachments: user_content_attachments)
preloaded_user_content_attachments: user_content_attachments,
include_visibility: includes.include?('assignment_visibility'))
}
end

View File

@ -129,40 +129,61 @@ describe AssignmentGroupsController, type: :request do
compare_json(json, expected)
end
it "should only return visible assignments when differentiated assignments is on" do
set_up_course_with_groups
set_up_four_assignments(only_visible_to_overrides: true)
@user.enrollments.each(&:delete)
@section = @course.course_sections.create!(name: "test section")
student_in_section(@section, user: @user)
# make a1 and a3 visible
create_section_override_for_assignment(@a1, course_section: @section)
@a3.grade_student(@user, {grade: 10})
context "differentiated assignments on" do
it "should only return visible assignments when differentiated assignments is on" do
set_up_course_with_groups
set_up_four_assignments(only_visible_to_overrides: true)
@user.enrollments.each(&:delete)
@section = @course.course_sections.create!(name: "test section")
student_in_section(@section, user: @user)
# make a1 and a3 visible
create_section_override_for_assignment(@a1, course_section: @section)
@a3.grade_student(@user, {grade: 10})
[@a1, @a2, @a3, @a4].each(&:reload)
[@a1, @a2, @a3, @a4].each(&:reload)
@course.enable_feature!(:differentiated_assignments)
@course.enable_feature!(:differentiated_assignments)
json = api_call(:get,
json = api_call(:get,
"/api/v1/courses/#{@course.id}/assignment_groups.json?include[]=assignments",
{ :controller => 'assignment_groups', :action => 'index',
:format => 'json', :course_id => @course.id.to_s,
:include => ['assignments'] })
json.each do |ag_json|
ag_json["assignments"].length.should == 1
json.each do |ag_json|
ag_json["assignments"].length.should == 1
end
@course.disable_feature!(:differentiated_assignments)
json = api_call(:get,
"/api/v1/courses/#{@course.id}/assignment_groups.json?include[]=assignments",
{ :controller => 'assignment_groups', :action => 'index',
:format => 'json', :course_id => @course.id.to_s,
:include => ['assignments'] })
json.each do |ag_json|
ag_json["assignments"].length.should == 2
end
end
@course.disable_feature!(:differentiated_assignments)
json = api_call(:get,
"/api/v1/courses/#{@course.id}/assignment_groups.json?include[]=assignments",
{ :controller => 'assignment_groups', :action => 'index',
:format => 'json', :course_id => @course.id.to_s,
:include => ['assignments'] })
json.each do |ag_json|
ag_json["assignments"].length.should == 2
it "should include assignment_visibility when requested" do
course_with_teacher active_all: true
@course.assignments.create!
@course.enable_feature!(:differentiated_assignments)
json = api_call(:get,
"/api/v1/courses/#{@course.id}/assignment_groups.json",
{
:controller => 'assignment_groups', :action => 'index',
:format => 'json', :course_id => @course.id.to_s
},
:include => ['assignments', 'assignment_visibility']
)
json.each do |ag|
ag["assignments"].each do |a|
a.has_key?("assignment_visibility").should == true
end
end
end
end
@ -386,6 +407,24 @@ describe AssignmentGroupsApiController, type: :request do
json['assignments'].should_not be_empty
end
it "should include assignment_visibility when requested and with DA on" do
@course.enable_feature!(:differentiated_assignments)
@course.assignments.create!(:title => "test", :assignment_group => @group, :points_possible => 10)
json = api_call(:get, "/api/v1/courses/#{@course.id}/assignment_groups/#{@group.id}.json",
{
:controller => 'assignment_groups_api',
:action => 'show',
:format => 'json',
:course_id => @course.id.to_s,
:assignment_group_id => @group.id.to_s
},
:include => ['assignments', 'assignment_visibility']
)
json['assignments'].each do |a|
a.has_key?("assignment_visibility").should == true
end
end
it 'should return never_drop rules as strings with Accept header' do
rules = {'never_drop' => ["1","2"], 'drop_lowest' => 1, 'drop_highest' => 1}
json = api_call(:get, "/api/v1/courses/#{@course.id}/assignment_groups/#{@group.id}", {

View File

@ -298,6 +298,21 @@ describe AssignmentsApiController, type: :request do
@json.has_key?('only_visible_to_overrides').should be_true
@json['only_visible_to_overrides'].should be_false
end
it "should include visibility data if included" do
@course.account.enable_feature!(:differentiated_assignments)
json = api_call(:get,
"/api/v1/courses/#{@course.id}/assignments.json",
{
:controller => 'assignments_api', :action => 'index',
:format => 'json', :course_id => @course.id.to_s
},
:include => ['assignment_visibility']
)
json.each do |a|
a.has_key?("assignment_visibility").should == true
end
end
end
it "includes submission info with include flag" do
@ -1814,6 +1829,50 @@ describe AssignmentsApiController, type: :request do
json['unpublishable'].should == false
end
end
context "differentiated assignments" do
before :once do
course_with_teacher_logged_in(:active_all => true)
@course.enable_feature!(:differentiated_assignments)
@assignment1 = @course.assignments.create! :only_visible_to_overrides => true
@assignment2 = @course.assignments.create! :only_visible_to_overrides => true
section1 = @course.course_sections.create!
section2 = @course.course_sections.create!
@student1 = User.create!(name: "Test Student")
@student2 = User.create!(name: "Test Student2")
@student3 = User.create!(name: "Test Student3")
student_in_section(section1, user: @student1)
student_in_section(section2, user: @student2)
student_in_section(section2, user: @student3)
create_section_override_for_assignment(@assignment1, {course_section: section1})
create_section_override_for_assignment(@assignment2, {course_section: section2})
end
def visibility_api_request(assignment)
api_call(:get,
"/api/v1/courses/#{@course.id}/assignments/#{assignment.id}.json",
{
:controller => 'assignments_api', :action => 'show',
:format => 'json', :course_id => @course.id.to_s,
:id => assignment.id.to_s
},
:include => ['assignment_visibility']
)
end
it "includes assignment_visibility" do
json = visibility_api_request @assignment1
json.has_key?("assignment_visibility").should == true
end
it "assignment_visibility includes the correct user_ids" do
json = visibility_api_request @assignment1
json["assignment_visibility"].include?(@student1.id).should == true
json = visibility_api_request @assignment2
json["assignment_visibility"].include?(@student2.id).should == true
json["assignment_visibility"].include?(@student3.id).should == true
end
end
end
describe "assignment_json" do