fedora-migrate 0.3.0 → 0.4.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +128 -0
  3. data/.rubocop_todo.yml +9 -0
  4. data/.travis.yml +3 -2
  5. data/Gemfile +2 -0
  6. data/fedora-migrate.gemspec +1 -0
  7. data/lib/fedora-migrate.rb +3 -5
  8. data/lib/fedora_migrate/content_mover.rb +7 -11
  9. data/lib/fedora_migrate/datastream_mover.rb +21 -24
  10. data/lib/fedora_migrate/datastream_verification.rb +15 -17
  11. data/lib/fedora_migrate/dates_mover.rb +0 -2
  12. data/lib/fedora_migrate/file_configurator.rb +3 -5
  13. data/lib/fedora_migrate/hooks.rb +0 -2
  14. data/lib/fedora_migrate/logger.rb +8 -11
  15. data/lib/fedora_migrate/migration_options.rb +6 -7
  16. data/lib/fedora_migrate/migration_report.rb +18 -22
  17. data/lib/fedora_migrate/mover.rb +4 -6
  18. data/lib/fedora_migrate/object_mover.rb +28 -34
  19. data/lib/fedora_migrate/permissions.rb +8 -10
  20. data/lib/fedora_migrate/permissions_mover.rb +7 -11
  21. data/lib/fedora_migrate/rdf_datastream_mover.rb +1 -2
  22. data/lib/fedora_migrate/rels_ext_datastream_mover.rb +29 -31
  23. data/lib/fedora_migrate/repository_migrator.rb +40 -43
  24. data/lib/fedora_migrate/rights_metadata.rb +109 -114
  25. data/lib/fedora_migrate/rubydora_connection.rb +4 -5
  26. data/lib/fedora_migrate/target_constructor.rb +19 -22
  27. data/lib/fedora_migrate/version.rb +1 -1
  28. data/spec/integration/content_versions_spec.rb +12 -14
  29. data/spec/integration/custom_target_spec.rb +44 -0
  30. data/spec/integration/fedora3_interface_spec.rb +7 -11
  31. data/spec/integration/missing_relationships_spec.rb +8 -10
  32. data/spec/integration/object_migration_spec.rb +20 -31
  33. data/spec/integration/permission_migration_spec.rb +4 -6
  34. data/spec/integration/rdf_migration_spec.rb +3 -6
  35. data/spec/integration/relationship_migration_spec.rb +6 -7
  36. data/spec/integration/repository_migration_spec.rb +14 -19
  37. data/spec/integration/versions_spec.rb +6 -8
  38. data/spec/spec_helper.rb +3 -3
  39. data/spec/support/example_model.rb +23 -25
  40. data/spec/unit/content_mover_spec.rb +21 -23
  41. data/spec/unit/datastream_mover_spec.rb +10 -14
  42. data/spec/unit/datastream_verification_spec.rb +7 -9
  43. data/spec/unit/dates_mover_spec.rb +3 -4
  44. data/spec/unit/fedora_migrate_spec.rb +2 -6
  45. data/spec/unit/file_configurator_spec.rb +4 -8
  46. data/spec/unit/migration_options_spec.rb +1 -3
  47. data/spec/unit/migration_report_spec.rb +5 -6
  48. data/spec/unit/mover_spec.rb +10 -12
  49. data/spec/unit/object_mover_spec.rb +9 -16
  50. data/spec/unit/permissions_mover_spec.rb +8 -11
  51. data/spec/unit/rels_ext_datastream_mover_spec.rb +4 -6
  52. data/spec/unit/repository_migrator_spec.rb +12 -14
  53. data/spec/unit/rubydora_connection_spec.rb +3 -5
  54. data/spec/unit/target_constructor_spec.rb +10 -16
  55. data/tasks/dev.rake +9 -1
  56. metadata +21 -3
@@ -2,64 +2,64 @@ require 'active_support/core_ext/string'
2
2
 
3
3
  module FedoraMigrate
4
4
  # Implements Hydra RightsMetadata XML terminology for asserting access permissions
5
- class RightsMetadata < ActiveFedora::OmDatastream
5
+ class RightsMetadata < ActiveFedora::OmDatastream
6
6
  extend Deprecation
7
-
7
+
8
8
  set_terminology do |t|
