moodle2cc 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.
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/Guardfile +14 -0
- data/LICENSE +661 -0
- data/README.md +38 -0
- data/Rakefile +12 -0
- data/bin/moodle2cc +6 -0
- data/lib/moodle2cc.rb +60 -0
- data/lib/moodle2cc/canvas/.converter.rb.swo +0 -0
- data/lib/moodle2cc/canvas/.wiki.rb.swo +0 -0
- data/lib/moodle2cc/canvas/assessment.rb +109 -0
- data/lib/moodle2cc/canvas/assignment.rb +108 -0
- data/lib/moodle2cc/canvas/converter.rb +28 -0
- data/lib/moodle2cc/canvas/course.rb +145 -0
- data/lib/moodle2cc/canvas/discussion_topic.rb +64 -0
- data/lib/moodle2cc/canvas/label.rb +8 -0
- data/lib/moodle2cc/canvas/question.rb +468 -0
- data/lib/moodle2cc/canvas/question_bank.rb +54 -0
- data/lib/moodle2cc/canvas/resource.rb +16 -0
- data/lib/moodle2cc/canvas/templates/assignment.html.erb +9 -0
- data/lib/moodle2cc/canvas/templates/syllabus.html.erb +9 -0
- data/lib/moodle2cc/canvas/templates/wiki_content.html.erb +10 -0
- data/lib/moodle2cc/canvas/web_content.rb +10 -0
- data/lib/moodle2cc/canvas/web_link.rb +17 -0
- data/lib/moodle2cc/canvas/wiki.rb +25 -0
- data/lib/moodle2cc/cc/assessment.rb +25 -0
- data/lib/moodle2cc/cc/assignment.rb +66 -0
- data/lib/moodle2cc/cc/cc_helper.rb +282 -0
- data/lib/moodle2cc/cc/converter.rb +136 -0
- data/lib/moodle2cc/cc/course.rb +16 -0
- data/lib/moodle2cc/cc/discussion_topic.rb +53 -0
- data/lib/moodle2cc/cc/label.rb +6 -0
- data/lib/moodle2cc/cc/question.rb +23 -0
- data/lib/moodle2cc/cc/resource.rb +30 -0
- data/lib/moodle2cc/cc/templates/assignment.html.erb +9 -0
- data/lib/moodle2cc/cc/templates/syllabus.html.erb +9 -0
- data/lib/moodle2cc/cc/templates/wiki_content.html.erb +10 -0
- data/lib/moodle2cc/cc/web_content.rb +40 -0
- data/lib/moodle2cc/cc/web_link.rb +53 -0
- data/lib/moodle2cc/cc/wiki.rb +72 -0
- data/lib/moodle2cc/cli.rb +14 -0
- data/lib/moodle2cc/error.rb +3 -0
- data/lib/moodle2cc/migrator.rb +23 -0
- data/lib/moodle2cc/moodle/backup.rb +38 -0
- data/lib/moodle2cc/moodle/course.rb +24 -0
- data/lib/moodle2cc/moodle/grade_item.rb +24 -0
- data/lib/moodle2cc/moodle/info.rb +8 -0
- data/lib/moodle2cc/moodle/mod.rb +127 -0
- data/lib/moodle2cc/moodle/question.rb +98 -0
- data/lib/moodle2cc/moodle/question_category.rb +17 -0
- data/lib/moodle2cc/moodle/section.rb +37 -0
- data/lib/moodle2cc/resource_factory.rb +32 -0
- data/lib/moodle2cc/version.rb +3 -0
- data/moodle2cc.gemspec +29 -0
- data/test/acceptance/migrator_test.rb +23 -0
- data/test/fixtures/cc.imscc +0 -0
- data/test/fixtures/moodle_backup/course_files/folder/test.txt +1 -0
- data/test/fixtures/moodle_backup/course_files/test.txt +1 -0
- data/test/fixtures/moodle_backup/moodle.xml +916 -0
- data/test/test_helper.rb +43 -0
- data/test/test_question_helper.rb +107 -0
- data/test/test_wiki_helper.rb +21 -0
- data/test/unit/canvas/assessment_test.rb +218 -0
- data/test/unit/canvas/assignment_test.rb +220 -0
- data/test/unit/canvas/converter_test.rb +159 -0
- data/test/unit/canvas/course_test.rb +176 -0
- data/test/unit/canvas/discussion_topic_test.rb +129 -0
- data/test/unit/canvas/label_test.rb +32 -0
- data/test/unit/canvas/question_bank_test.rb +73 -0
- data/test/unit/canvas/question_test.rb +824 -0
- data/test/unit/canvas/web_content_test.rb +37 -0
- data/test/unit/canvas/web_link_test.rb +48 -0
- data/test/unit/canvas/wiki_test.rb +74 -0
- data/test/unit/cc/assessment_test.rb +48 -0
- data/test/unit/cc/assignment_test.rb +67 -0
- data/test/unit/cc/cc_helper_test.rb +19 -0
- data/test/unit/cc/converter_test.rb +159 -0
- data/test/unit/cc/course_test.rb +36 -0
- data/test/unit/cc/discussion_topic_test.rb +83 -0
- data/test/unit/cc/label_test.rb +29 -0
- data/test/unit/cc/question_test.rb +49 -0
- data/test/unit/cc/web_content_test.rb +76 -0
- data/test/unit/cc/web_link_test.rb +79 -0
- data/test/unit/cc/wiki_test.rb +139 -0
- data/test/unit/migrator_test.rb +56 -0
- data/test/unit/moodle/backup_test.rb +30 -0
- data/test/unit/moodle/course_test.rb +57 -0
- data/test/unit/moodle/grade_item_test.rb +72 -0
- data/test/unit/moodle/info_test.rb +21 -0
- data/test/unit/moodle/mod_test.rb +301 -0
- data/test/unit/moodle/question_category_test.rb +34 -0
- data/test/unit/moodle/question_test.rb +185 -0
- data/test/unit/moodle/section_test.rb +75 -0
- data/test/unit/resource_factory_test.rb +119 -0
- metadata +342 -0
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'zip/zipfilesystem'
|
|
2
|
+
|
|
3
|
+
module TestHelper
|
|
4
|
+
def create_moodle_backup_zip
|
|
5
|
+
moodle_backup_path = File.expand_path("../tmp/moodle_backup.zip", __FILE__)
|
|
6
|
+
Zip::ZipFile.open(moodle_backup_path, Zip::ZipFile::CREATE) do |zipfile|
|
|
7
|
+
zipfile.add("moodle.xml", File.expand_path("../fixtures/moodle_backup/moodle.xml", __FILE__))
|
|
8
|
+
zipfile.mkdir("course_files")
|
|
9
|
+
zipfile.mkdir("course_files/folder")
|
|
10
|
+
zipfile.add("course_files/test.txt", File.expand_path("../fixtures/moodle_backup/course_files/test.txt", __FILE__))
|
|
11
|
+
zipfile.add("course_files/folder/test.txt", File.expand_path("../fixtures/moodle_backup/course_files/folder/test.txt", __FILE__))
|
|
12
|
+
end
|
|
13
|
+
moodle_backup_path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def convert_moodle_backup(format='cc')
|
|
17
|
+
raise "must be 'cc' or 'canvas'" unless ['cc', 'canvas'].include?(format)
|
|
18
|
+
converter_class = format == 'cc' ? Moodle2CC::CC::Converter : Moodle2CC::Canvas::Converter
|
|
19
|
+
@backup_path = create_moodle_backup_zip
|
|
20
|
+
@backup = Moodle2CC::Moodle::Backup.read @backup_path
|
|
21
|
+
@export_dir = File.expand_path("../tmp", __FILE__)
|
|
22
|
+
@converter = converter_class.new @backup, @export_dir
|
|
23
|
+
@converter.convert
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_imsmanifest_xml
|
|
27
|
+
Zip::ZipFile.open(@converter.imscc_path) do |zipfile|
|
|
28
|
+
xml = Nokogiri::XML(zipfile.read("imsmanifest.xml"))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_imscc_file(file)
|
|
33
|
+
Zip::ZipFile.open(@converter.imscc_path) do |zipfile|
|
|
34
|
+
zipfile.read(file)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clean_tmp_folder
|
|
39
|
+
Dir[File.expand_path("../tmp/*", __FILE__)].each do |file|
|
|
40
|
+
FileUtils.rm_r file
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module TestQuestionHelper
|
|
2
|
+
def match_question!
|
|
3
|
+
@question.type = 'match'
|
|
4
|
+
|
|
5
|
+
match1 = Moodle2CC::Moodle::Question::Match.new
|
|
6
|
+
match1.code = 123
|
|
7
|
+
match1.question_text = 'Ruby on Rails is written in this language'
|
|
8
|
+
match1.answer_text = 'Ruby'
|
|
9
|
+
|
|
10
|
+
match2 = Moodle2CC::Moodle::Question::Match.new
|
|
11
|
+
match2.code = 234
|
|
12
|
+
match2.question_text = ''
|
|
13
|
+
match2.answer_text = 'Python'
|
|
14
|
+
|
|
15
|
+
match3 = Moodle2CC::Moodle::Question::Match.new
|
|
16
|
+
match3.code = 345
|
|
17
|
+
match3.question_text = 'Files with .coffee extension use which language?'
|
|
18
|
+
match3.answer_text = 'CoffeeScript'
|
|
19
|
+
|
|
20
|
+
@question.matches = [match1, match2, match3]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def multiple_choice_question!
|
|
24
|
+
@question.type = 'multichoice'
|
|
25
|
+
|
|
26
|
+
answer1 = Moodle2CC::Moodle::Question::Answer.new
|
|
27
|
+
answer1.id = 123
|
|
28
|
+
answer1.text = 'Ruby'
|
|
29
|
+
answer1.fraction = 1
|
|
30
|
+
answer1.feedback = 'Yippee!'
|
|
31
|
+
|
|
32
|
+
answer2 = Moodle2CC::Moodle::Question::Answer.new
|
|
33
|
+
answer2.id = 234
|
|
34
|
+
answer2.text = 'CoffeeScript'
|
|
35
|
+
answer2.fraction = 0.75
|
|
36
|
+
answer2.feedback = 'Nope'
|
|
37
|
+
|
|
38
|
+
answer3 = Moodle2CC::Moodle::Question::Answer.new
|
|
39
|
+
answer3.id = 345
|
|
40
|
+
answer3.text = 'Java'
|
|
41
|
+
answer3.fraction = 0.25
|
|
42
|
+
answer3.feedback = 'No way'
|
|
43
|
+
|
|
44
|
+
answer4 = Moodle2CC::Moodle::Question::Answer.new
|
|
45
|
+
answer4.id = 456
|
|
46
|
+
answer4.text = 'Clojure'
|
|
47
|
+
answer4.fraction = 0
|
|
48
|
+
answer4.feedback = 'Not even close'
|
|
49
|
+
|
|
50
|
+
@question.answers = [answer1, answer2, answer3, answer4]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def multiple_dropdowns_question!
|
|
54
|
+
@question.type = nil
|
|
55
|
+
@question.type_id = 8 # rate 1..5 question
|
|
56
|
+
@question.length = 3
|
|
57
|
+
@question.text = nil
|
|
58
|
+
@question.content = "This is a rating question"
|
|
59
|
+
choice1 = Moodle2CC::Moodle::Question::Choice.new
|
|
60
|
+
choice1.id = 1
|
|
61
|
+
choice1.content = '1=Almost Never'
|
|
62
|
+
choice2 = Moodle2CC::Moodle::Question::Choice.new
|
|
63
|
+
choice2.id = 2
|
|
64
|
+
choice2.content = '2=Sometimes'
|
|
65
|
+
choice3 = Moodle2CC::Moodle::Question::Choice.new
|
|
66
|
+
choice3.id = 3
|
|
67
|
+
choice3.content = '3=Always'
|
|
68
|
+
choice4 = Moodle2CC::Moodle::Question::Choice.new
|
|
69
|
+
choice4.id = 4
|
|
70
|
+
choice4.content = 'I test my code'
|
|
71
|
+
choice5 = Moodle2CC::Moodle::Question::Choice.new
|
|
72
|
+
choice5.id = 5
|
|
73
|
+
choice5.content = 'I am happy'
|
|
74
|
+
@question.choices = [choice1, choice2, choice3, choice4, choice5]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def multiple_answers_question!
|
|
78
|
+
@question.type = nil
|
|
79
|
+
@question.type_id = 5 # check boxes question
|
|
80
|
+
@question.length = 3
|
|
81
|
+
@question.text = nil
|
|
82
|
+
@question.content = "What are your favorite languages?"
|
|
83
|
+
choice1 = Moodle2CC::Moodle::Question::Choice.new
|
|
84
|
+
choice1.id = 1
|
|
85
|
+
choice1.content = 'Ruby'
|
|
86
|
+
choice2 = Moodle2CC::Moodle::Question::Choice.new
|
|
87
|
+
choice2.id = 2
|
|
88
|
+
choice2.content = 'Javascript'
|
|
89
|
+
choice3 = Moodle2CC::Moodle::Question::Choice.new
|
|
90
|
+
choice3.id = 3
|
|
91
|
+
choice3.content = 'Python'
|
|
92
|
+
choice4 = Moodle2CC::Moodle::Question::Choice.new
|
|
93
|
+
@question.choices = [choice1, choice2, choice3]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def numerical_question!
|
|
97
|
+
@question = @mod.questions.find { |q| q.type == 'numerical' }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def short_answer_question!
|
|
101
|
+
@question = @mod.questions.find { |q| q.type == 'shortanswer' }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def true_false_question!
|
|
105
|
+
@question = @mod.questions.find { |q| q.type == 'truefalse' }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module TestWikiHelper
|
|
2
|
+
def pages!
|
|
3
|
+
@page1 = Moodle2CC::Moodle::Mod::Page.new
|
|
4
|
+
@page1.page_name = 'My Wiki'
|
|
5
|
+
@page1.version = 1
|
|
6
|
+
@page1.content = 'First version'
|
|
7
|
+
|
|
8
|
+
@page2 = Moodle2CC::Moodle::Mod::Page.new
|
|
9
|
+
@page2.page_name = 'My Wiki'
|
|
10
|
+
@page2.version = 2
|
|
11
|
+
@page2.content = 'Second version'
|
|
12
|
+
|
|
13
|
+
@page3 = Moodle2CC::Moodle::Mod::Page.new
|
|
14
|
+
@page3.page_name = 'New Page'
|
|
15
|
+
@page3.version = 1
|
|
16
|
+
@page3.content = 'This is a link to [My Wiki]'
|
|
17
|
+
|
|
18
|
+
@mod.page_name = 'My Wiki'
|
|
19
|
+
@mod.pages = [@page1, @page2, @page3]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
require 'minitest/autorun'
|
|
2
|
+
require 'test/test_helper'
|
|
3
|
+
require 'moodle2cc'
|
|
4
|
+
|
|
5
|
+
class TestUnitCanvasAssessment < MiniTest::Unit::TestCase
|
|
6
|
+
include TestHelper
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
convert_moodle_backup('canvas')
|
|
10
|
+
@mod = @backup.course.mods.find { |m| m.mod_type == "quiz" }
|
|
11
|
+
@assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def teardown
|
|
15
|
+
clean_tmp_folder
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_it_inherits_from_cc
|
|
19
|
+
assert Moodle2CC::Canvas::Assessment.ancestors.include?(Moodle2CC::CC::Assessment), 'does not inherit from base CC class'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_it_converts_description_from_intro
|
|
23
|
+
@mod.intro = %(<h1>Hello World</h1><img src="$@FILEPHP@$$@SLASH@$folder$@SLASH@$stuff.jpg" />)
|
|
24
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
25
|
+
assert_equal %(<h1>Hello World</h1><img src="$IMS_CC_FILEBASE$/folder/stuff.jpg" />), assessment.description
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_it_converts_description_from_content
|
|
29
|
+
@mod.intro = nil
|
|
30
|
+
@mod.content = %(<h1>Hello World</h1><img src="$@FILEPHP@$$@SLASH@$folder$@SLASH@$stuff.jpg" />)
|
|
31
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
32
|
+
assert_equal %(<h1>Hello World</h1><img src="$IMS_CC_FILEBASE$/folder/stuff.jpg" />), assessment.description
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_it_converts_description_from_text
|
|
36
|
+
@mod.intro = nil
|
|
37
|
+
@mod.content = nil
|
|
38
|
+
@mod.text = %(<h1>Hello World</h1><img src="$@FILEPHP@$$@SLASH@$folder$@SLASH@$stuff.jpg" />)
|
|
39
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
40
|
+
assert_equal %(<h1>Hello World</h1><img src="$IMS_CC_FILEBASE$/folder/stuff.jpg" />), assessment.description
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_it_converts_description_from_summary
|
|
44
|
+
@mod.intro = nil
|
|
45
|
+
@mod.content = nil
|
|
46
|
+
@mod.text = nil
|
|
47
|
+
@mod.summary = %(<h1>Hello World</h1><img src="$@FILEPHP@$$@SLASH@$folder$@SLASH@$stuff.jpg" />)
|
|
48
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
49
|
+
assert_equal %(<h1>Hello World</h1><img src="$IMS_CC_FILEBASE$/folder/stuff.jpg" />), assessment.description
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_it_converts_lock_at
|
|
53
|
+
@mod.time_close = Time.parse("2012/12/12 12:12:12 +0000").to_i
|
|
54
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
55
|
+
assert_equal '2012-12-12T12:12:12', assessment.lock_at
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_it_converts_unlock_at
|
|
59
|
+
@mod.time_open = Time.parse("2012/12/12 12:12:12 +0000").to_i
|
|
60
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
61
|
+
assert_equal '2012-12-12T12:12:12', assessment.unlock_at
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_it_converts_time_limit
|
|
65
|
+
@mod.time_limit = 45
|
|
66
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
67
|
+
assert_equal 45, assessment.time_limit
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_it_converts_allowed_attempts
|
|
71
|
+
@mod.attempts_number = 2
|
|
72
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
73
|
+
assert_equal 2, assessment.allowed_attempts
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_it_converts_scoring_policy
|
|
77
|
+
@mod.grade_method = 1
|
|
78
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
79
|
+
assert_equal 'keep_highest', assessment.scoring_policy
|
|
80
|
+
|
|
81
|
+
@mod.grade_method = 2
|
|
82
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
83
|
+
assert_equal 'keep_highest', assessment.scoring_policy
|
|
84
|
+
|
|
85
|
+
@mod.grade_method = 3
|
|
86
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
87
|
+
assert_equal 'keep_highest', assessment.scoring_policy
|
|
88
|
+
|
|
89
|
+
@mod.grade_method = 4
|
|
90
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
91
|
+
assert_equal 'keep_latest', assessment.scoring_policy
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_it_converts_access_code
|
|
95
|
+
@mod.password = 'password'
|
|
96
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
97
|
+
assert_equal 'password', assessment.access_code
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_it_converts_ip_filter
|
|
101
|
+
@mod.subnet = '127.0.0.1'
|
|
102
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
103
|
+
assert_equal '127.0.0.1', assessment.ip_filter
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def test_it_converts_shuffle_answers
|
|
107
|
+
@mod.shuffle_answers = true
|
|
108
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
109
|
+
assert_equal true, assessment.shuffle_answers
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_it_converts_quiz_type
|
|
113
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
114
|
+
assert_equal 'practice_quiz', assessment.quiz_type
|
|
115
|
+
|
|
116
|
+
questionnaire_mod = @backup.course.mods.find { |mod| mod.mod_type == 'questionnaire' }
|
|
117
|
+
assessment = Moodle2CC::Canvas::Assessment.new questionnaire_mod
|
|
118
|
+
assert_equal 'survey', assessment.quiz_type
|
|
119
|
+
|
|
120
|
+
choice_mod = @backup.course.mods.find { |mod| mod.mod_type == 'choice' }
|
|
121
|
+
assessment = Moodle2CC::Canvas::Assessment.new choice_mod
|
|
122
|
+
assert_equal 'survey', assessment.quiz_type
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_it_has_a_non_cc_assessments_identifier
|
|
126
|
+
@mod.id = 321
|
|
127
|
+
assessment = Moodle2CC::Canvas::Assessment.new @mod
|
|
128
|
+
assert_equal 'ibe158496fef4c2255274cdf9113e1daf', assessment.non_cc_assessments_identifier
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_it_creates_resource_in_imsmanifest
|
|
132
|
+
node = Builder::XmlMarkup.new
|
|
133
|
+
xml = node.root do |root_node|
|
|
134
|
+
@assessment.create_resource_node(node)
|
|
135
|
+
end
|
|
136
|
+
xml = Nokogiri::XML(xml)
|
|
137
|
+
|
|
138
|
+
resource = xml.root.xpath('resource[@type="imsqti_xmlv1p2/imscc_xmlv1p1/assessment"]').first
|
|
139
|
+
assert resource, 'assessment resource does not exist for assessment'
|
|
140
|
+
assert_equal 'i058d7533a77712b6e7757b34e66df7fc', resource.attributes['identifier'].value
|
|
141
|
+
|
|
142
|
+
dependency = resource.xpath('dependency[@identifierref="ibe158496fef4c2255274cdf9113e1daf"]').first
|
|
143
|
+
assert dependency, 'assessment resource does not have dependency on learning-application-resource'
|
|
144
|
+
|
|
145
|
+
resource = xml.root.xpath('resource[@type="associatedcontent/imscc_xmlv1p1/learning-application-resource"]').first
|
|
146
|
+
assert resource, 'learning-application-resource does not exist for assessment'
|
|
147
|
+
assert_equal 'i058d7533a77712b6e7757b34e66df7fc/assessment_meta.xml', resource.attributes['href'].value
|
|
148
|
+
assert_equal 'ibe158496fef4c2255274cdf9113e1daf', resource.attributes['identifier'].value
|
|
149
|
+
|
|
150
|
+
file = resource.xpath('file[@href="i058d7533a77712b6e7757b34e66df7fc/assessment_meta.xml"]').first
|
|
151
|
+
assert file
|
|
152
|
+
|
|
153
|
+
file = resource.xpath('file[@href="non_cc_assessments/i058d7533a77712b6e7757b34e66df7fc.xml.qti"]').first
|
|
154
|
+
assert file
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_it_creates_item_in_module_meta
|
|
158
|
+
node = Builder::XmlMarkup.new
|
|
159
|
+
xml = Nokogiri::XML(@assessment.create_module_meta_item_node(node, 5))
|
|
160
|
+
|
|
161
|
+
assert_equal 'item', xml.root.name
|
|
162
|
+
assert_equal 'if474f80fb2019d59f25ff2a96c9aa381', xml.root.attributes['identifier'].value
|
|
163
|
+
assert_equal "First Quiz", xml.root.xpath('title').text
|
|
164
|
+
assert_equal '5', xml.root.xpath('position').text
|
|
165
|
+
assert_equal '', xml.root.xpath('new_tab').text
|
|
166
|
+
assert_equal '0', xml.root.xpath('indent').text
|
|
167
|
+
assert_equal 'Quiz', xml.root.xpath('content_type').text
|
|
168
|
+
assert_equal 'i058d7533a77712b6e7757b34e66df7fc', xml.root.xpath('identifierref').text
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_it_creates_assessment_meta_xml
|
|
172
|
+
tmp_dir = File.expand_path('../../../tmp', __FILE__)
|
|
173
|
+
@assessment.create_assessment_meta_xml(tmp_dir)
|
|
174
|
+
xml = Nokogiri::XML(File.read(File.join(tmp_dir, @assessment.identifier, 'assessment_meta.xml')))
|
|
175
|
+
|
|
176
|
+
assert xml
|
|
177
|
+
assert_equal "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd", xml.root.attributes['schemaLocation'].value
|
|
178
|
+
assert_equal "http://www.w3.org/2001/XMLSchema-instance", xml.namespaces['xmlns:xsi']
|
|
179
|
+
assert_equal "http://canvas.instructure.com/xsd/cccv1p0", xml.namespaces['xmlns']
|
|
180
|
+
assert_equal @assessment.identifier, xml.xpath('xmlns:quiz').first.attributes['identifier'].value
|
|
181
|
+
|
|
182
|
+
assert_equal 'First Quiz', xml.xpath('xmlns:quiz/xmlns:title').text
|
|
183
|
+
assert_equal 'Pop quiz hot shot', xml.xpath('xmlns:quiz/xmlns:description').text
|
|
184
|
+
assert_equal '2012-06-11T18:50:00', xml.xpath('xmlns:quiz/xmlns:unlock_at').text
|
|
185
|
+
assert_equal '2012-06-12T18:50:00', xml.xpath('xmlns:quiz/xmlns:lock_at').text
|
|
186
|
+
assert_equal '45', xml.xpath('xmlns:quiz/xmlns:time_limit').text
|
|
187
|
+
assert_equal '2', xml.xpath('xmlns:quiz/xmlns:allowed_attempts').text
|
|
188
|
+
assert_equal 'keep_highest', xml.xpath('xmlns:quiz/xmlns:scoring_policy').text
|
|
189
|
+
assert_equal 'password', xml.xpath('xmlns:quiz/xmlns:access_code').text
|
|
190
|
+
assert_equal '127.0.0.1', xml.xpath('xmlns:quiz/xmlns:ip_filter').text
|
|
191
|
+
assert_equal 'true', xml.xpath('xmlns:quiz/xmlns:shuffle_answers').text
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def test_it_creates_non_cc_qti_xml
|
|
195
|
+
tmp_dir = File.expand_path('../../../tmp', __FILE__)
|
|
196
|
+
@assessment.create_non_cc_qti_xml(tmp_dir)
|
|
197
|
+
xml = Nokogiri::XML(File.read(File.join(tmp_dir, 'non_cc_assessments', "#{@assessment.identifier}.xml.qti")))
|
|
198
|
+
|
|
199
|
+
assert xml
|
|
200
|
+
assert_equal "http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd", xml.root.attributes['schemaLocation'].value
|
|
201
|
+
assert_equal "http://www.w3.org/2001/XMLSchema-instance", xml.namespaces['xmlns:xsi']
|
|
202
|
+
assert_equal "http://www.imsglobal.org/xsd/ims_qtiasiv1p2", xml.namespaces['xmlns']
|
|
203
|
+
assert_equal 'questestinterop', xml.root.name
|
|
204
|
+
assert_equal @assessment.identifier, xml.root.xpath('xmlns:assessment').first.attributes['ident'].value
|
|
205
|
+
|
|
206
|
+
time_data = xml.root.xpath('xmlns:assessment/xmlns:qtimetadata/xmlns:qtimetadatafield[xmlns:fieldlabel="qmd_timelimit" and xmlns:fieldentry="45"]').first
|
|
207
|
+
assert time_data, 'qtimetadata does not exist for time limit'
|
|
208
|
+
|
|
209
|
+
time_data = xml.root.xpath('xmlns:assessment/xmlns:qtimetadata/xmlns:qtimetadatafield[xmlns:fieldlabel="cc_maxattempts" and xmlns:fieldentry="2"]').first
|
|
210
|
+
assert time_data, 'qtimetadata does not exist for max attempts'
|
|
211
|
+
|
|
212
|
+
section = xml.root.xpath('xmlns:assessment/xmlns:section[@ident="root_section"]').first
|
|
213
|
+
assert section, 'root sections node does not exist'
|
|
214
|
+
|
|
215
|
+
items = xml.root.xpath('xmlns:assessment/xmlns:section/xmlns:item')
|
|
216
|
+
assert_equal 5, items.length
|
|
217
|
+
end
|
|
218
|
+
end
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
require 'nokogiri'
|
|
2
|
+
require 'minitest/autorun'
|
|
3
|
+
require 'test/test_helper'
|
|
4
|
+
require 'moodle2cc'
|
|
5
|
+
|
|
6
|
+
class TestUnitCanvasAssignment < MiniTest::Unit::TestCase
|
|
7
|
+
include TestHelper
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
convert_moodle_backup('canvas')
|
|
11
|
+
@mod = @backup.course.mods.find { |m| m.mod_type == "assignment" }
|
|
12
|
+
@workshop_mod = @backup.course.mods.find { |m| m.mod_type == "workshop" }
|
|
13
|
+
@assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def teardown
|
|
17
|
+
clean_tmp_folder
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_it_inherits_from_cc
|
|
21
|
+
assert Moodle2CC::Canvas::Assignment.ancestors.include?(Moodle2CC::CC::Assignment), 'does not inherit from base CC class'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_it_converts_assignment_group_identifierref
|
|
25
|
+
@mod.section_mod.section.id = 987
|
|
26
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
27
|
+
assert_equal 'ie9418dcb7e475d6f4676915b0e72f0c7', assignment.assignment_group_identifierref
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_it_converts_points_possible
|
|
31
|
+
grade_item = @mod.grade_item
|
|
32
|
+
grade_item.grade_max = 187
|
|
33
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
34
|
+
assert_equal 187, assignment.points_possible
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_it_converts_grading_type
|
|
38
|
+
assert_equal 'points', @assignment.grading_type
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_it_converts_due_at
|
|
42
|
+
@mod.time_due = Time.parse("2012/12/12 12:12:12 +0000").to_i
|
|
43
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
44
|
+
assert_equal '2012-12-12T12:12:12', assignment.due_at
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_it_converts_due_at_from_submission_end_time
|
|
48
|
+
@workshop_mod.submission_end = Time.parse("2009/09/09 09:09:09 +0000").to_i
|
|
49
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
50
|
+
assert_equal '2009-09-09T09:09:09', assignment.due_at
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_it_converts_unlock_at
|
|
54
|
+
@mod.time_available = Time.parse("2012/12/12 12:12:12 +0000").to_i
|
|
55
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
56
|
+
assert_equal '2012-12-12T12:12:12', assignment.unlock_at
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_it_converts_lock_at
|
|
60
|
+
@mod.time_due = Time.parse("2012/12/12 12:12:12 +0000").to_i
|
|
61
|
+
@mod.prevent_late = false
|
|
62
|
+
|
|
63
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
64
|
+
refute assignment.lock_at
|
|
65
|
+
|
|
66
|
+
@mod.prevent_late = true
|
|
67
|
+
|
|
68
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
69
|
+
assert_equal '2012-12-12T12:12:12', assignment.lock_at
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_it_converts_all_day
|
|
73
|
+
@mod.time_due = Time.parse("2012/12/12 23:58:00 +0000").to_i
|
|
74
|
+
|
|
75
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
76
|
+
assert_equal false, assignment.all_day
|
|
77
|
+
|
|
78
|
+
@mod.time_due = Time.parse("2012/12/12 23:59:00 +0000").to_i
|
|
79
|
+
|
|
80
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
81
|
+
assert_equal true, assignment.all_day
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_it_converts_all_day_date
|
|
85
|
+
@mod.time_due = Time.parse("2012/12/12 23:59:00 +0000").to_i
|
|
86
|
+
|
|
87
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
88
|
+
assert_equal '2012-12-12', assignment.all_day_date
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_it_converts_submission_types
|
|
92
|
+
@mod.assignment_type = 'offline'
|
|
93
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
94
|
+
assert_equal 'none', assignment.submission_types
|
|
95
|
+
|
|
96
|
+
@mod.assignment_type = 'online'
|
|
97
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
98
|
+
assert_equal 'online_text_entry', assignment.submission_types
|
|
99
|
+
|
|
100
|
+
@mod.assignment_type = 'upload'
|
|
101
|
+
@mod.var2 = 0
|
|
102
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
103
|
+
assert_equal 'online_upload', assignment.submission_types
|
|
104
|
+
|
|
105
|
+
@mod.assignment_type = 'upload'
|
|
106
|
+
@mod.var2 = 1
|
|
107
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
108
|
+
assert_equal 'online_upload,online_text_entry', assignment.submission_types
|
|
109
|
+
|
|
110
|
+
@mod.assignment_type = 'uploadsingle'
|
|
111
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
112
|
+
assert_equal 'online_upload', assignment.submission_types
|
|
113
|
+
|
|
114
|
+
@workshop_mod.number_of_attachments = 0
|
|
115
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
116
|
+
assert_equal 'online_text_entry', assignment.submission_types
|
|
117
|
+
|
|
118
|
+
@workshop_mod.number_of_attachments = 1
|
|
119
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
120
|
+
assert_equal 'online_upload,online_text_entry', assignment.submission_types
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_it_converts_peer_reviews
|
|
124
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
125
|
+
assert_equal false, assignment.peer_reviews
|
|
126
|
+
|
|
127
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
128
|
+
assert_equal true, assignment.peer_reviews
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_it_converts_automatic_peer_reviews
|
|
132
|
+
assignment = Moodle2CC::Canvas::Assignment.new @mod
|
|
133
|
+
assert_equal false, assignment.automatic_peer_reviews
|
|
134
|
+
|
|
135
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
136
|
+
assert_equal true, assignment.automatic_peer_reviews
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_it_converts_peer_review_count
|
|
140
|
+
@workshop_mod.number_of_student_assessments = 5
|
|
141
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
142
|
+
assert_equal 5, assignment.peer_review_count
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_it_converts_anonymous_peer_review
|
|
146
|
+
@workshop_mod.anonymous = true
|
|
147
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
148
|
+
assert_equal true, assignment.anonymous_peer_reviews
|
|
149
|
+
|
|
150
|
+
@workshop_mod.anonymous = false
|
|
151
|
+
assignment = Moodle2CC::Canvas::Assignment.new @workshop_mod
|
|
152
|
+
assert_equal false, assignment.anonymous_peer_reviews
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_it_creates_resource_in_imsmanifest
|
|
156
|
+
node = Builder::XmlMarkup.new
|
|
157
|
+
xml = Nokogiri::XML(@assignment.create_resource_node(node))
|
|
158
|
+
|
|
159
|
+
resource = xml.xpath('resource').first
|
|
160
|
+
assert resource
|
|
161
|
+
assert_equal 'associatedcontent/imscc_xmlv1p1/learning-application-resource', resource.attributes['type'].value
|
|
162
|
+
assert_equal 'i6b162484accdf6081cea43b39219d129/create-a-rails-site.html', resource.attributes['href'].value
|
|
163
|
+
assert_equal 'i6b162484accdf6081cea43b39219d129', resource.attributes['identifier'].value
|
|
164
|
+
|
|
165
|
+
file = resource.xpath('file[@href="i6b162484accdf6081cea43b39219d129/create-a-rails-site.html"]').first
|
|
166
|
+
assert file
|
|
167
|
+
|
|
168
|
+
file = resource.xpath('file[@href="i6b162484accdf6081cea43b39219d129/assignment_settings.xml"]').first
|
|
169
|
+
assert file
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_it_creates_item_in_module_meta
|
|
173
|
+
node = Builder::XmlMarkup.new
|
|
174
|
+
xml = Nokogiri::XML(@assignment.create_module_meta_item_node(node, 5))
|
|
175
|
+
|
|
176
|
+
assert_equal 'item', xml.root.name
|
|
177
|
+
assert_equal 'i10241816e5909d8e76da003b2814c6a4', xml.root.attributes['identifier'].value
|
|
178
|
+
assert_equal 'Create a Rails site', xml.root.xpath('title').text
|
|
179
|
+
assert_equal '5', xml.root.xpath('position').text
|
|
180
|
+
assert_equal '', xml.root.xpath('new_tab').text
|
|
181
|
+
assert_equal '0', xml.root.xpath('indent').text
|
|
182
|
+
assert_equal 'Assignment', xml.root.xpath('content_type').text
|
|
183
|
+
assert_equal 'i6b162484accdf6081cea43b39219d129', xml.root.xpath('identifierref').text
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def test_it_creates_assignment_html
|
|
187
|
+
tmp_dir = File.expand_path('../../../tmp', __FILE__)
|
|
188
|
+
@assignment.create_html(tmp_dir)
|
|
189
|
+
html = Nokogiri::HTML(File.read(File.join(tmp_dir, @assignment.identifier, 'create-a-rails-site.html')))
|
|
190
|
+
|
|
191
|
+
assert html
|
|
192
|
+
assert_equal 'Assignment: Create a Rails site', html.search('title').text
|
|
193
|
+
assert_equal '<h1>Hello World</h1>', html.search('body').inner_html.strip
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def test_it_creates_assignment_settings_file
|
|
197
|
+
tmp_dir = File.expand_path('../../../tmp', __FILE__)
|
|
198
|
+
@assignment.position = 9
|
|
199
|
+
@assignment.create_settings_xml(tmp_dir)
|
|
200
|
+
xml = Nokogiri::XML(File.read(File.join(tmp_dir, @assignment.identifier, 'assignment_settings.xml')))
|
|
201
|
+
|
|
202
|
+
assert xml
|
|
203
|
+
assert_equal "http://canvas.instructure.com/xsd/cccv1p0 http://canvas.instructure.com/xsd/cccv1p0.xsd", xml.root.attributes['schemaLocation'].value
|
|
204
|
+
assert_equal "http://www.w3.org/2001/XMLSchema-instance", xml.namespaces['xmlns:xsi']
|
|
205
|
+
assert_equal "http://canvas.instructure.com/xsd/cccv1p0", xml.namespaces['xmlns']
|
|
206
|
+
assert_equal @assignment.identifier, xml.xpath('xmlns:assignment').first.attributes['identifier'].value
|
|
207
|
+
|
|
208
|
+
assert_equal 'Create a Rails site', xml.xpath('xmlns:assignment/xmlns:title').text
|
|
209
|
+
assert_equal 'i521ff0228432bb106b9535e8c5139df3', xml.xpath('xmlns:assignment/xmlns:assignment_group_identifierref').text
|
|
210
|
+
assert_equal '150.0', xml.xpath('xmlns:assignment/xmlns:points_possible').text
|
|
211
|
+
assert_equal 'points', xml.xpath('xmlns:assignment/xmlns:grading_type').text
|
|
212
|
+
assert_equal 'true', xml.xpath('xmlns:assignment/xmlns:all_day').text
|
|
213
|
+
assert_equal 'none', xml.xpath('xmlns:assignment/xmlns:submission_types').text
|
|
214
|
+
assert_equal '9', xml.xpath('xmlns:assignment/xmlns:position').text
|
|
215
|
+
assert_equal '2012-12-12T23:59:00', xml.xpath('xmlns:assignment/xmlns:due_at').text
|
|
216
|
+
assert_equal '2012-12-12', xml.xpath('xmlns:assignment/xmlns:all_day_date').text
|
|
217
|
+
assert_equal '2012-12-12T23:59:00', xml.xpath('xmlns:assignment/xmlns:lock_at').text
|
|
218
|
+
assert_equal '2012-12-12T12:12:12', xml.xpath('xmlns:assignment/xmlns:unlock_at').text
|
|
219
|
+
end
|
|
220
|
+
end
|