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,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