Validate Sync to SIS in quizzes and assignments

fixes LX-1857

flag=selective_release_ui_api

Test plan:
- Enable required sync to SIS and
make due dates required in account settings.
- Navigate to the assignment edit page.
- Check the Sync to SIS option.
- Open Manage Assign To tray.
- Verify that the cards mark the due date as
required.
- Close the tray without making changes.
- Click the Save button.
- Expect a flash alert to appear to
notify the user about the due date.
- Click the alert link
- Expect the tray to be open.
- Set the due dates.
- Apply the changes in the tray.
- Save the assignment.
- Expect no errors to appear.

Repeat the validations on the quiz edition page.

Change-Id: I7ade56276eb18fe873043611957563a31c7ed614
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/352090
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Juan Chavez <juan.chavez@instructure.com>
QA-Review: Juan Chavez <juan.chavez@instructure.com>
Product-Review: Jonathan Guardado <jonathan.guardado@instructure.com>
This commit is contained in:
Jonathan Guardado 2024-07-05 19:13:20 -06:00
parent d35667d9d1
commit 8d6d4b6a47
8 changed files with 164 additions and 17 deletions

View File

@ -519,4 +519,83 @@ describe "assignments show page assign to", :ignore_js_errors do
expect(@nq_assignment.assignment_overrides.last.assignment_override_students.count).to eq(1)
end
end
context "post to sis" do
before do
@course.account.set_feature_flag! "post_grades", "on"
@course.account.set_feature_flag! :new_sis_integrations, "on"
@course.account.settings[:sis_syncing] = { value: true, locked: false }
@course.account.settings[:sis_require_assignment_due_date] = { value: true }
@course.account.save!
@assignment_ = @course.assignments.create(name: "assignment")
end
it "blocks saving empty due dates when enabled", :ignore_js_errors do
AssignmentCreateEditPage.visit_assignment_edit_page(@course.id, @assignment_.id)
AssignmentCreateEditPage.click_post_to_sis_checkbox
wait_for_ajaximations
expect(driver.current_url).to include("edit")
AssignmentCreateEditPage.save_assignment
expect_instui_flash_message("Please set a due date or change your selection for the “Sync to SIS” option.")
AssignmentCreateEditPage.click_manage_assign_to_button
wait_for_assign_to_tray_spinner
keep_trying_until { expect(item_tray_exists?).to be_truthy }
expect(assign_to_date_and_time[0].text).to include("Please add a due date")
update_due_date(0, format_date_for_view(Time.zone.now, "%-m/%-d/%Y"))
update_due_time(0, "11:59 PM")
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
expect(is_checked(AssignmentCreateEditPage.post_to_sis_checkbox_selector)).to be_truthy
end
it "does not block empty due dates when disabled" do
AssignmentCreateEditPage.visit_assignment_edit_page(@course.id, @assignment_.id)
AssignmentCreateEditPage.save_assignment
expect(driver.current_url).not_to include("edit")
expect(@assignment_.post_to_sis).to be_falsey
AssignmentCreateEditPage.visit_assignment_edit_page(@course.id, @assignment_.id)
expect(is_checked(AssignmentCreateEditPage.post_to_sis_checkbox_selector)).to be_falsey
end
it "validates due date when user checks/unchecks the option", :ignore_js_errors do
AssignmentCreateEditPage.visit_assignment_edit_page(@course.id, @assignment_.id)
AssignmentCreateEditPage.click_manage_assign_to_button
wait_for_assign_to_tray_spinner
keep_trying_until { expect(item_tray_exists?).to be_truthy }
expect(assign_to_date_and_time[0].text).not_to include("Please add a due date")
click_cancel_button
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
AssignmentCreateEditPage.click_post_to_sis_checkbox
AssignmentCreateEditPage.click_manage_assign_to_button
wait_for_assign_to_tray_spinner
keep_trying_until { expect(item_tray_exists?).to be_truthy }
expect(assign_to_date_and_time[0].text).to include("Please add a due date")
update_due_date(0, format_date_for_view(Time.zone.now, "%-m/%-d/%Y"))
update_due_time(0, "11:59 PM")
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
AssignmentCreateEditPage.save_assignment
expect(driver.current_url).not_to include("edit")
end
end
end

