DA - quiz edit page

fixes CNVS-9766

test plan:
 * turn on the Differentiated Assignments feature flag
 * from the quiz edit page
  - add a due date for some of the sections, but not all
  - save (update quiz)
  > the only_visible_to_overrides flag on the quiz should be true
  > edit the quiz again and there should not be an
    empty due date row for 'Everyone else'
  - add a due date for all the sections
  - update the quiz
  > the only_visible_to_overrides flag should not be there
  - edit the quiz so that there are only due dates
    for some sections but not all
 * on the normal quiz show page and
 * on the new Quiz Statistics show page
  > there should not be a row in the due date area
    for 'Everyone else'
 - turn off the DA flag and make sure the quiz show page works
   with the 'New Quiz Stats page' flag and without it
 - make sure the edit page works with the DA flag off as well

Change-Id: Ifb090a195ff3283d963df12ae7a9eb503f32ee86
Reviewed-on: https://gerrit.instructure.com/34085
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Amber Taniuchi <amber@instructure.com>
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
Product-Review: Cameron Sutter <csutter@instructure.com>
This commit is contained in:
Cameron Sutter 2014-04-30 13:21:05 -06:00
parent 67835ce809
commit 79f45f569d
12 changed files with 100 additions and 9 deletions

View File

@ -79,6 +79,9 @@ define [
when 'graded_survey' then I18n.t 'graded_survey', 'Graded Survey'
when 'practice_quiz' then I18n.t 'practice_quiz', 'Practice Quiz'
).property('quizType')
onlyVisibleToOverrides: attr()
daEnabled: ENV.FLAGS.differentiated_assignments
differentiatedAssignmentsApplies: Em.computed.and('daEnabled', 'onlyVisibleToOverrides')
quizSubmissionHtmlUrl: attr()
quizSubmissionVersionsHtmlUrl: attr()
@ -97,7 +100,7 @@ define [
allDates: (->
dates = []
overrides = @get('assignmentOverrides').toArray()
if overrides.length == 0 || overrides.length != @get 'sectionCount'
if (overrides.length == 0 || overrides.length != @get 'sectionCount') && !@get 'differentiatedAssignmentsApplies'
title = if overrides.length > 0
I18n.t('everyone_else', 'Everyone Else')
else

View File

@ -4,6 +4,9 @@ define ['../shared/environment'], (env) ->
PERMISSIONS: {
manage: false,
update: false,
},
FLAGS: {
differentiated_assignments: true
}
}
env.setEnv ENV

View File

@ -121,6 +121,10 @@ define [
singleSectionDueDate: =>
_.find(@allDates(), 'dueAt')?.dueAt.toISOString() || @dueAt()
isOnlyVisibleToOverrides: (overrideFlag) ->
return @get('only_visible_to_overrides') || false unless arguments.length > 0
@set('only_visible_to_overrides', overrideFlag)
toView: =>
fields = [
'htmlUrl', 'multipleDueDates', 'allDates', 'dueAt', 'lockAt', 'unlockAt', 'singleSectionDueDate'

View File

@ -50,7 +50,8 @@ class Quizzes::QuizzesController < ApplicationController
:FLAGS => {
:question_banks => feature_enabled?(:question_banks),
:quiz_statistics => true,
:quiz_moderate => @context.feature_enabled?(:quiz_moderate)
:quiz_moderate => @context.feature_enabled?(:quiz_moderate),
:differentiated_assignments => @context.feature_enabled?(:differentiated_assignments)
})
# headless prevents inception in submission preview
@ -244,6 +245,7 @@ class Quizzes::QuizzesController < ApplicationController
sections = @context.course_sections.active
hash = { :ASSIGNMENT_ID => @assigment.present? ? @assignment.id : nil,
:ASSIGNMENT_OVERRIDES => assignment_overrides_json(@quiz.overrides_for(@current_user)),
:DIFFERENTIATED_ASSIGNMENTS_ENABLED => @context.feature_enabled?(:differentiated_assignments),
:QUIZ => quiz_json(@quiz, @context, @current_user, session),
:SECTION_LIST => sections.map { |section| { :id => section.id, :name => section.name } },
:QUIZZES_URL => course_quizzes_url(@context),
@ -282,6 +284,7 @@ class Quizzes::QuizzesController < ApplicationController
@quiz.content_being_saved_by(@current_user)
@quiz.infer_times
overrides = delete_override_params
params[:quiz].delete(:only_visible_to_overrides) unless @context.feature_enabled?(:differentiated_assignments)
@quiz.transaction do
@quiz.update_attributes!(params[:quiz])
batch_update_assignment_overrides(@quiz,overrides) unless overrides.nil?
@ -335,6 +338,7 @@ class Quizzes::QuizzesController < ApplicationController
auto_publish = @context.feature_enabled?(:draft_state) && @quiz.published?
@quiz.with_versioning(auto_publish) do
params[:quiz].delete(:only_visible_to_overrides) unless @context.feature_enabled?(:differentiated_assignments)
# using attributes= here so we don't need to make an extra
# database call to get the times right after save!
@quiz.attributes = params[:quiz]

View File

@ -37,7 +37,7 @@ class Quizzes::Quiz < ActiveRecord::Base
:require_lockdown_browser_for_results, :context, :notify_of_update,
:one_question_at_a_time, :cant_go_back, :show_correct_answers_at, :hide_correct_answers_at,
:require_lockdown_browser_monitor, :lockdown_browser_monitor_data,
:one_time_results
:one_time_results, :only_visible_to_overrides
attr_readonly :context_id, :context_type
attr_accessor :notify_of_update
@ -61,7 +61,8 @@ class Quizzes::Quiz < ActiveRecord::Base
:id, :title, :description, :quiz_data, :points_possible, :context_id, :context_type, :assignment_id, :workflow_state, :shuffle_answers, :show_correct_answers, :time_limit,
:allowed_attempts, :scoring_policy, :quiz_type, :created_at, :updated_at, :lock_at, :unlock_at, :deleted_at, :could_be_locked, :cloned_item_id, :unpublished_question_count,
:due_at, :question_count, :last_assignment_id, :published_at, :last_edited_at, :anonymous_submissions, :assignment_group_id, :hide_results, :ip_filter, :require_lockdown_browser,
:require_lockdown_browser_for_results, :one_question_at_a_time, :cant_go_back, :show_correct_answers_at, :hide_correct_answers_at, :require_lockdown_browser_monitor, :lockdown_browser_monitor_data
:require_lockdown_browser_for_results, :one_question_at_a_time, :cant_go_back, :show_correct_answers_at, :hide_correct_answers_at, :require_lockdown_browser_monitor, :lockdown_browser_monitor_data,
:only_visible_to_overrides
]
EXPORTABLE_ASSOCIATIONS = [:quiz_questions, :quiz_submissions, :quiz_groups, :quiz_statistics, :attachments, :quiz_regrades, :context, :assignment, :assignment_group]
@ -218,6 +219,7 @@ class Quizzes::Quiz < ActiveRecord::Base
assignment = self.assignment
assignment ||= self.context.assignments.build(:title => self.title, :due_at => self.due_at, :submission_types => 'online_quiz')
assignment.assignment_group_id = self.assignment_group_id
assignment.only_visible_to_overrides = self.only_visible_to_overrides
assignment.saved_by = :quiz
if context.feature_enabled?(:draft_state) && !deleted?
assignment.workflow_state = self.published? ? 'published' : 'unpublished'
@ -404,6 +406,7 @@ class Quizzes::Quiz < ActiveRecord::Base
a.due_at = self.due_at
a.lock_at = self.lock_at
a.unlock_at = self.unlock_at
a.only_visible_to_overrides = self.only_visible_to_overrides
a.submission_types = "online_quiz"
a.assignment_group_id = self.assignment_group_id
a.saved_by = :quiz

View File

@ -19,7 +19,7 @@ module Quizzes
:message_students_url, :quiz_submission_html_url, :section_count,
:moderate_url, :take_quiz_url, :quiz_extensions_url, :takeable,
:quiz_submissions_zip_url, :preview_url, :quiz_submission_versions_html_url,
:assignment_id, :one_time_results
:assignment_id, :one_time_results, :only_visible_to_overrides
def_delegators :@controller,
:api_v1_course_assignment_group_url,
@ -175,7 +175,9 @@ module Quizzes
:speed_grader_url,
:message_students_url,
:submitted_students,
:unsubmitted_students then user_may_grade?
:only_visible_to_overrides then user_may_grade?
when :unsubmitted_students then user_may_grade? || user_may_manage?
when :quiz_extensions_url,
:moderate_url,
@ -234,6 +236,7 @@ module Quizzes
hash['links']['quiz_statistics'] = hash.delete(:quiz_statistics_url)
hash['links']['quiz_reports'] = hash.delete(:quiz_reports_url)
end
hash.delete(:only_visible_to_overrides) unless quiz.context.feature_enabled?(:differentiated_assignments)
hash
end
@ -253,6 +256,10 @@ module Quizzes
api_v1_course_quiz_extensions_create_url(quiz.context, quiz)
end
def only_visible_to_overrides
quiz.only_visible_to_overrides || false
end
def stringify_ids?
!!(accepts_jsonapi? || stringify_json_ids?)
end

View File

@ -378,6 +378,18 @@
</div>
</fieldset>
<hr>
<% if @context.feature_enabled?(:differentiated_assignments) %>
<div class="text-center pad-box-mini" style="margin-bottom:10px">
<span>
<em>
<%= mt(:only_visible_to_overrides_note, "Note: This quiz is **only** visible to the section(s) specified below:") %>
</em>
</span>
</div>
<% end %>
<div class="js-assignment-overrides"></div>
</div>

View File

@ -0,0 +1,11 @@
class AddOnlyVisibleToOverridesToQuizzes < ActiveRecord::Migration
tag :predeploy
def self.up
add_column :quizzes, :only_visible_to_overrides, :boolean
end
def self.down
remove_column :quizzes, :only_visible_to_overrides
end
end

View File

@ -69,7 +69,7 @@ module DatesOverridable
def differentiated_assignments_applies?
return false if !context.feature_enabled?(:differentiated_assignments)
if self.is_a?(Assignment)
if self.is_a?(Assignment) || self.is_a?(Quizzes::Quiz)
self.only_visible_to_overrides
elsif self.assignment
self.assignment.only_visible_to_overrides

View File

@ -1555,6 +1555,9 @@ define([
data['quiz[allowed_attempts]'] = attempts;
overrideView.updateOverrides();
var overrides = overrideView.getOverrides();
if (ENV.DIFFERENTIATED_ASSIGNMENTS_ENABLED) {
data['quiz[only_visible_to_overrides]'] = overrideView.containsSectionsWithoutOverrides();
}
var quizData = overrideView.getDefaultDueDate();
if (quizData) {
quizData = quizData.toJSON().assignment_override;

View File

@ -213,10 +213,10 @@ describe Quizzes::Quiz do
end
it "should update the assignment it is associated with" do
a = @course.assignments.create!(:title => "some assignment", :points_possible => 5)
a = @course.assignments.create!(:title => "some assignment", :points_possible => 5, :only_visible_to_overrides => false)
a.points_possible.should eql(5.0)
a.submission_types.should_not eql("online_quiz")
q = @course.quizzes.build(:assignment_id => a.id, :title => "some quiz", :points_possible => 10)
q = @course.quizzes.build(:assignment_id => a.id, :title => "some quiz", :points_possible => 10, :only_visible_to_overrides => true)
q.workflow_state = 'available'
q.save
q.should be_available

View File

@ -491,4 +491,45 @@ describe Quizzes::QuizSerializer do
output[:due_at].should == quiz.due_at
end
describe "only_visible_to_overrides" do
context "as a teacher" do
before :once do
course_with_teacher_logged_in(active_all: true)
course_quiz(true)
end
it "returns the value when the feature flag is on" do
@quiz.context.stubs(:feature_enabled?).with(:differentiated_assignments).returns true
@quiz.only_visible_to_overrides = true
json = quiz_serializer(scope: @teacher).as_json
json[:quiz][:only_visible_to_overrides].should be_true
@quiz.only_visible_to_overrides = false
json = quiz_serializer(scope: @teacher).as_json
json[:quiz].should have_key :only_visible_to_overrides
json[:quiz][:only_visible_to_overrides].should be_false
end
it "is not in the hash when the feature flag is off" do
@quiz.only_visible_to_overrides = true
json = quiz_serializer(scope: @teacher).as_json
json[:quiz].should_not have_key :only_visible_to_overrides
end
end
context "as a student" do
before :once do
course_with_student_logged_in(active_all: true)
course_quiz(true)
end
it "is not in the hash" do
@quiz.only_visible_to_overrides = true
json = quiz_serializer(scope: @student).as_json
json[:quiz].should_not have_key :only_visible_to_overrides
end
end
end
end