9
- t.root(:path=>"rightsMetadata", :xmlns=>"http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1", :schema=>"http://github.com/projecthydra/schemas/tree/v1/rightsMetadata.xsd")
10
- t.copyright {
9
+ t.root(path: "rightsMetadata", xmlns: "http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1", schema: "http://github.com/projecthydra/schemas/tree/v1/rightsMetadata.xsd")
10
+ t.copyright do
11
11
  ## BEGIN possible delete, justin 2012-06-22
12
- t.machine {
13
- t.cclicense
14
- t.license
15
- }
16
- t.human_readable(:path=>"human")
17
- t.license(:proxy=>[:machine, :license ])
18
- t.cclicense(:proxy=>[:machine, :cclicense ])
12
+ t.machine do
13
+ t.cclicense
14
+ t.license
15
+ end
16
+ t.human_readable(path: "human")
17
+ t.license(proxy: [:machine, :license])
18
+ t.cclicense(proxy: [:machine, :cclicense])
19
19
  ## END possible delete
20
20
 
21
- t.title(:path=>'human', :attributes=>{:type=>'title'})
22
- t.description(:path=>'human', :attributes=>{:type=>'description'})
23
- t.url(:path=>'machine', :attributes=>{:type=>'uri'})
24
- }
21
+ t.title(path: 'human', attributes: { type: 'title' })
22
+ t.description(path: 'human', attributes: { type: 'description' })
23
+ t.url(path: 'machine', attributes: { type: 'uri' })
24
+ end
25
25
  t.access do
26
- t.human_readable(:path=>"human")
27
- t.machine {
26
+ t.human_readable(path: "human")
27
+ t.machine do
28
28
  t.group
29
29
  t.person
30
- }
31
- t.person(:proxy=>[:machine, :person])
32
- t.group(:proxy=>[:machine, :group])
30
+ end
31
+ t.person(proxy: [:machine, :person])
32
+ t.group(proxy: [:machine, :group])
33
33
  # accessor :access_person, :term=>[:access, :machine, :person]
34
34
  end
35
- t.discover_access(:ref=>[:access], :attributes=>{:type=>"discover"})
36
- t.read_access(:ref=>[:access], :attributes=>{:type=>"read"})
37
- t.edit_access(:ref=>[:access], :attributes=>{:type=>"edit"})
35
+ t.discover_access(ref: [:access], attributes: { type: "discover" })
36
+ t.read_access(ref: [:access], attributes: { type: "read" })
37
+ t.edit_access(ref: [:access], attributes: { type: "edit" })
38
38
  # A bug in OM prevnts us from declaring proxy terms at the root of a Terminology
39
39
  # t.access_person(:proxy=>[:access,:machine,:person])
40
40
  # t.access_group(:proxy=>[:access,:machine,:group])
41
-
42
- t.embargo {
41
+
42
+ t.embargo do
43
43
  t.human_readable(path: "human")
44
- t.machine{
45
- t.date(type: :time, attributes: {type: "release"})
44
+ t.machine do
45
+ t.date(type: :time, attributes: { type: "release" })
46
46
  t.date_deactivated(type: "deactivated")
47
- t.visibility_during(path: "visibility", attributes: {scope: 'during'})
48
- t.visibility_after(path: "visibility", attributes: {scope: 'after'})
49
- }
50
- }
47
+ t.visibility_during(path: "visibility", attributes: { scope: 'during' })
48
+ t.visibility_after(path: "visibility", attributes: { scope: 'after' })
49
+ end
50
+ end
51
51
 
52
- t.lease {
52
+ t.lease do
53
53
  t.human_readable(path: "human")
54
- t.machine{
55
- t.date(type: :time, attributes: {type: "expire"})
56
- t.date_deactivated(type: :time, attributes: {type: "deactivated"})
57
- t.visibility_during(path: "visibility", attributes: {scope: 'during'})
58
- t.visibility_after(path: "visibility", attributes: {scope: 'after'})
59
- }
60
- }
54
+ t.machine do
55
+ t.date(type: :time, attributes: { type: "expire" })
56
+ t.date_deactivated(type: :time, attributes: { type: "deactivated" })
57
+ t.visibility_during(path: "visibility", attributes: { scope: 'during' })
58
+ t.visibility_after(path: "visibility", attributes: { scope: 'after' })
59
+ end
60
+ end
61
61
 
62
- t.license(:ref=>[:copyright])
62
+ t.license(ref: [:copyright])
63
63
 
