api: support turnitin_settings in assignment api

fixes #CNVS-2598

test plan:
- on an assignment in a course with turnitin enabled
- make sure turnitin_settings are returned in the api
- make sure you can modify them

Change-Id: Ief9465ef3ef9f1d180dd551dcb846b25bc63b3fa
Reviewed-on: https://gerrit.instructure.com/16583
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Amber Taniuchi <amber@instructure.com>
Reviewed-by: Stanley Stuart <stanley+gerrit@instructure.com>
This commit is contained in:
Simon Williams 2013-01-04 16:11:25 -07:00
parent 389bcb4ed2
commit 9038175eb4
7 changed files with 188 additions and 32 deletions

View File

@ -61,6 +61,29 @@
# // Turnitin plugin available
# turnitin_enabled: true,
#
# // Settings to pass along to turnitin to control what kinds of matches
# // should be considered.
# // originality_report_visibility can be 'immediate', 'after_grading', or 'after_due_date'
# // exclude_small_matches_type can be null, 'percent', 'words'
# // exclude_small_matches_value:
# // - if type is null, this will be null also
# // - if type is 'percent', this will be a number between 0 and 100
# // representing match size to exclude as a percentage of the document size.
# // - if type is 'words', this will be number > 0 representing how many
# // words a match must contain for it to be considered
# // NOTE: This flag will not appear unless your account has the
# // Turnitin plugin available
# turnitin_settings: {
# originality_report_visibility => 'after_grading',
# s_paper_check => false,
# internet_check => false,
# journal_check => false,
# exclude_biblio => false,
# exclude_quoted => false,
# exclude_small_matches_type => 'percent',
# exclude_small_matches_value => 50,
# },
#
# // If this is a group assignment, boolean flag indicating whether or
# // not students will be graded individually.
# grade_group_students_individually: false,
@ -71,9 +94,9 @@
# // Use the "External Tools" API if you need more information about
# // an external tool.
# external_tool_tag_attributes: {
# // URL to the external tool \
# // URL to the external tool
# url: "http://instructure.com",
# // Whether or not there is a new tab for the external tool\
# // Whether or not there is a new tab for the external tool
# new_tab: false
# },
#
@ -269,6 +292,10 @@ class AssignmentsApiController < ApplicationController
# Toggles Turnitin submissions for the assignment.
# Will be ignored if Turnitin is not available for the course.
#
# @argument assignment[turnitin_settings] [Optional]
# Settings to send along to turnitin. See Assignment object definition for
# format.
#
# @argument assignment[peer_reviews] [Optional,Boolean]
# If submission_types does not include external_tool,discussion_topic,
# online_quiz, or on_paper, determines whether or not peer reviews

View File

@ -871,7 +871,7 @@ class Account < ActiveRecord::Base
end
def turnitin_settings
if self.turnitin_account_id && self.turnitin_shared_secret && !self.turnitin_account_id.empty? && !self.turnitin_shared_secret.empty?
if self.turnitin_account_id.present? && self.turnitin_shared_secret.present?
[self.turnitin_account_id, self.turnitin_shared_secret]
else
self.parent_account.turnitin_settings rescue nil

View File

@ -312,10 +312,6 @@ class Assignment < ActiveRecord::Base
end
end
def turnitin_enabled?
self.turnitin_enabled
end
attr_accessor :updated_submissions
def update_submissions_later
if @old_assignment_group_id != self.assignment_group_id

View File

@ -71,6 +71,7 @@ module Api::V1::Assignment
if assignment.context && assignment.context.turnitin_enabled?
hash['turnitin_enabled'] = assignment.turnitin_enabled
hash['turnitin_settings'] = turnitin_settings_json(assignment)
end
if assignment.rubric_association
@ -108,6 +109,25 @@ module Api::V1::Assignment
hash
end
def turnitin_settings_json(assignment)
settings = assignment.turnitin_settings.with_indifferent_access
[:s_paper_check, :internet_check, :journal_check, :exclude_biblio, :exclude_quoted].each do |key|
settings[key] = value_to_boolean(settings[key])
end
ex_type = settings.delete(:exclude_type)
settings[:exclude_small_matches_type] = case ex_type
when '0'; nil
when '1'; 'words'
when '2'; 'percent'
end
ex_value = settings.delete(:exclude_value)
settings[:exclude_small_matches_value] = ex_value.present? ? ex_value.to_i : nil
settings.slice(*API_ALLOWED_TURNITIN_SETTINGS)
end
API_ALLOWED_ASSIGNMENT_INPUT_FIELDS = %w(
name
description
@ -127,6 +147,18 @@ module Api::V1::Assignment
grade_group_students_individually
set_custom_field_values
turnitin_enabled
turnitin_settings
)
API_ALLOWED_TURNITIN_SETTINGS = %w(
originality_report_visibility
s_paper_check
internet_check
journal_check
exclude_biblio
exclude_quoted
exclude_small_matches_type
exclude_small_matches_value
)
def update_api_assignment(assignment, assignment_params, save = true)
@ -137,24 +169,44 @@ module Api::V1::Assignment
update_params["submission_types"] = update_params["submission_types"].join(',')
end
if assignment_params.has_key?("assignment_group_id")
ag_id = assignment_params["assignment_group_id"]
if ag_id.nil? || ag_id.is_a?( Numeric )
assignment.assignment_group = assignment.context.assignment_groups.find_by_id(ag_id)
end
# validate and add to update_params
if update_params.has_key?("assignment_group_id")
ag_id = update_params.delete("assignment_group_id").presence
ag = assignment.context.assignment_groups.find_by_id(ag_id)
update_params["assignment_group_id"] = ag.try(:id)
end
if assignment_params.has_key?("group_category_id")
gc_id = assignment_params["group_category_id"]
if gc_id.nil? || gc_id.is_a?( Numeric )
assignment.group_category = assignment.context.group_categories.find_by_id(gc_id)
end
# validate and add to update_params
if update_params.has_key?("group_category_id")
gc_id = update_params["group_category_id"].presence
gc = assignment.context.group_categories.find_by_id(gc_id)
update_params["group_category_id"] = gc.try(:id)
end
# do some fiddling with due_at for fancy midnight and add to update_params
if update_params.has_key?("due_at")
update_params["time_zone_edited"] = Time.zone.name
# do some fiddling with due_at for fancy midnight
assignment.due_at = update_params["due_at"]
update_params["due_at"] = assignment.due_at
end
if !assignment.context.try(:turnitin_enabled?)
update_params.delete("turnitin_enabled")
update_params.delete("turnitin_settings")
end
# use Assignment#turnitin_settings= to normalize, but then assign back to
# hash so that it is written with update_params
if update_params.has_key?("turnitin_settings")
turnitin_settings = update_params["turnitin_settings"].slice(*API_ALLOWED_TURNITIN_SETTINGS)
turnitin_settings['exclude_type'] = case turnitin_settings['exclude_small_matches_type']
when nil; '0'
when 'words'; '1'
when 'percent'; '2'
end
turnitin_settings['exclude_value'] = turnitin_settings['exclude_small_matches_value']
assignment.turnitin_settings = turnitin_settings
update_params["turnitin_settings"] = assignment.turnitin_settings
end
# TODO: allow rubric creation

View File

@ -120,7 +120,8 @@ module Turnitin
settings[:originality_report_visibility] = 'immediate' unless ['immediate', 'after_grading', 'after_due_date'].include?(settings[:originality_report_visibility])
[:s_paper_check, :internet_check, :journal_check, :exclude_biblio, :exclude_quoted].each do |key|
settings[key] = '0' unless settings[key] == '1'
bool = Canvas::Plugin.value_to_boolean(settings[key])
settings[key] = bool ? '1' : '0'
end
exclude_value = settings[:exclude_value].to_i

View File

