fedora-migrate 0.1.0 → 0.2.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.
@@ -0,0 +1,166 @@
1
+ {
2
+ "scholarsphere:000000000": {
3
+ "status": true,
4
+ "object": {
5
+ "id": "000000000",
6
+ "class": "Batch",
7
+ "content_datastreams": [
8
+
9
+ ],
10
+ "rdf_datastreams": [
11
+ {
12
+ "ds": "descMetadata",
13
+ "status": [
14
+
15
+ ]
16
+ }
17
+ ],
18
+ "permissions": null,
19
+ "dates": {
20
+ "uploaded": null,
21
+ "modified": null
22
+ }
23
+ },
24
+ "relationships": [
25
+
26
+ ]
27
+ },
28
+ "scholarsphere:000000018": {
29
+ "status": true,
30
+ "object": {
31
+ "id": "000000018",
32
+ "class": "GenericFile",
33
+ "content_datastreams": [
34
+ {
35
+ "ds": "characterization",
36
+ "versions": [
37
+ {
38
+ "name": "",
39
+ "mime_type": "text/xml",
40
+ "original_date": "2013-03-15T11:08:21Z"
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "ds": "content",
46
+ "versions": [
47
+ {
48
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
49
+ "mime_type": "application/pdf",
50
+ "original_date": "2012-09-26T16:09:14Z"
51
+ },
52
+ {
53
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
54
+ "mime_type": "application/pdf",
55
+ "original_date": "2012-11-26T03:11:55Z"
56
+ },
57
+ {
58
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
59
+ "mime_type": "application/pdf",
60
+ "original_date": "2012-11-26T03:12:07Z"
61
+ },
62
+ {
63
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
64
+ "mime_type": "application/pdf",
65
+ "original_date": "2012-11-26T03:12:10Z"
66
+ },
67
+ {
68
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
69
+ "mime_type": "application/pdf",
70
+ "original_date": "2012-11-26T03:12:13Z"
71
+ },
72
+ {
73
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
74
+ "mime_type": "application/pdf",
75
+ "original_date": "2012-11-26T03:12:17Z"
76
+ },
77
+ {
78
+ "name": "Open_Up_Your_RepositoryWith_a_SWORD_.pdf",
79
+ "mime_type": "application/pdf",
80
+ "original_date": "2012-11-26T03:13:12Z"
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ "ds": "thumbnail",
86
+ "versions": [
87
+ {
88
+ "name": "",
89
+ "mime_type": "image/jpeg",
90
+ "original_date": "2014-09-10T15:12:43Z"
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ "ds": "full_text",
96
+ "versions": [
97
+ {
98
+ "name": "File Datastream",
99
+ "mime_type": "application/octet-stream",
100
+ "original_date": "2013-03-14T10:03:13Z"
101
+ }
102
+ ]
103
+ }
104
+ ],
105
+ "rdf_datastreams": [
106
+ {
107
+ "ds": "descMetadata",
108
+ "status": [
109
+
110
+ ]
111
+ }
112
+ ],
113
+ "permissions": [
114
+ "read_groups = [\"public\"]",
115
+ "edit_groups = []",
116
+ "discover_groups = []",
117
+ "read_users = []",
118
+ "edit_users = [\"mjg36\"]",
119
+ "discover_users = []"
120
+ ],
121
+ "dates": {
122
+ "uploaded": "2012-09-26T16:09:13.394Z",
123
+ "modified": "2015-01-02T22:16:02.961Z"
124
+ }
125
+ },
126
+ "relationships": [
127
+ "http://ssrepo2qa.dlt.psu.edu:8080/SSqaFedora4/rest/prod/00/00/00/01/000000018--info:fedora/fedora-system:def/relations-external#isPartOf--http://ssrepo2qa.dlt.psu.edu:8080/SSqaFedora4/rest/prod/00/00/00/00/000000000"
128
+ ]
129
+ },
130
+ "scholarsphere:05741r698": {
131
+ "status": true,
132
+ "object": {
133
+ "id": "05741r698",
134
+ "class": "Batch",
135
+ "content_datastreams": [
136
+
137
+ ],
138
+ "rdf_datastreams": [
139
+ {
140
+ "ds": "descMetadata",
141
+ "status": [
142
+
143
+ ]
144
+ }
145
+ ],
146
+ "permissions": null,
147
+ "dates": {
148
+ "uploaded": null,
149
+ "modified": null
150
+ }
151
+ },
152
+ "relationships": [
153
+
154
+ ]
155
+ },
156
+ "scholarsphere:6395wb555": {
157
+ "status": false,
158
+ "object": "#<Ldp::BadRequest: RDF was not parsable>",
159
+ "relationships": "#<FedoraMigrate::Errors::MigrationError: Target object was not found in Fedora 4. Did you migrate it?>"
160
+ },
161
+ "scholarsphere:x346dm27k": {
162
+ "status": false,
163
+ "object": "#<Ldp::BadRequest: RDF was not parsable>",
164
+ "relationships": "#<FedoraMigrate::Errors::MigrationError: Target object was not found in Fedora 4. Did you migrate it?>"
165
+ }
166
+ }
@@ -12,19 +12,28 @@ describe "Collections with missing files" do
12
12
  end
13
13
 
14
14
  context "when migrating relationships" do
15
-
16
15
  let(:migrated_collection) { ExampleModel::Collection.first }
17
16
  let(:error_message) do
18
17
  "scholarsphere:#{collection} could not migrate relationship info:fedora/fedora-system:def/relations-external#hasCollectionMember because info:fedora/scholarsphere:#{missing_file} doesn't exist in Fedora 4"
19
- end
20
-
21
- it "should only migrate existing relationships and log failed ones" do
22
- expect(FedoraMigrate::Logger).to receive(:warn).with(error_message)
23
- FedoraMigrate::RelsExtDatastreamMover.new(FedoraMigrate.find("scholarsphere:#{collection}")).migrate
18
+ end
19
+ before { FedoraMigrate::RelsExtDatastreamMover.new(FedoraMigrate.find("scholarsphere:#{collection}")).migrate }
20
+ it "should only migrate existing relationships" do
24
21
  expect(migrated_collection.members.count).to eql 2
25
22
  expect(migrated_collection.member_ids).to_not include(missing_file)
26
23
  end
24
+ end
27
25
 
26
+ context "when reporting" do
27
+ subject { FedoraMigrate::RelsExtDatastreamMover.new(FedoraMigrate.find("scholarsphere:#{collection}")).migrate }
28
+ it "should include failed relationships" do
29
+ expect(subject.sort.first).to match(/^could not migrate relationship/)
30
+ end
31
+ it "should include all the possible relationships" do
32
+ expect(subject.count).to eql 3
33
+ end
34
+ it "should include the successful relationships" do
35
+ expect(subject.sort.last).to match(/^http/)
36
+ end
28
37
  end
29
38
 
30
39
  end
@@ -10,9 +10,10 @@ describe "Migrating the repository" do
10
10
  Object.send(:remove_const, :Collection) if defined?(Collection)
11
11
  end
12
12
 
13
- it "should log warnings" do
14
- expect(FedoraMigrate::Logger).to receive(:warn).at_least(6).times
15
- FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata"})
13
+ subject { FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata"}).report }
14
+
15
+ it "should report warnings" do
16
+ expect(subject.failed_objects.count).to eql 9
16
17
  end
17
18
  end
18
19
 
@@ -51,9 +52,7 @@ describe "Migrating the repository" do
51
52
  let(:versions_report) { GenericFile.all.map { |f| f.content.versions.count }.uniq }
52
53
 
53
54
  context "by default" do
54
- before do
55
- FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata"})
56
- end
55
+ before { FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata"}) }
57
56
  it "should move every object and its versions" do
58
57
  expect(file1.title).to eql ["world.png"]
59
58
  expect(file2.title).to eql ["Sample Migration Object A"]
@@ -80,7 +79,27 @@ describe "Migrating the repository" do
80
79
  end
81
80
  end
82
81
 
82
+ context "with an existing report" do
83
+ let(:report) { "spec/fixtures/failed-report.json" }
84
+ let(:new_report) { FedoraMigrate::MigrationReport.new("report.json") }
85
+ before do
86
+ FileUtils.rm("report.json") if File.exists?("report.json")
87
+ migrator = FedoraMigrate.migrate_repository(namespace: "sufia", options: {convert: "descMetadata", report: report})
88
+ migrator.report.save
89
+ end
90
+ after { FileUtils.rm("report.json") }
91
+ it "only migrates the objects that have failed" do
92
+ expect(GenericFile.all.count).to eql 1
93
+ expect(Batch.all.count).to eql 1
94
+ expect(Collection.all.count).to eql 0
95
+ expect(new_report.total_objects).to eql 9
96
+ expect(new_report.failures).to eql 0
97
+ end
98
+ end
99
+
83
100
  end
84
101
 
102
+
103
+
85
104
  end
86
105
 
@@ -12,12 +12,15 @@ describe FedoraMigrate::ContentMover do
12
12
  createDate: Time.new(1993, 02, 24, 12, 0, 0, "+09:00") # Rubydora returns Time objects for datastreams' creation dates
13
13
  )
14
14
  end
15
- let(:target) { double("Target", content: "") }
15
+ let(:target) { double("Target", content: "", original_name: nil, mime_type: nil) }
16
16
 
17
17
  describe "#migrate" do
18
18
  context "without content" do
19
19
  subject { FedoraMigrate::ContentMover.new(nil_source, target).migrate }
20
- it { is_expected.to be true }
20
+ it "reports a nil source" do
21
+ expect(subject).to be_kind_of FedoraMigrate::ContentMover::Report
22
+ expect(subject.error).to eql "Nil source -- it's probably defined in the target but not present in the source"
23
+ end
21
24
  end
22
25
  context "with content" do
23
26
  subject { FedoraMigrate::ContentMover.new(source, target).migrate }
@@ -25,7 +28,7 @@ describe FedoraMigrate::ContentMover do
25
28
  allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:move_content).and_return(true)
26
29
  allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:insert_date_created_by_application).and_return(true)
27
30
  end
28
- it { is_expected.to be true }
31
+ it { is_expected.to be_kind_of FedoraMigrate::ContentMover::Report }
29
32
  end
30
33
  end
31
34
 
@@ -34,13 +37,19 @@ describe FedoraMigrate::ContentMover do
34
37
  allow(target).to receive(:content=).with("foo")
35
38
  allow(target).to receive(:original_name=).with("label")
36
39
  allow(target).to receive(:mime_type=).with("mimetype")
37
- allow(target).to receive(:save).and_return(true)
38
- allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:insert_date_created_by_application).and_return(true)
40
+ allow(target).to receive(:save).and_return(true)
39
41
  end
40
42
  subject do
41
43
  FedoraMigrate::ContentMover.new(source, target).move_content
42
44
  end
43
- it { is_expected.to be true }
45
+ context "with a valid checksum" do
46
+ before { allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:valid?).and_return(true) }
47
+ it { is_expected.to be nil }
48
+ end
49
+ context "with an invalid checksum" do
50
+ before { allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:valid?).and_return(false) }
51
+ it { is_expected.to eql "Failed checksum" }
52
+ end
44
53
  end
45
54
 
46
55
  describe "#insert_date_created_by_application" do
@@ -48,14 +57,12 @@ describe FedoraMigrate::ContentMover do
48
57
  context "with a successful update" do
49
58
  let(:successful_status) { double("Result", status: 204) }
50
59
  before { allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:perform_sparql_insert).and_return(successful_status) }
51
- it { is_expected.to be true }
60
+ it { is_expected.to be nil }
52
61
  end
53
62
  context "with an unsuccessful update" do
54
63
  let(:unsuccessful_status) { double("Result", status: 404, body: "Error!") }
55
64
  before { allow_any_instance_of(FedoraMigrate::ContentMover).to receive(:perform_sparql_insert).and_return(unsuccessful_status) }
56
- it "should raise an error" do
57
- expect { subject }.to raise_error FedoraMigrate::Errors::MigrationError
58
- end
65
+ it { is_expected.to eql "There was a problem with sparql 404 Error!" }
59
66
  end
60
67
  end
61
68
 
@@ -23,10 +23,7 @@ describe FedoraMigrate::DatastreamVerification do
23
23
  context "that do not match Fedora4's checksum" do
24
24
  subject { TestSubject.new(bad_binary_source) }
25
25
  before { allow(subject).to receive(:target_checksum).twice.and_return("bar") }
26
- specify "are not valid and logged" do
27
- expect(FedoraMigrate::Logger).to receive(:warn)
28
- expect(subject).to_not be_valid
29
- end
26
+ it { is_expected.to_not be_valid }
30
27
  end
31
28
  context "when the checksum is missing" do
32
29
  subject { TestSubject.new(missing_checksum) }
@@ -37,10 +34,7 @@ describe FedoraMigrate::DatastreamVerification do
37
34
  end
38
35
  context "and a newly calculated checksum does not match" do
39
36
  before { expect_any_instance_of(TestSubject).to receive(:target_checksum).twice.and_return(Digest::SHA1.hexdigest("bar")) }
40
- specify "are not valid and logged" do
41
- expect(FedoraMigrate::Logger).to receive(:warn)
42
- expect(subject).to_not be_valid
43
- end
37
+ it { is_expected.to_not be_valid }
44
38
  end
45
39
  end
46
40
  end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe FedoraMigrate::MigrationReport do
4
+
5
+ let(:existing_report) { FedoraMigrate::MigrationReport.new("spec/fixtures/sample-report.json") }
6
+ let(:new_report) { FedoraMigrate::MigrationReport.new }
7
+
8
+ context "with an existing report" do
9
+ subject { existing_report }
10
+ it { is_expected.not_to be_empty }
11
+ describe "::results" do
12
+ subject { existing_report.results }
13
+ it { is_expected.to be_kind_of(Hash) }
14
+ end
15
+ describe "::failed_objects" do
16
+ subject { existing_report.failed_objects }
17
+ it { is_expected.to include("scholarsphere:6395wb555", "scholarsphere:x346dm27k") }
18
+ end
19
+ describe "::failures" do
20
+ subject { existing_report.failures }
21
+ context "when the report contains failed migrations" do
22
+ it { is_expected.to eq 2 }
23
+ end
24
+ end
25
+ describe "::total_objects" do
26
+ subject { existing_report.total_objects }
27
+ it { is_expected.to eq 5 }
28
+ end
29
+ describe "::report_failures" do
30
+ subject { existing_report.report_failures }
31
+ it { is_expected.to be_kind_of(String) }
32
+ end
33
+ describe "::save" do
34
+ context "with the default path" do
35
+ it "should write the report" do
36
+ expect(File).to receive(:write).with("report.json", "{\n}")
37
+ new_report.save
38
+ end
39
+ end
40
+ context "with a user-provided path" do
41
+ it "should write the report" do
42
+ expect(File).to receive(:write).with("foo/path/report.json", "{\n}")
43
+ new_report.save("foo/path")
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ context "as a new report" do
50
+ subject { new_report }
51
+ it { is_expected.to be_empty }
52
+ describe "::results" do
53
+ subject { new_report.results }
54
+ it { is_expected.to be_kind_of(Hash) }
55
+ end
56
+ end
57
+
58
+ end
@@ -14,7 +14,7 @@ describe FedoraMigrate::ObjectMover do
14
14
 
15
15
  describe "#prepare_target" do
16
16
  subject do
17
- FedoraMigrate::ObjectMover.new("source", "target").prepare_target
17
+ FedoraMigrate::ObjectMover.new("source", double("Target", id: nil)).prepare_target
18
18
  end
19
19
  it "should call the before hook and save the target" do
20
20
  expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:before_object_migration)