View File

@ -161,7 +161,6 @@ describe "assignments sync to sis" do
end
it "validates due date while sis is on", :ignore_js_errors do
# LX-1857: Does not show any error, but not submits, we should verify an error here
AssignmentCreateEditPage.save_assignment
AssignmentCreateEditPage.click_manage_assign_to_button
@ -182,17 +181,16 @@ describe "assignments sync to sis" do
end
it "does not validate when sis is off" do
AssignmentCreateEditPage.select_post_to_sis_checkbox
AssignmentCreateEditPage.click_post_to_sis_checkbox
AssignmentCreateEditPage.save_assignment
check_due_date_table("Everyone")
end
it "validates due date when user checks/unchecks the box", :ignore_js_errors do
# LX-1857: Does not show any error, but not submits, we should verify an error here
AssignmentCreateEditPage.save_assignment
AssignmentCreateEditPage.select_post_to_sis_checkbox
AssignmentCreateEditPage.click_post_to_sis_checkbox
AssignmentCreateEditPage.click_manage_assign_to_button
wait_for_assign_to_tray_spinner
@ -203,7 +201,7 @@ describe "assignments sync to sis" do
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
AssignmentCreateEditPage.select_post_to_sis_checkbox
AssignmentCreateEditPage.click_post_to_sis_checkbox
AssignmentCreateEditPage.click_manage_assign_to_button
wait_for_assign_to_tray_spinner
@ -226,7 +224,6 @@ describe "assignments sync to sis" do
let(:section_to_set) { "Section B" }
it "checks each due date when on", :ignore_js_errors do
# LX-1857: Does not show any error, but not submits, we should verify an error here
AssignmentCreateEditPage.save_assignment
AssignmentCreateEditPage.click_manage_assign_to_button
@ -254,7 +251,6 @@ describe "assignments sync to sis" do
end
it "checks due date when first add cards then fill fields", :ignore_js_errors do
# LX-1857: Does not show any error, but not submits, we should verify an error here
AssignmentCreateEditPage.save_assignment
AssignmentCreateEditPage.click_manage_assign_to_button
@ -283,8 +279,7 @@ describe "assignments sync to sis" do
end
it "does not check when sis is off", :ignore_js_errors do
skip("LX-1856: Tray is not using the checkbox value")
AssignmentCreateEditPage.select_post_to_sis_checkbox
AssignmentCreateEditPage.click_post_to_sis_checkbox
AssignmentCreateEditPage.click_manage_assign_to_button
wait_for_assign_to_tray_spinner

View File

@ -256,7 +256,7 @@ class AssignmentCreateEditPage
option_element.click
end
def select_post_to_sis_checkbox
def click_post_to_sis_checkbox
post_to_sis_checkbox.click
end
end

View File

@ -89,7 +89,7 @@ module QuizzesEditPage
expect(driver.current_url).not_to include("edit")
end
def select_post_to_sis_checkbox
def click_post_to_sis_checkbox
post_to_sis_checkbox.click
end
end

View File

@ -312,7 +312,6 @@ describe "creating a quiz" do
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
click_quiz_save_button
# LX-1857: Does not show any error, but not submits, we should verify an error here
expect(driver.current_url).to include("edit")
end
@ -349,7 +348,6 @@ describe "creating a quiz" do
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
click_quiz_save_button
# LX-1857: Does not show any error, but not submits, we should verify an error here
expect(driver.current_url).to include("edit")
end
@ -369,7 +367,6 @@ describe "creating a quiz" do
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
click_quiz_save_button
# LX-1857: Does not show any error, but not submits, we should verify an error here
expect(driver.current_url).to include("edit")
end
end

View File

