preserve file student date restrictions on import/export

(also shift/remove file dates)

test plan:
* add date based restrictions for students to a file
* export the course
* import the file into a new course
* should retain the restrictions

* importing/copying with the shift dates/remove dates option
 should work as well

closes #CNVS-22352

Change-Id: Ie7510fc9b45664ce2dab49850dd09fce7023c306
Reviewed-on: https://gerrit.instructure.com/60040
Tested-by: Jenkins
Reviewed-by: Jeremy Stanley <jeremy@instructure.com>
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: James Williams  <jamesw@instructure.com>
This commit is contained in:
James Williams 2015-08-05 11:27:48 -06:00
parent 2f8bbc1e15
commit 5df55f1344
8 changed files with 60 additions and 3 deletions

View File

@ -1957,6 +1957,7 @@ class Course < ActiveRecord::Base
end end
new_file.folder_id = new_folder_id new_file.folder_id = new_folder_id
new_file.save_without_broadcasting! new_file.save_without_broadcasting!
cm.add_imported_item(new_file)
map_merge(file, new_file) map_merge(file, new_file)
rescue rescue
cm.add_warning(t(:file_copy_error, "Couldn't copy file \"%{name}\"", :name => file.display_name || file.path_name), $!) cm.add_warning(t(:file_copy_error, "Couldn't copy file \"%{name}\"", :name => file.display_name || file.path_name), $!)

View File

@ -68,6 +68,8 @@ module Importers
item.context = context item.context = context
item.migration_id = hash[:migration_id] item.migration_id = hash[:migration_id]
item.locked = true if hash[:locked] item.locked = true if hash[:locked]
item.lock_at = Canvas::Migration::MigratorHelper.get_utc_time_from_timestamp(hash[:lock_at]) if hash[:lock_at]
item.unlock_at = Canvas::Migration::MigratorHelper.get_utc_time_from_timestamp(hash[:unlock_at]) if hash[:unlock_at]
item.file_state = 'hidden' if hash[:hidden] item.file_state = 'hidden' if hash[:hidden]
item.display_name = hash[:display_name] if hash[:display_name] item.display_name = hash[:display_name] if hash[:display_name]
item.usage_rights_id = find_or_create_usage_rights(context, hash[:usage_rights], created_usage_rights_map) if hash[:usage_rights] item.usage_rights_id = find_or_create_usage_rights(context, hash[:usage_rights], created_usage_rights_map) if hash[:usage_rights]

View File

@ -169,6 +169,12 @@ module Importers
event.save_without_broadcasting event.save_without_broadcasting
end end
migration.imported_migration_items_by_class(Attachment).each do |event|
event.lock_at = shift_date(event.lock_at, shift_options)
event.unlock_at = shift_date(event.unlock_at, shift_options)
event.save_without_broadcasting
end
migration.imported_migration_items_by_class(DiscussionTopic).each do |event| migration.imported_migration_items_by_class(DiscussionTopic).each do |event|
event.delayed_post_at = shift_date(event.delayed_post_at, shift_options) event.delayed_post_at = shift_date(event.delayed_post_at, shift_options)
event.lock_at = shift_date(event.lock_at, shift_options) event.lock_at = shift_date(event.lock_at, shift_options)

View File

@ -36,7 +36,7 @@ module CC::Importer::Canvas
file_map file_map
end end
def convert_file_metadata(file_map) def convert_file_metadata(file_map)
path = File.join(@unzipped_file_path, COURSE_SETTINGS_DIR, FILES_META) path = File.join(@unzipped_file_path, COURSE_SETTINGS_DIR, FILES_META)
return unless File.exist? path return unless File.exist? path
@ -57,6 +57,14 @@ module CC::Importer::Canvas
if file_map[id] if file_map[id]
file_map[id][:hidden] = true if get_bool_val(file, 'hidden', false) file_map[id][:hidden] = true if get_bool_val(file, 'hidden', false)
file_map[id][:locked] = true if get_bool_val(file, 'locked', false) file_map[id][:locked] = true if get_bool_val(file, 'locked', false)
if unlock_at = get_time_val(file, 'unlock_at')
file_map[id][:unlock_at] = unlock_at
end
if lock_at = get_time_val(file, 'lock_at')
file_map[id][:lock_at] = lock_at
end
if display_name = file.at_css("display_name") if display_name = file.at_css("display_name")
file_map[id][:display_name] = display_name.text file_map[id][:display_name] = display_name.text
end end

