Mass Disable Sync to SIS Backend
Refs: SIS-2708 Test plan: - Activate the api one of the following ways: -- Install a post_grades lti tool -- Enable the bulk_sis_grade_export feature and enable the New SIS Integrations feature - PUT /api/sis/courses/:course_id/disable_post_to_sis -- Assignments for the course will have the `post_to_sis` attribute set to false - Repeat previous step and send in a valid grading period id -- Assignments for the course inside the particular grading will have the `post_to_sis` attribute set to false Change-Id: I512f99943463a2d15278a1bdb3a60ed0c19034ec Reviewed-on: https://gerrit.instructure.com/111164 Reviewed-by: Tyler Pickett <tpickett@instructure.com> Reviewed-by: Brad Humphrey <brad@instructure.com> Tested-by: Jenkins QA-Review: Mark McDermott <mmcdermott@instructure.com> Product-Review: Brad Humphrey <brad@instructure.com>
This commit is contained in:
parent
1644463879
commit
cc0ae2b7a2
|
@ -0,0 +1,127 @@
|
|||
#
|
||||
# Copyright (C) 2017 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# @API SIS Integration
|
||||
#
|
||||
# Includes helpers for integration with SIS systems.
|
||||
#
|
||||
class DisablePostToSisApiController < ApplicationController
|
||||
|
||||
before_action :require_authorized_user
|
||||
before_action :require_post_to_sis
|
||||
before_action :require_published_course
|
||||
before_action :require_valid_grading_period
|
||||
|
||||
# @API Disable assignments currently enabled for grade export to SIS
|
||||
# @beta
|
||||
#
|
||||
# Disable all assignments flagged as "post_to_sis", with the option of making it
|
||||
# specific to a grading period, in a course.
|
||||
#
|
||||
# @argument course_id [Integer] The ID of the course.
|
||||
#
|
||||
# @argument grading_period_id [Integer] The ID of the grading period.
|
||||
#
|
||||
# On success, the response will be 204 No Content with an empty body.
|
||||
#
|
||||
# On failure, the response will be 400 Bad Request with a body of a specific
|
||||
# message.
|
||||
#
|
||||
# @example_request
|
||||
#
|
||||
# curl 'https://<canvas>/api/sis/courses/<course_id>/disable_post_to_sis' \
|
||||
# -X PUT \
|
||||
# -H "Authorization: Bearer <token>" \
|
||||
# -H "Content-Length: 0"
|
||||
#
|
||||
# For disabling assignments in a specific grading period
|
||||
#
|
||||
# @example_request
|
||||
#
|
||||
# curl 'https://<canvas>/api/sis/courses/<course_id>/disable_post_to_sis' \
|
||||
# -X PUT \
|
||||
# -H "Authorization: Bearer <token>" \
|
||||
# -H "Content-Length: 0" \
|
||||
# -d 'grading_period_id=1'
|
||||
#
|
||||
def disable_post_to_sis
|
||||
assignments = published_assignments.where(post_to_sis: true).limit(1000)
|
||||
while assignments.update_all(post_to_sis: false) > 0 do end
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def context
|
||||
@context ||=
|
||||
if params[:course_id]
|
||||
api_find(Course, params[:course_id])
|
||||
else
|
||||
fail ActiveRecord::RecordNotFound, 'unknown context type'
|
||||
end
|
||||
end
|
||||
|
||||
def grading_period
|
||||
@grading_period ||=
|
||||
GradingPeriod.for(context, inherit: true).find_by(id: params[:grading_period_id])
|
||||
end
|
||||
|
||||
def published_assignments
|
||||
assignments = Assignment.published.for_course(context)
|
||||
if grading_period
|
||||
assignments.where("due_at BETWEEN ? AND ? OR due_at IS NULL",
|
||||
grading_period.start_date, grading_period.end_date)
|
||||
else
|
||||
assignments
|
||||
end
|
||||
end
|
||||
|
||||
def post_to_sis_enabled?
|
||||
# We'll need to remove sis_grade_export_enabled?
|
||||
# check when we deprecate the feature option
|
||||
Assignment.sis_grade_export_enabled?(context) &&
|
||||
AssignmentUtil.sis_integration_settings_enabled?(context)
|
||||
end
|
||||
|
||||
def require_authorized_user
|
||||
head :unauthorized unless context.grants_right?(@current_user, session, :manage_assignments)
|
||||
end
|
||||
|
||||
def require_valid_grading_period
|
||||
body = {
|
||||
code: 'not_found',
|
||||
error: I18n.t('The Grading Period cannot be found')
|
||||
}
|
||||
render json: body, status: :bad_request if params[:grading_period_id] && grading_period.blank?
|
||||
end
|
||||
|
||||
def require_post_to_sis
|
||||
body = {
|
||||
code: 'not_enabled',
|
||||
error: I18n.t('A SIS integration is not configured and the Enable new SIS integration settings feature is not enabled')
|
||||
}
|
||||
render json: body, status: :bad_request unless post_to_sis_enabled?
|
||||
end
|
||||
|
||||
def require_published_course
|
||||
body = {
|
||||
code: 'unpublished_course',
|
||||
error: I18n.t('Disabling Post to SIS is not available for non-published courses')
|
||||
}
|
||||
render json: body, status: :bad_request if context.is_a?(Course) && !context.published?
|
||||
end
|
||||
end
|
|
@ -2057,5 +2057,8 @@ CanvasRails::Application.routes.draw do
|
|||
get 'accounts/:account_id/assignments', action: 'sis_assignments', as: :sis_account_assignments
|
||||
get 'courses/:course_id/assignments', action: 'sis_assignments', as: :sis_course_assignments
|
||||
end
|
||||
scope(controller: :disable_post_to_sis_api) do
|
||||
put 'courses/:course_id/disable_post_to_sis', action: 'disable_post_to_sis', as: :disable_post_to_sis_course_assignments
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#
|
||||
# Copyright (C) 2017 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||
|
||||
describe DisablePostToSisApiController do
|
||||
describe "PUT disable_post_to_sis" do
|
||||
let(:account) {account_model}
|
||||
let(:course) {course_model(account: account, workflow_state: 'available')}
|
||||
let(:admin) {account_admin_user(account: account)}
|
||||
|
||||
before do
|
||||
bypass_rescue
|
||||
user_session(admin)
|
||||
end
|
||||
|
||||
it 'responds with 400 when post_to_sis is disabled' do
|
||||
put 'disable_post_to_sis', course_id: course.id
|
||||
|
||||
parsed_json = json_parse(response.body)
|
||||
expect(response.code).to eq "400"
|
||||
expect(parsed_json['code']).to eq 'not_enabled'
|
||||
end
|
||||
|
||||
context 'with bulk_sis_grade_export and new_sis_integrations enabled' do
|
||||
before do
|
||||
account.enable_feature!(:bulk_sis_grade_export)
|
||||
account.enable_feature!(:new_sis_integrations)
|
||||
end
|
||||
|
||||
it 'responds with 400 when course is unpublished' do
|
||||
course.workflow_state = 'unpublished'
|
||||
course.save!
|
||||
put 'disable_post_to_sis', course_id: course.id
|
||||
|
||||
parsed_json = json_parse(response.body)
|
||||
expect(response.code).to eq "400"
|
||||
expect(parsed_json['code']).to eq 'unpublished_course'
|
||||
end
|
||||
|
||||
it 'responds with 200' do
|
||||
put 'disable_post_to_sis', course_id: course.id
|
||||
|
||||
expect(response.code).to eq "204"
|
||||
expect(response.success?).to be_truthy
|
||||
end
|
||||
|
||||
it 'disables assignments with post_to_sis enabled' do
|
||||
assignment = assignment_model(course: course,
|
||||
post_to_sis: true,
|
||||
workflow_state: 'published')
|
||||
|
||||
put 'disable_post_to_sis', course_id: course.id
|
||||
assignment = Assignment.find(assignment.id)
|
||||
|
||||
expect(response.code).to eq "204"
|
||||
expect(response.success?).to be_truthy
|
||||
expect(assignment.post_to_sis).to be_falsey
|
||||
end
|
||||
|
||||
context 'with assignments in a grading_period' do
|
||||
let(:grading_period_group) do
|
||||
group = account.grading_period_groups.create!(title: "A Group")
|
||||
term = course.enrollment_term
|
||||
group.enrollment_terms << term
|
||||
group
|
||||
end
|
||||
|
||||
let(:grading_period) do
|
||||
grading_period_group.grading_periods.create!(
|
||||
title: 'Too Much Tuna',
|
||||
start_date: 2.months.from_now(Time.zone.now),
|
||||
end_date: 3.months.from_now(Time.zone.now)
|
||||
)
|
||||
end
|
||||
|
||||
it 'responds with 400 when grading period does not exist' do
|
||||
put 'disable_post_to_sis', course_id: course.id,
|
||||
grading_period_id: 789465789
|
||||
|
||||
parsed_json = json_parse(response.body)
|
||||
expect(response.code).to eq "400"
|
||||
expect(parsed_json['code']).to eq 'not_found'
|
||||
end
|
||||
|
||||
it 'disables assignments with post_to_sis enabled based on grading period' do
|
||||
assignment = assignment_model(course: course,
|
||||
post_to_sis: true,
|
||||
workflow_state: 'published',
|
||||
due_at: grading_period.start_date + 1.minute)
|
||||
|
||||
put 'disable_post_to_sis', course_id: course.id,
|
||||
grading_period_id: grading_period.id
|
||||
assignment = Assignment.find(assignment.id)
|
||||
|
||||
expect(response.code).to eq "204"
|
||||
expect(response.success?).to be_truthy
|
||||
expect(assignment.post_to_sis).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue