github-to-canvas-quiz 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +48 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +21 -0
  7. data/NOTES.md +53 -0
  8. data/README.md +89 -0
  9. data/Rakefile +8 -0
  10. data/bin/console +29 -0
  11. data/bin/github-to-canvas-quiz +15 -0
  12. data/bin/setup +8 -0
  13. data/github-to-canvas-quiz.gemspec +50 -0
  14. data/lib/github_to_canvas_quiz/builder/quiz.rb +110 -0
  15. data/lib/github_to_canvas_quiz/canvas_api/client.rb +80 -0
  16. data/lib/github_to_canvas_quiz/canvas_api/endpoints/quiz_questions.rb +29 -0
  17. data/lib/github_to_canvas_quiz/canvas_api/endpoints/quizzes.rb +25 -0
  18. data/lib/github_to_canvas_quiz/canvas_api/endpoints.rb +10 -0
  19. data/lib/github_to_canvas_quiz/cli.rb +31 -0
  20. data/lib/github_to_canvas_quiz/markdown_builder.rb +90 -0
  21. data/lib/github_to_canvas_quiz/markdown_converter.rb +44 -0
  22. data/lib/github_to_canvas_quiz/model/answer/fill_in_multiple_blanks.rb +34 -0
  23. data/lib/github_to_canvas_quiz/model/answer/matching.rb +35 -0
  24. data/lib/github_to_canvas_quiz/model/answer/multiple_answers.rb +33 -0
  25. data/lib/github_to_canvas_quiz/model/answer/multiple_choice.rb +33 -0
  26. data/lib/github_to_canvas_quiz/model/answer/multiple_dropdowns.rb +34 -0
  27. data/lib/github_to_canvas_quiz/model/answer/short_answer.rb +33 -0
  28. data/lib/github_to_canvas_quiz/model/answer/true_false.rb +33 -0
  29. data/lib/github_to_canvas_quiz/model/question.rb +61 -0
  30. data/lib/github_to_canvas_quiz/model/quiz.rb +62 -0
  31. data/lib/github_to_canvas_quiz/parser/canvas/answer/base.rb +19 -0
  32. data/lib/github_to_canvas_quiz/parser/canvas/answer/fill_in_multiple_blanks.rb +30 -0
  33. data/lib/github_to_canvas_quiz/parser/canvas/answer/matching.rb +31 -0
  34. data/lib/github_to_canvas_quiz/parser/canvas/answer/multiple_answers.rb +33 -0
  35. data/lib/github_to_canvas_quiz/parser/canvas/answer/multiple_choice.rb +33 -0
  36. data/lib/github_to_canvas_quiz/parser/canvas/answer/multiple_dropdowns.rb +30 -0
  37. data/lib/github_to_canvas_quiz/parser/canvas/answer/short_answer.rb +29 -0
  38. data/lib/github_to_canvas_quiz/parser/canvas/answer/true_false.rb +29 -0
  39. data/lib/github_to_canvas_quiz/parser/canvas/answer.rb +34 -0
  40. data/lib/github_to_canvas_quiz/parser/canvas/helpers.rb +25 -0
  41. data/lib/github_to_canvas_quiz/parser/canvas/question.rb +55 -0
  42. data/lib/github_to_canvas_quiz/parser/canvas/quiz.rb +44 -0
  43. data/lib/github_to_canvas_quiz/parser/markdown/answer/base.rb +22 -0
  44. data/lib/github_to_canvas_quiz/parser/markdown/answer/fill_in_multiple_blanks.rb +21 -0
  45. data/lib/github_to_canvas_quiz/parser/markdown/answer/matching.rb +23 -0
  46. data/lib/github_to_canvas_quiz/parser/markdown/answer/multiple_answers.rb +21 -0
  47. data/lib/github_to_canvas_quiz/parser/markdown/answer/multiple_choice.rb +19 -0
  48. data/lib/github_to_canvas_quiz/parser/markdown/answer/multiple_dropdowns.rb +21 -0
  49. data/lib/github_to_canvas_quiz/parser/markdown/answer/short_answer.rb +21 -0
  50. data/lib/github_to_canvas_quiz/parser/markdown/answer/true_false.rb +21 -0
  51. data/lib/github_to_canvas_quiz/parser/markdown/answer.rb +34 -0
  52. data/lib/github_to_canvas_quiz/parser/markdown/base.rb +22 -0
  53. data/lib/github_to_canvas_quiz/parser/markdown/helpers/node_parser.rb +21 -0
  54. data/lib/github_to_canvas_quiz/parser/markdown/helpers/node_scanner.rb +208 -0
  55. data/lib/github_to_canvas_quiz/parser/markdown/question.rb +76 -0
  56. data/lib/github_to_canvas_quiz/parser/markdown/quiz.rb +42 -0
  57. data/lib/github_to_canvas_quiz/repository_interface.rb +42 -0
  58. data/lib/github_to_canvas_quiz/reverse_markdown/converters/p.rb +20 -0
  59. data/lib/github_to_canvas_quiz/reverse_markdown/converters/pre.rb +51 -0
  60. data/lib/github_to_canvas_quiz/reverse_markdown/register.rb +9 -0
  61. data/lib/github_to_canvas_quiz/synchronizer/quiz.rb +140 -0
  62. data/lib/github_to_canvas_quiz/version.rb +5 -0
  63. data/lib/github_to_canvas_quiz.rb +62 -0
  64. metadata +348 -0
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module CanvasAPI
5
+ module Endpoints
6
+ include Quizzes
7
+ include QuizQuestions
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ class CLI < Thor
5
+ option :course, type: :numeric, required: true, desc: 'Canvas Course ID'
6
+ option :quiz, type: :numeric, required: true, desc: 'Canvas Quiz ID'
7
+ option :directory, default: '.',
8
+ desc: '(optional) Directory to output markdown files. Defaults to current directory'
9
+ desc 'backup', 'Backup a Canvas quiz and its questions as markdown'
10
+ def backup
11
+ puts '⬇️ Converting quiz...'
12
+ Builder::Quiz.new(client, options[:course], options[:quiz], options[:directory]).build
13
+ puts '✅ Done'
14
+ end
15
+
16
+ option :directory, default: '.',
17
+ desc: '(optional) Directory with markdown files to align. Defaults to current directory'
18
+ desc 'align', 'Updates a Canvas quiz from Markdown files.'
19
+ def align
20
+ puts '⬆️ Aligning quiz...'
21
+ Synchronizer::Quiz.new(client, options[:directory]).sync
22
+ puts '✅ Done'
23
+ end
24
+
25
+ private
26
+
27
+ def client
28
+ @client ||= CanvasAPI::Client.new(api_key: ENV['CANVAS_API_KEY'], host: ENV['CANVAS_API_PATH'])
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ # Custom DSL for building a Markdown string
5
+ class MarkdownBuilder
6
+ # Provides a custom DSL for building a Markdown string
7
+ # Usage:
8
+ #
9
+ # MarkdownBuilder.build do |md|
10
+ # md.h1('Hello')
11
+ # md.ul('item 1', 'item 2')
12
+ # md.blockquote('comment')
13
+ # end
14
+ #
15
+ # # => "# Hello\n\n- item 1\n- item 2\n\n> comment\n"
16
+ def self.build
17
+ raise ArgumentError, 'no block given' unless block_given?
18
+
19
+ builder = new
20
+ yield(builder)
21
+ builder.to_s
22
+ end
23
+
24
+ attr_accessor :blocks
25
+
26
+ def initialize
27
+ @blocks = []
28
+ end
29
+
30
+ # @return [String] markdown produced by joining all blocks
31
+ def to_s
32
+ "#{blocks.join("\n\n")}\n"
33
+ end
34
+
35
+ # Adds a frontmatter block
36
+ # @param hash [Hash] the data to covert to YAML for the frontmatter
37
+ def frontmatter(hash)
38
+ blocks << "#{hash.to_yaml.strip}\n---"
39
+ end
40
+
41
+ # Adds a H1 heading
42
+ # @param text [String] heading text
43
+ def h1(text)
44
+ blocks << "# #{text}"
45
+ end
46
+
47
+ # Adds a H2 heading
48
+ # @param text [String] heading text
49
+ def h2(text)
50
+ blocks << "## #{text}"
51
+ end
52
+
53
+ # Adds a paragraph
54
+ # @param text [String] paragraph text
55
+ def p(text)
56
+ blocks << escape(text)
57
+ end
58
+
59
+ # Adds a blockquote
60
+ # @param text [String] blockquote text
61
+ def blockquote(text)
62
+ text = text.gsub("\n", "\n> ")
63
+ blocks << "> #{text}"
64
+ end
65
+
66
+ # Adds multiple list items
67
+ # @param texts* [Strings] a list of text to convert to list items
68
+ def ul(*texts)
69
+ blocks << texts.map { |text| "- #{escape(text)}" }.join("\n")
70
+ end
71
+
72
+ # Adds a block of arbitrary markdown
73
+ # @param markdown [String] markdown string
74
+ def md(markdown)
75
+ blocks << markdown.strip
76
+ end
77
+
78
+ # TODO: This doesn't belong here...
79
+ def html_to_markdown(html)
80
+ ReverseMarkdown.convert(html, github_flavored: true).strip
81
+ end
82
+
83
+ private
84
+
85
+ # TODO: What needs escaping??
86
+ def escape(text)
87
+ text.gsub('_', '\_')
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ # Custom HTML renderer for Redcarpet, using Rouge for syntax highlighting
5
+ class HTMLRenderer < Redcarpet::Render::HTML
6
+ include Rouge::Plugins::Redcarpet
7
+ end
8
+
9
+ # Convert a string of Markdown to HTML using Redcarpet and Rouge.
10
+ #
11
+ # Useage:
12
+ #
13
+ # MarkdownConverter.new("# Hello\n\nWorld\n").to_html
14
+ # # => "<h1>Hello</h1>\n\n<p>World</p>\n"
15
+ class MarkdownConverter
16
+ attr_reader :options, :markdown
17
+
18
+ OPTIONS = {
19
+ tables: true,
20
+ autolink: true,
21
+ fenced_code_blocks: true,
22
+ disable_indented_code_blocks: true,
23
+ no_intra_emphasis: true
24
+ }.freeze
25
+
26
+ # @param [String] markdown The markdown to be converted
27
+ # @param [Hash] options Overrides the defaults for the [Redcarpet](https://github.com/vmg/redcarpet) gem
28
+ def initialize(markdown, options = {})
29
+ @options = OPTIONS.merge(options)
30
+ @markdown = markdown
31
+ end
32
+
33
+ # @return [String] the markdown converted to HTML
34
+ def to_html
35
+ Redcarpet::Markdown.new(renderer, options).render(markdown)
36
+ end
37
+
38
+ private
39
+
40
+ def renderer
41
+ HTMLRenderer.new(escape_html: true)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class FillInMultipleBlanks
7
+ attr_accessor :title, :text, :comments, :blank_id
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.ul(text, blank_id)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments,
28
+ 'blank_id' => blank_id
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class Matching
7
+ attr_accessor :title, :text, :comments, :left, :right
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.ul(left, right)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => left,
26
+ 'answer_weight' => 100,
27
+ 'answer_comment_html' => comments,
28
+ 'answer_match_left' => left,
29
+ 'answer_match_right' => right
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class MultipleAnswers
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.md(md.html_to_markdown(text))
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_html' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class MultipleChoice
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.md(md.html_to_markdown(text))
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_html' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class MultipleDropdowns
7
+ attr_accessor :title, :text, :comments, :blank_id
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.ul(text, blank_id)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments,
28
+ 'blank_id' => blank_id
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class ShortAnswer
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.p(text)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ module Answer
6
+ class TrueFalse
7
+ attr_accessor :title, :text, :comments
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ send("#{key}=", value) if respond_to?("#{key}=")
12
+ end
13
+ end
14
+
15
+ def to_markdown
16
+ MarkdownBuilder.build do |md|
17
+ md.h2(title)
18
+ md.p(text)
19
+ md.blockquote(md.html_to_markdown(comments)) unless comments.empty?
20
+ end
21
+ end
22
+
23
+ def to_h
24
+ {
25
+ 'answer_text' => text,
26
+ 'answer_weight' => title == 'Correct' ? 100 : 0,
27
+ 'answer_comment_html' => comments
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ class Question
6
+ attr_accessor :course_id, :quiz_id, :id, :type, :sources, :name, :description, :answers, :distractors
7
+
8
+ def initialize(options)
9
+ options.each do |key, value|
10
+ send("#{key}=", value) if respond_to?("#{key}=")
11
+ end
12
+ end
13
+
14
+ def to_markdown
15
+ MarkdownBuilder.build do |md|
16
+ md.frontmatter(frontmatter_hash)
17
+ md.h1(name)
18
+ md.md(md.html_to_markdown(description))
19
+ answers.each do |answer|
20
+ md.md(answer.to_markdown)
21
+ end
22
+ unless distractors.empty?
23
+ md.h2('Incorrect')
24
+ md.ul(*distractors)
25
+ end
26
+ end
27
+ end
28
+
29
+ def to_h
30
+ {
31
+ 'question_name' => name,
32
+ 'question_text' => description,
33
+ 'question_type' => type,
34
+ 'points_possible' => 1,
35
+ 'neutral_comments_html' => sources.nil? || sources.empty? ? '' : sources_to_html,
36
+ 'answers' => answers.map(&:to_h),
37
+ 'matching_answer_incorrect_matches' => distractors.join("\n")
38
+ }
39
+ end
40
+
41
+ def frontmatter_hash
42
+ {
43
+ 'course_id' => course_id,
44
+ 'quiz_id' => quiz_id,
45
+ 'id' => id,
46
+ 'type' => type,
47
+ 'sources' => sources
48
+ }
49
+ end
50
+
51
+ private
52
+
53
+ def sources_to_html
54
+ comments = sources.map do |source|
55
+ "<a href=\"#{source['url']}\">#{source['name']}</a>"
56
+ end.join
57
+ "<p><strong>Source/s:</strong> #{comments}</p>"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Model
5
+ class Quiz
6
+ attr_accessor :course_id, :id, :repo, :title, :description
7
+
8
+ def initialize(options)
9
+ options.each do |key, value|
10
+ send("#{key}=", value) if respond_to?("#{key}=")
11
+ end
12
+ end
13
+
14
+ def to_markdown
15
+ MarkdownBuilder.build do |md|
16
+ md.frontmatter(frontmatter_hash)
17
+ md.h1(title)
18
+ md.md(md.html_to_markdown(description))
19
+ end
20
+ end
21
+
22
+ def to_h
23
+ {
24
+ 'title' => title,
25
+ 'description' => description_with_header,
26
+ 'quiz_type' => 'assignment',
27
+ 'shuffle_answers' => true,
28
+ 'hide_results' => 'until_after_last_attempt',
29
+ 'show_correct_answers_last_attempt' => true,
30
+ 'allowed_attempts' => 3,
31
+ 'scoring_policy' => 'keep_highest',
32
+ 'one_question_at_a_time' => true
33
+ }
34
+ end
35
+
36
+ def frontmatter_hash
37
+ {
38
+ 'id' => id,
39
+ 'course_id' => course_id,
40
+ 'repo' => repo
41
+ }
42
+ end
43
+
44
+ private
45
+
46
+ def description_with_header
47
+ [git_links_header, description].reject(&:nil?).join("\n")
48
+ end
49
+
50
+ def git_links_header
51
+ return unless repo
52
+
53
+ <<~HTML
54
+ <div id='git-data-element' data-org='learn-co-curriculum' data-repo='#{repo}'></div>
55
+ <header class='fis-header'>
56
+ <a class='fis-git-link' href='https://github.com/learn-co-curriculum/#{repo}/issues/new' target='_blank' rel='noopener'><img id='issue-img' title='Create New Issue' alt='Create New Issue' /></a>
57
+ </header>
58
+ HTML
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class Base
8
+ include Helpers
9
+
10
+ attr_reader :data
11
+
12
+ def initialize(data)
13
+ @data = data
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class FillInMultipleBlanks < Base
8
+ def parse
9
+ Model::Answer::FillInMultipleBlanks.new(
10
+ title: title,
11
+ text: data['text'],
12
+ comments: comments,
13
+ blank_id: data['blank_id']
14
+ )
15
+ end
16
+
17
+ private
18
+
19
+ def title
20
+ data.fetch('weight', 0).positive? ? 'Correct' : 'Incorrect'
21
+ end
22
+
23
+ def comments
24
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class Matching < Base
8
+ def parse
9
+ Model::Answer::Matching.new(
10
+ title: title,
11
+ text: data['text'],
12
+ comments: comments,
13
+ left: data['left'],
14
+ right: data['right']
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def title
21
+ data['left'].empty? ? 'Incorrect' : 'Correct'
22
+ end
23
+
24
+ def comments
25
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class MultipleAnswers < Base
8
+ def parse
9
+ Model::Answer::MultipleAnswers.new(
10
+ title: title,
11
+ text: text,
12
+ comments: comments
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def title
19
+ data.fetch('weight', 0).positive? ? 'Correct' : 'Incorrect'
20
+ end
21
+
22
+ def text
23
+ choose_text(data.fetch('text', ''), data.fetch('html', ''))
24
+ end
25
+
26
+ def comments
27
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubToCanvasQuiz
4
+ module Parser
5
+ module Canvas
6
+ module Answer
7
+ class MultipleChoice < Base
8
+ def parse
9
+ Model::Answer::MultipleChoice.new(
10
+ title: title,
11
+ text: text,
12
+ comments: comments
13
+ )
14
+ end
15
+
16
+ private
17
+
18
+ def title
19
+ data.fetch('weight', 0).positive? ? 'Correct' : 'Incorrect'
20
+ end
21
+
22
+ def text
23
+ choose_text(data.fetch('text', ''), data.fetch('html', ''))
24
+ end
25
+
26
+ def comments
27
+ choose_text(data.fetch('comments', ''), data.fetch('comments_html', ''))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end