178 lines
7.8 KiB
Ruby
178 lines
7.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2018 - 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__) + '/../api_spec_helper')
|
|
|
|
describe OutcomeImportsApiController, type: :request do
|
|
before :once do
|
|
@user = user_with_pseudonym :active_all => true
|
|
@account = Account.default
|
|
@account.account_users.create!(user: @user)
|
|
|
|
@outcome_count = LearningOutcome.count
|
|
@group_count = LearningOutcomeGroup.count
|
|
@import_count = OutcomeImport.count
|
|
end
|
|
|
|
def expect_keys(json, keys)
|
|
expect(keys - json.keys).to eq([])
|
|
keys.each { |k| json.delete(k) }
|
|
json
|
|
end
|
|
|
|
it "returns 404 when no latest import is available" do
|
|
raw_api_call(:get,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports/latest",
|
|
{ :controller => 'outcome_imports_api', :action => 'show',
|
|
:format => 'json', :account_id => @account.id.to_s, id: 'latest' })
|
|
assert_status(404)
|
|
end
|
|
|
|
it 'kicks off an outcome import via multipart attachment' do
|
|
json = nil
|
|
strand = "OutcomeImport::run::#{@account.root_account.global_id}"
|
|
expect do
|
|
json = api_call(:post,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports",
|
|
{ :controller => 'outcome_imports_api', :action => 'create',
|
|
:format => 'json', :account_id => @account.id.to_s },
|
|
{ :import_type => 'instructure_csv',
|
|
:attachment => fixture_file_upload("files/outcomes/test_outcomes_1.csv", 'text/csv') })
|
|
end.to change { Delayed::Job.strand_size(strand) }.by(1)
|
|
|
|
remaining_json = expect_keys(json, %w[created_at updated_at ended_at user])
|
|
import = OutcomeImport.last
|
|
expect(remaining_json).to eq({
|
|
"data" => { "import_type" => "instructure_csv" },
|
|
"progress" => 0,
|
|
"id" => import.id,
|
|
"processing_errors" => [],
|
|
"workflow_state" => "created"
|
|
})
|
|
|
|
expect(OutcomeImport.count).to eq @import_count + 1
|
|
run_jobs
|
|
|
|
expect(LearningOutcome.count).to eq @outcome_count + 1
|
|
expect(LearningOutcomeGroup.count).to eq @group_count + 3
|
|
expect(LearningOutcome.last.title).to eq "C"
|
|
|
|
json = api_call(:get, "/api/v1/accounts/#{@account.id}/outcome_imports/#{import.id}",
|
|
{ :controller => 'outcome_imports_api', :action => 'show', :format => 'json',
|
|
:account_id => @account.id.to_s, :id => import.id.to_s })
|
|
expect(json).to be_truthy
|
|
remaining_json = expect_keys(json, %w[created_at updated_at ended_at user])
|
|
|
|
expect(remaining_json).to eq({
|
|
"data" => { "import_type" => "instructure_csv" },
|
|
"processing_errors" => [],
|
|
"progress" => 100,
|
|
"id" => import.id,
|
|
"workflow_state" => "succeeded"
|
|
})
|
|
end
|
|
|
|
it "allows raw post without content-type" do
|
|
# In the current API docs, we specify that you need to send a content-type to make raw
|
|
# post work. However, long ago we added code to make it work even without the header,
|
|
# so we are going to maintain that behavior.
|
|
post "/api/v1/accounts/#{@account.id}/outcome_imports?import_type=instructure_csv",
|
|
params: "\xffab=\xffcd", headers: { "HTTP_AUTHORIZATION" => "Bearer #{access_token_for_user(@user)}" }
|
|
import = OutcomeImport.last
|
|
expect(import.attachment.filename).to eq "outcome_import.csv"
|
|
expect(import.attachment.content_type).to eq "application/x-www-form-urlencoded"
|
|
expect(import.attachment.size).to eq 7
|
|
end
|
|
|
|
it "allows raw post without charset" do
|
|
api_call(:post,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports?import_type=instructure_csv",
|
|
{ :controller => 'outcome_imports_api', :action => 'create',
|
|
:format => 'json', :account_id => @account.id.to_s,
|
|
:import_type => 'instructure_csv', :attachment => 'blah' },
|
|
{},
|
|
{ 'CONTENT_TYPE' => 'text/csv' })
|
|
import = OutcomeImport.last
|
|
expect(import.attachment.filename).to eq "outcome_import.csv"
|
|
expect(import.attachment.content_type).to eq "text/csv"
|
|
end
|
|
|
|
it "handles raw post content-types with attributes" do
|
|
api_call(:post,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports?import_type=instructure_csv",
|
|
{ :controller => 'outcome_imports_api', :action => 'create',
|
|
:format => 'json', :account_id => @account.id.to_s,
|
|
:import_type => 'instructure_csv', :attachment => 'blah' },
|
|
{},
|
|
{ 'CONTENT_TYPE' => 'text/csv; charset=utf-8' })
|
|
import = OutcomeImport.last
|
|
expect(import.attachment.filename).to eq "outcome_import.csv"
|
|
expect(import.attachment.content_type).to eq "text/csv"
|
|
end
|
|
|
|
it "rejects non-utf-8 encodings on content-type" do
|
|
raw_api_call(:post,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports?import_type=instructure_csv",
|
|
{ :controller => 'outcome_imports_api', :action => 'create',
|
|
:format => 'json', :account_id => @account.id.to_s,
|
|
:import_type => 'instructure_csv' },
|
|
{},
|
|
{ 'CONTENT_TYPE' => 'text/csv; charset=ISO-8859-1-Windows-3.0-Latin-1' })
|
|
assert_status(400)
|
|
expect(OutcomeImport.count).to eq 0
|
|
end
|
|
|
|
it "errors on user with no outcomes permissions" do
|
|
account_admin_user_with_role_changes(account: @account, role_changes: { manage_outcomes: true, import_outcomes: false })
|
|
api_call(:post,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports",
|
|
{ controller: 'outcome_imports_api', action: 'create',
|
|
format: 'json', account_id: @account.id.to_s },
|
|
{ import_type: 'instructure_csv',
|
|
attachment: fixture_file_upload("files/outcomes/test_outcomes_1.csv", 'text/csv') },
|
|
{},
|
|
expected_status: 401)
|
|
end
|
|
|
|
it "works with import permissions" do
|
|
account_admin_user_with_role_changes(user: @user, role_changes: { manage_outcomes: false, import_outcomes: true })
|
|
api_call(:post,
|
|
"/api/v1/accounts/#{@account.id}/outcome_imports",
|
|
{ controller: 'outcome_imports_api', action: 'create',
|
|
format: 'json', account_id: @account.id.to_s },
|
|
{ import_type: 'instructure_csv',
|
|
attachment: fixture_file_upload("files/outcomes/test_outcomes_1.csv", 'text/csv') },
|
|
{},
|
|
expected_status: 200)
|
|
end
|
|
|
|
it "includes processing_errors when there are errors" do
|
|
import = @account.outcome_imports.create!
|
|
3.times do |i|
|
|
import.outcome_import_errors.create(message: "some error #{i}")
|
|
end
|
|
|
|
json = api_call(:get, "/api/v1/accounts/#{@account.id}/outcome_imports/#{import.id}",
|
|
{ controller: 'outcome_imports_api', action: 'show', format: 'json',
|
|
account_id: @account.id.to_s, id: import.id.to_s })
|
|
expect(json).to be_key 'processing_errors'
|
|
end
|
|
end
|