64
64
  t.visibility_during_embargo proxy: [:embargo, :machine, :visibility_during]
65
65
  t.visibility_after_embargo proxy: [:embargo, :machine, :visibility_after]
@@ -71,62 +71,60 @@ module FedoraMigrate
71
71
  t.embargo_deactivation_date proxy: [:embargo, :machine, :date_deactivated]
72
72
  t.lease_expiration_date proxy: [:lease, :machine, :date], type: :time
73
73
  t.lease_deactivation_date proxy: [:lease, :machine, :date_deactivated]
74
-
75
74
  end
76
75
 
77
76
  # Generates an empty Mods Article (used when you call ModsArticle.new without passing in existing xml)
78
77
  def self.xml_template
79
78
  builder = Nokogiri::XML::Builder.new do |xml|
80
- xml.rightsMetadata(:version=>"0.1", "xmlns"=>"http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1") {
81
- xml.copyright {
82
- xml.human(:type=>'title')
83
- xml.human(:type=>'description')
84
- xml.machine(:type=>'uri')
85
-
86
- }
87
- xml.access(:type=>"discover") {
79
+ xml.rightsMetadata(:version => "0.1", "xmlns" => "http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1") do
80
+ xml.copyright do
81
+ xml.human(type: 'title')
82
+ xml.human(type: 'description')
83
+ xml.machine(type: 'uri')
84
+ end
85
+ xml.access(type: "discover") do
88
86
  xml.human
89
87
  xml.machine
90
- }
91
- xml.access(:type=>"read") {
92
- xml.human
88
+ end
89
+ xml.access(type: "read") do
90
+ xml.human
93
91
  xml.machine
94
- }
95
- xml.access(:type=>"edit") {
92
+ end
93
+ xml.access(type: "edit") do
96
94
  xml.human
97
95
  xml.machine
98
- }
99
- xml.embargo{
96
+ end
97
+ xml.embargo do
100
98
  xml.machine
101
- }
102
- xml.lease{
99
+ end
100
+ xml.lease do
103
101
  xml.machine
104
- }
105
- }
102
+ end
103
+ end
106
104
  end
107
- return builder.doc
105
+ builder.doc
108
106
  end
109
-
107
+
110
108
  # Returns the permissions for the selected person/group
111
- # If new_access_level is provided, updates the selected person/group access_level to the one specified
109
+ # If new_access_level is provided, updates the selected person/group access_level to the one specified
112
110
  # A new_access_level of "none" will remove all access_levels for the selected person/group
113
111
  # @param [Hash] selector hash in format {type => identifier}
114
112
  # @param new_access_level (default nil)
115
- # @return Hash in format {type => access_level}.
116
- #
117
- # ie.
113
+ # @return Hash in format {type => access_level}.
114
+ #
115
+ # ie.
118
116
  # permissions({:person=>"person123"})
119
117
  # => {"person123"=>"edit"}
120
118
  # permissions({:person=>"person123"}, "read")
121
119
  # => {"person123"=>"read"}
122
120
  # permissions({:person=>"person123"})
123
121
  # => {"person123"=>"read"}
124
- def permissions(selector, new_access_level=nil)
122
+ def permissions(selector, new_access_level = nil)
125
123
  type = selector.keys.first.to_sym
126
124
  actor = selector.values.first
127
125
  if new_access_level.nil?
128
126
  xpath = xpath(type, actor)
129
- nodeset = self.find_by_terms(xpath)
127
+ nodeset = find_by_terms(xpath)
130
128
  if nodeset.empty?
131
129
  return "none"
132
130
  else
@@ -134,24 +132,23 @@ module FedoraMigrate
134
132
  end
135
133
  else
136
134
  remove_all_permissions(selector)
137
- if new_access_level == "none"
138
- self.content = self.to_xml
135
+ if new_access_level == "none"
136
+ self.content = to_xml
139
137
  else
140
138
  access_type_symbol = "#{new_access_level}_access".to_sym
141
139
  current_values = term_values(access_type_symbol, type)
142
- self.update_values([access_type_symbol, type] => current_values + [actor] )
140
+ update_values([access_type_symbol, type] => current_values + [actor])
143
141
  end
144
142
  return new_access_level
145
143
  end
146
-
147
144
  end
148
-
145
+
149
146
  # Reports on which groups have which permissions
150
147
  # @return Hash in format {group_name => group_permissions, group_name => group_permissions}
