canvas_cc 0.0.1

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.
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,47 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe Discussion do
5
+
6
+ it_behaves_like 'it has an attribute for', :title
7
+ it_behaves_like 'it has an attribute for', :text
8
+ it_behaves_like 'it has an attribute for', :discussion_type
9
+ it_behaves_like 'it has an attribute for', :identifier
10
+ it_behaves_like 'it has an attribute for', :workflow_state
11
+
12
+ it 'creates resource' do
13
+ subject.stub(:discussion_resource) { :discussion_resource }
14
+ subject.stub(:meta_resource) { :meta_resource }
15
+ expect(subject.resources).to eq [:discussion_resource, :meta_resource]
16
+ end
17
+
18
+ it 'generates a discussion resource' do
19
+ subject.identifier = 'discussion_id'
20
+ subject.discussion_type = 'threaded'
21
+ subject.title = 'discussion title'
22
+ subject.text = 'discussion body'
23
+ discussion_resource = subject.discussion_resource
24
+ expect(discussion_resource).to be_a_kind_of Resource
25
+ expect(discussion_resource.dependencies.count).to eq 1
26
+ expect(discussion_resource.identifier).to eq 'discussion_id'
27
+ expect(discussion_resource.dependencies.first).to eq 'discussion_id_meta'
28
+ expect(discussion_resource.type).to eq 'imsdt_xmlv1p1'
29
+ expect(discussion_resource.files.count).to eq 1
30
+ expect(discussion_resource.files.first).to eq 'discussion_id.xml'
31
+ end
32
+
33
+ it 'generates a meta resource' do
34
+ subject.identifier = 'discussion_id'
35
+ subject.discussion_type = 'threaded'
36
+ subject.title = 'discussion title'
37
+ subject.text = 'discussion body'
38
+ meta_resource = subject.meta_resource
39
+ expect(meta_resource).to be_a_kind_of Resource
40
+ expect(meta_resource.type).to eq('associatedcontent/imscc_xmlv1p1/learning-application-resource')
41
+ expect(meta_resource.href).to eq('discussion_id_meta.xml')
42
+ expect(meta_resource.files.count).to eq 1
43
+ expect(meta_resource.files.first).to eq 'discussion_id_meta.xml'
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe DiscussionTopic do
5
+ it_behaves_like 'it has an attribute for', :text
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe ModuleItem do
5
+ it_behaves_like 'it has an attribute for', :identifier
6
+ it_behaves_like 'it has an attribute for', :content_type
7
+ it_behaves_like 'it has an attribute for', :workflow_state
8
+ it_behaves_like 'it has an attribute for', :title
9
+ it_behaves_like 'it has an attribute for', :new_tab
10
+ it_behaves_like 'it has an attribute for', :indent
11
+ it_behaves_like 'it has an attribute for', :resource
12
+ it_behaves_like 'it has an attribute for', :identifierref
13
+ it_behaves_like 'it has an attribute for', :url
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe Page do
5
+ subject(:page) { Page.new }
6
+
7
+ it_behaves_like 'a CanvasCc::CanvasCC::Models::Resource'
8
+
9
+ it_behaves_like 'it has an attribute for', :workflow_state
10
+ it_behaves_like 'it has an attribute for', :editing_roles
11
+ it_behaves_like 'it has an attribute for', :body
12
+ it_behaves_like 'it has an attribute for', :title
13
+
14
+ its(:type) { should eq 'webcontent' }
15
+
16
+ it "hashes the identifier" do
17
+ page.identifier = 3
18
+ expect(page.identifier).to eq 3
19
+ end
20
+
21
+ it "sets the wiki_dir, and title" do
22
+ page.page_name = 'My Page Name'
23
+ expect(page.href).to eq 'wiki_content/my-page-name.html'
24
+ expect(page.title).to eq 'My Page Name'
25
+ end
26
+
27
+ it "truncates urls that are too long" do
28
+ page.page_name = 'a' * 500
29
+ expected = "wiki_content/#{'a' * CanvasCc::CanvasCC::Models::Page::MAX_URL_LENGTH}.html"
30
+ expect(page.href).to eq expected
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe Question do
5
+ it_behaves_like 'it has an attribute for', :identifier
6
+ it_behaves_like 'it has an attribute for', :title
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe Resource do
5
+ it_behaves_like 'it has an attribute for', :href
6
+ it_behaves_like 'it has an attribute for', :type
7
+
8
+ it 'removes empty attributes when value is nil' do
9
+ subject.identifier = 'foo_bar'
10
+ subject.type = 'sometype'
11
+ expect(subject.attributes.keys.length).to eq(2)
12
+
13
+ subject.type = nil
14
+ expect(subject.attributes.keys.length).to eq(1)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe WebContent do
5
+ it_behaves_like 'it has an attribute for', :body
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC::Models
4
+ describe WebLink do
5
+ it_behaves_like 'it has an attribute for', :url
6
+ it_behaves_like 'it has an attribute for', :external_link
7
+ it_behaves_like 'it has an attribute for', :href
8
+ end
9
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe ModuleMetaWriter do
5
+
6
+ let(:canvas_module) { Models::CanvasModule.new }
7
+ let(:module_item) { Models::ModuleItem.new }
8
+ let(:tmpdir) { Dir.mktmpdir }
9
+
10
+ before :each do
11
+ Dir.mkdir(File.join(tmpdir, CartridgeCreator::COURSE_SETTINGS_DIR))
12
+ end
13
+
14
+ after :each do
15
+ FileUtils.rm_r tmpdir
16
+ end
17
+
18
+ it 'should have a valid schema' do
19
+ canvas_module.identifier = 'module_identifier'
20
+ canvas_module.title = 'test_title'
21
+ canvas_module.workflow_state = 'active'
22
+ xml = write_xml(canvas_module)
23
+
24
+ assert_xml_schema(xml)
25
+ end
26
+
27
+ it 'writes out modules correctly' do
28
+ canvas_module.identifier = 'ident'
29
+ canvas_module.title = 'module title'
30
+ canvas_module.workflow_state = 'active'
31
+ xml = write_xml(canvas_module)
32
+
33
+ expect(xml.at_xpath('xmlns:modules/xmlns:module/@identifier').text).to eq('ident')
34
+ expect(xml.%('modules/module/title').text).to eq('module title')
35
+ expect(xml.%('modules/module/workflow_state').text).to eq('active')
36
+ expect(xml.%('modules/module/position').text).to eq('0')
37
+ end
38
+
39
+ it 'increments the position for each module that is written' do
40
+ xml = write_xml(Models::CanvasModule.new, Models::CanvasModule.new)
41
+ expect(xml.%('modules/module/position').text).to eq('0')
42
+ expect(xml.%('modules/module[last()]/position').text).to eq('1')
43
+ end
44
+
45
+ context 'module items' do
46
+ it 'writes out module items correctly' do
47
+ module_item.identifier = "some_unique_hash"
48
+ module_item.content_type = "ContentType"
49
+ module_item.workflow_state = "active"
50
+ module_item.title = "Item Title"
51
+ module_item.new_tab = nil
52
+ module_item.indent = "1"
53
+ module_item.url = 'http://example.com'
54
+
55
+ module_item.identifierref = 'resource_id'
56
+
57
+ canvas_module.module_items << module_item
58
+
59
+ xml = write_xml(canvas_module)
60
+
61
+ item_node = xml.%('modules/module/items/item')
62
+ expect(item_node.at_xpath('@identifier').text).to eq('some_unique_hash')
63
+ expect(item_node.%('content_type').text).to eq('ContentType')
64
+ expect(item_node.%('workflow_state').text).to eq('active')
65
+ expect(item_node.%('title').text).to eq('Item Title')
66
+ expect(item_node.%('position').text).to eq('0')
67
+ expect(item_node.%('new_tab')).to be_nil
68
+ expect(item_node.%('indent').text).to eq('1')
69
+ expect(item_node.%('identifierref').text).to eq('resource_id')
70
+ expect(item_node.%('url').text).to eq('http://example.com')
71
+ end
72
+
73
+ it 'does not write the identifierref if it is not provided' do
74
+ canvas_module.module_items << module_item
75
+
76
+ xml = write_xml(canvas_module)
77
+
78
+ expect(xml.%('modules/module/items/item/identifierref')).to be_nil
79
+ end
80
+
81
+ it 'does not write the url if it is not provided' do
82
+ canvas_module.module_items << module_item
83
+
84
+ xml = write_xml(canvas_module)
85
+
86
+ expect(xml.%('modules/module/items/item/url')).to be_nil
87
+ end
88
+
89
+ it 'increments the position for each module item that is written in a module' do
90
+ canvas_module.module_items << Models::ModuleItem.new
91
+ canvas_module.module_items << Models::ModuleItem.new
92
+
93
+ xml = write_xml(canvas_module)
94
+
95
+ expect(xml.%('modules/module/items/item/position').text).to eq('0')
96
+ expect(xml.%('modules/module/items/item[last()]/position').text).to eq('1')
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def write_xml(*mod)
103
+ writer = ModuleMetaWriter.new(tmpdir, *mod)
104
+ writer.write
105
+ path = File.join(tmpdir,
106
+ CartridgeCreator::COURSE_SETTINGS_DIR,
107
+ ModuleMetaWriter::MODULE_META_FILE)
108
+ Nokogiri::XML(File.read(path))
109
+ end
110
+
111
+ def assert_xml_schema(xml)
112
+ valid_schema = File.read(fixture_path(File.join('common_cartridge', 'schema', 'cccv1p0.xsd')))
113
+ xsd = Nokogiri::XML::Schema(valid_schema)
114
+ expect(xsd.validate(xml)).to be_empty
115
+ end
116
+
117
+ end
118
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe MultipleAnswersQuestionWriter do
5
+
6
+ let(:question) { CanvasCc::CanvasCC::Models::Question.create('multiple_answers_question')}
7
+
8
+ it 'creates the question item xml for a multiple_choice_question' do
9
+ question.identifier = 420
10
+ question.title = 'hello'
11
+ question.general_feedback = 'feedbacks'
12
+ question.material = 'materiaru'
13
+
14
+ answer1 = CanvasCc::CanvasCC::Models::Answer.new
15
+ answer1.id = '1'
16
+ answer1.answer_text = 'something'
17
+ answer1.fraction = '0.5'
18
+ answer2 = CanvasCc::CanvasCC::Models::Answer.new
19
+ answer2.id = '2'
20
+ answer2.answer_text = 'something else'
21
+ answer2.fraction = '0'
22
+ answer3 = CanvasCc::CanvasCC::Models::Answer.new
23
+ answer3.id = '3'
24
+ answer3.answer_text = 'something something else'
25
+ answer3.fraction = '0.5'
26
+ question.answers = [answer1, answer2, answer3]
27
+
28
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
29
+ QuestionWriter.write_question(node, question)
30
+ end.doc
31
+
32
+ expect(xml.at_xpath('item/@ident').value).to eq question.identifier.to_s
33
+ expect(xml.at_xpath('item/@title').value).to eq question.title
34
+ expect(xml.at_xpath("item/itemmetadata/qtimetadata/qtimetadatafield[fieldlabel=\"question_type\" and fieldentry=\"#{question.question_type}\"]")).to_not be_nil
35
+
36
+ response = xml.at_xpath('item/presentation/response_lid')
37
+ expect(response.attributes['rcardinality'].value).to eq 'Multiple'
38
+ expect(response.attributes['ident'].value).to eq 'response1'
39
+
40
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer1.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer1.answer_text}\"]")).not_to be_nil
41
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer2.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer2.answer_text}\"]")).not_to be_nil
42
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer3.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer3.answer_text}\"]")).not_to be_nil
43
+
44
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]")
45
+ expect(condition.at_xpath("conditionvar/and/varequal[@respident=\"response1\" and text()=\"#{answer1.id}\"]")).not_to be_nil
46
+ expect(condition.at_xpath("conditionvar/and/not/varequal[@respident=\"response1\" and text()=\"#{answer2.id}\"]")).not_to be_nil
47
+ expect(condition.at_xpath("conditionvar/and/varequal[@respident=\"response1\" and text()=\"#{answer3.id}\"]")).not_to be_nil
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe MultipleBlanksQuestionWriter do
5
+
6
+ let(:question) { CanvasCc::CanvasCC::Models::Question.create('fill_in_multiple_blanks_question')}
7
+
8
+ it 'creates the question item xml for a multiple blanks question' do
9
+ question.identifier = 4200
10
+ question.title = 'hello'
11
+ question.general_feedback = 'feedbacks'
12
+ question.material = 'the first question is: [response1] and the second is: [response2]'
13
+
14
+ answer1 = CanvasCc::CanvasCC::Models::Answer.new
15
+ answer1.id = '1'
16
+ answer1.fraction = 1
17
+ answer1.answer_text = 'i take specs seriously'
18
+ answer1.feedback = 'feedfbavks'
19
+ answer1.resp_ident = 'response1'
20
+
21
+ answer2 = CanvasCc::CanvasCC::Models::Answer.new
22
+ answer2.id = '2'
23
+ answer2.fraction = 1
24
+ answer2.answer_text = 'imm the right one for the second'
25
+ answer2.feedback = 'moar feedback'
26
+ answer2.resp_ident = 'response2'
27
+ question.answers = [answer1, answer2]
28
+
29
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
30
+ QuestionWriter.write_question(node, question)
31
+ end.doc
32
+
33
+ expect(xml.at_xpath('item/@ident').value).to eq question.identifier.to_s
34
+ expect(xml.at_xpath('item/@title').value).to eq question.title
35
+ expect(xml.at_xpath("item/itemmetadata/qtimetadata/qtimetadatafield[fieldlabel=\"question_type\" and fieldentry=\"#{question.question_type}\"]")).to_not be_nil
36
+
37
+ # first response
38
+ response = xml.xpath('item/presentation/response_lid')[0]
39
+ expect(response.attributes['rcardinality'].value).to eq 'Single'
40
+ expect(response.attributes['ident'].value).to eq 'response1'
41
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer1.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer1.answer_text}\"]")).not_to be_nil
42
+
43
+ # second response
44
+ response = xml.xpath('item/presentation/response_lid')[1]
45
+ expect(response.attributes['rcardinality'].value).to eq 'Single'
46
+ expect(response.attributes['ident'].value).to eq 'response2'
47
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer2.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer2.answer_text}\"]")).not_to be_nil
48
+
49
+ # Feedback
50
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"Yes\"]/conditionvar/varequal[@respident=\"response1\" and text()=\"#{answer1.id}\"]/../..")
51
+ expect(condition).not_to be_nil
52
+ feedback = condition.at_xpath("displayfeedback[@feedbacktype=\"Response\" and @linkrefid=\"#{answer1.id}_fb\"]")
53
+ expect(feedback).not_to be_nil
54
+
55
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"Yes\"]/conditionvar/varequal[@respident=\"response2\" and text()=\"#{answer2.id}\"]/../..")
56
+ expect(condition).not_to be_nil
57
+ feedback = condition.at_xpath("displayfeedback[@feedbacktype=\"Response\" and @linkrefid=\"#{answer2.id}_fb\"]")
58
+ expect(feedback).not_to be_nil
59
+
60
+ feedback = xml.at_xpath("item/itemfeedback[@ident=\"#{answer1.id}_fb\"]/flow_mat/material/mattext[@texttype=\"text/html\"]")
61
+ expect(feedback.text).to eq answer1.feedback
62
+ feedback = xml.at_xpath("item/itemfeedback[@ident=\"#{answer2.id}_fb\"]/flow_mat/material/mattext[@texttype=\"text/html\"]")
63
+ expect(feedback.text).to eq answer2.feedback
64
+
65
+ # Conditions
66
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]/conditionvar/varequal[@respident=\"response1\" and text()=\"#{answer1.id}\"]/../..")
67
+ expect(condition).not_to be_nil
68
+ setvar = condition.at_xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]')
69
+ expect(setvar).not_to be_nil
70
+
71
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]/conditionvar/varequal[@respident=\"response2\" and text()=\"#{answer2.id}\"]/../..")
72
+ expect(condition).not_to be_nil
73
+ setvar = condition.at_xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]')
74
+ expect(setvar).not_to be_nil
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe MultipleChoiceQuestionWriter do
5
+
6
+ let(:question) { CanvasCc::CanvasCC::Models::Question.create('multiple_choice_question')}
7
+
8
+ it 'creates the question item xml for a multiple_choice_question' do
9
+ question.identifier = 420
10
+ question.title = 'hello'
11
+ question.general_feedback = 'feedbacks'
12
+ question.material = 'materiaru'
13
+
14
+ answer1 = CanvasCc::CanvasCC::Models::Answer.new
15
+ answer1.id = 'correcto'
16
+ answer1.fraction = 1.0
17
+ answer1.answer_text = 'so true'
18
+ answer1.feedback = 'was there ever any doubt?'
19
+ answer2 = CanvasCc::CanvasCC::Models::Answer.new
20
+ answer2.id = 'farusu'
21
+ answer2.fraction = 0.0
22
+ answer2.answer_text = 'falrse'
23
+ answer2.feedback = 'bakaaaa'
24
+ question.answers = [answer1, answer2]
25
+
26
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
27
+ QuestionWriter.write_question(node, question)
28
+ end.doc
29
+
30
+ expect(xml.at_xpath('item/@ident').value).to eq question.identifier.to_s
31
+ expect(xml.at_xpath('item/@title').value).to eq question.title
32
+ expect(xml.at_xpath("item/itemmetadata/qtimetadata/qtimetadatafield[fieldlabel=\"question_type\" and fieldentry=\"#{question.question_type}\"]")).to_not be_nil
33
+
34
+ response = xml.at_xpath('item/presentation/response_lid')
35
+ expect(response.attributes['rcardinality'].value).to eq 'Single'
36
+ expect(response.attributes['ident'].value).to eq 'response1'
37
+
38
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer1.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer1.answer_text}\"]")).not_to be_nil
39
+ expect(response.at_xpath("render_choice/response_label[@ident=\"#{answer2.id}\"]/material/mattext[@texttype=\"text/html\" and text()=\"#{answer2.answer_text}\"]")).not_to be_nil
40
+
41
+ # Feedback
42
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"Yes\"]/conditionvar/varequal[@respident=\"response1\" and text()=\"#{answer1.id}\"]/../..")
43
+ expect(condition).not_to be_nil
44
+ feedback = condition.at_xpath("displayfeedback[@feedbacktype=\"Response\" and @linkrefid=\"#{answer1.id}_fb\"]")
45
+ expect(feedback).not_to be_nil
46
+
47
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"Yes\"]/conditionvar/varequal[@respident=\"response1\" and text()=\"#{answer2.id}\"]/../..")
48
+ expect(condition).not_to be_nil
49
+ feedback = condition.at_xpath("displayfeedback[@feedbacktype=\"Response\" and @linkrefid=\"#{answer2.id}_fb\"]")
50
+ expect(feedback).not_to be_nil
51
+
52
+ feedback = xml.at_xpath("item/itemfeedback[@ident=\"#{answer1.id}_fb\"]/flow_mat/material/mattext[@texttype=\"text/html\"]")
53
+ expect(feedback.text).to eq answer1.feedback
54
+ feedback = xml.at_xpath("item/itemfeedback[@ident=\"#{answer2.id}_fb\"]/flow_mat/material/mattext[@texttype=\"text/html\"]")
55
+ expect(feedback.text).to eq answer2.feedback
56
+
57
+ # Conditions
58
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]/conditionvar/varequal[@respident=\"response1\" and text()=\"#{answer1.id}\"]/../..")
59
+ expect(condition).not_to be_nil
60
+ setvar = condition.at_xpath('setvar[@varname="SCORE" and @action="Set" and text()="100"]')
61
+ expect(setvar).not_to be_nil
62
+
63
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]/conditionvar/varequal[@respident=\"response1\" and text()=\"#{answer2.id}\"]/../..")
64
+ expect(condition).not_to be_nil
65
+ setvar = condition.at_xpath('setvar[@varname="SCORE" and @action="Set" and text()="0"]')
66
+ expect(setvar).not_to be_nil
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe MultipleDropdownsQuestionWriter do
5
+
6
+ let(:question) { CanvasCc::CanvasCC::Models::Question.create('multiple_dropdowns_question')}
7
+
8
+ it 'creates the question item xml for a multiple_dropdowns_question' do
9
+ question.identifier = 4200
10
+ question.title = 'hello'
11
+ question.general_feedback = 'feedbacks'
12
+ question.material = 'the first question is [response1] and the second is [response2]'
13
+ question.answers = []
14
+ question.responses = [
15
+ {:id => "response1", :choices => [
16
+ {:id => "3_choice_0_0", :text => "1"},
17
+ {:id => "3_choice_0_1", :text => "2"}
18
+ ]},
19
+ {:id => "response2", :choices => [
20
+ {:id => "3_choice_1_0", :text => "1"},
21
+ {:id => "3_choice_1_1", :text => "2"}
22
+ ]}
23
+ ]
24
+
25
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
26
+ QuestionWriter.write_question(node, question)
27
+ end.doc
28
+
29
+ expect(xml.at_xpath('item/@ident').value).to eq question.identifier.to_s
30
+ expect(xml.at_xpath('item/@title').value).to eq question.title
31
+ expect(xml.at_xpath("item/itemmetadata/qtimetadata/qtimetadatafield[fieldlabel=\"question_type\" and fieldentry=\"#{question.question_type}\"]")).to_not be_nil
32
+
33
+ # first response
34
+ response = xml.xpath('item/presentation/response_lid')[0]
35
+ expect(response.attributes['ident'].value).to eq 'response_response1'
36
+ expect(response.at_xpath("render_choice/response_label[@ident=\"3_choice_0_0\"]/material/mattext[@texttype=\"text/plain\" and text()=\"1\"]")).not_to be_nil
37
+ expect(response.at_xpath("render_choice/response_label[@ident=\"3_choice_0_1\"]/material/mattext[@texttype=\"text/plain\" and text()=\"2\"]")).not_to be_nil
38
+
39
+ # second response
40
+ response = xml.xpath('item/presentation/response_lid')[1]
41
+ expect(response.attributes['ident'].value).to eq 'response_response2'
42
+ expect(response.at_xpath("render_choice/response_label[@ident=\"3_choice_1_0\"]/material/mattext[@texttype=\"text/plain\" and text()=\"1\"]")).not_to be_nil
43
+ expect(response.at_xpath("render_choice/response_label[@ident=\"3_choice_1_1\"]/material/mattext[@texttype=\"text/plain\" and text()=\"2\"]")).not_to be_nil
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe NumericalQuestionWriter do
5
+
6
+ let(:question) { CanvasCc::CanvasCC::Models::Question.create('numerical_question')}
7
+
8
+ it 'creates the question item xml for a numerical question' do
9
+ question.identifier = 9001
10
+ question.title = 'its over nine thousannnd'
11
+ question.general_feedback = 'ur totes awesome'
12
+ question.material = 'this is a question, or is it?'
13
+
14
+ answer1 = CanvasCc::CanvasCC::Models::Answer.new
15
+ answer1.id = 'answer1_id'
16
+ answer1.answer_text = 20
17
+ answer1.fraction = 1
18
+ answer1.feedback = 'feedbak1'
19
+ answer2 = CanvasCc::CanvasCC::Models::Answer.new
20
+ answer2.id = 'answer2_id'
21
+ answer2.answer_text = 30
22
+ answer2.fraction = 0
23
+ answer2.feedback = 'also feedback2'
24
+ question.answers = [answer1, answer2]
25
+
26
+ question.tolerances = {'answer1_id' => 1, 'answer2_id' => 2}
27
+
28
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
29
+ QuestionWriter.write_question(node, question)
30
+ end.doc
31
+
32
+ expect(xml.at_xpath('item/@ident').value).to eq question.identifier.to_s
33
+ expect(xml.at_xpath('item/@title').value).to eq question.title
34
+ expect(xml.at_xpath("item/itemmetadata/qtimetadata/qtimetadatafield[fieldlabel=\"question_type\" and fieldentry=\"#{question.question_type}\"]")).to_not be_nil
35
+
36
+ response = xml.at_xpath('item/presentation/response_str')
37
+ expect(response.attributes['rcardinality'].value).to eq 'Single'
38
+ expect(response.attributes['ident'].value).to eq 'response1'
39
+ expect(response.at_xpath('render_fib').attributes['fibtype'].value).to eq 'Decimal'
40
+ expect(response.at_xpath('render_fib/response_label').attributes['ident'].value).to eq 'answer1'
41
+
42
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]/displayfeedback[@linkrefid=\"#{answer1.id}_fb\"]/..")
43
+ varequal = condition.at_xpath('conditionvar/or/varequal[@respident="response1"]')
44
+ expect(varequal.text).to eq answer1.answer_text.to_s
45
+ vargte = condition.at_xpath('conditionvar/or/and/vargte[@respident="response1"]')
46
+ expect(vargte.text).to eq (answer1.answer_text.to_f - 1).to_s
47
+ varlte = condition.at_xpath('conditionvar/or/and/varlte[@respident="response1"]')
48
+ expect(varlte.text).to eq (answer1.answer_text.to_f + 1).to_s
49
+
50
+ setvar = condition.at_xpath('setvar')
51
+ expect(setvar.text).to eq '100'
52
+ expect(setvar.attributes['varname'].value).to eq 'SCORE'
53
+ expect(setvar.attributes['action'].value).to eq 'Set'
54
+
55
+ condition = xml.at_xpath("item/resprocessing/respcondition[@continue=\"No\"]/displayfeedback[@linkrefid=\"#{answer2.id}_fb\"]/..")
56
+ varequal = condition.at_xpath('conditionvar/or/varequal[@respident="response1"]')
57
+ expect(varequal.text).to eq answer2.answer_text.to_s
58
+ vargte = condition.at_xpath('conditionvar/or/and/vargte[@respident="response1"]')
59
+ expect(vargte.text).to eq (answer2.answer_text.to_f - 2).to_s
60
+ varlte = condition.at_xpath('conditionvar/or/and/varlte[@respident="response1"]')
61
+ expect(varlte.text).to eq (answer2.answer_text.to_f + 2).to_s
62
+
63
+ setvar = condition.at_xpath('setvar')
64
+ expect(setvar.text).to eq '0'
65
+ expect(setvar.attributes['varname'].value).to eq 'SCORE'
66
+ expect(setvar.attributes['action'].value).to eq 'Set'
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe CanvasCc::CanvasCC::PageWriter do
4
+ subject(:writer) { CanvasCc::CanvasCC::PageWriter.new(work_dir, page) }
5
+ let(:work_dir) { Dir.mktmpdir }
6
+ let(:page) {CanvasCc::CanvasCC::Models::Page.new}
7
+
8
+ after(:each) do
9
+ FileUtils.rm_r work_dir
10
+ end
11
+
12
+ it 'creates the page html' do
13
+ page.identifier = 'my_id'
14
+ page.workflow_state = 'active'
15
+ page.body = '<h2>This is the body</h2>'
16
+ page.editing_roles = 'teachers'
17
+ page.page_name ='My Page Title'
18
+ writer.write
19
+ html = Nokogiri::HTML(File.read(File.join(work_dir, page.href)))
20
+ expect(html.at_css('meta[http-equiv]')[:'http-equiv']).to eq 'Content-Type'
21
+ expect(html.at_css('meta[http-equiv]')[:content]).to eq 'text/html; charset=utf-8'
22
+ expect(html.at_css('meta[name=identifier]')[:content]).to eq 'my_id'
23
+ expect(html.at_css('meta[name=editing_roles]')[:content]).to eq 'teachers'
24
+ expect(html.at_css('meta[name=workflow_state]')[:content]).to eq 'active'
25
+ expect(html.at_css('title').text).to eq 'My Page Title'
26
+ expect(html.at_css('body').inner_html.to_s).to eq '<h2>This is the body</h2>'
27
+ end
28
+
29
+ end