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,55 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Categorization do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "classic_quiz", "calculated.json")) }
|
10
|
+
let(:question) do
|
11
|
+
File.read(File.join(SPEC_ROOT,
|
12
|
+
"fixtures",
|
13
|
+
"sample_data",
|
14
|
+
"new_quiz",
|
15
|
+
"categorization.json"))
|
16
|
+
end
|
17
|
+
|
18
|
+
subject { described_class.new(question) }
|
19
|
+
|
20
|
+
it_behaves_like "handles common errors"
|
21
|
+
|
22
|
+
it "converts to a valid classification item" do
|
23
|
+
conversion = subject.convert
|
24
|
+
expect(conversion[:question]).to eq(
|
25
|
+
{
|
26
|
+
possible_responses: ["C3PO",
|
27
|
+
"JarJar Binks",
|
28
|
+
"Luke Skywalker",
|
29
|
+
"Darth Maul",
|
30
|
+
"Obi-Wan Kenobi",
|
31
|
+
"Darth Sidious",
|
32
|
+
"Ahsoka Tano",
|
33
|
+
"R2D2",
|
34
|
+
"Yoda",
|
35
|
+
"Mace Windu",
|
36
|
+
"Anakin Skywalker",
|
37
|
+
"Darth Tyranus"],
|
38
|
+
stimulus: "\u003cp\u003ePlease categorize the following \u003cstrong\u003eForce\u003c/strong\u003e users into the category that best fits them:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi\" alt=\"Alternative Text\" /\u003e\u003c/p\u003e",
|
39
|
+
type: "classification",
|
40
|
+
ui_style: {
|
41
|
+
column_count: 3,
|
42
|
+
column_titles: ["Light side of the Force", "Dark side of the Force", "Gray side of the Force"]
|
43
|
+
},
|
44
|
+
validation: {
|
45
|
+
scoring_type: "exactMatch",
|
46
|
+
valid_response: {
|
47
|
+
score: 5,
|
48
|
+
value: [[4, 8, 9, 2], [3, 5, 11], [10, 6]]
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
)
|
53
|
+
expect(conversion[:title]).to eq("Categorization Question 1")
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Essay do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "essay.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to longtextV2 item" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ stimulus: "<p><strong>Question</strong> <em>stimulus</em> here <span style=\"text-decoration: underline;\">with</span> some <span style=\"text-decoration: underline;\"><em>extra</em></span> weird <span style=\"color: #000000;\">and</span> wacky <sup><span style=\"background-color: #e03e2d;\">words</span></sup> for testing of <span style=\"color: #fbeeb8;\">conversion</span></p>\u003cp\u003e\u003cimg src=\"https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi\" alt=\"Alternative Text\" /\u003e\u003c/p\u003e",
|
18
|
+
spellcheck: true,
|
19
|
+
type: "longtextV2",
|
20
|
+
metadata: { rubric: "This is the rubric and should translate as such.",
|
21
|
+
rubric_points: 1.0 },
|
22
|
+
show_word_count: false,
|
23
|
+
show_word_limit: "off" })
|
24
|
+
expect(conversion[:title]).to eq("Rich Content Editor - no word limit, no word count, no spell check")
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::FileUpload do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "file_upload.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to essay item with placeholder text" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ stimulus: "The File upload item was removed from the quiz because there is no equivalent item type in Mastery Connect. Please check the original quiz for this question.",
|
18
|
+
type: "unsupported_canvas_question_type",
|
19
|
+
validation: { valid_response: { score: 0, value: "" },
|
20
|
+
scoring_type: "exactMatch" },
|
21
|
+
is_math: true })
|
22
|
+
expect(conversion[:title]).to eq("File Upload")
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,111 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::FillInBlank do
|
9
|
+
let(:file_name) { "" }
|
10
|
+
let(:question) do
|
11
|
+
File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", file_name))
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { described_class.new(question) }
|
15
|
+
|
16
|
+
context "when new quiz question contains only text entry" do
|
17
|
+
let(:file_name) { "fill_in_blank_text.json" }
|
18
|
+
|
19
|
+
it_behaves_like "handles common errors"
|
20
|
+
|
21
|
+
it "converts to clozetext item" do
|
22
|
+
conversion = subject.convert
|
23
|
+
expect(conversion[:question]).to eq(
|
24
|
+
{ stimulus: "Question 1",
|
25
|
+
template: '<p>Roses are {{response}},</p><p>Violets are {{response}}. </p><p>Sugar is {{response}}, </p><p>And so are {{response}}.</p><p>That is {{response}}, </p><p>I love you {{response}}.</p><p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
26
|
+
type: "clozetext",
|
27
|
+
validation: { scoring_type: "exactMatch",
|
28
|
+
valid_response: { score: 1, value: %w[red blue sweet you why too] },
|
29
|
+
alt_responses: [{ score: 1, value: %w[red blue sweet youu why tooo] },
|
30
|
+
{ score: 1, value: %w[red blue sweet youuu why toooo] }],
|
31
|
+
match_all_possible_responses: true } }
|
32
|
+
)
|
33
|
+
expect(conversion[:title]).to eq("Question 1")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when new quiz question contains only dropdown" do
|
38
|
+
let(:file_name) { "fill_in_blank_dropdown.json" }
|
39
|
+
|
40
|
+
it_behaves_like "handles common errors"
|
41
|
+
|
42
|
+
it "converts to clozedropdown item" do
|
43
|
+
conversion = subject.convert
|
44
|
+
expect(conversion[:question]).to eq(
|
45
|
+
{ stimulus: "Question 1",
|
46
|
+
template: '<p>Roses are {{response}},</p><p>Violets are {{response}}. </p><p>Sugar is {{response}}, </p><p>And so are {{response}}.</p><p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
47
|
+
type: "clozedropdown",
|
48
|
+
validation: { scoring_type: "exactMatch",
|
49
|
+
valid_response: { score: 1, value: %w[red blue sweet you] } },
|
50
|
+
possible_responses: [%w[red green yellow],
|
51
|
+
%w[blue purple gray],
|
52
|
+
%w[sweet sour bitter],
|
53
|
+
["you", "they", "that guy"]] }
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when new quiz question contains only association" do
|
59
|
+
let(:file_name) { "fill_in_blank_association.json" }
|
60
|
+
|
61
|
+
it_behaves_like "handles common errors"
|
62
|
+
|
63
|
+
it "converts to clozeassociation item" do
|
64
|
+
conversion = subject.convert
|
65
|
+
expect(conversion[:question]).to eq(
|
66
|
+
{ stimulus: "Question 1",
|
67
|
+
template: '<p>Roses are {{response}},</p><p>Violets are {{response}}. </p><p>Sugar is {{response}}, </p><p>And so are {{response}}.</p><p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
68
|
+
type: "clozeassociation",
|
69
|
+
validation: { scoring_type: "exactMatch",
|
70
|
+
valid_response: { score: 1, value: %w[red blue sweet you] } },
|
71
|
+
possible_responses: %w[green red blue sweet you purple orange sour bitter they] }
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when new quiz question contains math in the template" do
|
77
|
+
let(:file_name) { "fill_in_blank_math.json" }
|
78
|
+
|
79
|
+
it "converts math to LaTeX format" do
|
80
|
+
conversion = subject.convert
|
81
|
+
expect(conversion[:question]).to eq(
|
82
|
+
{ stimulus: "Question 1",
|
83
|
+
template: '<p>\\(2+2=\\) {{response}}<img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
84
|
+
type: "clozetext",
|
85
|
+
validation: { scoring_type: "exactMatch", valid_response: { score: 1, value: ["4"] } },
|
86
|
+
is_math: true }
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when new quiz question contains mixed answer types" do
|
92
|
+
let(:file_name) { "fill_in_blank_mixed.json" }
|
93
|
+
|
94
|
+
it "converts item as best it can and notifies user that additional configuration might be required" do
|
95
|
+
conversion = subject.convert
|
96
|
+
expect(conversion[:question]).to eq(
|
97
|
+
{ stimulus: "Question 1",
|
98
|
+
template: "<p>Roses are {{response}}, violets are {{response}}.</p><p>Sugar is {{response}}, and so are {{response}}.</p><p>To each their {{response}}.</p><p>Bada bing, bada {{response}}.</p><p>Like two peas in a {{response}}.</p>",
|
99
|
+
type: "clozetext",
|
100
|
+
validation: { scoring_type: "exactMatch",
|
101
|
+
valid_response: { score: 1, value: %w[red blue sweet you own boom pod] },
|
102
|
+
alt_responses: [{ score: 1, value: %w[red blue sweet youu own boom pod] },
|
103
|
+
{ score: 1, value: %w[red blue sweet youuu own boom pod] }],
|
104
|
+
match_all_possible_responses: true } }
|
105
|
+
)
|
106
|
+
expect(subject.notifications).to eq(
|
107
|
+
["Fill in the blank question with mixed answer types have been converted to open entry exact match"]
|
108
|
+
)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Formula do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "formula.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to essay item with placeholder text" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ stimulus: "The Formula item was removed from the quiz because there is no equivalent item type in Mastery Connect. Please check the original quiz for this question.",
|
18
|
+
type: "unsupported_canvas_question_type",
|
19
|
+
validation: { valid_response: { score: 0, value: "" },
|
20
|
+
scoring_type: "exactMatch" },
|
21
|
+
is_math: true })
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,182 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Hotspot do
|
9
|
+
let(:file_name) { "" }
|
10
|
+
let(:question) do
|
11
|
+
File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", file_name))
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
stub_request(:get, "https://dummyfileurl.com/file.png")
|
16
|
+
.with(
|
17
|
+
headers: {
|
18
|
+
"Accept" => "*/*",
|
19
|
+
"Accept-Encoding" => "identity",
|
20
|
+
"User-Agent" => "Ruby"
|
21
|
+
}
|
22
|
+
)
|
23
|
+
.to_return(status: 200, body: "", headers: {})
|
24
|
+
end
|
25
|
+
|
26
|
+
subject { described_class.new(question) }
|
27
|
+
|
28
|
+
context "when the hotspot type is square" do
|
29
|
+
let(:file_name) { "hotspot_square.json" }
|
30
|
+
|
31
|
+
it_behaves_like "handles common errors"
|
32
|
+
|
33
|
+
it "converts NQ JSON to hotspot item" do
|
34
|
+
conversion = subject.convert
|
35
|
+
|
36
|
+
expect(conversion[:question]).to eq({
|
37
|
+
type: "hotspot",
|
38
|
+
stimulus: "\u003cp\u003e\u003cem\u003e\u003cstrong\u003eThis\u003c/strong\u003e\u003c/em\u003e is a \u003cstrong\u003equestion\u003c/strong\u003e stem \u003cem\u003ewith\u003c/em\u003e some \u003cspan style=\"text-decoration: underline;\"\u003eadditional\u003c/span\u003e text to \u003cspan style=\"color: #ba372a;\"\u003etest \u003c/span\u003ewacky \u003cspan style=\"background-color: #fbeeb8;\"\u003eformatting\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\\(234+\\alpha^4-56\\)\u003c/p\u003e\u003cp\u003eSome math is before this for \u003csub\u003etesting\u003c/sub\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi\" alt=\"Alternative Text\" /\u003e\u003c/p\u003e",
|
39
|
+
image: {
|
40
|
+
source: "https://dummyfileurl.com/file.png",
|
41
|
+
width: 500,
|
42
|
+
height: 500
|
43
|
+
},
|
44
|
+
areas: [
|
45
|
+
[
|
46
|
+
{
|
47
|
+
x: 44.259838136427874,
|
48
|
+
y: 43.53909783154884
|
49
|
+
},
|
50
|
+
{
|
51
|
+
x: 44.259838136427874,
|
52
|
+
y: 50.71315372424723
|
53
|
+
},
|
54
|
+
{
|
55
|
+
x: 52.070397807562195,
|
56
|
+
y: 50.71315372424723
|
57
|
+
},
|
58
|
+
{
|
59
|
+
x: 52.070397807562195,
|
60
|
+
y: 43.53909783154884
|
61
|
+
}
|
62
|
+
]
|
63
|
+
],
|
64
|
+
area_attributes: {
|
65
|
+
global: {
|
66
|
+
fill: "rgba(12, 176, 216, 0.48)",
|
67
|
+
stroke: "rgba(25, 90, 107, 0.83)"
|
68
|
+
}
|
69
|
+
},
|
70
|
+
validation: {
|
71
|
+
scoring_type: "exactMatch",
|
72
|
+
valid_response: {
|
73
|
+
score: 1.0,
|
74
|
+
value: ["0"]
|
75
|
+
}
|
76
|
+
},
|
77
|
+
is_math: true
|
78
|
+
})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when the hotspot type is oval" do
|
83
|
+
let(:file_name) { "hotspot_oval.json" }
|
84
|
+
|
85
|
+
it_behaves_like "handles common errors"
|
86
|
+
|
87
|
+
it "converts NQ JSON to hotspot item" do
|
88
|
+
conversion = subject.convert
|
89
|
+
|
90
|
+
expect(conversion[:question]).to eq({
|
91
|
+
type: "hotspot",
|
92
|
+
stimulus: "\u003cp\u003e\u003cem\u003e\u003cstrong\u003eThis\u003c/strong\u003e\u003c/em\u003e is a \u003cstrong\u003equestion\u003c/strong\u003e stem \u003cem\u003ewith\u003c/em\u003e some \u003cspan style=\"text-decoration: underline;\"\u003eadditional\u003c/span\u003e text to \u003cspan style=\"color: #ba372a;\"\u003etest \u003c/span\u003ewacky \u003cspan style=\"background-color: #fbeeb8;\"\u003eformatting\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\\(234+\\alpha^4-56\\)\u003c/p\u003e\u003cp\u003eSome math is before this for \u003csub\u003etesting\u003c/sub\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi\" alt=\"Alternative Text\" /\u003e\u003c/p\u003e",
|
93
|
+
image: {
|
94
|
+
source: "https://dummyfileurl.com/file.png",
|
95
|
+
width: 500,
|
96
|
+
height: 500
|
97
|
+
},
|
98
|
+
areas: [
|
99
|
+
[
|
100
|
+
{ x: 44.032765159525724, y: 29.48407951334979 },
|
101
|
+
{ x: 42.4667627323164, y: 36.15418092808709 },
|
102
|
+
{ x: 38.00716512438368, y: 41.80881986705052 },
|
103
|
+
{ x: 31.33290564518235, y: 45.58712881121254 },
|
104
|
+
{ x: 23.460079798107966, y: 46.91389447428033 },
|
105
|
+
{ x: 15.587253951033581, y: 45.58712881121254 },
|
106
|
+
{ x: 8.912994471832251, y: 41.80881986705052 },
|
107
|
+
{ x: 4.453396863899535, y: 36.15418092808709 },
|
108
|
+
{ x: 2.887394436690208, y: 29.484079513349794 },
|
109
|
+
{ x: 4.453396863899535, y: 22.8139780986125 },
|
110
|
+
{ x: 8.912994471832247, y: 17.159339159649065 },
|
111
|
+
{ x: 15.58725395103357, y: 13.381030215487055 },
|
112
|
+
{ x: 23.460079798107962, y: 12.054264552419248 },
|
113
|
+
{ x: 31.332905645182358, y: 13.381030215487051 },
|
114
|
+
{ x: 38.007165124383675, y: 17.159339159649065 },
|
115
|
+
{ x: 42.46676273231639, y: 22.813978098612488 }
|
116
|
+
]
|
117
|
+
],
|
118
|
+
area_attributes: {
|
119
|
+
global: {
|
120
|
+
fill: "rgba(12, 176, 216, 0.48)", stroke: "rgba(25, 90, 107, 0.83)"
|
121
|
+
}
|
122
|
+
},
|
123
|
+
validation: {
|
124
|
+
scoring_type: "exactMatch",
|
125
|
+
valid_response: {
|
126
|
+
score: 1.0,
|
127
|
+
value: ["0"]
|
128
|
+
}
|
129
|
+
},
|
130
|
+
is_math: true
|
131
|
+
})
|
132
|
+
|
133
|
+
expect(conversion[:title]).to eq("Oval Type Question")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when the hotspot type is polygon" do
|
138
|
+
let(:file_name) { "hotspot_polygon.json" }
|
139
|
+
|
140
|
+
it_behaves_like "handles common errors"
|
141
|
+
|
142
|
+
it "converts NQ JSON to hotspot item" do
|
143
|
+
conversion = subject.convert
|
144
|
+
|
145
|
+
expect(conversion[:question]).to eq({
|
146
|
+
type: "hotspot",
|
147
|
+
stimulus: "\u003cp\u003e\u003cem\u003e\u003cstrong\u003eThis\u003c/strong\u003e\u003c/em\u003e is a \u003cstrong\u003equestion\u003c/strong\u003e stem \u003cem\u003ewith\u003c/em\u003e some \u003cspan style=\"text-decoration: underline;\"\u003eadditional\u003c/span\u003e text to \u003cspan style=\"color: #ba372a;\"\u003etest \u003c/span\u003ewacky \u003cspan style=\"background-color: #fbeeb8;\"\u003eformatting\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\\(234+\\alpha^4-56\\)\u003c/p\u003e\u003cp\u003eSome math is before this for \u003csub\u003etesting\u003c/sub\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi\" alt=\"Alternative Text\" /\u003e\u003c/p\u003e",
|
148
|
+
image: {
|
149
|
+
source: "https://dummyfileurl.com/file.png",
|
150
|
+
width: 500,
|
151
|
+
height: 500
|
152
|
+
},
|
153
|
+
areas: [
|
154
|
+
[
|
155
|
+
{ x: 9.384031919243187, y: 17.26691949400596 },
|
156
|
+
{ x: 3.428780893569626, y: 23.294051770215578 },
|
157
|
+
{ x: 1.082772913758829, y: 33.230675252615235 },
|
158
|
+
{ x: 17.86575307702068, y: 34.696734454936504 },
|
159
|
+
{ x: 36.814279067800186, y: 34.370943521087334 },
|
160
|
+
{ x: 44.21322731181886, y: 20.19903789864848 },
|
161
|
+
{ x: 28.3325579100227, y: 10.26241441624882 },
|
162
|
+
{ x: 16.24159370638244, y: 14.49769655628802 },
|
163
|
+
{ x: 9.384031919243187, y: 17.26691949400596 }
|
164
|
+
]
|
165
|
+
],
|
166
|
+
area_attributes: {
|
167
|
+
global: { fill: "rgba(12, 176, 216, 0.48)",
|
168
|
+
stroke: "rgba(25, 90, 107, 0.83)" }
|
169
|
+
},
|
170
|
+
validation: {
|
171
|
+
scoring_type: "exactMatch",
|
172
|
+
valid_response: {
|
173
|
+
score: 1.0,
|
174
|
+
value: ["0"]
|
175
|
+
}
|
176
|
+
},
|
177
|
+
is_math: true
|
178
|
+
})
|
179
|
+
expect(conversion[:title]).to eq("Polygon Question")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Matching do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "matching.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to association item" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ possible_responses: ["This is a distractor", "4", "2", "1", "3"],
|
18
|
+
stimulus_list: %w[A B C D],
|
19
|
+
stimulus: "<p>Match the letter with its corresponding number. </p>" \
|
20
|
+
'<p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" ' \
|
21
|
+
'alt="Some alternative text about how this is a sink spitting fire" /></p>' \
|
22
|
+
'<p><em><strong>This</strong></em> is <span style="color: #236fa1;">some</span> <strong>extra</strong> text I ' \
|
23
|
+
'<span style="text-decoration: underline;">addded</span> to do <em>some</em> <span style="background-color: #236fa1;">funky</span> ' \
|
24
|
+
"<sub>formatting</sub> with :)</p><ul><li>this</li><li>is </li><li><strong>a</strong></li><li>list</li></ul>",
|
25
|
+
type: "association",
|
26
|
+
validation: { valid_response: { score: 2, value: %w[1 2 3 4] },
|
27
|
+
scoring_type: "partialMatchV2" },
|
28
|
+
metadata: { distractor_rationale_response_level: ["This is a distractor"] } })
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::MultipleAnswer do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "multiple_answer.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to mcq item" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ stimulus: '<p>wewe</p><p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
18
|
+
options: [{ label: "<p>c1</p>", value: "c74e82c2-433b-4ee3-89b1-ed70e5f7fdc0" },
|
19
|
+
{ label: "<p>c2</p>",
|
20
|
+
value: "50430f5d-8001-4157-800f-f721bd89132a" },
|
21
|
+
{ label: "<p>c3</p>",
|
22
|
+
value: "79a7fd67-8940-4f33-a0c2-e4117441449d" },
|
23
|
+
{ label: "<p>c4</p>",
|
24
|
+
value: "148659e6-dc03-400a-bbd5-5ab5b8c3c1c2" }],
|
25
|
+
type: "mcq",
|
26
|
+
validation: {
|
27
|
+
valid_response: { score: 1,
|
28
|
+
value: %w[c74e82c2-433b-4ee3-89b1-ed70e5f7fdc0
|
29
|
+
50430f5d-8001-4157-800f-f721bd89132a] },
|
30
|
+
scoring_type: "exactMatch"
|
31
|
+
},
|
32
|
+
multiple_responses: true })
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::MultipleChoice do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "multiple_choice.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to mcq item" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ stimulus: '<p>This is <strong>stem</strong> with <span style="text-decoration: underline;">formatting<br /><br /></span></p><p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
18
|
+
options: [{ label: "<p>a</p>", value: "c537d12a-863d-4d09-ab72-76443d011fc3" },
|
19
|
+
{ label: "<p>b</p>",
|
20
|
+
value: "ef867920-4248-40ed-8407-824ad950b06a" },
|
21
|
+
{ label: "<p>c</p>",
|
22
|
+
value: "62af8f8c-edbe-4fd4-963a-b440e5b4b15c" },
|
23
|
+
{ label: "<p>d</p>",
|
24
|
+
value: "c97895b1-184e-4894-b3f0-5b6f14dca68d" }],
|
25
|
+
type: "mcq",
|
26
|
+
validation: { valid_response: { score: 3, value: ["c537d12a-863d-4d09-ab72-76443d011fc3"] },
|
27
|
+
scoring_type: "exactMatch" },
|
28
|
+
metadata: { distractor_rationale_response_level: ["<p>feedback a</p>",
|
29
|
+
"<p>feedback b</p>",
|
30
|
+
"<p>Feedback c</p>"] } })
|
31
|
+
end
|
32
|
+
|
33
|
+
context "contains math in the stimulus and options" do
|
34
|
+
let(:question) do
|
35
|
+
File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "multiple_choice_math.json"))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "converts math to LaTeX format" do
|
39
|
+
conversion = subject.convert
|
40
|
+
expect(conversion[:question]).to eq({ stimulus: '<p>Which of the following statements are not equivalent to the following?</p><p>\\(2x=4\\)<img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
41
|
+
options: [{ label: '<p>\\(1x=2\\)</p>', value: "f6bfe582-afbd-4289-9a74-e581856c98ac" },
|
42
|
+
{ label: '<p>\\(3x=6\\)</p>',
|
43
|
+
value: "289a9b39-f922-48c1-aabf-1a91f68ea0f3" },
|
44
|
+
{ label: '<p>\\(4x=8\\)</p>',
|
45
|
+
value: "b9c8eb14-fea5-44c1-a049-4cf767c01c27" },
|
46
|
+
{ label: '<p>\\(3x=3\\)</p>',
|
47
|
+
value: "2fe41298-b4b5-418c-ab5d-2604ff7b8a45" }],
|
48
|
+
type: "mcq",
|
49
|
+
validation: { valid_response: { score: 1, value: ["2fe41298-b4b5-418c-ab5d-2604ff7b8a45"] },
|
50
|
+
scoring_type: "exactMatch" },
|
51
|
+
is_math: true })
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Numerical do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "numerical.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to clozeformula item" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ stimulus: '<p>This is a sample question for numerical type</p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" />',
|
18
|
+
template: "{{response}}",
|
19
|
+
response_container: { template: "" },
|
20
|
+
type: "clozeformula",
|
21
|
+
validation: { scoring_type: "exactMatch",
|
22
|
+
valid_response: { score: 1,
|
23
|
+
value: [[{ method: "equivLiteral", value: "100", options: { ignoreOrder: false, inverseResult: false } },
|
24
|
+
{ method: "equivValue",
|
25
|
+
value: '50.0\\pm10.0',
|
26
|
+
options: {
|
27
|
+
ignoreOrder: false, inverseResult: false
|
28
|
+
} },
|
29
|
+
{ method: "equivValue",
|
30
|
+
value: '50.0\\pm15.0',
|
31
|
+
options: {
|
32
|
+
ignoreOrder: false, inverseResult: false
|
33
|
+
} },
|
34
|
+
{ method: "equivValue",
|
35
|
+
value: '75.0\\pm25.0',
|
36
|
+
options: {
|
37
|
+
ignoreOrder: false, inverseResult: false
|
38
|
+
} },
|
39
|
+
{ method: "equivValue",
|
40
|
+
value: "12.345",
|
41
|
+
options: { decimalPlaces: 3 } },
|
42
|
+
{ method: "equivValue",
|
43
|
+
value: "3.14159",
|
44
|
+
options: { decimalPlaces: 5 } }]] } },
|
45
|
+
response_containers: [],
|
46
|
+
is_math: true })
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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
|
+
require "spec_helper"
|
6
|
+
require_relative "../common_error"
|
7
|
+
|
8
|
+
describe AmsMigration::Canvas::Converter::NewQuiz::Ordering do
|
9
|
+
let(:question) { File.read(File.join(SPEC_ROOT, "fixtures", "sample_data", "new_quiz", "ordering.json")) }
|
10
|
+
|
11
|
+
subject { described_class.new(question) }
|
12
|
+
|
13
|
+
it_behaves_like "handles common errors"
|
14
|
+
|
15
|
+
it "converts to ordering item" do
|
16
|
+
conversion = subject.convert
|
17
|
+
expect(conversion[:question]).to eq({ list: ["<p>3</p>", "<p>4</p>", "<p>2</p>", "<p>11</p>", "<p>0</p>"],
|
18
|
+
stimulus: '<p>Question <strong>stem</strong></p><p><img src="https://dummy-inscloudgate.net/files/3ec7226b-fd6d-49df-8236-cb52001ea10b?token=eyJ0eXAiOiJKV1QiLCJhbGciOi" alt="Alternative Text" /></p>',
|
19
|
+
type: "orderlist",
|
20
|
+
validation: { scoring_type: "exactMatch",
|
21
|
+
valid_response: { score: 1, value: [1, 0, 2, 3, 4] } },
|
22
|
+
ui_style: { type: "list" } })
|
23
|
+
expect(conversion[:title]).to eq("Order Quiz #2")
|
24
|
+
end
|
25
|
+
end
|