Export all accessible course items
closes OFFW-128 Test plan - Create assignments, quizzes, discussions and wiki pages that are _not_ in modules - Export the offline course package - The non-module items should show up in course-data.js in the 'assignments', 'quizzes', 'pages', 'discussion_topics' keys - Data should mostly match what each type looks like in module items, but won't have module completion stuff or type and the ID will be the export ID. Change-Id: I7c6a5ea5b43bbbce4ae4ba54578aa0f1359436a3 Reviewed-on: https://gerrit.instructure.com/104819 Tested-by: Jenkins Reviewed-by: Jon Willesen <jonw+gerrit@instructure.com> QA-Review: Nathan Rogowski <nathan@instructure.com> Product-Review: Mysti Sadler <mysti@instructure.com>
This commit is contained in:
parent
cb5dbd41da
commit
d93d9aad54
|
@ -3,6 +3,10 @@ module CC::Exporter::WebZip
|
|||
|
||||
def initialize(exporter, course, user, progress_key)
|
||||
@files = exporter.unsupported_files + exporter.cartridge_json[:files]
|
||||
@pages = exporter.cartridge_json[:pages]
|
||||
@assignments = exporter.cartridge_json[:assignments]
|
||||
@topics = exporter.cartridge_json[:topics]
|
||||
@quizzes = exporter.cartridge_json[:quizzes]
|
||||
@filename_prefix = exporter.filename_prefix
|
||||
@viewer_path_prefix = @filename_prefix + '/viewer'
|
||||
@files_path_prefix = @viewer_path_prefix + '/files'
|
||||
|
@ -68,7 +72,11 @@ module CC::Exporter::WebZip
|
|||
lastDownload: force_timezone(last_web_export_time),
|
||||
title: course.name,
|
||||
files: create_tree_data,
|
||||
modules: parse_module_data
|
||||
modules: parse_module_data,
|
||||
pages: parse_non_module_items(:wiki_pages),
|
||||
assignments: parse_non_module_items(:assignments),
|
||||
discussion_topics: parse_non_module_items(:discussion_topics),
|
||||
quizzes: parse_non_module_items(:quizzes)
|
||||
}
|
||||
|
||||
f.write("window.COURSE_DATA = #{data.to_json}")
|
||||
|
@ -152,12 +160,13 @@ module CC::Exporter::WebZip
|
|||
end
|
||||
|
||||
def parse_module_item_details(item, item_hash)
|
||||
add_assignment_details(item, item_hash) if ASSIGNMENT_TYPES.include?(item.content_type)
|
||||
add_assignment_details(item.content, item_hash) if ASSIGNMENT_TYPES.include?(item.content_type)
|
||||
requirement, score = parse_requirement(item)
|
||||
item_hash[:requirement] = requirement
|
||||
item_hash[:requiredPoints] = score if score
|
||||
item_hash[:completed] = item_completed?(item)
|
||||
item_hash[:content] = parse_content(item) unless item_hash[:locked]
|
||||
item_hash[:content] = parse_content(item.content) unless item_hash[:locked] || item.content_type == 'ExternalUrl'
|
||||
item_hash[:content] = item.url if !item_hash[:locked] && item.content_type == 'ExternalUrl'
|
||||
item_hash[:exportId] = find_export_id(item) if CONTENT_TYPES.include?(item.content_type)
|
||||
end
|
||||
|
||||
|
@ -170,24 +179,22 @@ module CC::Exporter::WebZip
|
|||
end
|
||||
end
|
||||
|
||||
def add_assignment_details(item, item_hash)
|
||||
case item.content_type
|
||||
when 'Assignment'
|
||||
assignment = item.content
|
||||
item_hash[:submissionTypes] = assignment.readable_submission_types
|
||||
item_hash[:graded] = assignment.grading_type != 'not_graded'
|
||||
when 'Quizzes::Quiz'
|
||||
assignment = item.content
|
||||
item_hash[:questionCount] = assignment.question_count
|
||||
item_hash[:timeLimit] = assignment.time_limit
|
||||
item_hash[:attempts] = assignment.allowed_attempts
|
||||
item_hash[:graded] = assignment.quiz_type != 'survey'
|
||||
when 'DiscussionTopic'
|
||||
assignment = item.content&.assignment
|
||||
item_hash[:graded] = assignment.present?
|
||||
def add_assignment_details(item_content, item_hash)
|
||||
case item_content
|
||||
when Assignment
|
||||
item_hash[:submissionTypes] = item_content.readable_submission_types
|
||||
item_hash[:graded] = item_content.grading_type != 'not_graded'
|
||||
when Quizzes::Quiz
|
||||
item_hash[:questionCount] = item_content.question_count
|
||||
item_hash[:timeLimit] = item_content.time_limit
|
||||
item_hash[:attempts] = item_content.allowed_attempts
|
||||
item_hash[:graded] = item_content.quiz_type != 'survey'
|
||||
when DiscussionTopic
|
||||
item_content = item_content.assignment
|
||||
item_hash[:graded] = item_content.present?
|
||||
end
|
||||
return unless assignment
|
||||
assignment = AssignmentOverrideApplicator.assignment_overridden_for(assignment, user, skip_clone: true)
|
||||
return unless item_content
|
||||
assignment = AssignmentOverrideApplicator.assignment_overridden_for(item_content, user, skip_clone: true)
|
||||
item_hash[:pointsPossible] = assignment&.points_possible if item_hash[:graded]
|
||||
item_hash[:dueAt] = force_timezone(assignment&.due_at)
|
||||
item_hash[:lockAt] = force_timezone(assignment&.lock_at)
|
||||
|
@ -202,24 +209,41 @@ module CC::Exporter::WebZip
|
|||
[reqs_for_item[:type], reqs_for_item[:min_score]]
|
||||
end
|
||||
|
||||
def parse_content(item)
|
||||
case item.content_type
|
||||
when 'Assignment', 'Quizzes::Quiz'
|
||||
convert_html_to_local(item.content&.description)
|
||||
when 'DiscussionTopic'
|
||||
convert_html_to_local(item.content&.message)
|
||||
when 'WikiPage'
|
||||
convert_html_to_local(item.content&.body)
|
||||
when 'ExternalUrl'
|
||||
item.url
|
||||
when 'Attachment'
|
||||
path = file_path(item)
|
||||
"viewer/files#{path}#{item.content&.display_name}"
|
||||
def parse_content(item_content)
|
||||
case item_content
|
||||
when Assignment, Quizzes::Quiz
|
||||
convert_html_to_local(item_content&.description)
|
||||
when DiscussionTopic
|
||||
convert_html_to_local(item_content&.message)
|
||||
when WikiPage
|
||||
convert_html_to_local(item_content&.body)
|
||||
when Attachment
|
||||
path = file_path(item_content)
|
||||
"viewer/files#{path}#{item_content&.display_name}"
|
||||
end
|
||||
end
|
||||
|
||||
def file_path(item)
|
||||
folder = item.content&.folder&.full_name || ''
|
||||
def parse_non_module_items(type)
|
||||
list = {wiki_pages: @pages, assignments: @assignments, discussion_topics: @topics, quizzes: @quizzes}[type]
|
||||
canvas_items = {}
|
||||
course.send(type).each do |item|
|
||||
tag = (type == :wiki_pages ? item.url : CC::CCHelper.create_key(item))
|
||||
canvas_items[tag] = item
|
||||
end
|
||||
list.map do |export_item|
|
||||
item = canvas_items[export_item[:identifier]]
|
||||
item_hash = {
|
||||
exportId: export_item[:identifier],
|
||||
title: export_item[:title],
|
||||
content: parse_content(item) || export_item[:text]
|
||||
}
|
||||
add_assignment_details(item, item_hash) unless type == :wiki_pages
|
||||
item_hash
|
||||
end
|
||||
end
|
||||
|
||||
def file_path(item_content)
|
||||
folder = item_content&.folder&.full_name || ''
|
||||
local_folder = folder.sub(/\/?course files\/?/, '')
|
||||
local_folder.length > 0 ? "/#{local_folder}/" : '/'
|
||||
end
|
||||
|
|
|
@ -473,6 +473,68 @@ describe "ZipPackage" do
|
|||
end
|
||||
end
|
||||
|
||||
context "parse_non_module_items" do
|
||||
def create_zip_package
|
||||
export = @course.content_exports.build
|
||||
export.export_type = ContentExport::COMMON_CARTRIDGE
|
||||
export.user = @student
|
||||
export.save
|
||||
export.export_course
|
||||
exporter = CC::Exporter::WebZip::Exporter.new(export.attachment.open, false, :web_zip)
|
||||
CC::Exporter::WebZip::ZipPackage.new(exporter, @course, @student, @cache_key)
|
||||
end
|
||||
|
||||
it "should parse non-module assignments" do
|
||||
due = 1.day.from_now
|
||||
lock = 2.days.from_now
|
||||
unlock = 1.day.ago
|
||||
assign = @course.assignments.create!(title: 'Assignment 1', points_possible: 10, description: '<p>Hi</p>',
|
||||
submission_types: 'online_text_entry,online_upload', due_at: due, lock_at: lock,
|
||||
unlock_at: unlock)
|
||||
zip_package = create_zip_package
|
||||
assignment_data = zip_package.parse_non_module_items(:assignments)
|
||||
expect(assignment_data).to eq [{exportId: CC::CCHelper.create_key(assign), title: 'Assignment 1',
|
||||
content: '<p>Hi</p>', submissionTypes: "a text entry box or a file upload", graded: true,
|
||||
pointsPossible: 10.0, dueAt: due.in_time_zone(@student.time_zone).iso8601,
|
||||
lockAt: lock.in_time_zone(@student.time_zone).iso8601,
|
||||
unlockAt: unlock.in_time_zone(@student.time_zone).iso8601}]
|
||||
end
|
||||
|
||||
it "should parse non-module discussions" do
|
||||
disc = @course.discussion_topics.create!(title: 'Discussion 1', message: "<h1>Discussion</h1>")
|
||||
zip_package = create_zip_package
|
||||
disc_data = zip_package.parse_non_module_items(:discussion_topics)
|
||||
expect(disc_data).to eq [{exportId: CC::CCHelper.create_key(disc), title: 'Discussion 1',
|
||||
graded: false, content: "<h1>Discussion</h1>"}]
|
||||
end
|
||||
|
||||
it "should parse non-module quizzes" do
|
||||
quiz = @course.quizzes.create!(title: 'Quiz 1', time_limit: 5, allowed_attempts: 2)
|
||||
quiz.publish!
|
||||
zip_package = create_zip_package
|
||||
quiz_data = zip_package.parse_non_module_items(:quizzes)
|
||||
expect(quiz_data).to eq [{exportId: CC::CCHelper.create_key(quiz), title: 'Quiz 1', questionCount: 0,
|
||||
timeLimit: 5, attempts: 2, graded: true, pointsPossible: 0.0, dueAt: nil, lockAt: nil,
|
||||
unlockAt: nil, content: nil}]
|
||||
end
|
||||
|
||||
it "should parse non-module wiki pages" do
|
||||
@course.wiki_pages.create!(title: 'Wiki Page 1', url: 'wiki-page-1', wiki: @course.wiki)
|
||||
zip_package = create_zip_package
|
||||
wiki_data = zip_package.parse_non_module_items(:wiki_pages)
|
||||
expect(wiki_data).to eq [{exportId: 'wiki-page-1', title: 'Wiki Page 1', content: ''}]
|
||||
end
|
||||
|
||||
it "should not fail on missing items" do
|
||||
wiki = @course.wiki_pages.create!(title: 'Wiki Page 1', url: 'wiki-page-1', wiki: @course.wiki, body: '<p>Hi</p>')
|
||||
zip_package = create_zip_package
|
||||
wiki.title = 'Wiki Page 2'
|
||||
wiki.save!
|
||||
wiki_data = zip_package.parse_non_module_items(:wiki_pages)
|
||||
expect(wiki_data).to eq [{exportId: 'wiki-page-1', title: 'Wiki Page 1', content: '<p>Hi</p>'}]
|
||||
end
|
||||
end
|
||||
|
||||
context "convert_html_to_local" do
|
||||
before do
|
||||
@zip_package = CC::Exporter::WebZip::ZipPackage.new(@exporter, @course, @student, 'key')
|
||||
|
|
Loading…
Reference in New Issue