@ -221,7 +221,7 @@ describe "quiz edit page assign to" do
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
select_post_to_sis_checkbox
click_post_to_sis_checkbox
click_manage_assign_to_button
wait_for_assign_to_tray_spinner
@ -234,5 +234,72 @@ describe "quiz edit page assign to" do
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
end
it "blocks saving empty due dates when enabled", :ignore_js_errors do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/edit"
click_post_to_sis_checkbox
wait_for_ajaximations
expect(driver.current_url).to include("edit")
click_quiz_save_button
expect_instui_flash_message("Please set a due date or change your selection for the “Sync to SIS” option.")
click_manage_assign_to_button
wait_for_assign_to_tray_spinner
keep_trying_until { expect(item_tray_exists?).to be_truthy }
expect(assign_to_date_and_time[0].text).to include("Please add a due date")
update_due_date(0, format_date_for_view(Time.zone.now, "%-m/%-d/%Y"))
update_due_time(0, "11:59 PM")
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
expect(is_checked(post_to_sis_checkbox_selector)).to be_truthy
end
it "does not block empty due dates when disabled" do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/edit"
expect(is_checked(post_to_sis_checkbox_selector)).to be_falsey
click_quiz_save_button
expect(driver.current_url).not_to include("edit")
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/edit"
expect(is_checked(post_to_sis_checkbox_selector)).to be_falsey
end
it "validates due date when user checks/unchecks the option", :ignore_js_errors do
get "/courses/#{@course.id}/quizzes/#{@quiz.id}/edit"
click_manage_assign_to_button
wait_for_assign_to_tray_spinner
keep_trying_until { expect(item_tray_exists?).to be_truthy }
expect(assign_to_date_and_time[0].text).not_to include("Please add a due date")
click_cancel_button
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
click_post_to_sis_checkbox
click_manage_assign_to_button
wait_for_assign_to_tray_spinner
keep_trying_until { expect(item_tray_exists?).to be_truthy }
expect(assign_to_date_and_time[0].text).to include("Please add a due date")
update_due_date(0, format_date_for_view(Time.zone.now, "%-m/%-d/%Y"))
update_due_time(0, "11:59 PM")
click_save_button("Apply")
keep_trying_until { expect(element_exists?(module_item_edit_tray_selector)).to be_falsey }
click_quiz_save_button
expect(driver.current_url).not_to include("edit")
end
end
end

View File

@ -33,6 +33,7 @@ import GradingPeriodsAPI from '@canvas/grading/jquery/gradingPeriodsApi'
import * as tz from '@instructure/moment-utils'
import '@canvas/jquery/jquery.instructure_forms'
import sanitizeData from '../../../forms/sanitizeData'
import {showPostToSisFlashAlert, combinedDates} from '../../util/differentiatedModulesUtil'
const I18n = useI18nScope('DueDateOverrideView')
@ -170,9 +171,17 @@ DueDateOverrideView.prototype.validateBeforeSave = function (data, errors) {
if (!data) {
return errors
}
if(ENV.FEATURES?.selective_release_ui_api){
data = {...data, assignment_overrides: data.assignment_overrides.map(o => ({...o, rowKey: combinedDates(o) }))}
}
errors = this.validateDatetimes(data, errors)
errors = this.validateTokenInput(data, errors)
errors = this.validateGroupOverrides(data, errors)
const hasEmptyDueDates = data.assignment_overrides.some(o => o.due_at === null)
const requiredDueDates = ENV.DUE_DATE_REQUIRED_FOR_ACCOUNT
if(hasEmptyDueDates && data.postToSIS && requiredDueDates){
showPostToSisFlashAlert('manage-assign-to')()
}
return errors
}
@ -324,7 +333,7 @@ DueDateOverrideView.prototype.validateGroupOverrides = function (data, errors) {
DueDateOverrideView.prototype.showError = function (element, message) {
// some forms will already handle this on their own, this exists
// as a fallback for forms that do not
if (!element) {
if (!element || element.length === 0) {
return
}
return element.errorBox(message).css('z-index', '20').attr('role', 'alert')

View File

@ -30,7 +30,7 @@ const I18n = useI18nScope('DueDateOverrideView')
export const cloneObject = object => JSON.parse(JSON.stringify(object))
const combinedDates = override => {
export const combinedDates = override => {
const overrideId = override.id == null ? '0' : override.id
const dueAt = override.due_at == null ? '' : override.due_at
const unlockAt = override.unlock_at == null ? '' : override.unlock_at