fedora-migrate 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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