151
148
  def groups
152
- return quick_search_by_type(:group)
149
+ quick_search_by_type(:group)
153
150
  end
154
-
151
+
155
152
  def individuals
156
153
  Deprecation.warn(RightsMetadata, "The method `individuals' is deprecated and will be removed from Hydra::Datastream::RightsMetadata in hydra-head 8.0. Use `users' instead.", caller)
157
154
  users
@@ -160,42 +157,42 @@ module FedoraMigrate
160
157
  # Reports on which users have which permissions
161
158
  # @return Hash in format {user_name => user_permissions, user_name => user_permissions}
162
159
  def users
163
- return quick_search_by_type(:person)
160
+ quick_search_by_type(:person)
164
161
  end
165
-
162
+
166
163
  # Updates permissions for all of the persons and groups in a hash
167
164
  # @param params ex. {"group"=>{"group1"=>"discover","group2"=>"edit"}, "person"=>{"person1"=>"read","person2"=>"discover"}}
168
165
  # Currently restricts actor type to group or person. Any others will be ignored
169
166
  def update_permissions(params)
170
- params.fetch("group", {}).each_pair {|group_id, access_level| self.permissions({"group"=>group_id}, access_level)}
171
- params.fetch("person", {}).each_pair {|person_id, access_level| self.permissions({"person"=>person_id}, access_level)}
167
+ params.fetch("group", {}).each_pair { |group_id, access_level| permissions({ "group" => group_id }, access_level) }
168
+ params.fetch("person", {}).each_pair { |person_id, access_level| permissions({ "person" => person_id }, access_level) }
172
169
  end
173
170
 
174
171
  # Updates all permissions
175
172
  # @param params ex. {"group"=>{"group1"=>"discover","group2"=>"edit"}, "person"=>{"person1"=>"read","person2"=>"discover"}}
176
173
  # Restricts actor type to group or person. Any others will be ignored
177
- def permissions= (params)
174
+ def permissions=(params)
178
175
  groups_for_update = params['group'] ? params['group'].keys : []
179
176
  group_ids = groups.keys | groups_for_update
180
- group_ids.each {|group_id| self.permissions({"group"=>group_id}, params['group'].fetch(group_id, 'none'))}
177
+ group_ids.each { |group_id| permissions({ "group" => group_id }, params['group'].fetch(group_id, 'none')) }
181
178
  users_for_update = params['person'] ? params['person'].keys : []
182
179
  user_ids = users.keys | users_for_update
183
- user_ids.each {|person_id| self.permissions({"person"=>person_id}, params['person'].fetch(person_id, 'none'))}
180
+ user_ids.each { |person_id| permissions({ "person" => person_id }, params['person'].fetch(person_id, 'none')) }
184
181
  end
185
-
182
+
186
183
  # @param [Symbol] type (either :group or :person)
187
- # @return
184
+ # @return
188
185
  # This method limits the response to known access levels. Probably runs a bit faster than .permissions().
189
186
  def quick_search_by_type(type)
190
187
  result = {}
191
- [{:discover_access=>"discover"},{:read_access=>"read"},{:edit_access=>"edit"}].each do |access_levels_hash|
188
+ [{ discover_access: "discover" }, { read_access: "read" }, { edit_access: "edit" }].each do |access_levels_hash|
192
189
  access_level = access_levels_hash.keys.first
193
190
  access_level_name = access_levels_hash.values.first
194
- self.find_by_terms(*[access_level, type]).each do |entry|
191
+ find_by_terms(*[access_level, type]).each do |entry|
195
192
  result[entry.text] = access_level_name
196
193
  end
197
194
  end
198
- return result
195
+ result
199
196
  end
200
197
 
201
198
  def under_embargo?
@@ -206,7 +203,7 @@ module FedoraMigrate
206
203
  lease_expiration_date.present? && Date.today < lease_expiration_date.first
207
204
  end
208
205
 
209
- def to_solr(solr_doc=Hash.new)
206
+ def to_solr(solr_doc = {})
210
207
  [:discover, :read, :edit].each do |access|
211
208
  vals = send("#{access}_access").machine.group
212
209
  solr_doc[Hydra.config.permissions[access].group] = vals unless vals.empty?
@@ -214,11 +211,11 @@ module FedoraMigrate
214
211
  solr_doc[Hydra.config.permissions[access].individual] = vals unless vals.empty?
