canvas_cc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/canvas_cc.gemspec +37 -0
  8. data/lib/canvas_cc/canvas/assessment.rb +124 -0
  9. data/lib/canvas_cc/canvas/assignment.rb +98 -0
  10. data/lib/canvas_cc/canvas/converter.rb +30 -0
  11. data/lib/canvas_cc/canvas/course.rb +143 -0
  12. data/lib/canvas_cc/canvas/discussion_topic.rb +64 -0
  13. data/lib/canvas_cc/canvas/label.rb +8 -0
  14. data/lib/canvas_cc/canvas/question.rb +492 -0
  15. data/lib/canvas_cc/canvas/question_bank.rb +57 -0
  16. data/lib/canvas_cc/canvas/question_group.rb +35 -0
  17. data/lib/canvas_cc/canvas/resource.rb +16 -0
  18. data/lib/canvas_cc/canvas/templates/assignment.html.erb +9 -0
  19. data/lib/canvas_cc/canvas/templates/syllabus.html.erb +9 -0
  20. data/lib/canvas_cc/canvas/templates/wiki_content.html.erb +10 -0
  21. data/lib/canvas_cc/canvas/web_content.rb +15 -0
  22. data/lib/canvas_cc/canvas/web_link.rb +16 -0
  23. data/lib/canvas_cc/canvas/wiki.rb +26 -0
  24. data/lib/canvas_cc/canvas_cc/assessment_writer.rb +82 -0
  25. data/lib/canvas_cc/canvas_cc/assignment_group_writer.rb +48 -0
  26. data/lib/canvas_cc/canvas_cc/assignment_writer.rb +68 -0
  27. data/lib/canvas_cc/canvas_cc/calculated_question_writer.rb +72 -0
  28. data/lib/canvas_cc/canvas_cc/canvas_export_writer.rb +18 -0
  29. data/lib/canvas_cc/canvas_cc/cartridge_creator.rb +60 -0
  30. data/lib/canvas_cc/canvas_cc/course_setting_writer.rb +35 -0
  31. data/lib/canvas_cc/canvas_cc/discussion_writer.rb +52 -0
  32. data/lib/canvas_cc/canvas_cc/essay_question_writer.rb +19 -0
  33. data/lib/canvas_cc/canvas_cc/file_meta_writer.rb +38 -0
  34. data/lib/canvas_cc/canvas_cc/ims_manifest_generator.rb +123 -0
  35. data/lib/canvas_cc/canvas_cc/matching_question_writer.rb +43 -0
  36. data/lib/canvas_cc/canvas_cc/models/answer.rb +12 -0
  37. data/lib/canvas_cc/canvas_cc/models/assessment.rb +102 -0
  38. data/lib/canvas_cc/canvas_cc/models/assignment.rb +30 -0
  39. data/lib/canvas_cc/canvas_cc/models/assignment_group.rb +9 -0
  40. data/lib/canvas_cc/canvas_cc/models/calculated_question.rb +19 -0
  41. data/lib/canvas_cc/canvas_cc/models/canvas_file.rb +22 -0
  42. data/lib/canvas_cc/canvas_cc/models/canvas_module.rb +10 -0
  43. data/lib/canvas_cc/canvas_cc/models/course.rb +53 -0
  44. data/lib/canvas_cc/canvas_cc/models/discussion.rb +36 -0
  45. data/lib/canvas_cc/canvas_cc/models/discussion_topic.rb +5 -0
  46. data/lib/canvas_cc/canvas_cc/models/matching_question.rb +7 -0
  47. data/lib/canvas_cc/canvas_cc/models/module_item.rb +16 -0
  48. data/lib/canvas_cc/canvas_cc/models/multiple_dropdowns_question.rb +7 -0
  49. data/lib/canvas_cc/canvas_cc/models/numerical_question.rb +7 -0
  50. data/lib/canvas_cc/canvas_cc/models/page.rb +41 -0
  51. data/lib/canvas_cc/canvas_cc/models/question.rb +37 -0
  52. data/lib/canvas_cc/canvas_cc/models/question_bank.rb +42 -0
  53. data/lib/canvas_cc/canvas_cc/models/question_group.rb +10 -0
  54. data/lib/canvas_cc/canvas_cc/models/resource.rb +23 -0
  55. data/lib/canvas_cc/canvas_cc/models/web_content.rb +7 -0
  56. data/lib/canvas_cc/canvas_cc/models/web_link.rb +7 -0
  57. data/lib/canvas_cc/canvas_cc/models/workflow_state.rb +6 -0
  58. data/lib/canvas_cc/canvas_cc/module_meta_writer.rb +52 -0
  59. data/lib/canvas_cc/canvas_cc/multiple_answers_question_writer.rb +41 -0
  60. data/lib/canvas_cc/canvas_cc/multiple_blanks_question_writer.rb +51 -0
  61. data/lib/canvas_cc/canvas_cc/multiple_choice_question_writer.rb +48 -0
  62. data/lib/canvas_cc/canvas_cc/multiple_dropdowns_question_writer.rb +30 -0
  63. data/lib/canvas_cc/canvas_cc/numerical_question_writer.rb +40 -0
  64. data/lib/canvas_cc/canvas_cc/page_writer.rb +38 -0
  65. data/lib/canvas_cc/canvas_cc/question_bank_writer.rb +44 -0
  66. data/lib/canvas_cc/canvas_cc/question_group_writer.rb +23 -0
  67. data/lib/canvas_cc/canvas_cc/question_writer.rb +129 -0
  68. data/lib/canvas_cc/canvas_cc/short_answer_question_writer.rb +42 -0
  69. data/lib/canvas_cc/canvas_cc/text_only_question_writer.rb +19 -0
  70. data/lib/canvas_cc/canvas_cc/true_false_question_writer.rb +38 -0
  71. data/lib/canvas_cc/cc/assessment.rb +25 -0
  72. data/lib/canvas_cc/cc/assignment.rb +61 -0
  73. data/lib/canvas_cc/cc/cc_helper.rb +285 -0
  74. data/lib/canvas_cc/cc/converter.rb +137 -0
  75. data/lib/canvas_cc/cc/course.rb +16 -0
  76. data/lib/canvas_cc/cc/discussion_topic.rb +53 -0
  77. data/lib/canvas_cc/cc/label.rb +6 -0
  78. data/lib/canvas_cc/cc/question.rb +23 -0
  79. data/lib/canvas_cc/cc/resource.rb +30 -0
  80. data/lib/canvas_cc/cc/templates/assignment.html.erb +13 -0
  81. data/lib/canvas_cc/cc/templates/syllabus.html.erb +9 -0
  82. data/lib/canvas_cc/cc/templates/wiki_content.html.erb +10 -0
  83. data/lib/canvas_cc/cc/web_content.rb +48 -0
  84. data/lib/canvas_cc/cc/web_link.rb +75 -0
  85. data/lib/canvas_cc/cc/wiki.rb +73 -0
  86. data/lib/canvas_cc/version.rb +3 -0
  87. data/lib/canvas_cc.rb +94 -0
  88. data/spec/moodle2cc/canvas_cc/assessment_writer_spec.rb +95 -0
  89. data/spec/moodle2cc/canvas_cc/assignment_group_writer_spec.rb +51 -0
  90. data/spec/moodle2cc/canvas_cc/assignment_writer_spec.rb +74 -0
  91. data/spec/moodle2cc/canvas_cc/calculated_question_writer_spec.rb +88 -0
  92. data/spec/moodle2cc/canvas_cc/canvas_export_writer_spec.rb +26 -0
  93. data/spec/moodle2cc/canvas_cc/cartridge_creator_spec.rb +50 -0
  94. data/spec/moodle2cc/canvas_cc/course_setting_writer_spec.rb +47 -0
  95. data/spec/moodle2cc/canvas_cc/discussion_writer_spec.rb +38 -0
  96. data/spec/moodle2cc/canvas_cc/essay_question_writer_spec.rb +31 -0
  97. data/spec/moodle2cc/canvas_cc/file_meta_writer_spec.rb +57 -0
  98. data/spec/moodle2cc/canvas_cc/ims_manifest_generator_spec.rb +141 -0
  99. data/spec/moodle2cc/canvas_cc/matching_question_writer_spec.rb +51 -0
  100. data/spec/moodle2cc/canvas_cc/models/assessment_spec.rb +131 -0
  101. data/spec/moodle2cc/canvas_cc/models/assignment_group_spec.rb +9 -0
  102. data/spec/moodle2cc/canvas_cc/models/assignment_spec.rb +45 -0
  103. data/spec/moodle2cc/canvas_cc/models/calculated_question_spec.rb +25 -0
  104. data/spec/moodle2cc/canvas_cc/models/canvas_file_spec.rb +23 -0
  105. data/spec/moodle2cc/canvas_cc/models/canvas_module_spec.rb +16 -0
  106. data/spec/moodle2cc/canvas_cc/models/course_spec.rb +43 -0
  107. data/spec/moodle2cc/canvas_cc/models/discussion_spec.rb +47 -0
  108. data/spec/moodle2cc/canvas_cc/models/discussion_topic_spec.rb +7 -0
  109. data/spec/moodle2cc/canvas_cc/models/module_item_spec.rb +15 -0
  110. data/spec/moodle2cc/canvas_cc/models/page_spec.rb +34 -0
  111. data/spec/moodle2cc/canvas_cc/models/question_spec.rb +8 -0
  112. data/spec/moodle2cc/canvas_cc/models/resource_spec.rb +17 -0
  113. data/spec/moodle2cc/canvas_cc/models/web_content_spec.rb +7 -0
  114. data/spec/moodle2cc/canvas_cc/models/web_link_spec.rb +9 -0
  115. data/spec/moodle2cc/canvas_cc/module_meta_writer_spec.rb +118 -0
  116. data/spec/moodle2cc/canvas_cc/multiple_answers_question_writer_spec.rb +50 -0
  117. data/spec/moodle2cc/canvas_cc/multiple_blanks_question_writer_spec.rb +77 -0
  118. data/spec/moodle2cc/canvas_cc/multiple_choice_question_writer_spec.rb +69 -0
  119. data/spec/moodle2cc/canvas_cc/multiple_dropdowns_question_writer_spec.rb +46 -0
  120. data/spec/moodle2cc/canvas_cc/numerical_question_writer_spec.rb +69 -0
  121. data/spec/moodle2cc/canvas_cc/page_writer_spec.rb +29 -0
  122. data/spec/moodle2cc/canvas_cc/question_bank_writer_spec.rb +43 -0
  123. data/spec/moodle2cc/canvas_cc/question_writer_spec.rb +129 -0
  124. data/spec/moodle2cc/canvas_cc/short_answer_question_writer_spec.rb +50 -0
  125. data/spec/moodle2cc/canvas_cc/text_only_question_writer_spec.rb +23 -0
  126. data/spec/moodle2cc/canvas_cc/true_false_question_writer_spec.rb +62 -0
  127. data/spec/spec_helper.rb +12 -0
  128. data/spec/support/shared_examples_for_models.rb +26 -0
  129. data/test/acceptance/migrator_test.rb +24 -0
  130. data/test/fixtures/cc.imscc +0 -0
  131. data/test/fixtures/common_cartridge/ims_manifest_simple.xml +45 -0
  132. data/test/fixtures/common_cartridge/schema/cccv1p0.xsd +563 -0
  133. data/test/fixtures/common_cartridge/schema/ccv1p1_imsccauth_v1p1.xsd +203 -0
  134. data/test/fixtures/common_cartridge/schema/ccv1p1_imscp_v1p2_v1p0.xsd +827 -0
  135. data/test/fixtures/common_cartridge/schema/ccv1p1_lommanifest_v1p0.xsd +822 -0
  136. data/test/fixtures/common_cartridge/schema/ccv1p1_lomresource_v1p0.xsd +273 -0
  137. data/test/fixtures/common_cartridge/schema/xml.xsd +286 -0
  138. data/test/test_helper.rb +71 -0
  139. data/test/test_question_helper.rb +122 -0
  140. data/test/test_wiki_helper.rb +21 -0
  141. data/test/unit/canvas/assessment_test.rb +261 -0
  142. data/test/unit/canvas/assignment_test.rb +220 -0
  143. data/test/unit/canvas/converter_test.rb +171 -0
  144. data/test/unit/canvas/course_test.rb +176 -0
  145. data/test/unit/canvas/discussion_topic_test.rb +129 -0
  146. data/test/unit/canvas/label_test.rb +32 -0
  147. data/test/unit/canvas/question_bank_test.rb +92 -0
  148. data/test/unit/canvas/question_group_test.rb +90 -0
  149. data/test/unit/canvas/question_test.rb +876 -0
  150. data/test/unit/canvas/web_content_test.rb +46 -0
  151. data/test/unit/canvas/web_link_test.rb +48 -0
  152. data/test/unit/canvas/wiki_test.rb +74 -0
  153. data/test/unit/cc/assessment_test.rb +48 -0
  154. data/test/unit/cc/assignment_test.rb +72 -0
  155. data/test/unit/cc/cc_helper_test.rb +19 -0
  156. data/test/unit/cc/converter_test.rb +173 -0
  157. data/test/unit/cc/course_test.rb +36 -0
  158. data/test/unit/cc/discussion_topic_test.rb +83 -0
  159. data/test/unit/cc/label_test.rb +29 -0
  160. data/test/unit/cc/question_test.rb +54 -0
  161. data/test/unit/cc/web_content_test.rb +76 -0
  162. data/test/unit/cc/web_link_test.rb +159 -0
  163. data/test/unit/cc/wiki_test.rb +139 -0
  164. data/test/unit/logger_test.rb +33 -0
  165. data/test/unit/migrator_test.rb +67 -0
  166. data/test/unit/resource_factory_test.rb +216 -0
  167. metadata +499 -0