@@ -24,7 +24,7 @@ describe FedoraMigrate::ObjectMover do
24
24
 
25
25
  describe "#complete_target" do
26
26
  subject do
27
- FedoraMigrate::ObjectMover.new("source", "target").complete_target
27
+ FedoraMigrate::ObjectMover.new("source", double("Target", id: nil)).complete_target
28
28
  end
29
29
  it "should call the after hook and save the target" do
30
30
  expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:after_object_migration)
@@ -5,23 +5,52 @@ describe FedoraMigrate::RepositoryMigrator do
5
5
  let(:namespace) { "sufia" }
6
6
 
7
7
  it { is_expected.to respond_to(:source_objects) }
8
- it { is_expected.to respond_to(:failed) }
8
+ it { is_expected.to respond_to(:report) }
9
9
  it { is_expected.to respond_to(:namespace) }
10
10
 
11
- describe "#failed" do
12
- specify "sets to zero" do
13
- expect(subject.failed).to eql(0)
11
+ def mock_report content
12
+ report = FedoraMigrate::MigrationReport.new
13
+ report.results = JSON.parse(content.to_json)
14
+ report
15
+ end
16
+
17
+ describe "#failures" do
18
+ context "when objects have failed to migrate" do
19
+ let(:failing_report) { { "sufia:rb68xc089" => FedoraMigrate::RepositoryMigrator::SingleObjectReport.new(false, "objects", "relationships") } }
20
+ before { allow_any_instance_of(FedoraMigrate::RepositoryMigrator).to receive(:report).and_return(mock_report(failing_report)) }
21
+ subject do
22
+ migrator = FedoraMigrate::RepositoryMigrator.new(namespace)
23
+ migrator.failures
24
+ end
25
+ it { is_expected.to be 1 }
26
+ end
27
+ context "when all objects have migrated" do
28
+ let(:passing_report) { { "sufia:rb68xc089" => FedoraMigrate::RepositoryMigrator::SingleObjectReport.new(true, "objects", "relationships") } }
29
+ before { allow_any_instance_of(FedoraMigrate::RepositoryMigrator).to receive(:report).and_return(mock_report(passing_report)) }
30
+ subject do
31
+ migrator = FedoraMigrate::RepositoryMigrator.new(namespace)
32
+ migrator.failures
33
+ end
34
+ it { is_expected.to eql 0 }
14
35
  end