215
212
  end
216
213
  if embargo_release_date.present?
217
- key = Hydra.config.permissions.embargo.release_date.sub(/_[^_]+$/, '') #Strip off the suffix
214
+ key = Hydra.config.permissions.embargo.release_date.sub(/_[^_]+$/, '') # Strip off the suffix
218
215
  ::Solrizer.insert_field(solr_doc, key, embargo_release_date, :stored_sortable)
219
216
  end
220
217
  if lease_expiration_date.present?
221
- key = Hydra.config.permissions.lease.expiration_date.sub(/_[^_]+$/, '') #Strip off the suffix
218
+ key = Hydra.config.permissions.lease.expiration_date.sub(/_[^_]+$/, '') # Strip off the suffix
222
219
  ::Solrizer.insert_field(solr_doc, key, lease_expiration_date, :stored_sortable)
223
220
  end
224
221
  solr_doc[::Solrizer.solr_name("visibility_during_embargo", :symbol)] = visibility_during_embargo unless visibility_during_embargo.nil?
@@ -248,34 +245,32 @@ module FedoraMigrate
248
245
 
249
246
  # Completely clear the permissions
250
247
  def clear_permissions!
251
- remove_all_permissions({:person=>true})
252
- remove_all_permissions({:group=>true})
248
+ remove_all_permissions(person: true)
249
+ remove_all_permissions(group: true)
253
250
  end
254
251
 
255
-
256
-
257
252
  private
258
- # Purge all access given group/person
259
- def remove_all_permissions(selector)
260
- return unless ng_xml
261
- type = selector.keys.first.to_sym
262
- actor = selector.values.first
263
- xpath = xpath(type, actor)
264
- nodes_to_purge = self.find_by_terms(xpath)
265
- nodes_to_purge.each {|node| node.remove}
266
- end
267
253
 
268
- # @param [Symbol] type (:group, :person)
269
- # @param [String,TrueClass] actor the user we want to find. If actor is true, then don't query.
270
- def xpath(type, actor)
271
- raise ArgumentError, "Type must either be ':group' or ':person'. You provided: '#{type.inspect}'" unless [:group, :person].include?(type)
272
- path = "//oxns:access/oxns:machine/oxns:#{type}"
273
- if actor.is_a? String
274
- clean_actor = actor.gsub("'", '')
275
- path += "[text() = '#{clean_actor}']"
254
+ # Purge all access given group/person
255
+ def remove_all_permissions(selector)
256
+ return unless ng_xml
257
+ type = selector.keys.first.to_sym
258
+ actor = selector.values.first
259
+ xpath = xpath(type, actor)
260
+ nodes_to_purge = find_by_terms(xpath)
261
+ nodes_to_purge.each(&:remove)
262
+ end
263
+
264
+ # @param [Symbol] type (:group, :person)
265
+ # @param [String,TrueClass] actor the user we want to find. If actor is true, then don't query.
266
+ def xpath(type, actor)
267
+ raise ArgumentError, "Type must either be ':group' or ':person'. You provided: '#{type.inspect}'" unless [:group, :person].include?(type)
268
+ path = "//oxns:access/oxns:machine/oxns:#{type}"
269
+ if actor.is_a? String
270
+ clean_actor = actor.delete("'")
271
+ path += "[text() = '#{clean_actor}']"
272
+ end
273
+ path
276
274
  end
277
- path
278
- end
279
-
280
275
  end
281
276
  end
@@ -1,18 +1,17 @@
1
1
  module FedoraMigrate
2
2
  class RubydoraConnection
3
-
4
3
  attr_accessor :options, :connection
5
4
 
6
- def initialize(params={})
5
+ def initialize(params = {})
7
6
  params = params.dup
8
7
  self.options = params
9
8
  connect
10
9
  end
11
10
 
12
- def connect(force=false)
13
- return unless @connection.nil? or force
11
+ def connect(force = false)
12
+ return unless @connection.nil? || force
14
13
  allowable_options = [:url, :user, :password, :timeout, :open_timeout, :ssl_client_cert, :ssl_client_key, :validateChecksum]
15
- client_options = options.reject { |k,v| not allowable_options.include?(k) }
14
+ client_options = options.reject { |k, _v| !allowable_options.include?(k) }
16
15
  @connection = Rubydora.connect client_options
17
16
  end
18
17
  end