@@ -0,0 +1,876 @@
1
+ require 'nokogiri'
2
+ require 'minitest/autorun'
3
+ require 'test_helper'
4
+ require 'test_question_helper'
5
+ require 'moodle2cc'
6
+
7
+ class TestUnitCanvasQuestion < MiniTest::Unit::TestCase
8
+ include TestHelper
9
+ include TestQuestionHelper
10
+
11
+ def setup
12
+ convert_moodle_backup 'canvas'
13
+ @mod = @backup.course.mods.find { |mod| mod.mod_type == 'quiz' }
14
+ @question = @mod.questions.first
15
+ @question.image = nil
16
+ end
17
+
18
+ def teardown
19
+ clean_tmp_folder
20
+ end
21
+
22
+ def test_it_inherits_from_cc
23
+ assert CanvasCc::Canvas::Question.ancestors.include?(CanvasCc::CC::Question), 'does not inherit from base CC class'
24
+ end
25
+
26
+ def test_it_converts_length
27
+ @question.length = 5
28
+ question = CanvasCc::Canvas::Question.new @question
29
+ assert_equal 5, question.length
30
+ end
31
+
32
+ def test_it_converts_question_type
33
+ @question.type = 'calculated'
34
+ question = CanvasCc::Canvas::Question.new @question
35
+ assert_equal 'calculated_question', question.question_type
36
+
37
+ @question.type = 'description'
38
+ question = CanvasCc::Canvas::Question.new @question
39
+ assert_equal 'text_only_question', question.question_type
40
+
41
+ @question.type = 'essay'
42
+ question = CanvasCc::Canvas::Question.new @question
43
+ assert_equal 'essay_question', question.question_type
44
+
45
+ @question.type = 'match'
46
+ question = CanvasCc::Canvas::Question.new @question
47
+ assert_equal 'matching_question', question.question_type
48
+
49
+ @question.type = 'multianswer'
50
+ question = CanvasCc::Canvas::Question.new @question
51
+ assert_equal 'embedded_answers_question', question.question_type
52
+
53
+ @question.type = 'multichoice'
54
+ question = CanvasCc::Canvas::Question.new @question
55
+ assert_equal 'multiple_choice_question', question.question_type
56
+
57
+ @question.type = 'shortanswer'
58
+ question = CanvasCc::Canvas::Question.new @question
59
+ assert_equal 'short_answer_question', question.question_type
60
+
61
+ @question.type = 'numerical'
62
+ question = CanvasCc::Canvas::Question.new @question
63
+ assert_equal 'numerical_question', question.question_type
64
+
65
+ @question.type = 'truefalse'
66
+ question = CanvasCc::Canvas::Question.new @question
67
+ assert_equal 'true_false_question', question.question_type
68
+
69
+ @question.type = nil
70
+
71
+ @question.type_id = 1
72
+ question = CanvasCc::Canvas::Question.new @question
73
+ assert_equal 'true_false_question', question.question_type
74
+
75
+ @question.type_id = 2
76
+ question = CanvasCc::Canvas::Question.new @question
77
+ assert_equal 'essay_question', question.question_type
78
+
79
+ @question.type_id = 3
80
+ question = CanvasCc::Canvas::Question.new @question
81
+ assert_equal 'essay_question', question.question_type
82
+
83
+ @question.type_id = 4
84
+ question = CanvasCc::Canvas::Question.new @question
85
+ assert_equal 'multiple_choice_question', question.question_type
86
+
87
+ @question.type_id = 5
88
+ question = CanvasCc::Canvas::Question.new @question
89
+ assert_equal 'multiple_answers_question', question.question_type
90
+
91
+ @question.type_id = 6
92
+ question = CanvasCc::Canvas::Question.new @question
93
+ assert_equal 'multiple_choice_question', question.question_type
94
+
95
+ @question.type_id = 8
96
+ question = CanvasCc::Canvas::Question.new @question
97
+ assert_equal 'multiple_dropdowns_question', question.question_type
98
+
99
+ @question.type_id = 9
100
+ question = CanvasCc::Canvas::Question.new @question
101
+ assert_equal 'essay_question', question.question_type
102
+
103
+ @question.type_id = 10
104
+ question = CanvasCc::Canvas::Question.new @question
105
+ assert_equal 'numerical_question', question.question_type
106
+
107
+ @question.type_id = 100
108
+ question = CanvasCc::Canvas::Question.new @question
109
+ assert_equal 'text_only_question', question.question_type
110
+ end
111
+
112
+ def test_it_converts_points_possible
113
+ @question.grade = 5
114
+ question = CanvasCc::Canvas::Question.new @question
115
+ assert_equal 5, question.points_possible
116
+ end
117
+
118
+ def test_it_converts_material
119
+ @question.text = "How much is {a} + {b} ?"
120
+ question = CanvasCc::Canvas::Question.new @question
121
+ assert_equal "How much is [a] + [b] ?", question.material
122
+ end
123
+
124
+ def test_it_adds_image_tag_to_material
125
+ @question.text = "How much is {a} + {b} ?"
126
+ @question.image = "test.jpg"
127
+ question = CanvasCc::Canvas::Question.new @question
128
+ assert_equal %{How much is [a] + [b] ?<p><img src="$IMS_CC_FILEBASE$/test.jpg" alt="test.jpg"/></p>}, question.material
129
+ end
130
+
131
+ def test_it_converts_markdown_text_to_html_material
132
+ @question.text = "This is **bold** and this is _italic_"
133
+ @question.format = 4 # markdown
134
+ question = CanvasCc::Canvas::Question.new @question
135
+ assert_equal "<p>This is <strong>bold</strong> and this is <em>italic</em></p>\n", question.material
136
+ end
137
+
138
+ def test_it_converts_material_for_multiple_dropdowns_question
139
+ multiple_dropdowns_question!
140
+ @question.content = "This is a rating question"
141
+ question = CanvasCc::Canvas::Question.new @question
142
+ assert_equal "This is a rating question\nI test my code [response1]\nI am happy [response2]", question.material
143
+ end
144
+
145
+ def test_it_converts_material_for_multiple_dropdowns_question_without_choices
146
+ multiple_dropdowns_question_without_choices!
147
+ question = CanvasCc::Canvas::Question.new @question
148
+ assert_equal "This is a rating question but not formatted very well\nthis isn't actually a choice [response1]\nso add the choices automatically [response2]", question.material
149
+ end
150
+
151
+ def test_it_converts_general_feedback
152
+ @question.general_feedback = "This should be easy"
153
+ question = CanvasCc::Canvas::Question.new @question
154
+ assert_equal "This should be easy", question.general_feedback
155
+ end
156
+
157
+ def test_it_converts_answer_tolerance
158
+ @question.calculations.first.tolerance = 0.01
159
+ question = CanvasCc::Canvas::Question.new @question
160
+ assert_equal 0.01, question.answer_tolerance
161
+ end
162
+
163
+ def test_it_converts_formula_decimal_places
164
+ calculation = @question.calculations.first
165
+ calculation.correct_answer_format = 1 # decimal
166
+ calculation.correct_answer_length = 2
167
+
168
+ question = CanvasCc::Canvas::Question.new @question
169
+ assert_equal 2, question.formula_decimal_places
170
+
171
+ calculation.correct_answer_format = 2 # significant figures
172
+
173
+ question = CanvasCc::Canvas::Question.new @question
174
+ assert_equal 0, question.formula_decimal_places
175
+ end
176
+
177
+ def test_it_converts_formulas
178
+ answer1 = @question.answers.first
179
+ answer2 = answer1.dup
180
+ @question.answers << answer2
181
+
182
+ answer1.text = '{a} + {b}'
183
+ answer2.text = '{a} * {b}'
184
+
185
+ question = CanvasCc::Canvas::Question.new @question
186
+ assert_equal 2, question.formulas.length
187
+ assert_equal 'a+b', question.formulas.first
188
+ assert_equal 'a*b', question.formulas.last
189
+ end
190
+
191
+ def test_it_converts_vars
192
+ calculation = @question.calculations.first
193
+ ds_def1 = calculation.dataset_definitions.first
194
+ ds_def2 = calculation.dataset_definitions.last
195
+
196
+ ds_def1.name = 'a'
197
+ ds_def1.options = 'uniform:3.0:9.0:3'
198
+
199
+ ds_def2.name = 'b'
200
+ ds_def2.options = 'uniform:1.0:10.0:1'
201
+
202
+ question = CanvasCc::Canvas::Question.new @question
203
+ assert_equal 2, question.vars.length
204
+ assert_equal({:name => 'a', :scale => '3', :min => '3.0', :max => '9.0'}, question.vars.first)
205
+ assert_equal({:name => 'b', :scale => '1', :min => '1.0', :max => '10.0'}, question.vars.last)
206
+ end
207
+
208
+ def test_it_converts_var_sets
209
+ calculation = @question.calculations.first
210
+ ds_def1 = calculation.dataset_definitions.first
211
+ ds_def2 = calculation.dataset_definitions.last
212
+
213
+ ds_def1.name = 'a'
214
+ ds_item1 = ds_def1.dataset_items.first
215
+ ds_item2 = ds_item1.dup
216
+ ds_def1.dataset_items[1] = ds_item2
217
+
218
+ ds_item1.number = 1
219
+ ds_item1.value = 3.0
220
+ ds_item2.number = 2
221
+ ds_item2.value = 5.5
222
+
223
+ ds_def2.name = 'b'
224
+ ds_item1 = ds_def2.dataset_items.first
225
+ ds_item2 = ds_item1.dup
226
+ ds_def2.dataset_items[1] = ds_item2
227
+
228
+ ds_item1.number = 1
229
+ ds_item1.value = 6.0
230
+ ds_item2.number = 2
231
+ ds_item2.value = 1.0
232
+
233
+ question = CanvasCc::Canvas::Question.new @question
234
+ assert_equal 2, question.var_sets.length
235
+ assert_equal({:vars => {'a' => 3.0, 'b' => 6.0}, :answer => 9.0}, question.var_sets.first)
236
+ assert_equal({:vars => {'a' => 5.5, 'b' => 1.0}, :answer => 6.5}, question.var_sets.last)
237
+ end
238
+
239
+ def test_it_converts_matches
240
+ match_question!
241
+
242
+ question = CanvasCc::Canvas::Question.new @question
243
+ assert_equal 2, question.matches.length
244
+ assert_equal(CanvasCc::OpenStruct.new(
245
+ :question => 'Ruby on Rails is written in this language',
246
+ :answers => {123 => 'Ruby', 234 => 'Python', 345 => 'CoffeeScript'},
247
+ :answer => 123
248
+ ), question.matches.first)
249
+ assert_equal(CanvasCc::OpenStruct.new(
250
+ :question => 'Files with .coffee extension use which language?',
251
+ :answers => {123 => 'Ruby', 234 => 'Python', 345 => 'CoffeeScript'},
252
+ :answer => 345
253
+ ), question.matches.last)
254
+ end
255
+
256
+ def test_it_converts_numericals
257
+ answer = CanvasCc::Moodle::Question::Answer.new
258
+ answer.id = 43
259
+ answer.text = "Blah"
260
+ numerical = CanvasCc::Moodle::Question::Numerical.new
261
+ numerical.answer_id = 43
262
+ numerical.tolerance = 3
263
+ @question.numericals = [numerical]
264
+ @question.answers = [answer]
265
+ question = CanvasCc::Canvas::Question.new @question
266
+
267
+ assert_equal 1, question.numericals.length
268
+
269
+ assert_equal(CanvasCc::OpenStruct.new(
270
+ :answer => question.answers.first,
271
+ :tolerance => 3
272
+ ), question.numericals.first)
273
+ end
274
+
275
+ def test_it_converts_answers
276
+ multiple_choice_question!
277
+
278
+ question = CanvasCc::Canvas::Question.new @question
279
+ assert_equal 4, question.answers.length
280
+
281
+ assert_equal(CanvasCc::OpenStruct.new(
282
+ :id => 123,
283
+ :text => 'Ruby',
284
+ :fraction => 1,
285
+ :feedback => 'Yippee!'
286
+ ), question.answers[0])
287
+ assert_equal(CanvasCc::OpenStruct.new(
288
+ :id => 234,
289
+ :text => 'CoffeeScript',
290
+ :fraction => 0.75,
291
+ :feedback => 'Nope'
292
+ ), question.answers[1])
293
+ assert_equal(CanvasCc::OpenStruct.new(
294
+ :id => 345,
295
+ :text => 'Java',
296
+ :fraction => 0.25,
297
+ :feedback => 'No way'
298
+ ), question.answers[2])
299
+ assert_equal(CanvasCc::OpenStruct.new(
300
+ :id => 456,
301
+ :text => 'Clojure',
302
+ :fraction => 0,
303
+ :feedback => 'Not even close'
304
+ ), question.answers[3])
305
+ end
306
+
307
+ def test_it_converts_answers_from_questionnaire_choices
308
+ @question.type = nil
309
+ @question.type_id = 4
310
+
311
+ choice1 = CanvasCc::Moodle::Question::Choice.new
312
+ choice1.id = 123
313
+ choice1.content = 'Ruby'
314
+
315
+ choice2 = CanvasCc::Moodle::Question::Choice.new
316
+ choice2.id = 234
317
+ choice2.content = 'CoffeeScript'
318
+
319
+ choice3 = CanvasCc::Moodle::Question::Choice.new
320
+ choice3.id = 345
321
+ choice3.content = 'Java'
322
+
323
+ choice4 = CanvasCc::Moodle::Question::Choice.new
324
+ choice4.id = 456
325
+ choice4.content = 'Clojure'
326
+
327
+ @question.choices = [choice1, choice2, choice3, choice4]
328
+ @question.answers = []
329
+
330
+ question = CanvasCc::Canvas::Question.new @question
331
+ assert_equal 4, question.answers.length
332
+
333
+ assert_equal(CanvasCc::OpenStruct.new(
334
+ :id => 123,
335
+ :text => 'Ruby'
336
+ ), question.answers[0])
337
+ assert_equal(CanvasCc::OpenStruct.new(
338
+ :id => 234,
339
+ :text => 'CoffeeScript'
340
+ ), question.answers[1])
341
+ assert_equal(CanvasCc::OpenStruct.new(
342
+ :id => 345,
343
+ :text => 'Java'
344
+ ), question.answers[2])
345
+ assert_equal(CanvasCc::OpenStruct.new(
346
+ :id => 456,
347
+ :text => 'Clojure'
348
+ ), question.answers[3])
349
+ end
350
+
351
+ def test_it_has_an_identifier_based_on_id
352
+ @question.id = 989
353
+ @question.instance_id = nil
354
+ question = CanvasCc::Canvas::Question.new @question
355
+ assert_equal 'i04823ed56ffd4fd5f9c21db0cf25be6c', question.identifier
356
+ # question_989
357
+ end
358
+
359
+ def test_it_has_an_identifier_based_on_instance_id
360
+ @question.instance_id = 787
361
+ question = CanvasCc::Canvas::Question.new @question
362
+ assert_equal 'i2edcb021d100c968ba3f570253a6aa1c', question.identifier
363
+ # question_instance_787
364
+ end
365
+
366
+ def test_it_has_an_assessment_question_identifierref_if_instance_id_exists
367
+ @question.id = 989
368
+ @question.instance_id = 787
369
+ question = CanvasCc::Canvas::Question.new @question
370
+ assert_equal 'i04823ed56ffd4fd5f9c21db0cf25be6c', question.assessment_question_identifierref
371
+ # question_989
372
+ end
373
+
374
+ def test_it_does_not_have_an_assessment_question_identifierref_if_instance_id_does_not_exist
375
+ @question.id = 989
376
+ @question.instance_id = nil
377
+ question = CanvasCc::Canvas::Question.new @question
378
+ refute question.assessment_question_identifierref
379
+ # question_989
380
+ end
381
+
382
+ def test_it_creates_fractions
383
+ question = CanvasCc::Canvas::Question.new @question
384
+ assert_equal 100, question.get_score(1)
385
+ assert_equal 50, question.get_score(0.5)
386
+ assert_equal 0, question.get_score(0)
387
+ assert_equal 100, question.get_score(nil)
388
+ end
389
+
390
+ def test_it_create_multple_question_from_choice_mod
391
+ @choice_mod = @backup.course.mods.find { |m| m.mod_type == 'choice' }
392
+ question = CanvasCc::Canvas::Question.new @choice_mod.questions.first
393
+
394
+ assert_equal 'multiple_choice_question', question.question_type
395
+ end
396
+
397
+ def test_it_creates_item_xml
398
+ @question.image = 'test.jpg'
399
+ question = CanvasCc::Canvas::Question.new @question
400
+ node = Builder::XmlMarkup.new
401
+ xml = Nokogiri::XML(question.create_item_xml(node))
402
+
403
+ assert xml.root
404
+ assert_equal 'item', xml.root.name
405
+ assert_equal 'Basic Arithmetic', xml.root.attributes['title'].value
406
+ assert_equal 'i7cf4483ef2da120de20ff6cfc9dd3e58', xml.root.attributes['ident'].value
407
+
408
+ assert xml.root.xpath('itemmetadata/qtimetadata/qtimetadatafield[fieldlabel="question_type" and fieldentry="calculated_question"]').first, 'does not have meta data for question type'
409
+ assert xml.root.xpath('itemmetadata/qtimetadata/qtimetadatafield[fieldlabel="points_possible" and fieldentry="1"]').first, 'does not have meta data for points possible'
410
+ assert xml.root.xpath('itemmetadata/qtimetadata/qtimetadatafield[fieldlabel="assessment_question_identifierref" and fieldentry="i04823ed56ffd4fd5f9c21db0cf25be6c"]').first, 'does not have meta data for assessment_question_identifierref'
411
+
412
+ assert_equal %{How much is [a] + [b] ?<p><img src="$IMS_CC_FILEBASE$/test.jpg" alt="test.jpg"/></p>}, xml.root.xpath('presentation/material/mattext[@texttype="text/html"]').text
413
+
414
+ # Score
415
+ outcome = xml.root.xpath('resprocessing/outcomes/decvar').first
416
+ assert_equal '100', outcome.attributes['maxvalue'].value
417
+ assert_equal '0', outcome.attributes['minvalue'].value
418
+ assert_equal 'SCORE', outcome.attributes['varname'].value
419
+ assert_equal 'Decimal', outcome.attributes['vartype'].value
420
+
421
+ # General Feedback
422
+ general_feedback = xml.root.xpath('resprocessing/respcondition[1]').first
423
+ assert_equal 'Yes', general_feedback.attributes['continue'].value
424
+ assert general_feedback.xpath('conditionvar/other').first, 'does not contain conditionvar'
425
+ assert_equal 'Response', general_feedback.xpath('displayfeedback').first.attributes['feedbacktype'].value
426
+ assert_equal 'general_fb', general_feedback.xpath('displayfeedback').first.attributes['linkrefid'].value
427
+
428
+ general_feedback = xml.root.xpath('itemfeedback[@ident="general_fb"]').first
429
+ assert general_feedback, 'no feeback node'
430
+ material = general_feedback.xpath('flow_mat/material/mattext[@texttype="text/html"]').first
431
+ assert material, 'no feedback text'
432
+ assert_equal 'This should be easy', material.text
433
+ end
434
+
435
+ def test_it_creates_item_xml_for_calculated_question
436
+ @question.type = 'calculated'
437
+ question = CanvasCc::Canvas::Question.new @question
438
+ node = Builder::XmlMarkup.new
439
+ xml = Nokogiri::XML(question.create_item_xml(node))
440
+
441
+ response = xml.root.xpath('presentation/response_str').first
442
+ assert_equal 'Single', response.attributes['rcardinality'].value
443
+ assert_equal 'response1', response.attributes['ident'].value
444
+ assert_equal 'Decimal', response.xpath('render_fib').first.attributes['fibtype'].value
445
+ assert_equal 'answer1', response.xpath('render_fib/response_label').first.attributes['ident'].value
446
+
447
+ # Correct Condition
448
+ condition = xml.root.xpath('resprocessing/respcondition[@title="correct"]').first
449
+ assert condition, 'correct condition node does not exist'
450
+ assert condition.xpath('conditionvar/other').first, 'conditionvar does not exist for correct condition node'
451
+ setvar = condition.xpath('setvar').first
452
+ assert setvar, 'setvar does not exist for correct condition node'
453
+ assert_equal 'SCORE', setvar.attributes['varname'].value
454
+ assert_equal 'Set', setvar.attributes['action'].value
455
+ assert_equal '100', setvar.text
456
+
457
+ # Incorrect Condition
458
+ condition = xml.root.xpath('resprocessing/respcondition[@title="incorrect"]').first
459
+ assert condition, 'incorrect condition node does not exist'
460
+ assert condition.xpath('conditionvar/other').first, 'conditionvar does not exist for incorrect condition node'
461
+ setvar = condition.xpath('setvar').first
462
+ assert setvar, 'setvar does not exist for incorrect condition node'
463
+ assert_equal 'SCORE', setvar.attributes['varname'].value
464
+ assert_equal 'Set', setvar.attributes['action'].value
465
+ assert_equal '0', setvar.text
466
+
467
+ # Calculations
468
+ calculated = xml.root.xpath('itemproc_extension/calculated').first
469
+ assert calculated, 'calculated node does not exist'
470
+ assert_equal '0.01', calculated.xpath('answer_tolerance').text
471
+
472
+ # Formulas
473
+ assert calculated.xpath('formulas[@decimal_places="2"]').first, 'calculated node does not contain formulas with decimal_places'
474
+ assert calculated.xpath('formulas/formula["a+b"]').first, 'calculated node does not contain the formula a+b'
475
+
476
+ # Var
477
+ a_var = calculated.xpath('vars/var[@scale="1"][@name="a"]').first
478
+ assert a_var, 'calculated node does not have variable for a'
479
+ assert_equal '1.0', a_var.xpath('min').text
480
+ assert_equal '10.0', a_var.xpath('max').text
481
+ b_var = calculated.xpath('vars/var[@scale="1"][@name="b"]').first
482
+ assert b_var, 'calculated node does not have variable for b'
483
+ assert_equal '1.0', b_var.xpath('min').text
484
+ assert_equal '10.0', b_var.xpath('max').text
485
+
486
+ # Var Sets
487
+ var_set1 = calculated.xpath('var_sets/var_set[1]').first
488
+ assert var_set1, 'first var_set does not exist'
489
+ assert_equal '3060', var_set1.attributes['ident'].value
490
+ assert var_set1.xpath('var[@name="a"][3.0]'), 'first var_set does not have a value for a'
491
+ assert var_set1.xpath('var[@name="b"][6.0]'), 'first var_set does not have a value for b'
492
+ assert var_set1.xpath('answer[9.0]'), 'first var_set does not have an answer'
493
+
494
+ var_set2 = calculated.xpath('var_sets/var_set[2]').first
495
+ assert var_set2, 'second var_set does not exist'
496
+ assert_equal '5510', var_set2.attributes['ident'].value
497
+ assert var_set2.xpath('var[@name="a"][5.5]'), 'second var_set does not have a value for a'
498
+ assert var_set2.xpath('var[@name="b"][1.0]'), 'second var_set does not have a value for b'
499
+ assert var_set2.xpath('answer[6.5]'), 'second var_set does not have an answer'
500
+ end
501
+
502
+ def test_it_creates_item_xml_for_essay_question
503
+ @question.type = 'essay'
504
+ question = CanvasCc::Canvas::Question.new @question
505
+ node = Builder::XmlMarkup.new
506
+ xml = Nokogiri::XML(question.create_item_xml(node))
507
+
508
+ response = xml.root.xpath('presentation/response_str').first
509
+ assert_equal 'Single', response.attributes['rcardinality'].value
510
+ assert_equal 'response1', response.attributes['ident'].value
511
+ assert_equal 'No', response.xpath('render_fib/response_label').first.attributes['rshuffle'].value
512
+ assert_equal 'answer1', response.xpath('render_fib/response_label').first.attributes['ident'].value
513
+
514
+ # No Continue Condition
515
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]').first
516
+ assert condition, 'no continue condition node does not exist'
517
+ assert condition.xpath('conditionvar/other').first, 'conditionvar does not exist for no continue condition node'
518
+ end
519
+
520
+ def test_it_creates_item_xml_for_matching_question
521
+ match_question!
522
+
523
+ question = CanvasCc::Canvas::Question.new @question
524
+ node = Builder::XmlMarkup.new
525
+ xml = Nokogiri::XML(question.create_item_xml(node))
526
+
527
+ response = xml.root.xpath('presentation/response_lid[@ident="response_123"]').first
528
+ assert response, 'response for first matching question does not exist'
529
+ assert_equal 'Ruby on Rails is written in this language', response.xpath('material/mattext[@texttype="text/html"]').text
530
+ assert_equal 'Ruby', response.xpath('render_choice/response_label[@ident="123"]/material/mattext').text
531
+ assert_equal 'Python', response.xpath('render_choice/response_label[@ident="234"]/material/mattext').text
532
+ assert_equal 'CoffeeScript', response.xpath('render_choice/response_label[@ident="345"]/material/mattext').text
533
+
534
+ response = xml.root.xpath('presentation/response_lid[@ident="response_345"]').first
535
+ assert response, 'response for second matching question does not exist'
536
+ assert_equal 'Files with .coffee extension use which language?', response.xpath('material/mattext[@texttype="text/html"]').text
537
+ assert_equal 'Ruby', response.xpath('render_choice/response_label[@ident="123"]/material/mattext').text
538
+ assert_equal 'Python', response.xpath('render_choice/response_label[@ident="234"]/material/mattext').text
539
+ assert_equal 'CoffeeScript', response.xpath('render_choice/response_label[@ident="345"]/material/mattext').text
540
+
541
+ condition = xml.root.xpath('resprocessing/respcondition/conditionvar[varequal=123]/..').first
542
+ assert condition, 'first matching condition does not exist'
543
+ assert condition.xpath('conditionvar/varequal[@respident="response_123"]').first, 'condition does not reference correct response'
544
+ set_var = condition.xpath('setvar').first
545
+ assert_equal 'SCORE', set_var.attributes['varname'].value
546
+ assert_equal 'Add', set_var.attributes['action'].value
547
+ assert_equal '50.00', set_var.text
548
+
549
+ condition = xml.root.xpath('resprocessing/respcondition/conditionvar[varequal=345]/..').first
550
+ assert condition, 'second matching condition does not exist'
551
+ assert condition.xpath('conditionvar/varequal[@respident="response_345"]').first, 'condition does not reference correct response'
552
+ set_var = condition.xpath('setvar').first
553
+ assert_equal 'SCORE', set_var.attributes['varname'].value
554
+ assert_equal 'Add', set_var.attributes['action'].value
555
+ assert_equal '50.00', set_var.text
556
+ end
557
+
558
+ def test_it_creates_item_xml_for_multiple_choice_question
559
+ multiple_choice_question!
560
+
561
+ question = CanvasCc::Canvas::Question.new @question
562
+ node = Builder::XmlMarkup.new
563
+ xml = Nokogiri::XML(question.create_item_xml(node))
564
+
565
+ # Responses
566
+ response = xml.root.xpath('presentation/response_lid[@ident="response1"]').first
567
+ assert response, 'response for multiple choice question does not exist'
568
+ assert_equal 'Single', response.attributes['rcardinality'].value
569
+ assert_equal 'Ruby', response.xpath('render_choice/response_label[@ident="123"]/material/mattext[@texttype="text/html"]').text
570
+ assert_equal 'CoffeeScript', response.xpath('render_choice/response_label[@ident="234"]/material/mattext[@texttype="text/html"]').text
571
+ assert_equal 'Java', response.xpath('render_choice/response_label[@ident="345"]/material/mattext[@texttype="text/html"]').text
572
+ assert_equal 'Clojure', response.xpath('render_choice/response_label[@ident="456"]/material/mattext[@texttype="text/html"]').text
573
+
574
+ # Feedback
575
+ feedback = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="123"]/../..').first
576
+ assert feedback, 'feedback does not exist for first answer'
577
+ display = feedback.xpath('displayfeedback[@feedbacktype="Response"][@linkrefid="123_fb"]').first
578
+ assert display, 'display feedback does not exist for first answer'
579
+
580
+ feedback = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="234"]/../..').first
581
+ assert feedback, 'feedback does not exist for second answer'
582
+ display = feedback.xpath('displayfeedback[@feedbacktype="Response"][@linkrefid="234_fb"]').first
583
+ assert display, 'display feedback does not exist for second answer'
584
+
585
+ feedback = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="345"]/../..').first
586
+ assert feedback, 'feedback does not exist for third answer'
587
+ display = feedback.xpath('displayfeedback[@feedbacktype="Response"][@linkrefid="345_fb"]').first
588
+ assert display, 'display feedback does not exist for third answer'
589
+
590
+ feedback = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="456"]/../..').first
591
+ assert feedback, 'feedback does not exist for fourth answer'
592
+ display = feedback.xpath('displayfeedback[@feedbacktype="Response"][@linkrefid="456_fb"]').first
593
+ assert display, 'display feedback does not exist for fourth answer'
594
+
595
+ feedback = xml.root.xpath('itemfeedback[@ident="123_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
596
+ assert feedback, 'feedback text does not exist for first answer'
597
+ assert_equal 'Yippee!', feedback.text
598
+
599
+ feedback = xml.root.xpath('itemfeedback[@ident="234_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
600
+ assert feedback, 'feedback text does not exist for second answer'
601
+ assert_equal 'Nope', feedback.text
602
+
603
+ feedback = xml.root.xpath('itemfeedback[@ident="345_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
604
+ assert feedback, 'feedback text does not exist for third answer'
605
+ assert_equal 'No way', feedback.text
606
+
607
+ feedback = xml.root.xpath('itemfeedback[@ident="456_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
608
+ assert feedback, 'feedback text does not exist for fourth answer'
609
+ assert_equal 'Not even close', feedback.text
610
+
611
+ # Conditions
612
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="123"]/../..').first
613
+ assert condition, 'condition does not exist for first answer'
614
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]').first
615
+ assert var, 'score does not exist for first answer'
616
+
617
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="234"]/../..').first
618
+ assert condition, 'condition does not exist for first answer'
619
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="75"]').first
620
+ assert var, 'score does not exist for second answer'
621
+
622
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="345"]/../..').first
623
+ assert condition, 'condition does not exist for first answer'
624
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="25"]').first
625
+ assert var, 'score does not exist for third answer'
626
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="456"]/../..').first
627
+
628
+ assert condition, 'condition does not exist for first answer'
629
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="0"]').first
630
+ assert var, 'score does not exist for fourth answer'
631
+ end
632
+
633
+ def test_it_creates_item_xml_for_multiple_dropdowns_question
634
+ multiple_dropdowns_question!
635
+
636
+ question = CanvasCc::Canvas::Question.new @question
637
+ node = Builder::XmlMarkup.new
638
+ xml = Nokogiri::XML(question.create_item_xml(node))
639
+
640
+ # Responses
641
+ response = xml.root.xpath('presentation/response_lid[@ident="response_response1"]').first
642
+ assert response, 'first response for multiple dropdowns question does not exist'
643
+ assert response.xpath('material/mattext["response1"]').first, 'material text does not exist for multiple dropdowns question first response'
644
+ assert_equal '1=Almost Never', response.xpath('render_choice/response_label[@ident="11"]/material/mattext[@texttype="text/html"]').text
645
+ assert_equal '2=Sometimes', response.xpath('render_choice/response_label[@ident="12"]/material/mattext[@texttype="text/html"]').text
646
+ assert_equal '3=Always', response.xpath('render_choice/response_label[@ident="13"]/material/mattext[@texttype="text/html"]').text
647
+ refute response.xpath('render_choice/response_label[4]').first, 'there should not be a response for answer text'
648
+ refute response.xpath('render_choice/response_label[5]').first, 'there should not be a response for answer text'
649
+
650
+ response = xml.root.xpath('presentation/response_lid[@ident="response_response2"]').first
651
+ assert response, 'second response for multiple dropdowns question does not exist'
652
+ assert response.xpath('material/mattext["response2"]').first, 'material text does not exist for multiple dropdowns question second response'
653
+ assert_equal '1=Almost Never', response.xpath('render_choice/response_label[@ident="21"]/material/mattext[@texttype="text/html"]').text
654
+ assert_equal '2=Sometimes', response.xpath('render_choice/response_label[@ident="22"]/material/mattext[@texttype="text/html"]').text
655
+ assert_equal '3=Always', response.xpath('render_choice/response_label[@ident="23"]/material/mattext[@texttype="text/html"]').text
656
+ refute response.xpath('render_choice/response_label[4]').first, 'there should not be a response for answer text'
657
+ refute response.xpath('render_choice/response_label[5]').first, 'there should not be a response for answer text'
658
+
659
+ # Conditions
660
+ condition = xml.root.xpath('resprocessing/respcondition/conditionvar/varequal[@respident="response_response1" and text()="11"]/../..').first
661
+ assert condition, 'condition does not exist for first answer'
662
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Add" and text()="50.00"]').first
663
+ assert var, 'score does not exist for first answer'
664
+
665
+ condition = xml.root.xpath('resprocessing/respcondition/conditionvar/varequal[@respident="response_response2" and text()="21"]/../..').first
666
+ assert condition, 'condition does not exist for first answer'
667
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Add" and text()="50.00"]').first
668
+ assert var, 'score does not exist for second answer'
669
+ end
670
+
671
+ def test_it_creates_item_xml_for_multiple_dropdowns_question_without_choices
672
+ multiple_dropdowns_question_without_choices!
673
+
674
+ question = CanvasCc::Canvas::Question.new @question
675
+ node = Builder::XmlMarkup.new
676
+ xml = Nokogiri::XML(question.create_item_xml(node))
677
+
678
+ # Responses
679
+ response = xml.root.xpath('presentation/response_lid[@ident="response_response1"]').first
680
+ assert response, 'first response for multiple dropdowns question does not exist'
681
+ assert response.xpath('material/mattext["response1"]').first, 'material text does not exist for multiple dropdowns question first response'
682
+ assert_equal '1', response.xpath('render_choice/response_label[@ident="11"]/material/mattext[@texttype="text/html"]').text
683
+ assert_equal '2', response.xpath('render_choice/response_label[@ident="12"]/material/mattext[@texttype="text/html"]').text
684
+ assert_equal '3', response.xpath('render_choice/response_label[@ident="13"]/material/mattext[@texttype="text/html"]').text
685
+ refute response.xpath('render_choice/response_label[4]').first, 'there should not be a response for answer text'
686
+ refute response.xpath('render_choice/response_label[5]').first, 'there should not be a response for answer text'
687
+
688
+ response = xml.root.xpath('presentation/response_lid[@ident="response_response2"]').first
689
+ assert response, 'second response for multiple dropdowns question does not exist'
690
+ assert response.xpath('material/mattext["response2"]').first, 'material text does not exist for multiple dropdowns question second response'
691
+ assert_equal '1', response.xpath('render_choice/response_label[@ident="21"]/material/mattext[@texttype="text/html"]').text
692
+ assert_equal '2', response.xpath('render_choice/response_label[@ident="22"]/material/mattext[@texttype="text/html"]').text
693
+ assert_equal '3', response.xpath('render_choice/response_label[@ident="23"]/material/mattext[@texttype="text/html"]').text
694
+ refute response.xpath('render_choice/response_label[4]').first, 'there should not be a response for answer text'
695
+ refute response.xpath('render_choice/response_label[5]').first, 'there should not be a response for answer text'
696
+
697
+ # Conditions
698
+ condition = xml.root.xpath('resprocessing/respcondition/conditionvar/varequal[@respident="response_response1" and text()="11"]/../..').first
699
+ assert condition, 'condition does not exist for first answer'
700
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Add" and text()="50.00"]').first
701
+ assert var, 'score does not exist for first answer'
702
+
703
+ condition = xml.root.xpath('resprocessing/respcondition/conditionvar/varequal[@respident="response_response2" and text()="21"]/../..').first
704
+ assert condition, 'condition does not exist for first answer'
705
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Add" and text()="50.00"]').first
706
+ assert var, 'score does not exist for second answer'
707
+ end
708
+
709
+ def test_it_create_item_xml_for_multiple_answers_question
710
+ multiple_answers_question!
711
+
712
+ question = CanvasCc::Canvas::Question.new @question
713
+ node = Builder::XmlMarkup.new
714
+ xml = Nokogiri::XML(question.create_item_xml(node))
715
+
716
+ # Responses
717
+ response = xml.root.xpath('presentation/response_lid[@ident="response1" and @rcardinality="Multiple"]').first
718
+ assert response, 'response for multiple answers question does not exist'
719
+ assert_equal 'Ruby', response.xpath('render_choice/response_label[@ident="1"]/material/mattext[@texttype="text/html"]').text
720
+ assert_equal 'Javascript', response.xpath('render_choice/response_label[@ident="2"]/material/mattext[@texttype="text/html"]').text
721
+ assert_equal 'Python', response.xpath('render_choice/response_label[@ident="3"]/material/mattext[@texttype="text/html"]').text
722
+
723
+ # Conditions
724
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]').first
725
+ assert condition, 'condition does not exist for multiple answer question'
726
+ var = condition.xpath('conditionvar/and/varequal[@respident="response1" and text()="1"]').first
727
+ assert var, 'varequal does not exist for first answer'
728
+ var = condition.xpath('conditionvar/and/not/varequal[@respident="response1" and text()="2"]').first
729
+ assert var, 'varequal does not exist for second answer'
730
+ var = condition.xpath('conditionvar/and/not/varequal[@respident="response1" and text()="3"]').first
731
+ assert var, 'varequal does not exist for third answer'
732
+ var = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]').first
733
+ assert var, 'score does not exist for first answer'
734
+ end
735
+
736
+ def test_it_creates_item_xml_for_numerical_question
737
+ numerical_question!
738
+
739
+ question = CanvasCc::Canvas::Question.new @question
740
+ node = Builder::XmlMarkup.new
741
+ xml = Nokogiri::XML(question.create_item_xml(node))
742
+
743
+ response = xml.root.xpath('presentation/response_str').first
744
+ assert_equal 'Single', response.attributes['rcardinality'].value
745
+ assert_equal 'response1', response.attributes['ident'].value
746
+ assert_equal 'Decimal', response.xpath('render_fib').first.attributes['fibtype'].value
747
+ assert_equal 'answer1', response.xpath('render_fib/response_label').first.attributes['ident'].value
748
+
749
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"][1]').first
750
+ assert condition, 'condition does not exist for first answer'
751
+ var = condition.xpath('conditionvar/or/varequal[@respident="response1" and text()="28"]').first
752
+ assert var, 'conditionvar varequal does not exist for first answer'
753
+ var = condition.xpath('conditionvar/or/and/vargte[@respident="response1" and text()="26.0"]').first
754
+ assert var, 'conditionvar vargte does not exist for first answer'
755
+ var = condition.xpath('conditionvar/or/and/varlte[@respident="response1" and text()="30.0"]').first
756
+ assert var, 'conditionvar varlte does not exist for first answer'
757
+ setvar = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]').first
758
+ assert setvar, 'setvar does not exist for first answer'
759
+ feedback = condition.xpath('displayfeedback[@feedbacktype="Response" and @linkrefid="43_fb"]').first
760
+ assert feedback, 'displayfeedback does not exist for first answer'
761
+
762
+ feedback = xml.root.xpath('itemfeedback[@ident="43_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
763
+ assert feedback, 'feedback text does not exist for first answer'
764
+ assert_equal 'Great age!', feedback.text
765
+ end
766
+
767
+
768
+ def test_it_creates_item_xml_for_short_answer_question
769
+ short_answer_question!
770
+
771
+ question = CanvasCc::Canvas::Question.new @question
772
+ node = Builder::XmlMarkup.new
773
+ xml = Nokogiri::XML(question.create_item_xml(node))
774
+
775
+ response = xml.root.xpath('presentation/response_str').first
776
+ assert_equal 'Single', response.attributes['rcardinality'].value
777
+ assert_equal 'response1', response.attributes['ident'].value
778
+ assert_equal 'No', response.xpath('render_fib/response_label').first.attributes['rshuffle'].value
779
+ assert_equal 'answer1', response.xpath('render_fib/response_label').first.attributes['ident'].value
780
+
781
+ # Conditions
782
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="Ruby"]/../..').first
783
+ assert condition, 'condition does not exist for first answer'
784
+ setvar = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]').first
785
+ assert setvar, 'setvar does not exist for first answer'
786
+
787
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="JavaScript"]/../..').first
788
+ assert condition, 'condition does not exist for second answer'
789
+ setvar = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="50"]').first
790
+ assert setvar, 'setvar does not exist for second answer'
791
+
792
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="Java"]/../..').first
793
+ assert condition, 'condition does not exist for third answer'
794
+ setvar = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="10"]').first
795
+ assert setvar, 'setvar does not exist for third answer'
796
+
797
+ # Feedback
798
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="Ruby"]/../..').first
799
+ assert condition, 'feedback condition does not exist for first answer'
800
+ feedback = condition.xpath('displayfeedback[@feedbacktype="Response" and @linkrefid="40_fb"]').first
801
+ assert feedback, 'displayfeedback does not exist for first answer'
802
+
803
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="JavaScript"]/../..').first
804
+ assert condition, 'feedback condition does not exist for second answer'
805
+ feedback = condition.xpath('displayfeedback[@feedbacktype="Response" and @linkrefid="41_fb"]').first
806
+ assert feedback, 'displayfeedback does not exist for second answer'
807
+
808
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="Yes"]/conditionvar/varequal[@respident="response1" and text()="Java"]/../..').first
809
+ assert condition, 'feedback condition does not exist for third answer'
810
+ feedback = condition.xpath('displayfeedback[@feedbacktype="Response" and @linkrefid="42_fb"]').first
811
+ assert feedback, 'displayfeedback does not exist for third answer'
812
+
813
+ feedback = xml.root.xpath('itemfeedback[@ident="40_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
814
+ assert feedback, 'feedback text does not exist for first answer'
815
+ assert_equal 'Good choice!', feedback.text
816
+ feedback = xml.root.xpath('itemfeedback[@ident="41_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
817
+ assert feedback, 'feedback text does not exist for second answer'
818
+ assert_equal 'Not what I would have chosen...', feedback.text
819
+ feedback = xml.root.xpath('itemfeedback[@ident="42_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
820
+ assert feedback, 'feedback text does not exist for third answer'
821
+ assert_equal "You're kidding, right?", feedback.text
822
+ end
823
+
824
+ def test_it_creates_item_xml_for_true_false_question
825
+ true_false_question!
826
+
827
+ question = CanvasCc::Canvas::Question.new @question
828
+ node = Builder::XmlMarkup.new
829
+ xml = Nokogiri::XML(question.create_item_xml(node))
830
+
831
+ response = xml.root.xpath('presentation/response_lid').first
832
+ assert_equal 'Single', response.attributes['rcardinality'].value
833
+ assert_equal 'response1', response.attributes['ident'].value
834
+ assert response.xpath('render_choice/response_label[@ident="44"]/material/mattext[@texttype="text/html" and text()="True"]').first, 'true response choice does not exist'
835
+ assert response.xpath('render_choice/response_label[@ident="45"]/material/mattext[@texttype="text/html" and text()="False"]').first, 'false response choice does not exist'
836
+
837
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="44"]/../..').first
838
+ assert condition, 'condition does not exist for first answer'
839
+ feedback = condition.xpath('displayfeedback[@feedbacktype="Response" and @linkrefid="44_fb"]').first
840
+ assert feedback, 'displayfeedback does not exist for first answer'
841
+ setvar = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]').first
842
+ assert setvar, 'setvar does not exist for first answer'
843
+
844
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]/conditionvar/varequal[@respident="response1" and text()="45"]/../..').first
845
+ assert condition, 'condition does not exist for second answer'
846
+ feedback = condition.xpath('displayfeedback[@feedbacktype="Response" and @linkrefid="45_fb"]').first
847
+ assert feedback, 'displayfeedback does not exist for second answer'
848
+ setvar = condition.xpath('setvar[@varname="SCORE" and @action="Set" and text()="0"]').first
849
+ assert setvar, 'setvar does not exist for second answer'
850
+
851
+ feedback = xml.root.xpath('itemfeedback[@ident="44_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
852
+ assert feedback, 'feedback text does not exist for first answer'
853
+ assert_equal 'Smarty pants!', feedback.text
854
+ feedback = xml.root.xpath('itemfeedback[@ident="45_fb"]/flow_mat/material/mattext[@texttype="text/html"]').first
855
+ assert feedback, 'feedback text does not exist for second answer'
856
+ assert_equal 'What exactly are you doing?', feedback.text
857
+ end
858
+
859
+ def test_it_creates_item_xml_for_embedded_answers_question
860
+ @question.type = 'multianswer'
861
+ question = CanvasCc::Canvas::Question.new @question
862
+ node = Builder::XmlMarkup.new
863
+ xml = Nokogiri::XML(question.create_item_xml(node))
864
+
865
+ response = xml.root.xpath('presentation/response_str').first
866
+ assert_equal 'Single', response.attributes['rcardinality'].value
867
+ assert_equal 'response1', response.attributes['ident'].value
868
+ assert_equal 'No', response.xpath('render_fib/response_label').first.attributes['rshuffle'].value
869
+ assert_equal 'answer1', response.xpath('render_fib/response_label').first.attributes['ident'].value
870
+
871
+ # No Continue Condition
872
+ condition = xml.root.xpath('resprocessing/respcondition[@continue="No"]').first
873
+ assert condition, 'no continue condition node does not exist'
874
+ assert condition.xpath('conditionvar/other').first, 'conditionvar does not exist for no continue condition node'
875
+ end
876
+ end