15
36
  end
16
37
 
17
- context "when forcing" do
38
+ describe "forcing relationship migration" do
18
39
  before do
19
- allow_any_instance_of(FedoraMigrate::RepositoryMigrator).to receive(:source_objects).and_return([])
20
- allow_any_instance_of(FedoraMigrate::RepositoryMigrator).to receive(:failed).and_return(1)
40
+ allow(subject).to receive(:source_objects).and_return([])
41
+ allow(subject).to receive(:failures).and_return(1)
42
+ end
43
+ context "without an explicit force" do
44
+ subject { FedoraMigrate::RepositoryMigrator.new(namespace) }
45
+ it "should not migrate relationships" do
46
+ expect(subject.migrate_relationships).to eql("Relationship migration halted because 1 objects didn't migrate successfully.")
47
+ end
21
48
  end
22
- subject { FedoraMigrate::RepositoryMigrator.new(namespace, { force: true }) }
23
- specify "migrate relationships if failures are present" do
24
- expect(subject.migrate_relationships).to be true
49
+ context "with an explicit force" do
50
+ subject { FedoraMigrate::RepositoryMigrator.new(namespace, { force: true }) }
51
+ it "should migrate relationships" do
52
+ expect(subject.migrate_relationships).to_not be_nil
53
+ end
25
54
  end
26
55
  end
27
56