api: allow admins to create/edit/delete enrollment terms
closes CNVS-17700 test plan: - as an account admin, try creating, editing, and deleting enrollment terms - it should all work - try it on a sub-account, it should fail - as someone who doesn't have permission to manage the root account, try it on the root account - it should fail - do a quick regression test of the terms UI interface Change-Id: Ibfa45c08ac661e7d905311bc2d66b335be33a5e8 Reviewed-on: https://gerrit.instructure.com/46407 Reviewed-by: Jeremy Stanley <jeremy@instructure.com> Product-Review: Jeremy Stanley <jeremy@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> QA-Review: Caleb Guanzon <cguanzon@instructure.com>
This commit is contained in:
parent
03cc4acfeb
commit
d425f77307
|
@ -18,7 +18,10 @@
|
|||
|
||||
# @API Enrollment Terms
|
||||
#
|
||||
# API for viewing enrollment terms.
|
||||
# API for viewing enrollment terms. For all actions, the specified account
|
||||
# must be a root account and the caller must have permission to manage the
|
||||
# account (when called on non-root accounts, the errorwill be indicate the
|
||||
# appropriate root account).
|
||||
#
|
||||
# @model EnrollmentTerm
|
||||
# {
|
||||
|
@ -65,9 +68,7 @@ class TermsApiController < ApplicationController
|
|||
|
||||
# @API List enrollment terms
|
||||
#
|
||||
# Return all of the terms in the account. Account must be a root account and
|
||||
# requires permission to manage the account (when called on non-root
|
||||
# accounts, will be directed to the appropriate root account).
|
||||
# Return all of the terms in the account.
|
||||
#
|
||||
# @argument workflow_state[] [String, 'active'| 'deleted'| 'all']
|
||||
# If set, only returns terms that are in the given state.
|
||||
|
@ -83,6 +84,6 @@ class TermsApiController < ApplicationController
|
|||
terms = terms.where(workflow_state: state) if state.present?
|
||||
|
||||
terms = Api.paginate(terms, self, api_v1_enrollment_terms_url)
|
||||
render json: {enrollment_terms: enrollment_terms_json(terms, @current_user, session)}
|
||||
render json: { enrollment_terms: enrollment_terms_json(terms, @current_user, session) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,28 +16,69 @@
|
|||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# @API Enrollment Terms
|
||||
class TermsController < ApplicationController
|
||||
before_filter :require_context, :require_root_account_management
|
||||
include Api::V1::EnrollmentTerm
|
||||
|
||||
def index
|
||||
@root_account = @context.root_account
|
||||
@context.default_enrollment_term
|
||||
@terms = @context.enrollment_terms.active.includes(:enrollment_dates_overrides).order("COALESCE(start_at, created_at) DESC").to_a
|
||||
end
|
||||
|
||||
# @API Create enrollment term
|
||||
#
|
||||
# Create a new enrollment term for the specified account.
|
||||
#
|
||||
# @argument enrollment_term[name] [String]
|
||||
# The name of the term.
|
||||
#
|
||||
# @argument enrollment_term[start_at] [Timestamp]
|
||||
# The day/time the term starts.
|
||||
# Accepts times in ISO 8601 format, e.g. 2015-01-10T18:48:00Z.
|
||||
#
|
||||
# @argument enrollment_term[end_at] [Timestamp]
|
||||
# The day/time the term ends.
|
||||
# Accepts times in ISO 8601 format, e.g. 2015-01-10T18:48:00Z.
|
||||
#
|
||||
# @returns EnrollmentTerm
|
||||
#
|
||||
def create
|
||||
overrides = params[:enrollment_term].delete(:overrides) rescue nil
|
||||
@term = @context.enrollment_terms.active.build(params[:enrollment_term])
|
||||
if @term.save
|
||||
@term.set_overrides(@context, overrides)
|
||||
render :json => @term.as_json(:include => :enrollment_dates_overrides)
|
||||
if api_request?
|
||||
render :json => enrollment_term_json(@term, @current_user, session)
|
||||
else
|
||||
render :json => @term.as_json(:include => :enrollment_dates_overrides)
|
||||
end
|
||||
else
|
||||
render :json => @term.errors, :status => :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
# @API Update enrollment term
|
||||
#
|
||||
# Update an existing enrollment term for the specified account.
|
||||
#
|
||||
# @argument enrollment_term[name] [String]
|
||||
# The name of the term.
|
||||
#
|
||||
# @argument enrollment_term[start_at] [Timestamp]
|
||||
# The day/time the term starts.
|
||||
# Accepts times in ISO 8601 format, e.g. 2015-01-10T18:48:00Z.
|
||||
#
|
||||
# @argument enrollment_term[end_at] [Timestamp]
|
||||
# The day/time the term ends.
|
||||
# Accepts times in ISO 8601 format, e.g. 2015-01-10T18:48:00Z.
|
||||
#
|
||||
# @returns EnrollmentTerm
|
||||
#
|
||||
def update
|
||||
overrides = params[:enrollment_term].delete(:overrides) rescue nil
|
||||
@term = @context.enrollment_terms.active.find(params[:id])
|
||||
@term = api_find(@context.enrollment_terms.active, params[:id])
|
||||
root_account = @context.root_account
|
||||
if sis_id = params[:enrollment_term].delete(:sis_source_id)
|
||||
if sis_id != @account.sis_source_id && root_account.grants_right?(@current_user, session, :manage_sis)
|
||||
|
@ -50,15 +91,29 @@ class TermsController < ApplicationController
|
|||
end
|
||||
if @term.update_attributes(params[:enrollment_term])
|
||||
@term.set_overrides(@context, overrides)
|
||||
render :json => @term.as_json(:include => :enrollment_dates_overrides)
|
||||
if api_request?
|
||||
render :json => enrollment_term_json(@term, @current_user, session)
|
||||
else
|
||||
render :json => @term.as_json(:include => :enrollment_dates_overrides)
|
||||
end
|
||||
else
|
||||
render :json => @term.errors, :status => :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
# @API Delete enrollment term
|
||||
#
|
||||
# Delete the specified enrollment term.
|
||||
#
|
||||
# @returns EnrollmentTerm
|
||||
#
|
||||
def destroy
|
||||
@term = @context.enrollment_terms.find(params[:id])
|
||||
@term = api_find(@context.enrollment_terms, params[:id])
|
||||
@term.destroy
|
||||
render :json => @term
|
||||
if api_request?
|
||||
render :json => enrollment_term_json(@term, @current_user, session)
|
||||
else
|
||||
render :json => @term
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -485,7 +485,7 @@ CanvasRails::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :terms
|
||||
resources :terms, except: [:show, :new, :edit]
|
||||
resources :sub_accounts
|
||||
|
||||
get :avatars
|
||||
|
@ -835,6 +835,12 @@ CanvasRails::Application.routes.draw do
|
|||
get 'accounts/:account_id/terms', action: :index, as: 'enrollment_terms'
|
||||
end
|
||||
|
||||
scope(controller: :terms) do
|
||||
post 'accounts/:account_id/terms', action: :create
|
||||
put 'accounts/:account_id/terms/:id', action: :update
|
||||
delete 'accounts/:account_id/terms/:id', action: :destroy
|
||||
end
|
||||
|
||||
scope(controller: :authentication_audit_api) do
|
||||
get 'audit/authentication/logins/:login_id', action: :for_login, as: 'audit_authentication_login'
|
||||
get 'audit/authentication/accounts/:account_id', action: :for_account, as: 'audit_authentication_account'
|
||||
|
|
|
@ -28,17 +28,19 @@ describe TermsApiController, type: :request do
|
|||
@term2 = @account.enrollment_terms.create(name: "Term 2")
|
||||
end
|
||||
|
||||
def get_terms(options={})
|
||||
def get_terms(body_params={})
|
||||
json = api_call(:get, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms_api', action: 'index', format: 'json', account_id: @account.to_param },
|
||||
options)
|
||||
body_params)
|
||||
json['enrollment_terms']
|
||||
end
|
||||
|
||||
describe "filtering by state" do
|
||||
it "should list all active terms by default" do
|
||||
before :once do
|
||||
@term2.destroy
|
||||
end
|
||||
|
||||
it "should list all active terms by default" do
|
||||
json = get_terms
|
||||
names = json.map{ |t| t['name'] }
|
||||
expect(names).to include(@term1.name)
|
||||
|
@ -46,8 +48,6 @@ describe TermsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "should list active terms with state=active" do
|
||||
@term2.destroy
|
||||
|
||||
json = get_terms(workflow_state: 'active')
|
||||
names = json.map{ |t| t['name'] }
|
||||
expect(names).to include(@term1.name)
|
||||
|
@ -55,8 +55,6 @@ describe TermsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "should list deleted terms with state=deleted" do
|
||||
@term2.destroy
|
||||
|
||||
json = get_terms(workflow_state: 'deleted')
|
||||
names = json.map{ |t| t['name'] }
|
||||
expect(names).not_to include(@term1.name)
|
||||
|
@ -64,8 +62,6 @@ describe TermsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "should list all terms, active and deleted, with state=all" do
|
||||
@term2.destroy
|
||||
|
||||
json = get_terms(workflow_state: 'all')
|
||||
names = json.map{ |t| t['name'] }
|
||||
expect(names).to include(@term1.name)
|
||||
|
@ -73,8 +69,6 @@ describe TermsApiController, type: :request do
|
|||
end
|
||||
|
||||
it "should list all terms, active and deleted, with state=[all]" do
|
||||
@term2.destroy
|
||||
|
||||
json = get_terms(workflow_state: ['all'])
|
||||
names = json.map{ |t| t['name'] }
|
||||
expect(names).to include(@term1.name)
|
||||
|
@ -87,11 +81,9 @@ describe TermsApiController, type: :request do
|
|||
@term1.update_attributes(start_at: 1.day.ago, end_at: 5.days.from_now)
|
||||
@term2.update_attributes(start_at: 2.days.ago, end_at: 6.days.from_now)
|
||||
|
||||
json = api_call(:get, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms_api', action: 'index', format: 'json', account_id: @account.to_param })
|
||||
|
||||
expect(json['enrollment_terms'].first['name']).to eq @term2.name
|
||||
expect(json['enrollment_terms'].last['name']).to eq @term1.name
|
||||
json = get_terms
|
||||
expect(json.first['name']).to eq @term2.name
|
||||
expect(json.last['name']).to eq @term1.name
|
||||
end
|
||||
|
||||
it "should order by end_at second" do
|
||||
|
@ -99,11 +91,9 @@ describe TermsApiController, type: :request do
|
|||
@term1.update_attributes(start_at: start_at, end_at: 6.days.from_now)
|
||||
@term2.update_attributes(start_at: start_at, end_at: 5.days.from_now)
|
||||
|
||||
json = api_call(:get, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms_api', action: 'index', format: 'json', account_id: @account.to_param })
|
||||
|
||||
expect(json['enrollment_terms'].first['name']).to eq @term2.name
|
||||
expect(json['enrollment_terms'].last['name']).to eq @term1.name
|
||||
json = get_terms
|
||||
expect(json.first['name']).to eq @term2.name
|
||||
expect(json.last['name']).to eq @term1.name
|
||||
end
|
||||
|
||||
it "should order by id last" do
|
||||
|
@ -112,11 +102,9 @@ describe TermsApiController, type: :request do
|
|||
@term1.update_attributes(start_at: start_at, end_at: end_at)
|
||||
@term2.update_attributes(start_at: start_at, end_at: end_at)
|
||||
|
||||
json = api_call(:get, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms_api', action: 'index', format: 'json', account_id: @account.to_param })
|
||||
|
||||
expect(json['enrollment_terms'].first['name']).to eq @term1.name
|
||||
expect(json['enrollment_terms'].last['name']).to eq @term2.name
|
||||
json = get_terms
|
||||
expect(json.first['name']).to eq @term1.name
|
||||
expect(json.last['name']).to eq @term2.name
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -126,5 +114,152 @@ describe TermsApiController, type: :request do
|
|||
expect(response.headers).to include('Link')
|
||||
expect(response.headers['Link']).to match(/rel="next"/)
|
||||
end
|
||||
|
||||
describe "authorization" do
|
||||
def expect_terms_index_401
|
||||
api_call(:get, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms_api', action: 'index', format: 'json', account_id: @account.to_param },
|
||||
{},
|
||||
{},
|
||||
{ expected_status: 401 })
|
||||
end
|
||||
|
||||
it "should require auth for the right account" do
|
||||
other_account = Account.create(name: 'other')
|
||||
account_admin_user(account: other_account)
|
||||
expect_terms_index_401
|
||||
end
|
||||
|
||||
it "should require root domain auth" do
|
||||
subaccount = @account.sub_accounts.create!(name: 'subaccount')
|
||||
account_admin_user(account: subaccount)
|
||||
expect_terms_index_401
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe TermsController, type: :request do
|
||||
before :once do
|
||||
@account = Account.create(name: 'new')
|
||||
account_admin_user(account: @account)
|
||||
@account.enrollment_terms.scoped.delete_all
|
||||
@term1 = @account.enrollment_terms.create(name: "Term 1")
|
||||
end
|
||||
|
||||
describe "create" do
|
||||
it "should allow creating a term" do
|
||||
start_at = 3.days.ago
|
||||
end_at = 3.days.from_now
|
||||
json = api_call(:post, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms', action: 'create', format: 'json', account_id: @account.to_param },
|
||||
{ enrollment_term: { name: 'Term 2', start_at: start_at.iso8601, end_at: end_at.iso8601 } })
|
||||
|
||||
expect(json['id']).to be_present
|
||||
expect(json['name']).to eq 'Term 2'
|
||||
expect(json['start_at']).to eq start_at.iso8601
|
||||
expect(json['end_at']).to eq end_at.iso8601
|
||||
|
||||
new_term = @account.reload.enrollment_terms.find(json['id'])
|
||||
expect(new_term.name).to eq 'Term 2'
|
||||
expect(new_term.start_at.to_i).to eq start_at.to_i
|
||||
expect(new_term.end_at.to_i).to eq end_at.to_i
|
||||
end
|
||||
|
||||
describe "authorization" do
|
||||
def expect_terms_create_401
|
||||
api_call(:post, "/api/v1/accounts/#{@account.id}/terms",
|
||||
{ controller: 'terms', action: 'create', format: 'json', account_id: @account.to_param },
|
||||
{ enrollment_term: { name: 'Term 2' } },
|
||||
{},
|
||||
{ expected_status: 401 })
|
||||
end
|
||||
|
||||
it "should require auth for the right account" do
|
||||
other_account = Account.create(name: 'other')
|
||||
account_admin_user(account: other_account)
|
||||
expect_terms_create_401
|
||||
end
|
||||
|
||||
it "should require root domain auth" do
|
||||
subaccount = @account.sub_accounts.create!(name: 'subaccount')
|
||||
account_admin_user(account: subaccount)
|
||||
expect_terms_create_401
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "update" do
|
||||
it "should allow updating a term" do
|
||||
start_at = 3.days.ago
|
||||
end_at = 3.days.from_now
|
||||
json = api_call(:put, "/api/v1/accounts/#{@account.id}/terms/#{@term1.id}",
|
||||
{ controller: 'terms', action: 'update', format: 'json', account_id: @account.to_param, id: @term1.to_param },
|
||||
{ enrollment_term: { name: 'Term 2', start_at: start_at.iso8601, end_at: end_at.iso8601 } })
|
||||
|
||||
expect(json['id']).to eq @term1.id
|
||||
expect(json['name']).to eq 'Term 2'
|
||||
expect(json['start_at']).to eq start_at.iso8601
|
||||
expect(json['end_at']).to eq end_at.iso8601
|
||||
|
||||
@term1.reload
|
||||
expect(@term1.name).to eq 'Term 2'
|
||||
expect(@term1.start_at.to_i).to eq start_at.to_i
|
||||
expect(@term1.end_at.to_i).to eq end_at.to_i
|
||||
end
|
||||
|
||||
describe "authorization" do
|
||||
def expect_terms_update_401
|
||||
api_call(:put, "/api/v1/accounts/#{@account.id}/terms/#{@term1.id}",
|
||||
{ controller: 'terms', action: 'update', format: 'json', account_id: @account.to_param, id: @term1.to_param},
|
||||
{ enrollment_term: { name: 'Term 2' } },
|
||||
{},
|
||||
{ :expected_status => 401 })
|
||||
end
|
||||
|
||||
it "should require auth for the right account" do
|
||||
other_account = Account.create(name: 'other')
|
||||
account_admin_user(account: other_account)
|
||||
expect_terms_update_401
|
||||
end
|
||||
|
||||
it "should require root domain auth" do
|
||||
subaccount = @account.sub_accounts.create!(name: 'subaccount')
|
||||
account_admin_user(account: subaccount)
|
||||
expect_terms_update_401
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "destroy" do
|
||||
it "should allow deleting a term" do
|
||||
json = api_call(:delete, "/api/v1/accounts/#{@account.id}/terms/#{@term1.id}",
|
||||
{ controller: 'terms', action: 'destroy', format: 'json', account_id: @account.to_param, id: @term1.to_param })
|
||||
|
||||
expect(json['id']).to eq @term1.id
|
||||
expect(@term1.reload).to be_deleted
|
||||
end
|
||||
|
||||
describe "authorization" do
|
||||
def expect_terms_destroy_401
|
||||
api_call(:delete, "/api/v1/accounts/#{@account.id}/terms/#{@term1.id}",
|
||||
{ controller: 'terms', action: 'destroy', format: 'json', account_id: @account.to_param, id: @term1.to_param },
|
||||
{},
|
||||
{},
|
||||
{ :expected_status => 401 })
|
||||
end
|
||||
|
||||
it "should require auth for the right account" do
|
||||
other_account = Account.create(name: 'other')
|
||||
account_admin_user(account: other_account)
|
||||
expect_terms_destroy_401
|
||||
end
|
||||
|
||||
it "should require root domain auth" do
|
||||
subaccount = @account.sub_accounts.create!(name: 'subaccount')
|
||||
account_admin_user(account: subaccount)
|
||||
expect_terms_destroy_401
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue