Add front end max_name_length validations for Discussions

Fixes: SIS-2743

Test plan:
- Navigate to the account settings page
- Navigate to the `Feature Options` tab
- Turn the `Enable new SIS integration settings` feature flag on
- Navigate back to the `Settings` tab
- Check "Limit assignment names lengths (max 255)" option
- Enter a max assignment name length value
- Save the settings
- Navigate to a course
- Create a Discussion
- Enter a name that is longer than the value you entered
- Check the 'Graded' option
- Check the `Post to SIS` optiona
- Click Save/Save & Publish
- Confirm the save fails and you are presented with a UI error
  "Name is too long, must be under #{the_value_you_entered} characters"
- Confirm upon changing the name you are able to save the discussion

Change-Id: Iafd578a5923fce35761065d3088ae1b2e8c4bbcd
Reviewed-on: https://gerrit.instructure.com/101040
Tested-by: Jenkins
Reviewed-by: Stewie aka Nicholas Stewart <nstewart@instructure.com>
QA-Review: Mark McDermott <mmcdermott@instructure.com>
Product-Review: Brad Humphrey <brad@instructure.com>
This commit is contained in:
Nick Houle 2017-02-13 14:53:38 -07:00
parent 3b860bc9c3
commit b664a85bbc
6 changed files with 148 additions and 0 deletions

View File

@ -341,6 +341,7 @@ ConditionalRelease, deparam, flashMessage, numberHelper) ->
assignment_overrides: @dueDateOverrideView.getAllDates()
errors = @dueDateOverrideView.validateBeforeSave(data2, errors)
errors = @_validatePointsPossible(data, errors)
errors = @_validateTitle(data, errors)
else
@model.set 'assignment', @model.createAssignment(set_assignment: false)
@ -356,6 +357,16 @@ ConditionalRelease, deparam, flashMessage, numberHelper) ->
errors
_validateTitle: (data, errors) =>
max_name_length = 256
if data.assignment.attributes.post_to_sis == '1' && ENV.MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT == true
max_name_length = ENV.MAX_NAME_LENGTH + 1
if $.trim(data.title.toString()).length > max_name_length
errors["title"] = [
message: I18n.t "Title is too long, must be under %{length} characters", length: max_name_length
]
errors
_validatePointsPossible: (data, errors) =>
assign = data.assignment
frozenPoints = _.contains(assign.frozenAttributes(), "points_possible")

View File

@ -454,6 +454,8 @@ class DiscussionTopicsController < ApplicationController
post_to_sis = Assignment.sis_grade_export_enabled?(@context)
js_hash[:POST_TO_SIS] = post_to_sis
js_hash[:POST_TO_SIS_DEFAULT] = @context.account.sis_default_grade_export[:value] if post_to_sis && @topic.new_record?
js_hash[:MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT] = AssignmentUtil.name_length_required_for_account?(@context.assignments.first) if @context.respond_to?(:assignments)
js_hash[:MAX_NAME_LENGTH] = AssignmentUtil.assignment_max_name_length(@context.assignments.first) if @context.respond_to?(:assignments)
if @context.is_a?(Course)
js_hash['SECTION_LIST'] = sections.map { |section|

View File

@ -11,6 +11,10 @@ module AssignmentUtil
assignment.post_to_sis.present? && name_length_required_for_account?(assignment)
end
def self.assignment_max_name_length(assignment)
assignment.try(:context).try(:account).try(:sis_assignment_name_length_input).try(:[], :value).to_i
end
def self.name_length_required_for_account?(assignment)
assignment.try(:context).try(:account).try(:sis_syncing).try(:[], :value) &&
assignment.try(:context).try(:account).try(:sis_assignment_name_length).try(:[], :value) &&

View File

@ -169,6 +169,88 @@ GroupCategorySelector, fakeENV, RichContentEditor) ->
view.loadConditionalRelease()
equal 1, view.$conditionalReleaseTarget.children().size()
test "has an error when a title > 255 chars", ->
view = @editView({ withAssignment: true})
assignment = view.assignment
l1 = 'aaaaaaaaaa'
l2 = l1 + l1 + l1 + l1 + l1 + l1
l3 = l2 + l2 + l2 + l2 + l2 + l2
ENV.IS_LARGE_ROSTER = true
ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED = false
errors = view.validateBeforeSave({title: l3, set_assignment: '1', assignment: assignment}, [])
equal errors["title"][0]["message"], "Title is too long, must be under 256 characters"
test "allows dicussion to save when a title < 255 chars, MAX_NAME_LENGTH is not required and post_to_sis is true", ->
view = @editView({ withAssignment: true})
assignment = view.assignment
assignment.attributes.post_to_sis = '1'
l1 = 'aaaaaaaaaa'
ENV.MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT = false
ENV.IS_LARGE_ROSTER = true
ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED = false
errors = view.validateBeforeSave({title: l1, set_assignment: '1', assignment: assignment}, [])
equal errors.length, 0
test "allows dicussion to save when a title < 255 chars, MAX_NAME_LENGTH is not required and post_to_sis is false", ->
view = @editView({ withAssignment: true})
assignment = view.assignment
assignment.attributes.post_to_sis = '1'
l1 = 'aaaaaaaaaa'
ENV.MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT = false
ENV.IS_LARGE_ROSTER = true
ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED = false
errors = view.validateBeforeSave({title: l1, set_assignment: '1', assignment: assignment}, [])
equal errors.length, 0
test "has an error when a title > MAX_NAME_LENGTH chars if MAX_NAME_LENGTH is custom, required and post_to_sis is true", ->
view = @editView({ withAssignment: true})
assignment = view.assignment
assignment.attributes.post_to_sis = '1'
l1 = 'aaaaaaaaaa'
ENV.MAX_NAME_LENGTH = 5
ENV.MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT = true
ENV.IS_LARGE_ROSTER = true
ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED = false
errors = view.validateBeforeSave({title: l1, set_assignment: '1', assignment: assignment}, [])
equal errors["title"][0]["message"], "Title is too long, must be under #{ENV.MAX_NAME_LENGTH + 1} characters"
test "allows discussion to save when title > MAX_NAME_LENGTH chars if MAX_NAME_LENGTH is custom, required and post_to_sis is false", ->
view = @editView({ withAssignment: true})
assignment = view.assignment
assignment.attributes.post_to_sis = '0'
l1 = 'aaaaaaaaaa'
l2 = l1 + l1 + l1 + l1 + l1 + l1
l3 = l2 + l2 + l2 + l2 + l2 + l2
ENV.MAX_NAME_LENGTH = 5
ENV.MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT = true
ENV.IS_LARGE_ROSTER = true
ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED = false
errors = view.validateBeforeSave({title: l3, set_assignment: '1', assignment: assignment}, [])
equal errors.length, 0
test "allows discussion to save when title < MAX_NAME_LENGTH chars if MAX_NAME_LENGTH is custom, required and post_to_sis is true", ->
view = @editView({ withAssignment: true})
assignment = view.assignment
assignment.attributes.post_to_sis = '1'
l1 = 'aaaaaaaaaa'
ENV.MAX_NAME_LENGTH = 20
ENV.MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT = true
ENV.IS_LARGE_ROSTER = true
ENV.CONDITIONAL_RELEASE_SERVICE_ENABLED = false
errors = view.validateBeforeSave({title: l1, set_assignment: '1', assignment: assignment}, [])
equal errors.length, 0
test 'conditional release editor is updated on tab change', ->
view = @editView({ withAssignment: true })
view.renderTabs()

