ams_migration 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +9 -0
- data/README.md +33 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/calculated.rb +33 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/classic_question.rb +114 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/essay.rb +36 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/file_upload.rb +35 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/fill_in_blank.rb +63 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/fill_in_multiple_blanks.rb +111 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/matching.rb +66 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/multiple_answer.rb +27 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/multiple_choice.rb +57 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/multiple_dropdown.rb +126 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/numerical.rb +89 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/text.rb +28 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/true_false.rb +14 -0
- data/lib/ams_migration/canvas/converter/classic_quiz/unknown.rb +31 -0
- data/lib/ams_migration/canvas/converter/new_quiz/categorization.rb +108 -0
- data/lib/ams_migration/canvas/converter/new_quiz/essay.rb +78 -0
- data/lib/ams_migration/canvas/converter/new_quiz/file_upload.rb +33 -0
- data/lib/ams_migration/canvas/converter/new_quiz/fill_in_blank.rb +180 -0
- data/lib/ams_migration/canvas/converter/new_quiz/formula.rb +33 -0
- data/lib/ams_migration/canvas/converter/new_quiz/hotspot.rb +166 -0
- data/lib/ams_migration/canvas/converter/new_quiz/matching.rb +85 -0
- data/lib/ams_migration/canvas/converter/new_quiz/multiple_answer.rb +28 -0
- data/lib/ams_migration/canvas/converter/new_quiz/multiple_choice.rb +70 -0
- data/lib/ams_migration/canvas/converter/new_quiz/new_question.rb +133 -0
- data/lib/ams_migration/canvas/converter/new_quiz/numerical.rb +117 -0
- data/lib/ams_migration/canvas/converter/new_quiz/ordering.rb +68 -0
- data/lib/ams_migration/canvas/converter/new_quiz/stimulus.rb +35 -0
- data/lib/ams_migration/canvas/converter/new_quiz/true_false.rb +33 -0
- data/lib/ams_migration/canvas/converter/new_quiz/unknown.rb +30 -0
- data/lib/ams_migration/canvas/converter/question_type.rb +30 -0
- data/lib/ams_migration/services/README.md +26 -0
- data/lib/ams_migration/services/data_provider.rb +26 -0
- data/lib/ams_migration/services/learnosity_bank_cleaner.rb +44 -0
- data/lib/ams_migration/services/learnosity_data_api_client.rb +135 -0
- data/lib/ams_migration/services/learnosity_sink.rb +190 -0
- data/lib/ams_migration/services/migration_service.rb +37 -0
- data/lib/ams_migration/services/new_quiz_learnosity_transformer.rb +115 -0
- data/lib/ams_migration/version.rb +3 -0
- data/lib/ams_migration.rb +45 -0
- data/lib/factories/classic_quiz_item_converter_factory.rb +43 -0
- data/lib/factories/new_quiz_item_converter_factory.rb +76 -0
- data/spec/fixtures/sample_data/classic_quiz/calculated.json +24 -0
- data/spec/fixtures/sample_data/classic_quiz/essay.json +24 -0
- data/spec/fixtures/sample_data/classic_quiz/file_upload.json +24 -0
- data/spec/fixtures/sample_data/classic_quiz/fill_in_bank.json +24 -0
- data/spec/fixtures/sample_data/classic_quiz/fill_in_blank.json +53 -0
- data/spec/fixtures/sample_data/classic_quiz/fill_in_multiple_blanks.json +57 -0
- data/spec/fixtures/sample_data/classic_quiz/matching.json +107 -0
- data/spec/fixtures/sample_data/classic_quiz/multiple_answer.json +48 -0
- data/spec/fixtures/sample_data/classic_quiz/multiple_choice.json +56 -0
- data/spec/fixtures/sample_data/classic_quiz/multiple_dropdown.json +73 -0
- data/spec/fixtures/sample_data/classic_quiz/numerical.json +55 -0
- data/spec/fixtures/sample_data/classic_quiz/text.json +24 -0
- data/spec/fixtures/sample_data/classic_quiz/true_false.json +39 -0
- data/spec/fixtures/sample_data/classic_quiz/unknown.json +24 -0
- data/spec/fixtures/sample_data/new_quiz/bank_entry_item.json +5 -0
- data/spec/fixtures/sample_data/new_quiz/bank_item.json +11 -0
- data/spec/fixtures/sample_data/new_quiz/categorization.json +135 -0
- data/spec/fixtures/sample_data/new_quiz/essay.json +40 -0
- data/spec/fixtures/sample_data/new_quiz/file_upload.json +30 -0
- data/spec/fixtures/sample_data/new_quiz/fill_in_blank_association.json +162 -0
- data/spec/fixtures/sample_data/new_quiz/fill_in_blank_dropdown.json +180 -0
- data/spec/fixtures/sample_data/new_quiz/fill_in_blank_math.json +45 -0
- data/spec/fixtures/sample_data/new_quiz/fill_in_blank_mixed.json +188 -0
- data/spec/fixtures/sample_data/new_quiz/fill_in_blank_text.json +140 -0
- data/spec/fixtures/sample_data/new_quiz/formula.json +51 -0
- data/spec/fixtures/sample_data/new_quiz/hotspot_oval.json +38 -0
- data/spec/fixtures/sample_data/new_quiz/hotspot_polygon.json +66 -0
- data/spec/fixtures/sample_data/new_quiz/hotspot_square.json +38 -0
- data/spec/fixtures/sample_data/new_quiz/matching.json +88 -0
- data/spec/fixtures/sample_data/new_quiz/multiple_answer.json +57 -0
- data/spec/fixtures/sample_data/new_quiz/multiple_choice.json +66 -0
- data/spec/fixtures/sample_data/new_quiz/multiple_choice_math.json +55 -0
- data/spec/fixtures/sample_data/new_quiz/numerical.json +64 -0
- data/spec/fixtures/sample_data/new_quiz/ordering.json +60 -0
- data/spec/fixtures/sample_data/new_quiz/stimulus.json +17 -0
- data/spec/fixtures/sample_data/new_quiz/true_false.json +27 -0
- data/spec/fixtures/sample_data/new_quiz/unknown.json +14 -0
- data/spec/lib/ams_migration/services/learnosity_sink_spec.rb +198 -0
- data/spec/lib/canvas/converter/classic_quiz/calculated_spec.rb +26 -0
- data/spec/lib/canvas/converter/classic_quiz/essay_spec.rb +26 -0
- data/spec/lib/canvas/converter/classic_quiz/file_upload_spec.rb +23 -0
- data/spec/lib/canvas/converter/classic_quiz/fill_in_blank_spec.rb +30 -0
- data/spec/lib/canvas/converter/classic_quiz/fill_in_multiple_blanks_spec.rb +33 -0
- data/spec/lib/canvas/converter/classic_quiz/matching_spec.rb +38 -0
- data/spec/lib/canvas/converter/classic_quiz/multiple_answer_spec.rb +33 -0
- data/spec/lib/canvas/converter/classic_quiz/multiple_choice_spec.rb +31 -0
- data/spec/lib/canvas/converter/classic_quiz/multiple_dropdown_spec.rb +39 -0
- data/spec/lib/canvas/converter/classic_quiz/numerical_spec.rb +41 -0
- data/spec/lib/canvas/converter/classic_quiz/text_spec.rb +20 -0
- data/spec/lib/canvas/converter/classic_quiz/true_false_spec.rb +28 -0
- data/spec/lib/canvas/converter/classic_quiz/unknown_spec.rb +25 -0
- data/spec/lib/canvas/converter/common_error.rb +16 -0
- data/spec/lib/canvas/converter/new_quiz/categorization_spec.rb +55 -0
- data/spec/lib/canvas/converter/new_quiz/essay_spec.rb +26 -0
- data/spec/lib/canvas/converter/new_quiz/file_upload_spec.rb +24 -0
- data/spec/lib/canvas/converter/new_quiz/fill_in_blank_spec.rb +111 -0
- data/spec/lib/canvas/converter/new_quiz/formula_spec.rb +23 -0
- data/spec/lib/canvas/converter/new_quiz/hotspot_spec.rb +182 -0
- data/spec/lib/canvas/converter/new_quiz/matching_spec.rb +30 -0
- data/spec/lib/canvas/converter/new_quiz/multiple_answer_spec.rb +34 -0
- data/spec/lib/canvas/converter/new_quiz/multiple_choice_spec.rb +54 -0
- data/spec/lib/canvas/converter/new_quiz/numerical_spec.rb +48 -0
- data/spec/lib/canvas/converter/new_quiz/ordering_spec.rb +25 -0
- data/spec/lib/canvas/converter/new_quiz/stimulus_spec.rb +20 -0
- data/spec/lib/canvas/converter/new_quiz/true_false_spec.rb +24 -0
- data/spec/lib/canvas/converter/new_quiz/unknown_spec.rb +36 -0
- data/spec/lib/factories/classic_quiz_item_converter_factory_spec.rb +183 -0
- data/spec/lib/factories/new_quiz_item_converter_factory_spec.rb +71 -0
- data/spec/lib/services/learnosity_data_api_client_spec.rb +130 -0
- data/spec/lib/services/new_quiz_learnosity_transformer_spec.rb +196 -0
- data/spec/spec_helper.rb +20 -0
- metadata +229 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
# Copyright (C) 2025 - present Instructure, Inc.
|
2
|
+
# This code is made publicly available for educational and reference purposes only.
|
3
|
+
# You may not copy, modify, redistribute, or use this code in any software or service without explicit permission.
|
4
|
+
|
5
|
+
module AmsMigration
|
6
|
+
module Services
|
7
|
+
class NewQuizLearnosityTransformer
|
8
|
+
attr_reader :root_account_uuid
|
9
|
+
|
10
|
+
def initialize(root_account_uuid:)
|
11
|
+
@root_account_uuid = root_account_uuid
|
12
|
+
end
|
13
|
+
|
14
|
+
def transform(quiz)
|
15
|
+
serialized = serialize_quiz_items(quiz[:quiz_items])
|
16
|
+
|
17
|
+
questions = convert_to_questions(quiz[:quiz_items], serialized)
|
18
|
+
features = {}
|
19
|
+
items = convert_to_items(quiz[:quiz_items], serialized)
|
20
|
+
activities = [convert_to_activity(quiz, serialized)]
|
21
|
+
|
22
|
+
{
|
23
|
+
activities:,
|
24
|
+
items:,
|
25
|
+
questions:,
|
26
|
+
features:
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def serialize_quiz_items(quiz_items)
|
33
|
+
quiz_items.to_h do |item|
|
34
|
+
converted = AmsMigration::CanvasQuizzes::NewQuizItemConverterFactory.create_converter(item).convert
|
35
|
+
[item[:id], converted]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_to_questions(quiz_entries, serialized)
|
40
|
+
quiz_entries.filter_map do |quiz_entry|
|
41
|
+
converted = serialized[quiz_entry[:id]]
|
42
|
+
next unless supported?(converted)
|
43
|
+
|
44
|
+
# TODO: should we use quiz_entry.id or item.id? here.
|
45
|
+
# This really depends on how we want to share bank items because in learnosity sharing is done at the item level, not question level.
|
46
|
+
# It is unclear how this is going to work with AMS Item Service either.
|
47
|
+
# For now I am using quiz_entry.id
|
48
|
+
id = quiz_entry[:id]
|
49
|
+
|
50
|
+
{
|
51
|
+
"reference" => "q-#{nq_ls_id(id)}",
|
52
|
+
"type" => converted.dig(:question, :type),
|
53
|
+
"data" => converted[:question]
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_to_activity(wrapper, serialized_items)
|
59
|
+
quiz = wrapper[:quiz]
|
60
|
+
quiz_entries = wrapper[:quiz_items]
|
61
|
+
data = {
|
62
|
+
"items" => quiz_entries.select { |item| supported?(serialized_items[item[:id]]) }
|
63
|
+
.sort_by { |item| item[:position] }
|
64
|
+
.map { |item| "i-#{nq_ls_id(item[:id])}" }
|
65
|
+
}
|
66
|
+
|
67
|
+
{
|
68
|
+
"reference" => "a-#{nq_ls_id(quiz[:id])}",
|
69
|
+
"data" => data,
|
70
|
+
"title" => quiz[:title],
|
71
|
+
"tags" => item_tags(quiz[:id])
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def convert_to_items(quiz_entries, serialized)
|
76
|
+
quiz_entries.filter_map do |quiz_entry|
|
77
|
+
converted = serialized[quiz_entry[:id]]
|
78
|
+
next unless supported?(converted)
|
79
|
+
|
80
|
+
title = converted[:title]
|
81
|
+
id = quiz_entry[:id]
|
82
|
+
{
|
83
|
+
"reference" => "i-#{nq_ls_id(id)}",
|
84
|
+
"title" => title,
|
85
|
+
"status" => "published",
|
86
|
+
"definition" => {
|
87
|
+
"widgets" => [
|
88
|
+
{ "reference" => "q-#{nq_ls_id(id)}" }
|
89
|
+
]
|
90
|
+
},
|
91
|
+
"tags" => item_tags(id)
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def nq_ls_id(id)
|
97
|
+
"nq-#{root_account_uuid}-#{id}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def supported?(converted)
|
101
|
+
question = converted[:question]
|
102
|
+
|
103
|
+
question.is_a?(Hash) && !question.empty? && question[:type] != "unsupported_canvas_question_type"
|
104
|
+
end
|
105
|
+
|
106
|
+
def item_tags(id)
|
107
|
+
[
|
108
|
+
{ "type" => "import_original_id", "name" => id.to_s },
|
109
|
+
{ "type" => "import_account_id", "name" => root_account_uuid.to_s },
|
110
|
+
{ "type" => "import_system", "name" => "NQ" }
|
111
|
+
]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "ams_migration/version"
|
2
|
+
|
3
|
+
require "nokogiri"
|
4
|
+
require "json"
|
5
|
+
require "active_support/core_ext/hash"
|
6
|
+
|
7
|
+
# Require base classes first
|
8
|
+
require_relative "ams_migration/canvas/converter/classic_quiz/classic_question"
|
9
|
+
require_relative "ams_migration/canvas/converter/classic_quiz/multiple_choice"
|
10
|
+
|
11
|
+
require_relative "ams_migration/canvas/converter/new_quiz/new_question"
|
12
|
+
require_relative "ams_migration/canvas/converter/new_quiz/multiple_choice"
|
13
|
+
|
14
|
+
Dir[File.expand_path("ams_migration/canvas/converter/**/*.rb", __dir__)].each do |file|
|
15
|
+
next if file.end_with?("classic_question.rb", "new_question.rb", "multiple_choice.rb")
|
16
|
+
|
17
|
+
require_relative file
|
18
|
+
end
|
19
|
+
|
20
|
+
# Require factories
|
21
|
+
Dir[File.expand_path("factories/*.rb", __dir__)].each do |file|
|
22
|
+
require_relative file
|
23
|
+
end
|
24
|
+
|
25
|
+
# require service classes
|
26
|
+
Dir[File.expand_path("ams_migration/services/**/*.rb", __dir__)].each do |file|
|
27
|
+
require_relative file
|
28
|
+
end
|
29
|
+
|
30
|
+
module AmsMigration
|
31
|
+
class Error < StandardError; end
|
32
|
+
|
33
|
+
module Canvas
|
34
|
+
module Converter
|
35
|
+
module ClassicQuiz
|
36
|
+
end
|
37
|
+
|
38
|
+
module NewQuiz
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module CanvasQuizzes
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module AmsMigration
|
2
|
+
module CanvasQuizzes
|
3
|
+
# Factory that handles the Canvas Quiz to MC Question converter
|
4
|
+
# based on the Classic Quiz Item passed into the create_converter method.
|
5
|
+
class ClassicQuizItemConverterFactory
|
6
|
+
TYPE_FIELD = "question_type".freeze
|
7
|
+
|
8
|
+
def self.create_converter(item)
|
9
|
+
type = item[TYPE_FIELD]
|
10
|
+
question = item.to_json
|
11
|
+
|
12
|
+
case type
|
13
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::MULTI_CHOICE
|
14
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::MultipleChoice.new(question)
|
15
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::MULTIPLE_ANSWERS
|
16
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::MultipleAnswer.new(question)
|
17
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::MATCHING
|
18
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::Matching.new(question)
|
19
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::FILL_IN_BLANK
|
20
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::FillInBlank.new(question)
|
21
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::FILL_IN_MULTIPLE_BLANKS
|
22
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::FillInMultipleBlanks.new(question)
|
23
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::MULTIPLE_DROPDOWNS
|
24
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::MultipleDropdown.new(question)
|
25
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::TRUE_FALSE
|
26
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::TrueFalse.new(question)
|
27
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::NUMERICAL
|
28
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::Numerical.new(question)
|
29
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::TEXT_ONLY
|
30
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::Text.new(question)
|
31
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::CALCULATED
|
32
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::Calculated.new(question)
|
33
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::FILE_UPLOAD
|
34
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::FileUpload.new(question)
|
35
|
+
when AmsMigration::Canvas::Converter::ClassicQuiz::ClassicQuestion::ESSAY
|
36
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::Essay.new(question)
|
37
|
+
else
|
38
|
+
AmsMigration::Canvas::Converter::ClassicQuiz::Unknown.new(question)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module AmsMigration
|
2
|
+
module CanvasQuizzes
|
3
|
+
# Factory that handles the Canvas Quiz to MC Question converter
|
4
|
+
# based on the New Quiz Item passed into the create_converter method.
|
5
|
+
class NewQuizItemConverterFactory
|
6
|
+
QUESTION_TYPE_KEY = "interaction_type_slug".freeze
|
7
|
+
ENTRY_TYPE_ITEM = "Item".freeze
|
8
|
+
ENTRY_TYPE_STIMULUS = "Stimulus".freeze
|
9
|
+
ENTRY_TYPE_BANK_ENTRY = "BankEntry".freeze
|
10
|
+
ENTRY_TYPE_BANK = "Bank".freeze
|
11
|
+
|
12
|
+
def self.create_converter(item)
|
13
|
+
item = normalize(item.dup.with_indifferent_access)
|
14
|
+
type = type_of(item)
|
15
|
+
question = item.to_json
|
16
|
+
|
17
|
+
case type
|
18
|
+
when "choice"
|
19
|
+
AmsMigration::Canvas::Converter::NewQuiz::MultipleChoice.new(question)
|
20
|
+
when "multi-answer"
|
21
|
+
AmsMigration::Canvas::Converter::NewQuiz::MultipleAnswer.new(question)
|
22
|
+
when "matching"
|
23
|
+
AmsMigration::Canvas::Converter::NewQuiz::Matching.new(question)
|
24
|
+
when "categorization"
|
25
|
+
AmsMigration::Canvas::Converter::NewQuiz::Categorization.new(question)
|
26
|
+
when "essay"
|
27
|
+
AmsMigration::Canvas::Converter::NewQuiz::Essay.new(question)
|
28
|
+
when "file-upload"
|
29
|
+
AmsMigration::Canvas::Converter::NewQuiz::FileUpload.new(question)
|
30
|
+
when "formula"
|
31
|
+
AmsMigration::Canvas::Converter::NewQuiz::Formula.new(question)
|
32
|
+
when "ordering"
|
33
|
+
AmsMigration::Canvas::Converter::NewQuiz::Ordering.new(question)
|
34
|
+
when "true-false"
|
35
|
+
AmsMigration::Canvas::Converter::NewQuiz::TrueFalse.new(question)
|
36
|
+
when "hot-spot"
|
37
|
+
AmsMigration::Canvas::Converter::NewQuiz::Hotspot.new(question)
|
38
|
+
when "rich-fill-blank"
|
39
|
+
AmsMigration::Canvas::Converter::NewQuiz::FillInBlank.new(question)
|
40
|
+
when "stimulus"
|
41
|
+
AmsMigration::Canvas::Converter::NewQuiz::Stimulus.new(question)
|
42
|
+
when "numeric"
|
43
|
+
AmsMigration::Canvas::Converter::NewQuiz::Numerical.new(question)
|
44
|
+
else
|
45
|
+
AmsMigration::Canvas::Converter::NewQuiz::Unknown.new(question)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.entry_type(item)
|
50
|
+
item["entry_type"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.type_of(item)
|
54
|
+
entry_type_map = {
|
55
|
+
ENTRY_TYPE_ITEM => item["entry"]&.[](QUESTION_TYPE_KEY) || item[QUESTION_TYPE_KEY],
|
56
|
+
ENTRY_TYPE_STIMULUS => "stimulus",
|
57
|
+
ENTRY_TYPE_BANK => "BankItem Type" # Currently Unsupported, See MCE-23091
|
58
|
+
}
|
59
|
+
|
60
|
+
entry_type_map[entry_type(item)]
|
61
|
+
end
|
62
|
+
|
63
|
+
# We hardcoded converters based on the 'Item' and 'Stimulus' entry types. When the input is 'BankEntry',
|
64
|
+
# we need to modify the input to have the expected shape so that it can be passed into our converters.
|
65
|
+
def self.normalize(item)
|
66
|
+
return item unless entry_type(item) == ENTRY_TYPE_BANK_ENTRY
|
67
|
+
|
68
|
+
item["entry_type"] = item["entry"]["entry_type"]
|
69
|
+
item["entry"] = item["entry"]["entry"]
|
70
|
+
item
|
71
|
+
end
|
72
|
+
|
73
|
+
private_class_method :entry_type, :type_of, :normalize
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"id": 603207,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251789,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "calculated_question",
|
9
|
+
"question_text": "<p></p>",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "<p>General comments</p>",
|
17
|
+
"answers": [],
|
18
|
+
"variables": null,
|
19
|
+
"formulas": null,
|
20
|
+
"answer_tolerance": null,
|
21
|
+
"formula_decimal_places": null,
|
22
|
+
"matches": null,
|
23
|
+
"matching_answer_incorrect_matches": null
|
24
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"id": 603207,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251789,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "essay_question",
|
9
|
+
"question_text": "<p>This is an essay</p> <img src=\"https://dummyfileurl.com/file.png\" alt=\"file.png\" data-api-endpoint=\"https://dummyfileurl.com\" data-api-returntype=\"File\" />",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "<p>General comments</p>",
|
17
|
+
"answers": [],
|
18
|
+
"variables": null,
|
19
|
+
"formulas": null,
|
20
|
+
"answer_tolerance": null,
|
21
|
+
"formula_decimal_places": null,
|
22
|
+
"matches": null,
|
23
|
+
"matching_answer_incorrect_matches": null
|
24
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"id": 603207,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251789,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "file_upload_question",
|
9
|
+
"question_text": "<p></p>",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "<p>General comments</p>",
|
17
|
+
"answers": [],
|
18
|
+
"variables": null,
|
19
|
+
"formulas": null,
|
20
|
+
"answer_tolerance": null,
|
21
|
+
"formula_decimal_places": null,
|
22
|
+
"matches": null,
|
23
|
+
"matching_answer_incorrect_matches": null
|
24
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"id": 603207,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251789,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "file_upload_question",
|
9
|
+
"question_text": "<p></p>",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "<p>General comments</p>",
|
17
|
+
"answers": [],
|
18
|
+
"variables": null,
|
19
|
+
"formulas": null,
|
20
|
+
"answer_tolerance": null,
|
21
|
+
"formula_decimal_places": null,
|
22
|
+
"matches": null,
|
23
|
+
"matching_answer_incorrect_matches": null
|
24
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"id": 603200,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251782,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "short_answer_question",
|
9
|
+
"question_text": "<p>This is the fill in the blank</p> <img src=\"https://dummyfileurl.com/file.png\" alt=\"file.png\" data-api-endpoint=\"https://dummyfileurl.com\" data-api-returntype=\"File\" />",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "",
|
17
|
+
"answers": [
|
18
|
+
{
|
19
|
+
"id": 8166,
|
20
|
+
"text": "answer 1",
|
21
|
+
"comments": "",
|
22
|
+
"comments_html": "<p>answer comment 1</p>",
|
23
|
+
"weight": 100
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"id": 1101,
|
27
|
+
"text": "answer 2",
|
28
|
+
"comments": "",
|
29
|
+
"comments_html": "<p>answer comment 2</p>",
|
30
|
+
"weight": 100
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"id": 4121,
|
34
|
+
"text": "answer 3",
|
35
|
+
"comments": "",
|
36
|
+
"comments_html": "<p>answer comment 3</p>",
|
37
|
+
"weight": 100
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"id": 814,
|
41
|
+
"text": "answer 4",
|
42
|
+
"comments": "",
|
43
|
+
"comments_html": "<p>answer comment 4</p>",
|
44
|
+
"weight": 100
|
45
|
+
}
|
46
|
+
],
|
47
|
+
"variables": null,
|
48
|
+
"formulas": null,
|
49
|
+
"answer_tolerance": null,
|
50
|
+
"formula_decimal_places": null,
|
51
|
+
"matches": null,
|
52
|
+
"matching_answer_incorrect_matches": null
|
53
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"id": 603201,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251783,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "fill_in_multiple_blanks_question",
|
9
|
+
"question_text": "<p><span>Roses are [color1], violets are [color2]</span></p> <img src=\"https://dummyfileurl.com/file.png\" alt=\"file.png\" data-api-endpoint=\"https://dummyfileurl.com\" data-api-returntype=\"File\" />",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "",
|
17
|
+
"answers": [
|
18
|
+
{
|
19
|
+
"id": "6444",
|
20
|
+
"text": "red",
|
21
|
+
"comments": "",
|
22
|
+
"comments_html": "<p>red comments</p>",
|
23
|
+
"weight": 100,
|
24
|
+
"blank_id": "color1"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"id": "4936",
|
28
|
+
"text": "blue",
|
29
|
+
"comments": "",
|
30
|
+
"comments_html": "<p>blue comments</p>",
|
31
|
+
"weight": 100,
|
32
|
+
"blank_id": "color1"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"id": "9143",
|
36
|
+
"text": "green",
|
37
|
+
"comments": "",
|
38
|
+
"comments_html": "<p>green comments</p>",
|
39
|
+
"weight": 100,
|
40
|
+
"blank_id": "color2"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"id": "9387",
|
44
|
+
"text": "pink",
|
45
|
+
"comments": "",
|
46
|
+
"comments_html": "<p>pink comments</p>",
|
47
|
+
"weight": 100,
|
48
|
+
"blank_id": "color2"
|
49
|
+
}
|
50
|
+
],
|
51
|
+
"variables": null,
|
52
|
+
"formulas": null,
|
53
|
+
"answer_tolerance": null,
|
54
|
+
"formula_decimal_places": null,
|
55
|
+
"matches": null,
|
56
|
+
"matching_answer_incorrect_matches": null
|
57
|
+
}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
{
|
2
|
+
"id": 603204,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251786,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "matching_question",
|
9
|
+
"question_text": "<p>Matching question</p> <img src=\"https://dummyfileurl.com/file.png\" alt=\"file.png\" data-api-endpoint=\"https://dummyfileurl.com\" data-api-returntype=\"File\" />",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "",
|
17
|
+
"answers": [
|
18
|
+
{
|
19
|
+
"id": 1803,
|
20
|
+
"text": "",
|
21
|
+
"left": "",
|
22
|
+
"right": "",
|
23
|
+
"comments": "",
|
24
|
+
"comments_html": "",
|
25
|
+
"match_id": 3540
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"id": 5931,
|
29
|
+
"text": "",
|
30
|
+
"left": "",
|
31
|
+
"right": "",
|
32
|
+
"comments": "",
|
33
|
+
"comments_html": "",
|
34
|
+
"match_id": 3540
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"id": 6193,
|
38
|
+
"text": "L1",
|
39
|
+
"left": "L1",
|
40
|
+
"right": "R1",
|
41
|
+
"comments": "",
|
42
|
+
"comments_html": "",
|
43
|
+
"match_id": 3284
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"id": 4501,
|
47
|
+
"text": "L2",
|
48
|
+
"left": "L2",
|
49
|
+
"right": "R2",
|
50
|
+
"comments": "",
|
51
|
+
"comments_html": "",
|
52
|
+
"match_id": 9849
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"id": 2844,
|
56
|
+
"text": "L3",
|
57
|
+
"left": "L3",
|
58
|
+
"right": "R3",
|
59
|
+
"comments": "",
|
60
|
+
"comments_html": "",
|
61
|
+
"match_id": 4557
|
62
|
+
}
|
63
|
+
],
|
64
|
+
"variables": null,
|
65
|
+
"formulas": null,
|
66
|
+
"answer_tolerance": null,
|
67
|
+
"formula_decimal_places": null,
|
68
|
+
"matches": [
|
69
|
+
{
|
70
|
+
"text": "",
|
71
|
+
"match_id": 3540
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"text": "R1",
|
75
|
+
"match_id": 3284
|
76
|
+
},
|
77
|
+
{
|
78
|
+
"text": "R2",
|
79
|
+
"match_id": 9849
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"text": "R3",
|
83
|
+
"match_id": 4557
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"text": "d1",
|
87
|
+
"match_id": 2385
|
88
|
+
},
|
89
|
+
{
|
90
|
+
"text": "d2",
|
91
|
+
"match_id": 8504
|
92
|
+
},
|
93
|
+
{
|
94
|
+
"text": "d3",
|
95
|
+
"match_id": 8560
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"text": "d4",
|
99
|
+
"match_id": 6143
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"text": "d5",
|
103
|
+
"match_id": 5727
|
104
|
+
}
|
105
|
+
],
|
106
|
+
"matching_answer_incorrect_matches": "d1\nd2\nd3\nd4\nd5"
|
107
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
{
|
2
|
+
"id": 603202,
|
3
|
+
"quiz_id": 70667,
|
4
|
+
"quiz_group_id": null,
|
5
|
+
"assessment_question_id": 1251784,
|
6
|
+
"position": null,
|
7
|
+
"question_name": "Question",
|
8
|
+
"question_type": "multiple_answers_question",
|
9
|
+
"question_text": "<p>Multiple answer text</p> <img src=\"https://dummyfileurl.com/file.png\" alt=\"file.png\" data-api-endpoint=\"https://dummyfileurl.com\" data-api-returntype=\"File\" />",
|
10
|
+
"points_possible": 1,
|
11
|
+
"correct_comments": "",
|
12
|
+
"incorrect_comments": "",
|
13
|
+
"neutral_comments": "",
|
14
|
+
"correct_comments_html": "",
|
15
|
+
"incorrect_comments_html": "",
|
16
|
+
"neutral_comments_html": "",
|
17
|
+
"answers": [
|
18
|
+
{
|
19
|
+
"id": "6739",
|
20
|
+
"text": "Answer 1",
|
21
|
+
"comments": "",
|
22
|
+
"comments_html": "<p>Answer 1 comments</p>",
|
23
|
+
"weight": 100,
|
24
|
+
"html": "<p>Answer 1</p>"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"id": "1316",
|
28
|
+
"text": "Answer 2",
|
29
|
+
"comments": "",
|
30
|
+
"comments_html": "<p>Answer 2 comments</p>",
|
31
|
+
"weight": 100,
|
32
|
+
"html": "<p>Answer 2</p>"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"id": "6779",
|
36
|
+
"text": "Answer 3",
|
37
|
+
"comments": "",
|
38
|
+
"comments_html": "<p>Answer 3 comments</p>",
|
39
|
+
"weight": 0
|
40
|
+
}
|
41
|
+
],
|
42
|
+
"variables": null,
|
43
|
+
"formulas": null,
|
44
|
+
"answer_tolerance": null,
|
45
|
+
"formula_decimal_places": null,
|
46
|
+
"matches": null,
|
47
|
+
"matching_answer_incorrect_matches": null
|
48
|
+
}
|