░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
pplmvsvm
LOCATION:
/var/www/canvas/spec/models/lti/content_migration_service
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: exporter_spec.rb
# frozen_string_literal: true # # Copyright (C) 2016 - 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_relative "../../../lti_spec_helper" RSpec.describe Lti::ContentMigrationService::Exporter do include WebMock::API include LtiSpecHelper describe "#export_completed?" do let(:course) { course_model } let(:tool) do course.context_external_tools.create!({ name: "a", domain: "lti.example.com", consumer_key: "12345", shared_secret: "sekret", }) end let(:migrator) { Lti::ContentMigrationService::Exporter.new(course, tool, {}) } let(:status_url) { "https://lti.example.com/export/42/status" } before do migrator.instance_variable_set(:@status_url, status_url) end it "must return true when the remote service indicates the export status is completed" do stub_request(:get, status_url) .to_return(status: 200, body: { status: "completed" }.to_json) expect(migrator).to be_export_completed end it "must raise an exception with the response message when the export has failed" do stub_request(:get, status_url) .to_return(status: 200, body: { status: "failed", message: "Oh, noes!" }.to_json) expect { migrator.export_completed? } .to raise_error RuntimeError, "Oh, noes!" end it "must return false when the remote service indicates the export status neither completed or failed" do stub_request(:get, status_url) .to_return(status: 200, body: { status: "foobar" }.to_json) expect(migrator).to_not be_export_completed end end describe "#retrieve_export" do let(:course) { course_model } let(:tool) do course.context_external_tools.create!({ name: "a", domain: "lti.example.com", consumer_key: "12345", shared_secret: "sekret", }) end let(:migrator) { Lti::ContentMigrationService::Exporter.new(course, tool, {}) } let(:fetch_url) { "https://lti.example.com/export/42" } before do migrator.instance_variable_set(:@fetch_url, fetch_url) end it "must return nil when the export status has indicated failure" do migrator.instance_variable_set(:@export_status, "failed") expect(migrator.retrieve_export).to be_nil end it "must return the parsed response body when the export status indicated completion" do response_body = { foo: "bar", baz: "qux" }.to_json stub_request(:get, fetch_url) .to_return(status: 200, body: response_body, headers: {}) migrator.instance_variable_set(:@export_status, "completed") expect(migrator.retrieve_export).to eq({ "foo" => "bar", "baz" => "qux" }) end it "must raise an exception when the response status is something other than 200" do response_body = { foo: "bar", baz: "qux" }.to_json stub_request(:get, fetch_url) .to_return(status: 404, body: response_body, headers: {}) expect { migrator.retrieve_export } .to raise_error RuntimeError, /404/ end end describe "#start!" do let(:export_url) { "https://lti.example.com/begin_export" } before do # creates @course :-( course_model @root_account = @course.root_account @root_account.ensure_defaults @root_account.save! @tool = @course.context_external_tools.build({ name: "a", domain: "lti.example.com", consumer_key: "12345", shared_secret: "secret", }) @tool.settings = Importers::ContextExternalToolImporter.create_tool_settings({ settings: { "custom_fields" => { "course_id" => "$Canvas.course.id", }, "content_migration" => { "export_start_url" => export_url, "import_start_url" => "https://lti.example.com/begin_import" }, } }) @tool.save! response_body = { status_url: "https://lti.example.com/export/42/status", fetch_url: "https://lti.example.com/export/42", }.to_json stub_request(:post, export_url) .to_return(status: 200, body: response_body, headers: {}) @options = {} @migrator = Lti::ContentMigrationService::Exporter.new(@course, @tool, @options) end context "for a full export" do before do @migrator.start! end it "must post the context_id to the configured tools" do assert_requested(:post, export_url, { body: hash_including(context_id: Lti::Asset.opaque_identifier_for(@course)) }) end it "must post the tool_consumer_instance_guid to the configured tools" do assert_requested(:post, export_url, { body: hash_including(tool_consumer_instance_guid: @root_account.lti_guid) }) end it "must include a JWT as the Authorization header for each request" do assert_requested(:post, export_url, { headers: { "Authorization" => /^Bearer [a-zA-Z0-9\-_]{36,}\.[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]{43}$/ } }) end it "must include any variable expansions requested by the tool" do assert_requested(:post, export_url, { body: hash_including("custom_course_id" => @course.id.to_s) }) end it "must not include the exported assets key" do assert_not_requested(:post, export_url, { body: hash_including("custom_exported_assets" => anything) }) end it "must mark the migration as successfully started" do expect(@migrator).to be_successfully_started end context "for the default body format" do it "must format request body as nested query" do assert_requested(:post, export_url, { body: Rack::Utils.build_nested_query({ context_id: Lti::Asset.opaque_identifier_for(@course), tool_consumer_instance_guid: @root_account.lti_guid, custom_course_id: @course.id.to_s }) }) end it "must post with correct content-type" do assert_requested(:post, export_url, { headers: { "Content-Type" => "application/x-www-form-urlencoded" } }) end end context "for json body format" do before do @tool.settings = Importers::ContextExternalToolImporter.create_tool_settings({ settings: { "content_migration" => { "export_start_url" => export_url, "import_start_url" => "https://lti.example.com/begin_import", "export_format" => "json" }, } }) @tool.save! @migrator = Lti::ContentMigrationService::Exporter.new(@course, @tool, @options) @migrator.start! end it "must format request body as json" do assert_requested(:post, export_url, { body: { context_id: Lti::Asset.opaque_identifier_for(@course), tool_consumer_instance_guid: @root_account.lti_guid, } }) end it "must post with correct content-type" do assert_requested(:post, export_url, { headers: { "Content-Type" => "application/json" } }) end end end context "for a partial export" do before do @options[:selective] = true @exports = @options[:exported_assets] = %w[assignment_42 learning_outcome_84 announcement_21] @migrator.start! end it "must include the exported assets in the request to the tool" do assert_requested(:post, export_url, { body: hash_including("custom_exported_assets" => @exports) }) end end end describe "#successfully_started?" do let(:migrator) { Lti::ContentMigrationService::Exporter.new("", "", {}) } it "must return true when status and fetch urls are both present" do migrator.instance_variable_set(:@status_url, "junk") migrator.instance_variable_set(:@fetch_url, "junk") expect(migrator).to be_successfully_started end it "must return false when there are not status and fetch urls" do expect(migrator).to_not be_successfully_started end end end
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 exporter_spec.rb
RB
11.2 KB
2023-09-24 03:36
EDIT
📄 importer_spec.rb
RB
13.6 KB
2023-09-24 03:36
EDIT