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,75 @@
1
+ module CanvasCc::CC
2
+ class WebLink
3
+ include CCHelper
4
+ include Resource
5
+
6
+ attr_accessor :url, :external_link, :href
7
+
8
+ def initialize(mod)
9
+ super
10
+ @url = mod.reference.to_s.strip
11
+ @external_link = self.class.external_link?(mod)
12
+ @href = @external_link ? "#{@identifier}.xml" : File.join(WEB_RESOURCES_FOLDER, @url)
13
+ @identifier = create_key(@href, 'resource_') unless @external_link
14
+ end
15
+
16
+ def self.create_resource_key(mod)
17
+ unless external_link?(mod)
18
+ create_key(File.join(WEB_RESOURCES_FOLDER, mod.reference), 'resource_')
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def self.external_link?(mod)
25
+ begin
26
+ !!URI.parse(mod.reference.to_s.strip.gsub(/\s/, '+')).scheme
27
+ rescue URI::InvalidURIError
28
+ !!mod.reference.strip.match(/^https?\:\/\//)
29
+ end
30
+ end
31
+
32
+ def create_resource_node(resources_node)
33
+ if @external_link
34
+ resources_node.resource(
35
+ :type => WEB_LINK,
36
+ :identifier => identifier
37
+ ) do |resource_node|
38
+ resource_node.file(:href => href)
39
+ end
40
+ else
41
+ resources_node.resource(
42
+ :type => WEBCONTENT,
43
+ :href => href,
44
+ :identifier => identifier
45
+ ) do |resource_node|
46
+ resource_node.file(:href => href)
47
+ end
48
+ end
49
+ end
50
+
51
+ def create_files(export_dir)
52
+ create_xml(export_dir)
53
+ end
54
+
55
+ def create_xml(export_dir)
56
+ return unless @external_link
57
+ path = File.join(export_dir, "#{identifier}.xml")
58
+ FileUtils.mkdir_p(File.dirname(path))
59
+ File.open(path, 'w') do |file|
60
+ settings_node = Builder::XmlMarkup.new(:target => file, :indent => 2)
61
+ settings_node.instruct!
62
+ settings_node.webLink(
63
+ :identifier => identifier,
64
+ 'xsi:schemaLocation' => "http://www.imsglobal.org/xsd/imsccv1p1/imswl_v1p1 http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imswl_v1p1.xsd",
65
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
66
+ 'xmlns' => "http://www.imsglobal.org/xsd/imsccv1p1/imswl_v1p1"
67
+ ) do |web_link_node|
68
+ web_link_node.title @title
69
+ web_link_node.url(:href => @url)
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,73 @@
1
+ module CanvasCc::CC
2
+ class Wiki
3
+ include CCHelper
4
+ include Resource
5
+
6
+ attr_accessor :pages
7
+
8
+ def initialize(mod)
9
+ super
10
+ @href_template ||= "#{CC_WIKI_FOLDER}/%s.html"
11
+ page_versions = mod.pages.inject({}) do |result, page|
12
+ version = result[page.page_name]
13
+ result[page.page_name] = page.version if version.nil? || page.version > version
14
+ result
15
+ end
16
+
17
+ @pages = mod.pages.map do |page|
18
+ if page.version == page_versions[page.page_name]
19
+ title_slug = file_slug(@title)
20
+ body = page.content
21
+ slug = [title_slug, file_slug(page.page_name)].join('-')
22
+ href = @href_template % slug
23
+ CanvasCc::OpenStruct.new(:title => page.page_name, :body => body, :href => href, :identifier => create_key(href))
24
+ end
25
+ end.compact
26
+
27
+ if @pages.empty?
28
+ slug = file_slug(@title)
29
+ href = @href_template % slug
30
+ @pages = [CanvasCc::OpenStruct.new(:title => @title, :body => mod.summary, :href => href, :identifier => create_key(href))]
31
+ end
32
+
33
+ @identifier = root_page.identifier
34
+ end
35
+
36
+ def self.create_resource_key(mod)
37
+ Wiki.new(mod).identifer
38
+ end
39
+
40
+ def root_page
41
+ @pages.find { |page| page.title.downcase == @title.downcase }
42
+ end
43
+
44
+ def create_resource_node(resources_node)
45
+ @pages.each do |page|
46
+ href = page.href
47
+ resources_node.resource(
48
+ :href => href,
49
+ :type => WEBCONTENT,
50
+ :identifier => create_key(href)
51
+ ) do |resource_node|
52
+ resource_node.file(:href => href)
53
+ end
54
+ end
55
+ end
56
+
57
+ def create_files(export_dir)
58
+ create_html(export_dir)
59
+ end
60
+
61
+ def create_html(export_dir)
62
+ template = File.expand_path('../templates/wiki_content.html.erb', __FILE__)
63
+ @pages.each do |page|
64
+ path = File.join(export_dir, page.href)
65
+ FileUtils.mkdir_p(File.dirname(path))
66
+ File.open(path, 'w') do |file|
67
+ erb = ERB.new(File.read(template))
68
+ file.write(erb.result(page.instance_eval { binding }))
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module CanvasCc
2
+ VERSION = "0.0.1"
3
+ end
data/lib/canvas_cc.rb ADDED
@@ -0,0 +1,94 @@
1
+ require "canvas_cc/version"
2
+ require 'builder'
3
+ require 'cgi'
4
+ require 'erb'
5
+ require 'fileutils'
6
+ require 'happymapper'
7
+ require 'logger'
8
+ require 'nokogiri'
9
+ require 'ostruct'
10
+ require 'rdiscount'
11
+ require 'uri'
12
+ require 'securerandom'
13
+
14
+ module CanvasCc
15
+ module CC
16
+ autoload :Assessment, 'canvas_cc/cc/assessment'
17
+ autoload :Assignment, 'canvas_cc/cc/assignment'
18
+ autoload :CCHelper, 'canvas_cc/cc/cc_helper'
19
+ autoload :Converter, 'canvas_cc/cc/converter'
20
+ autoload :Course, 'canvas_cc/cc/course'
21
+ autoload :DiscussionTopic, 'canvas_cc/cc/discussion_topic'
22
+ autoload :Label, 'canvas_cc/cc/label'
23
+ autoload :Question, 'canvas_cc/cc/question'
24
+ autoload :Resource, 'canvas_cc/cc/resource'
25
+ autoload :WebContent, 'canvas_cc/cc/web_content'
26
+ autoload :WebLink, 'canvas_cc/cc/web_link'
27
+ autoload :Wiki, 'canvas_cc/cc/wiki'
28
+ end
29
+ module Canvas
30
+ autoload :Assessment, 'canvas_cc/canvas/assessment'
31
+ autoload :Assignment, 'canvas_cc/canvas/assignment'
32
+ autoload :Converter, 'canvas_cc/canvas/converter'
33
+ autoload :Course, 'canvas_cc/canvas/course'
34
+ autoload :DiscussionTopic, 'canvas_cc/canvas/discussion_topic'
35
+ autoload :Label, 'canvas_cc/canvas/label'
36
+ autoload :Question, 'canvas_cc/canvas/question'
37
+ autoload :QuestionBank, 'canvas_cc/canvas/question_bank'
38
+ autoload :QuestionGroup, 'canvas_cc/canvas/question_group'
39
+ autoload :Resource, 'canvas_cc/canvas/resource'
40
+ autoload :WebContent, 'canvas_cc/canvas/web_content'
41
+ autoload :WebLink, 'canvas_cc/canvas/web_link'
42
+ autoload :Wiki, 'canvas_cc/canvas/wiki'
43
+ end
44
+ module CanvasCC
45
+ autoload :ImsManifestGenerator, 'canvas_cc/canvas_cc/ims_manifest_generator'
46
+ autoload :CartridgeCreator, 'canvas_cc/canvas_cc/cartridge_creator'
47
+ autoload :CourseSettingWriter, 'canvas_cc/canvas_cc/course_setting_writer'
48
+ autoload :ModuleMetaWriter, 'canvas_cc/canvas_cc/module_meta_writer'
49
+ autoload :FileMetaWriter, 'canvas_cc/canvas_cc/file_meta_writer'
50
+ autoload :CanvasExportWriter, 'canvas_cc/canvas_cc/canvas_export_writer'
51
+ autoload :PageWriter, 'canvas_cc/canvas_cc/page_writer'
52
+ autoload :DiscussionWriter, 'canvas_cc/canvas_cc/discussion_writer'
53
+ autoload :AssignmentWriter, 'canvas_cc/canvas_cc/assignment_writer'
54
+ autoload :AssignmentGroupWriter, 'canvas_cc/canvas_cc/assignment_group_writer'
55
+
56
+ autoload :QuestionWriter, 'canvas_cc/canvas_cc/question_writer'
57
+ autoload :CalculatedQuestionWriter, 'canvas_cc/canvas_cc/calculated_question_writer'
58
+ autoload :EssayQuestionWriter, 'canvas_cc/canvas_cc/essay_question_writer'
59
+ autoload :MatchingQuestionWriter, 'canvas_cc/canvas_cc/matching_question_writer'
60
+ autoload :MultipleAnswersQuestionWriter, 'canvas_cc/canvas_cc/multiple_answers_question_writer'
61
+ autoload :MultipleBlanksQuestionWriter, 'canvas_cc/canvas_cc/multiple_blanks_question_writer'
62
+ autoload :MultipleChoiceQuestionWriter, 'canvas_cc/canvas_cc/multiple_choice_question_writer'
63
+ autoload :MultipleDropdownsQuestionWriter, 'canvas_cc/canvas_cc/multiple_dropdowns_question_writer'
64
+ autoload :NumericalQuestionWriter, 'canvas_cc/canvas_cc/numerical_question_writer'
65
+ autoload :ShortAnswerQuestionWriter, 'canvas_cc/canvas_cc/short_answer_question_writer'
66
+ autoload :TextOnlyQuestionWriter, 'canvas_cc/canvas_cc/text_only_question_writer'
67
+ autoload :TrueFalseQuestionWriter, 'canvas_cc/canvas_cc/true_false_question_writer'
68
+
69
+ autoload :QuestionBankWriter, 'canvas_cc/canvas_cc/question_bank_writer'
70
+ autoload :QuestionGroupWriter, 'canvas_cc/canvas_cc/question_group_writer'
71
+ autoload :AssessmentWriter, 'canvas_cc/canvas_cc/assessment_writer'
72
+ module Models
73
+ autoload :Course, 'canvas_cc/canvas_cc/models/course'
74
+ autoload :Assignment, 'canvas_cc/canvas_cc/models/assignment'
75
+ autoload :AssignmentGroup, 'canvas_cc/canvas_cc/models/assignment_group'
76
+ autoload :Assessment, 'canvas_cc/canvas_cc/models/assessment'
77
+ autoload :DiscussionTopic, 'canvas_cc/canvas_cc/models/discussion_topic'
78
+ autoload :Question, 'canvas_cc/canvas_cc/models/question'
79
+ autoload :CalculatedQuestion, 'canvas_cc/canvas_cc/models/calculated_question'
80
+ autoload :Answer, 'canvas_cc/canvas_cc/models/answer'
81
+ autoload :QuestionBank, 'canvas_cc/canvas_cc/models/question_bank'
82
+ autoload :QuestionGroup, 'canvas_cc/canvas_cc/models/question_group'
83
+ autoload :WebContent, 'canvas_cc/canvas_cc/models/web_content'
84
+ autoload :WebLink, 'canvas_cc/canvas_cc/models/web_link'
85
+ autoload :Resource, 'canvas_cc/canvas_cc/models/resource'
86
+ autoload :CanvasModule, 'canvas_cc/canvas_cc/models/canvas_module'
87
+ autoload :ModuleItem, 'canvas_cc/canvas_cc/models/module_item'
88
+ autoload :CanvasFile, 'canvas_cc/canvas_cc/models/canvas_file'
89
+ autoload :Page, 'canvas_cc/canvas_cc/models/page'
90
+ autoload :Discussion, 'canvas_cc/canvas_cc/models/discussion'
91
+ autoload :WorkflowState, 'canvas_cc/canvas_cc/models/workflow_state'
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe AssessmentWriter do
5
+ subject { CanvasCc::CanvasCC::AssessmentWriter.new(work_dir, assessment) }
6
+ let(:work_dir) { Dir.mktmpdir }
7
+ let(:assessment) { CanvasCc::CanvasCC::Models::Assessment.new }
8
+
9
+ after(:each) do
10
+ FileUtils.rm_r work_dir
11
+ end
12
+
13
+ it 'raises an error unless question references are first resolved' do
14
+ expect { subject.write }.to raise_exception
15
+ end
16
+
17
+ it 'creates the assessment meta file' do
18
+
19
+ assessment.identifier = 'someidthing'
20
+ assessment.title = 'assersemurnt'
21
+ assessment.description = 'this is a bunch of description'
22
+ assessment.lock_at = Time.parse('Sat, 08 Feb 2014 17:00:00 GMT')
23
+ assessment.unlock_at = Time.parse('Sat, 08 Feb 2014 18:00:00 GMT')
24
+ assessment.time_limit = '12'
25
+ assessment.allowed_attempts = '13'
26
+ assessment.scoring_policy = '14'
27
+ assessment.access_code = 'tired of counting'
28
+ assessment.ip_filter = '42.42.42.42'
29
+ assessment.shuffle_answers = "every day i'm shuffling answers"
30
+ assessment.quiz_type = 'the best kind of quiz'
31
+
32
+ assessment.items = []
33
+ subject.write
34
+
35
+ xml = Nokogiri::XML(File.read(File.join(work_dir, assessment.meta_file_path)))
36
+
37
+ expect(xml.root.attributes['schemaLocation'].value).to eq "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd"
38
+ expect(xml.namespaces['xmlns:xsi']).to eq "http://www.w3.org/2001/XMLSchema-instance"
39
+ expect(xml.namespaces['xmlns']).to eq "http://canvas.instructure.com/xsd/cccv1p0"
40
+
41
+ root = xml.at_xpath('xmlns:quiz')
42
+ expect(root.attributes['identifier'].value).to eq assessment.identifier
43
+ expect(root.%('title').text).to eq assessment.title
44
+ expect(root.%('description').text).to eq assessment.description
45
+ expect(root.%('lock_at').text).to eq '2014-02-08T17:00:00'
46
+ expect(root.%('unlock_at').text).to eq '2014-02-08T18:00:00'
47
+ expect(root.%('time_limit').text).to eq assessment.time_limit
48
+ expect(root.%('allowed_attempts').text).to eq assessment.allowed_attempts
49
+ expect(root.%('scoring_policy').text).to eq assessment.scoring_policy
50
+ expect(root.%('access_code').text).to eq assessment.access_code
51
+ expect(root.%('ip_filter').text).to eq assessment.ip_filter
52
+ expect(root.%('shuffle_answers').text).to eq assessment.shuffle_answers
53
+ expect(root.%('quiz_type').text).to eq assessment.quiz_type
54
+ end
55
+
56
+ it 'creates the assessment qti file' do
57
+ assessment.identifier = 'someidthing'
58
+ assessment.title = 'assersemurnt'
59
+ assessment.time_limit = 10
60
+ assessment.allowed_attempts = 2
61
+
62
+ question = CanvasCc::CanvasCC::Models::Question.new
63
+ question.identifier = 42
64
+ assessment.items = [question]
65
+
66
+ QuestionWriter.register_writer_type(nil)
67
+ QuestionWriter.stub(:write_responses)
68
+ QuestionWriter.stub(:write_response_conditions)
69
+
70
+ subject.write
71
+
72
+ xml = Nokogiri::XML(File.read(File.join(work_dir, assessment.qti_file_path)))
73
+
74
+ expect(xml.root.attributes['schemaLocation'].value).to eq "http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd"
75
+ expect(xml.namespaces['xmlns:xsi']).to eq "http://www.w3.org/2001/XMLSchema-instance"
76
+ expect(xml.namespaces['xmlns']).to eq "http://www.imsglobal.org/xsd/ims_qtiasiv1p2"
77
+
78
+ root = xml.at_xpath('xmlns:questestinterop')
79
+ expect(root).to_not be_nil
80
+ expect(root.%('assessment').attributes['ident'].value).to eq assessment.identifier
81
+ expect(root.%('assessment').attributes['title'].value).to eq assessment.title
82
+
83
+ meta_fields = root.search('assessment/qtimetadata/qtimetadatafield')
84
+ expect(meta_fields[0].%('fieldlabel').text).to eq 'qmd_timelimit'
85
+ expect(meta_fields[0].%('fieldentry').text).to eq assessment.time_limit.to_s
86
+ expect(meta_fields[1].%('fieldlabel').text).to eq 'cc_maxattempts'
87
+ expect(meta_fields[1].%('fieldentry').text).to eq assessment.allowed_attempts.to_s
88
+
89
+ section = root.%('assessment/section')
90
+ expect(section.attributes['ident'].value).to eq 'root_section'
91
+ expect(section.%('item').attributes['ident'].value).to eq question.identifier.to_s
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe AssignmentGroupWriter do
5
+
6
+ let(:assignment_group) { CanvasCc::CanvasCC::Models::AssignmentGroup.new }
7
+ let(:tmpdir) { Dir.mktmpdir }
8
+
9
+ before :each do
10
+ Dir.mkdir(File.join(tmpdir, CartridgeCreator::COURSE_SETTINGS_DIR))
11
+ end
12
+
13
+ after :each do
14
+ FileUtils.rm_r tmpdir
15
+ end
16
+
17
+ it 'xml contains the correct schema' do
18
+ xml = write_xml(assignment_group)
19
+
20
+ valid_schema = File.read(fixture_path(File.join('common_cartridge', 'schema', 'cccv1p0.xsd')))
21
+ xsd = Nokogiri::XML::Schema(valid_schema)
22
+ expect(xsd.validate(xml)).to be_true
23
+ end
24
+
25
+ it 'adds assignment group' do
26
+ assignment_group.identifier = 'identifier'
27
+ assignment_group.title = 'title'
28
+ assignment_group.position = '1'
29
+ assignment_group.group_weight = '1'
30
+ assignment_group.rules << {b:2, c:3}
31
+ xml = write_xml(assignment_group)
32
+ expect(xml.at_xpath('/xmlns:assignmentGroups/xmlns:assignmentGroup/@identifier').text).to eq(assignment_group.identifier)
33
+ expect(xml.at_xpath('/xmlns:assignmentGroups/xmlns:assignmentGroup/xmlns:title').text).to eq(assignment_group.title)
34
+ expect(xml.at_xpath('/xmlns:assignmentGroups/xmlns:assignmentGroup/xmlns:position').text).to eq(assignment_group.position)
35
+ expect(xml.at_xpath('/xmlns:assignmentGroups/xmlns:assignmentGroup/xmlns:group_weight').text).to eq(assignment_group.group_weight)
36
+ expect(xml.at_xpath('/xmlns:assignmentGroups/xmlns:assignmentGroup/xmlns:rules/xmlns:rule/xmlns:b').text).to eq "2"
37
+ expect(xml.at_xpath('/xmlns:assignmentGroups/xmlns:assignmentGroup/xmlns:rules/xmlns:rule/xmlns:c').text).to eq "3"
38
+ end
39
+
40
+ private
41
+
42
+ def write_xml(assignment_group)
43
+ AssignmentGroupWriter.new(tmpdir, [assignment_group]).write
44
+ path = File.join(tmpdir,
45
+ CartridgeCreator::COURSE_SETTINGS_DIR,
46
+ AssignmentGroupWriter::ASSIGNMENT_GROUP_FILE)
47
+ Nokogiri::XML(File.read(path))
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe CanvasCc::CanvasCC::AssignmentWriter do
4
+ subject { CanvasCc::CanvasCC::AssignmentWriter.new(work_dir, assignment) }
5
+ let(:work_dir) { Dir.mktmpdir }
6
+ let(:assignment) { CanvasCc::CanvasCC::Models::Assignment.new }
7
+
8
+ after(:each) do
9
+ FileUtils.rm_r work_dir
10
+ end
11
+
12
+ it 'creates the assignment settings xml' do
13
+ assignment.identifier = 'assignment_id'
14
+ assignment.title = 'Assignment Title'
15
+ assignment.due_at = Time.parse('Sat, 08 Feb 2014 16:00:00 GMT')
16
+ assignment.lock_at = Time.parse('Sat, 08 Feb 2014 17:00:00 GMT')
17
+ assignment.unlock_at = Time.parse('Sat, 08 Feb 2014 18:00:00 GMT')
18
+ assignment.peer_reviews_due_at = Time.parse('Sat, 08 Feb 2014 19:00:00 GMT')
19
+ assignment.all_day_date = Time.parse('Sat, 08 Feb 2014 00:00:00 GMT')
20
+ assignment.assignment_group_identifier_ref = 'assignment_group_id'
21
+ assignment.workflow_state = 'active'
22
+ assignment.points_possible = '30'
23
+ assignment.grading_type = 'points'
24
+ assignment.all_day = 'true'
25
+ assignment.submission_types = %w(online_text_entry online_url online_upload)
26
+ assignment.position = '2'
27
+ assignment.peer_review_count = '0'
28
+ assignment.peer_reviews_assigned = 'false'
29
+ assignment.peer_reviews = 'false'
30
+ assignment.automatic_peer_reviews = 'true'
31
+ assignment.grade_group_students_individually = 'false'
32
+ assignment.muted = true
33
+
34
+ subject.write
35
+ xml = Nokogiri::XML(File.read(File.join(work_dir, assignment.assignment_resource.files.select{ |f| f.split(//).last(4).join("").to_s == '.xml'}.first)))
36
+ expect(xml.at_xpath('xmlns:assignment/@identifier').value).to eq('assignment_id')
37
+ expect(xml.%('assignment/title').text).to eq 'Assignment Title'
38
+ expect(xml.%('assignment/due_at').text).to eq '2014-02-08T16:00:00'
39
+ expect(xml.%('assignment/lock_at').text).to eq '2014-02-08T17:00:00'
40
+ expect(xml.%('assignment/unlock_at').text).to eq '2014-02-08T18:00:00'
41
+ expect(xml.%('assignment/all_day_date').text).to eq '2014-02-08T00:00:00'
42
+ expect(xml.%('assignment/peer_reviews_due_at').text).to eq '2014-02-08T19:00:00'
43
+ expect(xml.%('assignment/assignment_group_identifierref').text).to eq 'assignment_group_id'
44
+ expect(xml.%('assignment/workflow_state').text).to eq 'active'
45
+ expect(xml.%('assignment/points_possible').text).to eq '30'
46
+ expect(xml.%('assignment/grading_type').text).to eq 'points'
47
+ expect(xml.%('assignment/all_day').text).to eq 'true'
48
+ expect(xml.%('assignment/submission_types').text).to eq 'online_text_entry,online_url,online_upload'
49
+ expect(xml.%('assignment/position').text).to eq '2'
50
+ expect(xml.%('assignment/peer_review_count').text).to eq '0'
51
+ expect(xml.%('assignment/peer_reviews_assigned').text).to eq 'false'
52
+ expect(xml.%('assignment/peer_reviews').text).to eq 'false'
53
+ expect(xml.%('assignment/automatic_peer_reviews').text).to eq 'true'
54
+ expect(xml.%('assignment/grade_group_students_individually').text).to eq 'false'
55
+ expect(xml.%('assignment/muted').text).to eq 'true'
56
+
57
+ end
58
+
59
+ it 'creates the assignment html' do
60
+ assignment.identifier = 'assignment_id'
61
+ assignment.title = 'Assignment Title'
62
+ assignment.body = '<p>My Body Content</p>'
63
+
64
+ subject.write
65
+ html = Nokogiri::HTML(File.read(File.join(work_dir, assignment.assignment_resource.href)))
66
+
67
+ expect(html.at_css('meta[http-equiv]')[:'http-equiv']).to eq 'Content-Type'
68
+ expect(html.at_css('meta[http-equiv]')[:content]).to eq 'text/html; charset=utf-8'
69
+ expect(html.at_css('title').text).to eq 'Assignment: Assignment Title'
70
+ expect(html.at_css('body').inner_html.to_s).to eq '<p>My Body Content</p>'
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe CalculatedQuestionWriter do
5
+
6
+ let(:question) { CanvasCc::CanvasCC::Models::Question.create('calculated_question')}
7
+
8
+ it 'creates the question item xml for a calculated question' do
9
+ question.identifier = 42
10
+ question.title = 'hi title'
11
+ question.general_feedback = 'unconstructive feedback'
12
+ question.material = 'materlia'
13
+
14
+ question.correct_answer_format = '1'
15
+ question.correct_answer_length = '2'
16
+ question.tolerance = '0.01'
17
+
18
+ answer = CanvasCc::CanvasCC::Models::Answer.new
19
+ answer.answer_text = '{A}*{B}'
20
+ answer.fraction = 1
21
+ question.answers = [answer]
22
+
23
+ question.dataset_definitions = [
24
+ {
25
+ :name => 'A',
26
+ :options => 'uniform:1.0:10.0:1'
27
+ },
28
+ {
29
+ :name => 'B',
30
+ :options => 'uniform:10.0:20.0:1'
31
+ }
32
+ ]
33
+
34
+ question.var_sets = [{:ident => '1', :vars => {'A' => '3.6', 'B' => '3.1'}}]
35
+
36
+ xml = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |node|
37
+ QuestionWriter.write_question(node, question)
38
+ end.doc
39
+
40
+ expect(xml.at_xpath('item/@ident').value).to eq question.identifier.to_s
41
+ expect(xml.at_xpath('item/@title').value).to eq question.title
42
+ expect(xml.at_xpath("item/itemmetadata/qtimetadata/qtimetadatafield[fieldlabel=\"question_type\" and fieldentry=\"#{question.question_type}\"]")).to_not be_nil
43
+
44
+ response = xml.at_xpath('item/presentation/response_str')
45
+ expect(response.attributes['rcardinality'].value).to eq 'Single'
46
+ expect(response.attributes['ident'].value).to eq 'response1'
47
+ expect(response.at_xpath('render_fib').attributes['fibtype'].value).to eq 'Decimal'
48
+ expect(response.at_xpath('render_fib/response_label').attributes['ident'].value).to eq 'answer1'
49
+
50
+ # Correct Condition
51
+ condition = xml.root.at_xpath('resprocessing/respcondition[@title="correct"]')
52
+ expect(condition.at_xpath('conditionvar/other')).to_not be_nil
53
+ setvar = condition.at_xpath('setvar')
54
+ expect(setvar.text).to eq '100'
55
+ expect(setvar.attributes['varname'].value).to eq 'SCORE'
56
+ expect(setvar.attributes['action'].value).to eq 'Set'
57
+
58
+ condition = xml.root.at_xpath('resprocessing/respcondition[@title="incorrect"]')
59
+ expect(condition.at_xpath('conditionvar/other')).to_not be_nil
60
+ setvar = condition.at_xpath('setvar')
61
+ expect(setvar.text).to eq '0'
62
+ expect(setvar.attributes['varname'].value).to eq 'SCORE'
63
+ expect(setvar.attributes['action'].value).to eq 'Set'
64
+
65
+ # Calculations
66
+ calculated = xml.root.at_xpath('itemproc_extension/calculated')
67
+ expect(calculated.at_xpath('answer_tolerance').text).to eq question.tolerance
68
+
69
+ # Formulas
70
+ expect(calculated.at_xpath('formulas[@decimal_places="2"]')).to_not be_nil
71
+ expect(calculated.at_xpath('formulas/formula["A*B"]')).to_not be_nil
72
+
73
+ # Var
74
+ a_var = calculated.at_xpath('vars/var[@scale="1"][@name="A"]')
75
+ expect(a_var.at_xpath('min').text).to eq '1.0'
76
+ expect(a_var.at_xpath('max').text).to eq '10.0'
77
+
78
+ b_var = calculated.at_xpath('vars/var[@scale="1"][@name="B"]')
79
+ expect(b_var.at_xpath('min').text).to eq '10.0'
80
+ expect(b_var.at_xpath('max').text).to eq '20.0'
81
+
82
+ # Var sets
83
+ var_set = calculated.at_xpath('var_sets/var_set[@ident="3631"]')
84
+ expect(var_set.at_xpath('var[@name="A"]').text).to eq "3.6"
85
+ expect(var_set.at_xpath('var[@name="B"]').text).to eq "3.1"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe CanvasExportWriter do
5
+
6
+ subject { CanvasExportWriter.new(tmpdir) }
7
+ let(:tmpdir) { Dir.mktmpdir }
8
+
9
+ before :each do
10
+ Dir.mkdir(File.join(tmpdir, CartridgeCreator::COURSE_SETTINGS_DIR))
11
+ end
12
+
13
+ after :each do
14
+ FileUtils.rm_r tmpdir
15
+ end
16
+
17
+ it "writes to the export file" do
18
+ subject.write
19
+ path = File.join(tmpdir,
20
+ CartridgeCreator::COURSE_SETTINGS_DIR,
21
+ CanvasExportWriter::CANVAS_EXPORT_FILE)
22
+ expect(File.exist?(path)).to be_true
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module CanvasCc::CanvasCC
4
+ describe CartridgeCreator do
5
+ subject { CartridgeCreator.new(course) }
6
+
7
+ let(:tmpdir) { Dir.mktmpdir }
8
+ let(:course) { Models::Course.new }
9
+
10
+ before :each do
11
+ course.identifier = 'setting'
12
+ course.title = 'My Course'
13
+ course.canvas_modules << Models::CanvasModule.new
14
+
15
+ CanvasExportWriter.any_instance.stub(:write)
16
+ CourseSettingWriter.any_instance.stub(:write)
17
+ ModuleMetaWriter.any_instance.stub(:write)
18
+ ImsManifestGenerator.any_instance.stub(:write)
19
+ FileMetaWriter.any_instance.stub(:write)
20
+ PageWriter.any_instance.stub(:write)
21
+ DiscussionWriter.any_instance.stub(:write)
22
+ AssignmentWriter.any_instance.stub(:write)
23
+ QuestionBankWriter.any_instance.stub(:write)
24
+ end
25
+
26
+ after :each do
27
+ FileUtils.rm_r tmpdir
28
+ end
29
+
30
+ [CanvasExportWriter, CourseSettingWriter, ModuleMetaWriter, ImsManifestGenerator,
31
+ FileMetaWriter, PageWriter, DiscussionWriter, AssignmentWriter, QuestionBankWriter].each do |klass|
32
+ it "writes #{klass}" do
33
+ writer_double = double(write: nil)
34
+ klass.stub(:new).and_return(writer_double)
35
+ subject.create(tmpdir)
36
+ expect(writer_double).to have_received(:write)
37
+ end
38
+ end
39
+
40
+ describe 'filename' do
41
+ ['My Stuff', 'my/stuff', 'my.stuff', 'my-stuff', 'my--stuff', 'my---stuff', 'my-./stuff'].each do |title|
42
+ it "with course title: #{title}" do
43
+ course.title = title
44
+ expect(subject.filename).to eq('my_stuff.imscc')
45
+ end
46
+ end
47
+ end
48
+
49
+ end
50
+ end