@ -195,10 +195,19 @@ describe AssignmentsApiController, :type => :integration do
@json['position'].should == 1
@json['group_category_id'].should == @group_category.id
@json['turnitin_enabled'].should == true
@json['turnitin_settings'].should == {
'originality_report_visibility' => 'immediate',
's_paper_check' => true,
'internet_check' => true,
'journal_check' => true,
'exclude_biblio' => true,
'exclude_quoted' => true,
'exclude_small_matches_type' => nil,
'exclude_small_matches_value' => nil
}
@json['allowed_extensions'].should =~ [
'docx','ppt'
]
@json['turnitin_enabled'].should == true
@json['points_possible'].should == 12
@json['grading_type'].should == 'points'
@json['due_at'].should == @assignment.due_at.iso8601
@ -341,10 +350,10 @@ describe AssignmentsApiController, :type => :integration do
'points_possible' => '12',
'assignment_group_id' => @group.id,
'set_custom_field_values' => {
'test_custom' => {
'value' => '1'
}
},
'test_custom' => {
'value' => '1'
}
},
'group_category_id' => nil,
'description' => 'assignment description',
'grading_type' => 'points',
@ -428,7 +437,6 @@ describe AssignmentsApiController, :type => :integration do
it "updates custom fields" do
@assignment.get_custom_field_value('test_custom').true?.should == true
end
end
context "when updating assignment overrides on the assignment" do
@ -480,6 +488,78 @@ describe AssignmentsApiController, :type => :integration do
end
end
context "when turnitin is enabled on the context" do
before do
course_with_teacher(:active_all => true)
@assignment = @course.assignments.create!
acct = @course.account
acct.turnitin_account_id = 0
acct.turnitin_shared_secret = "blah"
acct.save!
end
it "should allow setting turnitin_enabled" do
@assignment.should_not be_turnitin_enabled
api_update_assignment_call(@course,@assignment,{
'turnitin_enabled' => '1',
})
@assignment.reload.should be_turnitin_enabled
api_update_assignment_call(@course,@assignment,{
'turnitin_enabled' => '0',
})
@assignment.reload.should_not be_turnitin_enabled
end
it "should allow setting valid turnitin_settings" do
update_settings = {
:originality_report_visibility => 'after_grading',
:s_paper_check => '0',
:internet_check => false,
:journal_check => '1',
:exclude_biblio => true,
:exclude_quoted => '0',
:exclude_small_matches_type => 'percent',
:exclude_small_matches_value => 50
}
json = api_update_assignment_call(@course, @assignment, {
:turnitin_settings => update_settings
})
json["turnitin_settings"].should == {
'originality_report_visibility' => 'after_grading',
's_paper_check' => false,
'internet_check' => false,
'journal_check' => true,
'exclude_biblio' => true,
'exclude_quoted' => false,
'exclude_small_matches_type' => 'percent',
'exclude_small_matches_value' => 50
}
@assignment.reload.turnitin_settings.should == {
'originality_report_visibility' => 'after_grading',
's_paper_check' => '0',
'internet_check' => '0',
'journal_check' => '1',
'exclude_biblio' => '1',
'exclude_quoted' => '0',
'exclude_type' => '2',
'exclude_value' => '50'
}
end
it "should not allow setting invalid turnitin_settings" do
update_settings = {
:blah => '1'
}.with_indifferent_access
api_update_assignment_call(@course, @assignment, {
:turnitin_settings => update_settings
})
@assignment.reload.turnitin_settings["blah"].should be_nil
end
end
context "when a non-admin tries to update a completely frozen assignment" do
it "doesn't allow the non-admin to update the frozen assignment" do
course_with_teacher(:active_all => true)

View File

@ -1960,20 +1960,20 @@ describe Assignment do
assignment.turnitin_settings = {
:originality_report_visibility => 'invalid',
:s_paper_check => '2',
:internet_check => '2',
:journal_check => '2',
:exclude_biblio => '2',
:exclude_quoted => '2',
:internet_check => 1,
:journal_check => 0,
:exclude_biblio => true,
:exclude_quoted => false,
:exclude_type => '3',
:exclude_value => 'asdf',
:bogus => 'haha'
}
assignment.turnitin_settings.should eql({
:originality_report_visibility => 'immediate',
:s_paper_check => '0',
:internet_check => '0',
:s_paper_check => '1',
:internet_check => '1',
:journal_check => '0',
:exclude_biblio => '0',
:exclude_biblio => '1',
:exclude_quoted => '0',
:exclude_type => '0',
:exclude_value => ''