View File

@ -19,6 +19,10 @@ require 'set'
module CC module CC
module WebResources module WebResources
def file_or_folder_restricted?(obj)
obj.hidden? || obj.locked || obj.unlock_at || obj.lock_at
end
def add_course_files def add_course_files
return if for_course_copy return if for_course_copy
@ -36,14 +40,14 @@ module CC
begin begin
if file.is_a? Folder if file.is_a? Folder
dir = File.join(folder_names[1..-1]) dir = File.join(folder_names[1..-1])
files_with_metadata[:folders] << [file, dir] if file.hidden? || file.locked files_with_metadata[:folders] << [file, dir] if file_or_folder_restricted?(file)
next next
end end
@added_attachment_ids << file.id @added_attachment_ids << file.id
path = File.join(folder_names, file.display_name) path = File.join(folder_names, file.display_name)
migration_id = CCHelper.create_key(file) migration_id = CCHelper.create_key(file)
if file.hidden? || file.locked || file.usage_rights if file_or_folder_restricted?(file) || file.usage_rights || file.display_name != file.unencoded_filename
files_with_metadata[:files] << [file, migration_id] files_with_metadata[:files] << [file, migration_id]
end end
@resources.resource( @resources.resource(
@ -110,6 +114,8 @@ module CC
folders_node.folder(:path => path) do |folder_node| folders_node.folder(:path => path) do |folder_node|
folder_node.locked "true" if folder.locked folder_node.locked "true" if folder.locked
folder_node.hidden "true" if folder.hidden? folder_node.hidden "true" if folder.hidden?
folder_node.lock_at CCHelper::ims_datetime(folder.lock_at) if folder.lock_at
folder_node.unlock_at CCHelper::ims_datetime(folder.unlock_at) if folder.unlock_at
end end
end end
end end
@ -121,6 +127,8 @@ module CC
files_node.file(:identifier => migration_id) do |file_node| files_node.file(:identifier => migration_id) do |file_node|
file_node.locked "true" if file.locked file_node.locked "true" if file.locked
file_node.hidden "true" if file.hidden? file_node.hidden "true" if file.hidden?
file_node.lock_at CCHelper::ims_datetime(file.lock_at) if file.lock_at
file_node.unlock_at CCHelper::ims_datetime(file.unlock_at) if file.unlock_at
file_node.display_name file.display_name if file.display_name != file.unencoded_filename file_node.display_name file.display_name if file.display_name != file.unencoded_filename
if file.usage_rights if file.usage_rights
file_node.usage_rights(:use_justification => file.usage_rights.use_justification) do |node| file_node.usage_rights(:use_justification => file.usage_rights.use_justification) do |node|

View File

@ -599,6 +599,8 @@
<xs:all minOccurs="0"> <xs:all minOccurs="0">
<xs:element name="hidden" type="xs:boolean" minOccurs="0"/> <xs:element name="hidden" type="xs:boolean" minOccurs="0"/>
<xs:element name="locked" type="xs:boolean" minOccurs="0"/> <xs:element name="locked" type="xs:boolean" minOccurs="0"/>
<xs:element name="lock_at" type="xs:dateTime" minOccurs="0"/>
<xs:element name="unlock_at" type="xs:dateTime" minOccurs="0"/>
</xs:all> </xs:all>
<xs:attribute name="path" type="xs:string" use="required"/> <xs:attribute name="path" type="xs:string" use="required"/>
</xs:complexType> </xs:complexType>
@ -615,6 +617,8 @@
<xs:element name="display_name" type="xs:string" minOccurs="0"/> <xs:element name="display_name" type="xs:string" minOccurs="0"/>
<xs:element name="hidden" type="xs:boolean" minOccurs="0"/> <xs:element name="hidden" type="xs:boolean" minOccurs="0"/>
<xs:element name="locked" type="xs:boolean" minOccurs="0"/> <xs:element name="locked" type="xs:boolean" minOccurs="0"/>
<xs:element name="lock_at" type="xs:dateTime" minOccurs="0"/>
<xs:element name="unlock_at" type="xs:dateTime" minOccurs="0"/>
<xs:element name="usage_rights" minOccurs="0" maxOccurs="1"> <xs:element name="usage_rights" minOccurs="0" maxOccurs="1">
<xs:complexType> <xs:complexType>
<xs:attribute name="use_justification" type="xs:string" use="required"> <xs:attribute name="use_justification" type="xs:string" use="required">

View File

@ -118,6 +118,19 @@ describe ContentMigration do
expect(@copy_to.attachments.where(migration_id: mig_id(att1)).first.usage_rights).to eq(usage_rights) expect(@copy_to.attachments.where(migration_id: mig_id(att1)).first.usage_rights).to eq(usage_rights)
end end
it "should preserve locked date restrictions on export/import" do
att = Attachment.create!(:filename => '1.txt', :uploaded_data => StringIO.new('1'), :folder => Folder.root_folders(@copy_from).first, :context => @copy_from)
att.unlock_at = 2.days.from_now
att.lock_at = 3.days.from_now
att.save!
run_export_and_import
copy = @copy_to.attachments.where(migration_id: mig_id(att)).first
expect(copy.unlock_at.to_i).to eq att.unlock_at.to_i
expect(copy.lock_at.to_i).to eq att.lock_at.to_i
end
it "should preserve usage rights on export/import" do it "should preserve usage rights on export/import" do
att1 = Attachment.create!(:filename => '1.txt', :uploaded_data => StringIO.new('1'), :folder => Folder.root_folders(@copy_from).first, :context => @copy_from) att1 = Attachment.create!(:filename => '1.txt', :uploaded_data => StringIO.new('1'), :folder => Folder.root_folders(@copy_from).first, :context => @copy_from)
att2 = Attachment.create!(:filename => '2.txt', :uploaded_data => StringIO.new('2'), :folder => Folder.root_folders(@copy_from).first, :context => @copy_from) att2 = Attachment.create!(:filename => '2.txt', :uploaded_data => StringIO.new('2'), :folder => Folder.root_folders(@copy_from).first, :context => @copy_from)

View File

@ -15,6 +15,13 @@ describe ContentMigration do
:lock_at => @old_start + 3.days, :lock_at => @old_start + 3.days,
:peer_reviews_due_at => @old_start + 4.days :peer_reviews_due_at => @old_start + 4.days
) )
att = Attachment.create!(:context => @copy_from, :filename => 'hi.txt',
:uploaded_data => StringIO.new("stuff"), :folder => Folder.unfiled_folder(@copy_from))
att.unlock_at = @old_start + 2.days
att.lock_at = @old_start + 3.days
att.save!
@copy_from.quizzes.create!(:due_at => "05 Jul 2012 06:00:00 UTC +00:00", @copy_from.quizzes.create!(:due_at => "05 Jul 2012 06:00:00 UTC +00:00",
:unlock_at => @old_start + 1.days, :unlock_at => @old_start + 1.days,
:lock_at => @old_start + 5.days, :lock_at => @old_start + 5.days,
@ -63,6 +70,10 @@ describe ContentMigration do
expect(new_asmnt.lock_at.to_i).to eq (@new_start + 3.day).to_i expect(new_asmnt.lock_at.to_i).to eq (@new_start + 3.day).to_i
expect(new_asmnt.peer_reviews_due_at.to_i).to eq (@new_start + 4.day).to_i expect(new_asmnt.peer_reviews_due_at.to_i).to eq (@new_start + 4.day).to_i
new_att = @copy_to.attachments.first
expect(new_att.unlock_at.to_i).to eq (@new_start + 2.day).to_i
expect(new_att.lock_at.to_i).to eq (@new_start + 3.day).to_i
new_quiz = @copy_to.quizzes.first new_quiz = @copy_to.quizzes.first
expect(new_quiz.due_at.to_i).to eq (@new_start + 4.day).to_i expect(new_quiz.due_at.to_i).to eq (@new_start + 4.day).to_i
expect(new_quiz.unlock_at.to_i).to eq (@new_start + 1.day).to_i expect(new_quiz.unlock_at.to_i).to eq (@new_start + 1.day).to_i
@ -109,6 +120,10 @@ describe ContentMigration do
expect(new_asmnt.lock_at).to be_nil expect(new_asmnt.lock_at).to be_nil
expect(new_asmnt.peer_reviews_due_at).to be_nil expect(new_asmnt.peer_reviews_due_at).to be_nil
new_att = @copy_to.attachments.first
expect(new_att.unlock_at).to be_nil
expect(new_att.lock_at).to be_nil
new_quiz = @copy_to.quizzes.first new_quiz = @copy_to.quizzes.first
expect(new_quiz.due_at).to be_nil expect(new_quiz.due_at).to be_nil
expect(new_quiz.unlock_at).to be_nil expect(new_quiz.unlock_at).to be_nil