fedora-migrate 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +19 -0
  5. data/Gemfile +7 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +31 -0
  8. data/Rakefile +5 -0
  9. data/config/fedora.yml +14 -0
  10. data/config/fedora3.yml +12 -0
  11. data/config/jetty.yml +6 -0
  12. data/config/solr.yml +15 -0
  13. data/fedora-migrate.gemspec +30 -0
  14. data/lib/fedora-migrate.rb +82 -0
  15. data/lib/fedora_migrate/datastream_mover.rb +78 -0
  16. data/lib/fedora_migrate/errors.rb +7 -0
  17. data/lib/fedora_migrate/file_configurator.rb +34 -0
  18. data/lib/fedora_migrate/hooks.rb +11 -0
  19. data/lib/fedora_migrate/logger.rb +36 -0
  20. data/lib/fedora_migrate/migration_options.rb +11 -0
  21. data/lib/fedora_migrate/mover.rb +44 -0
  22. data/lib/fedora_migrate/object_mover.rb +62 -0
  23. data/lib/fedora_migrate/permissions.rb +32 -0
  24. data/lib/fedora_migrate/permissions_mover.rb +31 -0
  25. data/lib/fedora_migrate/rdf_datastream_mover.rb +28 -0
  26. data/lib/fedora_migrate/rdf_datastream_parser.rb +29 -0
  27. data/lib/fedora_migrate/rels_ext_datastream_mover.rb +90 -0
  28. data/lib/fedora_migrate/repository_migrator.rb +60 -0
  29. data/lib/fedora_migrate/rights_metadata.rb +281 -0
  30. data/lib/fedora_migrate/rubydora_connection.rb +21 -0
  31. data/lib/fedora_migrate/triple_converter.rb +39 -0
  32. data/lib/fedora_migrate/version.rb +3 -0
  33. data/lib/tasks/fedora-migrate.rake +45 -0
  34. data/spec/fixtures/datastreams/rdf_ntriples_datastream.txt +2 -0
  35. data/spec/fixtures/datastreams/sufia-rb68xc089-characterization.xml +27 -0
  36. data/spec/fixtures/objects/f3-migration-a.xml +110 -0
  37. data/spec/fixtures/objects/gf-versioned-content.xml +2776 -0
  38. data/spec/fixtures/objects/sufia-batch-gf-1.xml +94 -0
  39. data/spec/fixtures/objects/sufia-batch-gf-2.xml +93 -0
  40. data/spec/fixtures/objects/sufia-batch.xml +51 -0
  41. data/spec/integration/content_versions_spec.rb +42 -0
  42. data/spec/integration/fedora3_interface_spec.rb +23 -0
  43. data/spec/integration/object_migration_spec.rb +112 -0
  44. data/spec/integration/permission_migration_spec.rb +13 -0
  45. data/spec/integration/rdf_migration_spec.rb +22 -0
  46. data/spec/integration/relationship_migration_spec.rb +51 -0
  47. data/spec/integration/repository_migration_spec.rb +59 -0
  48. data/spec/spec_helper.rb +39 -0
  49. data/spec/support/example_model.rb +36 -0
  50. data/spec/unit/datastream_mover_spec.rb +39 -0
  51. data/spec/unit/fedora_migrate_spec.rb +19 -0
  52. data/spec/unit/file_configurator_spec.rb +17 -0
  53. data/spec/unit/mover_spec.rb +39 -0
  54. data/spec/unit/object_mover_spec.rb +38 -0
  55. data/spec/unit/permissions_mover_spec.rb +53 -0
  56. data/spec/unit/rdf_datastream_mover_spec.rb +8 -0
  57. data/spec/unit/rdf_datastream_parser_spec.rb +38 -0
  58. data/spec/unit/rels_ext_datastream_mover_spec.rb +36 -0
  59. data/spec/unit/repository_migrator_spec.rb +43 -0
  60. data/spec/unit/rubydora_connection_spec.rb +25 -0
  61. data/spec/unit/triple_converter_spec.rb +35 -0
  62. data/tasks/dev.rake +37 -0
  63. metadata +246 -0
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Migrating objects with relationships" do
4
+
5
+ before :all do
6
+ class GenericFile < ActiveFedora::Base
7
+ belongs_to :batch, predicate: ActiveFedora::RDF::RelsExt.isPartOf
8
+ property :title, predicate: ::RDF::DC.title do |index|
9
+ index.as :stored_searchable, :facetable
10
+ end
11
+ property :creator, predicate: ::RDF::DC.creator do |index|
12
+ index.as :stored_searchable, :facetable
13
+ end
14
+ end
15
+
16
+ class Batch < ActiveFedora::Base
17
+ has_many :generic_files, predicate: ActiveFedora::RDF::RelsExt.isPartOf
18
+ end
19
+ end
20
+
21
+ after :all do
22
+ Object.send(:remove_const, :GenericFile) if defined?(GenericFile)
23
+ end
24
+
25
+ let(:parent_source) { FedoraMigrate.source.connection.find("sufia:rb68xc09k") }
26
+ let(:child_source) { FedoraMigrate.source.connection.find("sufia:rb68xc11m") }
27
+
28
+ context "when all objects exist in Fedora4" do
29
+
30
+ before do
31
+ FedoraMigrate::ObjectMover.new(parent_source).migrate
32
+ FedoraMigrate::ObjectMover.new(child_source).migrate
33
+ end
34
+
35
+ describe "migrating the parent object's relationships" do
36
+
37
+ before do
38
+ FedoraMigrate::RelsExtDatastreamMover.new(child_source).migrate
39
+ end
40
+
41
+ subject { Batch.find("rb68xc09k") }
42
+
43
+ specify "you can migrate the parent object's relationships" do
44
+ expect(subject.generic_files.count).to eql 1
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Migrating the repository" do
4
+
5
+ context "when no target objects are defined" do
6
+
7
+ before do
8
+ Object.send(:remove_const, :GenericFile) if defined?(GenericFile)
9
+ Object.send(:remove_const, :Batch) if defined?(Batch)
10
+ end
11
+
12
+ subject do
13
+ results = FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata"})
14
+ results.map { |e| e.values }.flatten
15
+ end
16
+ it { is_expected.to include("uninitialized constant GenericFile")}
17
+ it { is_expected.to include("uninitialized constant Batch")}
18
+ it { is_expected.to include("Source was not found in Fedora4. Did you migrated it?")}
19
+ end
20
+
21
+ context "with all target objects are defined" do
22
+
23
+ before do
24
+ Object.send(:remove_const, :GenericFile) if defined?(GenericFile)
25
+ class GenericFile < ExampleModel::MigrationObject
26
+ belongs_to :batch, predicate: ActiveFedora::RDF::RelsExt.isPartOf
27
+ property :title, predicate: ::RDF::DC.title do |index|
28
+ index.as :stored_searchable, :facetable
29
+ end
30
+ property :creator, predicate: ::RDF::DC.creator do |index|
31
+ index.as :stored_searchable, :facetable
32
+ end
33
+ end
34
+
35
+ Object.send(:remove_const, :Batch) if defined?(Batch)
36
+ class Batch < ActiveFedora::Base
37
+ has_many :generic_files, predicate: ActiveFedora::RDF::RelsExt.isPartOf
38
+ end
39
+ end
40
+
41
+ after do
42
+ Object.send(:remove_const, :GenericFile) if defined?(GenericFile)
43
+ Object.send(:remove_const, :Batch) if defined?(Batch)
44
+ end
45
+
46
+ it "should move every object" do
47
+ results = FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata"})
48
+ expect(results.collect { |r| r.values}.flatten.uniq).to eql [true]
49
+ expect(GenericFile.find("rb68xc089").title).to eql(["world.png"])
50
+ expect(GenericFile.find("xp68km39w").title).to eql(["Sample Migration Object A"])
51
+ expect(GenericFile.find("xp68km39w").creator).to eql(["Adam Wead"])
52
+ expect(GenericFile.all.count).to eql 4
53
+ expect(Batch.all.count).to eql 1
54
+ expect(Batch.first.generic_files.count).to eql 2
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,39 @@
1
+ require 'byebug' unless ENV['TRAVIS']
2
+ require 'fedora-migrate'
3
+ require 'equivalent-xml/rspec_matchers'
4
+ require 'support/example_model'
5
+ require 'active_fedora/cleaner'
6
+ ENV['environment'] = "test"
7
+
8
+ ActiveFedora::Base.logger = Logger.new(STDERR)
9
+ ActiveFedora::Base.logger.level = Logger::WARN
10
+
11
+ RSpec.configure do |config|
12
+ config.expect_with :rspec do |expectations|
13
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
14
+ end
15
+
16
+ # rspec-mocks config goes here. You can use an alternate test double
17
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
18
+ config.mock_with :rspec do |mocks|
19
+ # Prevents you from mocking or stubbing a method that does not exist on
20
+ # a real object. This is generally recommended, and will default to
21
+ # `true` in RSpec 4.
22
+ mocks.verify_partial_doubles = true
23
+ end
24
+
25
+ # Have a clean slate for every test
26
+ config.before(:each) do
27
+ ActiveFedora::Cleaner.clean!
28
+ ActiveFedora::SolrService.instance.conn.delete_by_query('*:*', params: {'softCommit' => true})
29
+ end
30
+
31
+ config.order = :random
32
+
33
+ config.include ExampleModel
34
+
35
+ end
36
+
37
+ def load_fixture file
38
+ File.open("spec/fixtures/datastreams/#{file}")
39
+ end
@@ -0,0 +1,36 @@
1
+ module ExampleModel
2
+
3
+ class RDFProperties < ActiveFedora::Base
4
+ property :title, predicate: ::RDF::DC.title do |index|
5
+ index.as :stored_searchable, :facetable
6
+ end
7
+ property :creator, predicate: ::RDF::DC.creator do |index|
8
+ index.as :stored_searchable, :facetable
9
+ end
10
+ end
11
+
12
+ class VersionedDatastream < ActiveFedora::File
13
+ has_many_versions
14
+ end
15
+
16
+ class VersionedContent < ActiveFedora::Base
17
+ contains "content", class_name: "ExampleModel::VersionedDatastream"
18
+ end
19
+
20
+ class MigrationObject < ActiveFedora::Base
21
+ include Hydra::AccessControls::Permissions
22
+ contains "content", class_name: "ExampleModel::VersionedDatastream"
23
+ contains "thumbnail", class_name: "ActiveFedora::File"
24
+ contains "characterization", class_name: "ActiveFedora::File"
25
+ end
26
+
27
+ class RDFObject < ActiveFedora::Base
28
+ property :title, predicate: ::RDF::DC.title do |index|
29
+ index.as :stored_searchable, :facetable
30
+ end
31
+ contains "content", class_name: "ExampleModel::VersionedDatastream"
32
+ contains "thumbnail", class_name: "ActiveFedora::File"
33
+ contains "characterization", class_name: "ActiveFedora::File"
34
+ end
35
+
36
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::DatastreamMover do
4
+
5
+ describe "#post_initialize" do
6
+ specify "a target is required" do
7
+ expect{subject.new}.to raise_error(StandardError)
8
+ end
9
+ end
10
+
11
+ describe "#versionable?" do
12
+
13
+ let(:versionable_target) { instance_double("Target", :versionable? => true) }
14
+ let(:non_versionable_target) { instance_double("Target", :versionable? => false) }
15
+
16
+ context "by default" do
17
+ subject { FedoraMigrate::DatastreamMover.new("foo","bar") }
18
+ it { is_expected.to_not be_versionable }
19
+ end
20
+ context "when the datastream is not versionable" do
21
+ subject { FedoraMigrate::DatastreamMover.new("source", non_versionable_target) }
22
+ it { is_expected.to_not be_versionable }
23
+ end
24
+ context "when the datastream is versionable" do
25
+ subject { FedoraMigrate::DatastreamMover.new("source", versionable_target) }
26
+ it { is_expected.to be_versionable }
27
+ context "but you want to override that" do
28
+ subject do
29
+ mover = FedoraMigrate::DatastreamMover.new("source", versionable_target)
30
+ mover.versionable = false
31
+ return mover
32
+ end
33
+ it { is_expected.to_not be_versionable }
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate do
4
+
5
+ describe "Fedora3 / " do
6
+
7
+ describe "configuration" do
8
+ subject { FedoraMigrate.fedora_config }
9
+ it { is_expected.to be_kind_of ActiveFedora::Config }
10
+ end
11
+
12
+ describe "connection" do
13
+ subject { FedoraMigrate.source }
14
+ it { is_expected.to be_kind_of FedoraMigrate::RubydoraConnection }
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::FileConfigurator do
4
+
5
+ subject { FedoraMigrate.configurator }
6
+
7
+ describe "#fedora3_config" do
8
+
9
+ it "should use the values from the yml file" do
10
+ expect(subject.fedora3_config[:user]).to eql "fedoraAdmin"
11
+ expect(subject.fedora3_config[:password]).to eql "fedoraAdmin"
12
+ expect(subject.fedora3_config[:url]).to eql "http://localhost:8983/fedora3"
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::Mover do
4
+
5
+ it { is_expected.to respond_to :source }
6
+ it { is_expected.to respond_to :target }
7
+ it { is_expected.to respond_to :options }
8
+
9
+ describe "#new" do
10
+
11
+ context "with two arguments" do
12
+ subject { FedoraMigrate::Mover.new("foo", "bar") }
13
+ specify "has a source" do
14
+ expect(subject.source).to eql("foo")
15
+ end
16
+ specify "has a target" do
17
+ expect(subject.target).to eql("bar")
18
+ end
19
+ end
20
+
21
+ context "with options" do
22
+ subject { FedoraMigrate::Mover.new("foo", "bar", {option: "optional"}) }
23
+ specify "it has an option" do
24
+ expect(subject.options).to eql({option: "optional"})
25
+ end
26
+ end
27
+
28
+ context "with optional arguments" do
29
+ subject { FedoraMigrate::Mover.new("foo") }
30
+ specify "has a source" do
31
+ expect(subject.source).to eql("foo")
32
+ end
33
+ specify "has a target" do
34
+ expect(subject.target).to be_nil
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::ObjectMover do
4
+
5
+ before do
6
+ allow_any_instance_of(FedoraMigrate::ObjectMover).to receive(:create_target_model).and_return("foo")
7
+ end
8
+
9
+ describe "#new" do
10
+
11
+ it { is_expected.to respond_to :source }
12
+ it { is_expected.to respond_to :target }
13
+ it { is_expected.to respond_to :post_initialize }
14
+ end
15
+
16
+ describe "#prepare_target" do
17
+ subject do
18
+ FedoraMigrate::ObjectMover.new("source", "target").prepare_target
19
+ end
20
+ it "should call the before hook and save the target" do
21
+ expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:before_object_migration)
22
+ expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:save).and_return(true)
23
+ expect(subject).to be true
24
+ end
25
+ end
26
+
27
+ describe "#complete_target" do
28
+ subject do
29
+ FedoraMigrate::ObjectMover.new("source", "target").complete_target
30
+ end
31
+ it "should call the after hook and save the target" do
32
+ expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:after_object_migration)
33
+ expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:save).and_return(true)
34
+ expect(subject).to be true
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::PermissionsMover do
4
+
5
+ it { is_expected.to respond_to :rightsMetadata }
6
+
7
+ describe "#post_initialize" do
8
+ specify "a target is required" do
9
+ expect{subject.new}.to raise_error(StandardError)
10
+ end
11
+ end
12
+
13
+ describe "#rightsMetadata" do
14
+ let(:target) { instance_double("Target") }
15
+ let(:source) { instance_double("Source", content: "<rightsMetadata></rightsMetadata>") }
16
+
17
+ subject { FedoraMigrate::PermissionsMover.new(source, target) }
18
+
19
+ it "should be FedoraMigrate::RightsMetadata datastream" do
20
+ expect(subject.rightsMetadata).to be_kind_of FedoraMigrate::RightsMetadata
21
+ end
22
+
23
+ context "with a user" do
24
+ specify "reading" do
25
+ expect(subject.read_users).to be_empty
26
+ end
27
+
28
+ specify "editing" do
29
+ expect(subject.edit_users).to be_empty
30
+ end
31
+
32
+ specify "discovering" do
33
+ expect(subject.discover_users).to be_empty
34
+ end
35
+ end
36
+
37
+ context "with a user" do
38
+ specify "reading" do
39
+ expect(subject.read_groups).to be_empty
40
+ end
41
+
42
+ specify "editing" do
43
+ expect(subject.edit_groups).to be_empty
44
+ end
45
+
46
+ specify "discovering" do
47
+ expect(subject.discover_groups).to be_empty
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::RDFDatastreamMover do
4
+
5
+
6
+
7
+
8
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::RDFDatastreamParser do
4
+
5
+ let(:ds_content) { load_fixture("rdf_ntriples_datastream.txt").read }
6
+ let(:rdf_subject) { 'http://127.0.0.1:8983/fedora/rest/dev/xp/68/km/41/xp68km41x' }
7
+ subject { FedoraMigrate::RDFDatastreamParser.new(rdf_subject, ds_content) }
8
+
9
+ describe "::new" do
10
+ it { is_expected.to respond_to(:subject) }
11
+ it { is_expected.to respond_to(:datastream) }
12
+ it { is_expected.to respond_to(:statements) }
13
+ end
14
+
15
+ describe "#parse" do
16
+
17
+ context "given the raw content from an ActiveFedora::NTriples datastream" do
18
+
19
+ subject { FedoraMigrate::RDFDatastreamParser.new(rdf_subject, ds_content) }
20
+
21
+ before :each do
22
+ subject.parse
23
+ end
24
+
25
+ it "should return an array" do
26
+ expect(subject.statements.count).to eql 2
27
+ end
28
+
29
+ it "should consist of RDF::Statment objects" do
30
+ expect(subject.statements.first).to be_kind_of(RDF::Statement)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+