@@ -1,38 +1,35 @@
1
1
  module FedoraMigrate
2
2
  class TargetConstructor
3
+ attr_accessor :source, :candidates, :target
3
4
 
4
- attr_accessor :candidates, :target
5
-
6
- def initialize candidates
7
- @candidates = candidates
5
+ def initialize(source)
6
+ @source = source
8
7
  end
9
8
 
10
9
  def build
11
- determine_target
12
- return self
10
+ raise FedoraMigrate::Errors::MigrationError, "No qualified targets found in #{source.pid}" if target.nil?
11
+ target.new(id: FedoraMigrate::Mover.id_component(source))
12
+ end
13
+
14
+ def target
15
+ @target ||= determine_target
13
16
  end
14
17
 
15
18
  private
16
19
 
17
- def determine_target
18
- case
19
- when @candidates.kind_of?(Array) then vote
20
- when @candidates.kind_of?(String) then vet(@candidates)
20
+ def determine_target
21
+ Array(candidates).map { |model| vet(model) }.compact.first
21
22
  end
22
- end
23
23
 
24
- def vote
25
- candidates.each do |model|
26
- vet(model)
27
- return unless @target.nil?
24
+ def vet(model)
25
+ FedoraMigrate::Mover.id_component(model).constantize
26
+ rescue NameError
27
+ Logger.debug "rejecting #{model} for target"
28
+ nil
28
29
  end
29
- end
30
-
31
- def vet model
32
- @target = FedoraMigrate::Mover.id_component(model).constantize
33
- rescue NameError
34
- Logger.debug "rejecting #{model} for target"
35
- end
36
30
 
31
+ def candidates
32
+ @candidates ||= source.models
33
+ end
37
34
  end
38
35
  end
@@ -1,3 +1,3 @@
1
1
  module FedoraMigrate
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0".freeze
3
3
  end
@@ -1,19 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Versioned content" do
4
-
3
+ describe FedoraMigrate::DatastreamMover do
5
4
  let(:mover) do
6
- FedoraMigrate::DatastreamMover.new(
7
- FedoraMigrate.source.connection.find("sufia:rb68xc089").datastreams["content"],
5
+ described_class.new(
6
+ FedoraMigrate.source.connection.find("sufia:rb68xc089").datastreams["content"],
8
7
  ExampleModel::VersionedContent.create.attached_files["content"]
9
8
  )
10
9
  end
11
10
 
12
11
  let(:application_mover) do
13
- FedoraMigrate::DatastreamMover.new(
14
- FedoraMigrate.source.connection.find("sufia:rb68xc089").datastreams["content"],
12
+ described_class.new(
13
+ FedoraMigrate.source.connection.find("sufia:rb68xc089").datastreams["content"],
15
14
  ExampleModel::VersionedContent.create.attached_files["content"],
16
- { application_creates_versions: true }
15
+ application_creates_versions: true
17
16
  )
18
17
  end
19
18
 
@@ -28,10 +27,10 @@ describe "Versioned content" do
28
27
  mover.migrate
29
28
  mover.target
30
29
  end
31
- it "should migrate all versions" do
30
+ it "migrates all versions" do
32
31
  expect(subject.versions.all.count).to eql 3
33
32
  end
34
- it "should preserve metadata" do
33
+ it "preserves metadata" do
35
34
  expect(subject.mime_type).to eql "image/png"
36
35
  expect(subject.original_name).to eql "world.png"
37
36
  end
@@ -44,7 +43,7 @@ describe "Versioned content" do
44
43
  expect(subject.versions.count).to eql 0
45
44
  end
46
45
  end
47
- end
46
+ end
48
47
 
49
48
  context "without migrating versions" do
50
49
  subject do
@@ -52,14 +51,13 @@ describe "Versioned content" do
52
51
  mover.migrate
53
52
  mover.target
54
53
  end
55
- it "should migrate only the most recent version" do
54
+ it "migrates only the most recent version" do
56
55
  expect(subject.versions.count).to eql 0
57
- expect(subject.content).to_not be_nil
56
+ expect(subject.content).not_to be_nil
58
57
  end
59
- it "should preserve metadata" do
58
+ it "preserves metadata" do
60
59
  expect(subject.mime_type).to eql "image/png"
61
60
  expect(subject.original_name).to eql "world.png"
62
61
  end
63
62
  end
64
-
65
63
  end