View File

@ -567,6 +567,27 @@ describe DiscussionTopicsController do
get 'new', course_id: @course.id, due_at: due_at.iso8601
expect(assigns[:js_env][:DISCUSSION_TOPIC][:ATTRIBUTES][:assignment][:due_at]).to eq due_at.iso8601
end
it "js_env MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT is true when AssignmentUtil.name_length_required_for_account? == true" do
user_session(@teacher)
AssignmentUtil.stubs(:name_length_required_for_account?).returns(true)
get 'new', :course_id => @course.id
expect(assigns[:js_env][:MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT]).to eq(true)
end
it "js_env MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT is false when AssignmentUtil.name_length_required_for_account? == false" do
user_session(@teacher)
AssignmentUtil.stubs(:name_length_required_for_account?).returns(false)
get 'new', :course_id => @course.id
expect(assigns[:js_env][:MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT]).to eq(false)
end
it "js_env MAX_NAME_LENGTH is a 15 when AssignmentUtil.assignment_max_name_length returns 15" do
user_session(@teacher)
AssignmentUtil.stubs(:assignment_max_name_length).returns(15)
get 'new', :course_id => @course.id
expect(assigns[:js_env][:MAX_NAME_LENGTH]).to eq(15)
end
end
describe "GET 'edit'" do
@ -590,6 +611,27 @@ describe DiscussionTopicsController do
expect(assigns[:js_env]).to have_key(:active_grading_periods)
end
it "js_env MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT is true when AssignmentUtil.name_length_required_for_account? == true" do
user_session(@teacher)
AssignmentUtil.stubs(:name_length_required_for_account?).returns(true)
get :edit, course_id: @course.id, id: @topic.id
expect(assigns[:js_env][:MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT]).to eq(true)
end
it "js_env MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT is false when AssignmentUtil.name_length_required_for_account? == false" do
user_session(@teacher)
AssignmentUtil.stubs(:name_length_required_for_account?).returns(false)
get :edit, course_id: @course.id, id: @topic.id
expect(assigns[:js_env][:MAX_NAME_LENGTH_REQUIRED_FOR_ACCOUNT]).to eq(false)
end
it "js_env MAX_NAME_LENGTH is a 15 when AssignmentUtil.assignment_max_name_length returns 15" do
user_session(@teacher)
AssignmentUtil.stubs(:assignment_max_name_length).returns(15)
get :edit, course_id: @course.id, id: @topic.id
expect(assigns[:js_env][:MAX_NAME_LENGTH]).to eq(15)
end
context 'conditional-release' do
before do
user_session(@teacher)

View File

@ -72,6 +72,13 @@ describe AssignmentUtil do
end
end
describe "assignment_max_name_length" do
it "returns 15 when the account setting sis_assignment_name_length_input is 15" do
assignment.context.account.stubs(:sis_assignment_name_length_input).returns({value: 15})
expect(described_class.assignment_max_name_length(assignment)).to eq(15)
end
end
describe "due_date_ok?" do
it "returns false when due_at is blank and due_date_required? is true" do
assignment.due_at = nil