hydra-works 0.7.1 → 0.8
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +38 -12
- data/hydra-works.gemspec +1 -1
- data/lib/hydra/works.rb +2 -0
- data/lib/hydra/works/models/concerns/collection_behavior.rb +7 -1
- data/lib/hydra/works/models/concerns/file_set/mime_types.rb +0 -5
- data/lib/hydra/works/models/concerns/file_set_behavior.rb +7 -3
- data/lib/hydra/works/models/concerns/work_behavior.rb +10 -1
- data/lib/hydra/works/not_collection_validator.rb +9 -0
- data/lib/hydra/works/not_file_set_validator.rb +9 -0
- data/lib/hydra/works/services/add_file_to_file_set.rb +4 -9
- data/lib/hydra/works/services/persist_derivative.rb +3 -1
- data/lib/hydra/works/version.rb +1 -1
- data/spec/hydra/works/models/characterization/fits_datastream_spec.rb +8 -0
- data/spec/hydra/works/models/collection_spec.rb +27 -1
- data/spec/hydra/works/models/concerns/file_set/virus_check_spec.rb +66 -32
- data/spec/hydra/works/models/concerns/file_set_behavior_spec.rb +4 -0
- data/spec/hydra/works/models/file_set_spec.rb +26 -0
- data/spec/hydra/works/models/work_spec.rb +55 -15
- data/spec/hydra/works/services/add_file_to_file_set_spec.rb +29 -0
- data/spec/hydra/works/services/persist_derivatives_spec.rb +24 -1
- data/spec/hydra/works/services/upload_file_spec.rb +15 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 028f44443d1d3bdcfbff713b15bc1b59cffb8e2c
|
4
|
+
data.tar.gz: 401c0b9112abc87e79319fe6ba0a3bf2849be4db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93b2a91ae3c98474558c00d1b23d9cc006028aa13f6691adc5850d28ca7efa39a15fdfca577852b3633eabaf259f0d7cc22c0b7964b40c32a32ce5f6f0ed9634
|
7
|
+
data.tar.gz: f0bc3421b8a91e55c20f815b0b6fb2600c2aee1bf287de7e36aca8fe204a3ebe104d10468360018a1ce35792c1d48875285f3cd5b1323598f4365fa4947c362c
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -9,15 +9,20 @@
|
|
9
9
|
[](http://rubydoc.info/gems/hydra-works)
|
10
10
|
[](https://waffle.io/projecthydra-labs/hydra-works?source=projecthydra-labs%2Fhydra-works)
|
11
11
|
|
12
|
-
The Hydra::Works gem
|
12
|
+
The Hydra::Works gem implements the [PCDM](https://github.com/duraspace/pcdm/wiki) [Works](https://github.com/duraspace/pcdm/blob/master/pcdm-ext/works.rdf) data model using ActiveFedora-based models. In addition to the models, Hydra::Works includes associated behaviors around the broad concept of describable "works" or intellectual entities, the need for which was expressed by a variety of [Hydra community use cases](https://github.com/projecthydra-labs/hydra-works/tree/master/use-cases). The PCDM Works domain model includes the following high-level entities:
|
13
13
|
|
14
|
-
* **
|
15
|
-
* **Work**: a *
|
16
|
-
* **
|
14
|
+
* **Collection**: a *pcdm:Collection* that indirectly contains zero or more **Works** and zero or more **Collection**s
|
15
|
+
* **Work**: a *pcdm:Object* that holds zero or more **FileSets** and zero or more **Works**
|
16
|
+
* **FileSet**: a *pcdm:Object* that groups one or more related *pcdm:Files*, such as an original file (e.g., PDF document), its derivatives (e.g., a thumbnail), and extracted full-text
|
17
17
|
|
18
|
-
|
18
|
+
Behaviors included in the model include:
|
19
19
|
|
20
|
-
|
20
|
+
* Characterization of original files within FileSets
|
21
|
+
* Generation of derivatives from original files
|
22
|
+
* Virus checking of original files
|
23
|
+
* Full-text extraction from original files
|
24
|
+
|
25
|
+
Check out the [Hydra::Derivatives README](https://github.com/projecthydra/hydra-derivatives#dependencies) for additional dependencies.
|
21
26
|
|
22
27
|
## Installation
|
23
28
|
|
@@ -90,12 +95,33 @@ If you'd like to contribute to this effort, please check out the [contributing g
|
|
90
95
|
|
91
96
|
## Development
|
92
97
|
|
93
|
-
|
98
|
+
### Testing with the continuous integration server
|
99
|
+
|
100
|
+
You can test Hydra::Works using the same process as our continuous
|
101
|
+
integration server. To do that, run the default rake task which will download Solr and Fedora, start them,
|
102
|
+
and run the tests for you.
|
103
|
+
|
104
|
+
```bash
|
105
|
+
rake
|
106
|
+
```
|
107
|
+
|
108
|
+
### Testing manually
|
94
109
|
|
95
|
-
|
96
|
-
$ rake hydra_works:jetty:config
|
110
|
+
If you want to run the tests manually, follow these instructions:
|
97
111
|
|
98
|
-
|
112
|
+
```bash
|
113
|
+
solr_wrapper -d solr/config/
|
114
|
+
```
|
99
115
|
|
100
|
-
|
101
|
-
|
116
|
+
To start FCRepo, open another shell and run:
|
117
|
+
|
118
|
+
```bash
|
119
|
+
fcrepo_wrapper -p 8984
|
120
|
+
```
|
121
|
+
|
122
|
+
Now you’re ready to run the tests. In the directory where hydra-works
|
123
|
+
is installed, run:
|
124
|
+
|
125
|
+
```bash
|
126
|
+
rake spec
|
127
|
+
```
|
data/hydra-works.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'hydra-pcdm', '~> 0.
|
21
|
+
spec.add_dependency 'hydra-pcdm', '~> 0.5'
|
22
22
|
spec.add_dependency 'hydra-derivatives', '~> 3.0'
|
23
23
|
spec.add_dependency 'hydra-file_characterization', '~> 0.3', '>= 0.3.3'
|
24
24
|
|
data/lib/hydra/works.rb
CHANGED
@@ -15,10 +15,16 @@ module Hydra::Works
|
|
15
15
|
# 9) Hydra::Works::Collection can have access metadata
|
16
16
|
module CollectionBehavior
|
17
17
|
extend ActiveSupport::Concern
|
18
|
-
include Hydra::PCDM::CollectionBehavior
|
19
18
|
|
20
19
|
included do
|
20
|
+
def self.type_validator
|
21
|
+
Hydra::PCDM::Validators::CompositeValidator.new(
|
22
|
+
super,
|
23
|
+
Hydra::Works::NotFileSetValidator
|
24
|
+
)
|
25
|
+
end
|
21
26
|
type [Hydra::PCDM::Vocab::PCDMTerms.Collection, Vocab::WorksTerms.Collection]
|
27
|
+
include Hydra::PCDM::CollectionBehavior
|
22
28
|
end
|
23
29
|
|
24
30
|
def ordered_works
|
@@ -23,11 +23,6 @@ module Hydra::Works
|
|
23
23
|
self.class.office_document_mime_types.include? mime_type
|
24
24
|
end
|
25
25
|
|
26
|
-
# TODO: remove?
|
27
|
-
def collection?
|
28
|
-
false
|
29
|
-
end
|
30
|
-
|
31
26
|
module ClassMethods
|
32
27
|
def image_mime_types
|
33
28
|
['image/png', 'image/jpeg', 'image/jpg', 'image/jp2', 'image/bmp', 'image/gif', 'image/tiff']
|
@@ -10,16 +10,20 @@ module Hydra::Works
|
|
10
10
|
# 6) Hydra::Works::FileSet can have access metadata
|
11
11
|
module FileSetBehavior
|
12
12
|
extend ActiveSupport::Concern
|
13
|
-
include Hydra::PCDM::ObjectBehavior
|
14
13
|
|
15
14
|
included do
|
15
|
+
def self.type_validator
|
16
|
+
Hydra::PCDM::Validators::CompositeValidator.new(
|
17
|
+
Hydra::Works::NotCollectionValidator,
|
18
|
+
super
|
19
|
+
)
|
20
|
+
end
|
16
21
|
type [Hydra::PCDM::Vocab::PCDMTerms.Object, Vocab::WorksTerms.FileSet]
|
17
|
-
|
22
|
+
include Hydra::PCDM::ObjectBehavior
|
18
23
|
include Hydra::Works::ContainedFiles
|
19
24
|
include Hydra::Works::Derivatives
|
20
25
|
include Hydra::Works::MimeTypes
|
21
26
|
include Hydra::Works::VersionedContent
|
22
|
-
|
23
27
|
before_destroy :remove_from_works
|
24
28
|
end
|
25
29
|
|
@@ -14,10 +14,17 @@ module Hydra::Works
|
|
14
14
|
# 10) Hydra::Works::Work can have access metadata
|
15
15
|
module WorkBehavior
|
16
16
|
extend ActiveSupport::Concern
|
17
|
-
|
17
|
+
extend Deprecation
|
18
18
|
|
19
19
|
included do
|
20
|
+
def self.type_validator
|
21
|
+
Hydra::PCDM::Validators::CompositeValidator.new(
|
22
|
+
Hydra::Works::NotCollectionValidator,
|
23
|
+
super
|
24
|
+
)
|
25
|
+
end
|
20
26
|
type [Hydra::PCDM::Vocab::PCDMTerms.Object, Vocab::WorksTerms.Work]
|
27
|
+
include Hydra::PCDM::ObjectBehavior
|
21
28
|
before_destroy :remove_from_parents
|
22
29
|
end
|
23
30
|
|
@@ -46,10 +53,12 @@ module Hydra::Works
|
|
46
53
|
end
|
47
54
|
|
48
55
|
def ordered_file_sets
|
56
|
+
Deprecation.warn WorkBehavior, "ordered_file_sets is deprecated and will be removed in Hydra::Works 1.0. If you need order, use an interstitial work node."
|
49
57
|
ordered_members.to_a.select(&:file_set?)
|
50
58
|
end
|
51
59
|
|
52
60
|
def ordered_file_set_ids
|
61
|
+
Deprecation.warn WorkBehavior, "ordered_file_set_ids is deprecated and will be removed in Hydra::Works 1.0. If you need order, use an interstitial work node."
|
53
62
|
ordered_file_sets.map(&:id)
|
54
63
|
end
|
55
64
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Hydra::Works
|
2
|
+
class NotCollectionValidator
|
3
|
+
def self.validate!(_association, record)
|
4
|
+
if record.try(:collection?)
|
5
|
+
raise ActiveFedora::AssociationTypeMismatch, "#{record} is a Collection and may not be a member of the association"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -56,15 +56,10 @@ module Hydra::Works
|
|
56
56
|
# Return mime_type based on methods available to file
|
57
57
|
# @param object for mimetype to be determined. Attempts to use methods: :mime_type, :content_type, and :path.
|
58
58
|
def determine_mime_type(file)
|
59
|
-
if file.respond_to? :mime_type
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
elsif file.respond_to? :path
|
64
|
-
Hydra::PCDM::GetMimeTypeForFile.call(file.path)
|
65
|
-
else
|
66
|
-
'application/octet-stream'
|
67
|
-
end
|
59
|
+
return file.mime_type if file.respond_to? :mime_type
|
60
|
+
return file.content_type if file.respond_to? :content_type
|
61
|
+
return Hydra::PCDM::GetMimeTypeForFile.call(file.path) if file.respond_to? :path
|
62
|
+
'application/octet-stream'
|
68
63
|
end
|
69
64
|
|
70
65
|
# Return original_name based on methods available to file
|
@@ -5,7 +5,9 @@ module Hydra::Works
|
|
5
5
|
##
|
6
6
|
# Persists a derivative to a FileSet
|
7
7
|
# This Service conforms to the signature of `Hydra::Derivatives::PersistOutputFileService`.
|
8
|
-
# The purpose of this Service is for use as an alternative to the default Hydra::Derivatives::PersistOutputFileService.
|
8
|
+
# The purpose of this Service is for use as an alternative to the default Hydra::Derivatives::PersistOutputFileService.
|
9
|
+
# It's necessary because the default behavior in Hydra::Derivatives assumes that you're using LDP Basic Containment.
|
10
|
+
# Hydra::Works::FileSets use IndirectContainment. This Service handles that case.
|
9
11
|
# This service will always update existing and does not do versioning of persisted files.
|
10
12
|
#
|
11
13
|
# @param [#read] stream the derivative filestream
|
data/lib/hydra/works/version.rb
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hydra::Works::Characterization::FitsDatastream do
|
4
|
+
it 'defines an xml template' do
|
5
|
+
templ = described_class.xml_template.remove_namespaces!
|
6
|
+
expect(templ.xpath('/fits/identification/identity/@toolname').first.value).to eq('FITS')
|
7
|
+
end
|
8
|
+
end
|
@@ -2,7 +2,6 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Hydra::Works::Collection do
|
4
4
|
let(:collection) { described_class.new }
|
5
|
-
|
6
5
|
let(:collection1) { described_class.new }
|
7
6
|
let(:work1) { Hydra::Works::Work.new }
|
8
7
|
|
@@ -89,6 +88,14 @@ describe Hydra::Works::Collection do
|
|
89
88
|
end
|
90
89
|
end
|
91
90
|
|
91
|
+
describe "#work_ids" do
|
92
|
+
subject { collection.work_ids }
|
93
|
+
it "returns IDs of works" do
|
94
|
+
collection.members = [work1]
|
95
|
+
expect(subject).to eq [work1.id]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
92
99
|
describe '#related_objects' do
|
93
100
|
subject { collection.related_objects }
|
94
101
|
let(:object) { Hydra::PCDM::Object.new }
|
@@ -110,4 +117,23 @@ describe Hydra::Works::Collection do
|
|
110
117
|
subject { collection.in_collections }
|
111
118
|
it { is_expected.to eq [collection1] }
|
112
119
|
end
|
120
|
+
|
121
|
+
describe 'adding file_sets to collections' do
|
122
|
+
let(:file_set) { Hydra::Works::FileSet.new }
|
123
|
+
let(:exception) { ActiveFedora::AssociationTypeMismatch }
|
124
|
+
context 'with ordered members' do
|
125
|
+
it 'raises AssociationTypeMismatch' do
|
126
|
+
expect { collection.ordered_members = [file_set] }.to raise_error(exception)
|
127
|
+
expect { collection.ordered_members += [file_set] }.to raise_error(exception)
|
128
|
+
expect { collection.ordered_members << file_set }.to raise_error(exception)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
context 'with unordered members' do
|
132
|
+
it 'raises AssociationTypeMismatch' do
|
133
|
+
expect { collection.members = [file_set] }.to raise_error(exception)
|
134
|
+
expect { collection.members += [file_set] }.to raise_error(exception)
|
135
|
+
expect { collection.members << file_set }.to raise_error(exception)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
113
139
|
end
|
@@ -1,53 +1,87 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hydra::Works::VirusCheck do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
class ClamAV
|
10
|
-
def self.instance
|
11
|
-
@instance ||= ClamAV.new
|
4
|
+
context "with ClamAV" do
|
5
|
+
before do
|
6
|
+
class FileWithVirusCheck < ActiveFedora::Base
|
7
|
+
include Hydra::Works::FileSetBehavior
|
8
|
+
include Hydra::Works::VirusCheck
|
12
9
|
end
|
10
|
+
class ClamAV
|
11
|
+
def self.instance
|
12
|
+
@instance ||= ClamAV.new
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
def scanfile(path)
|
16
|
+
puts "scanfile: #{path}"
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
subject { FileWithVirusCheck.new }
|
25
|
-
let(:file) { Hydra::PCDM::File.new File.join(fixture_path, 'sample-file.pdf') }
|
20
|
+
after do
|
21
|
+
Object.send(:remove_const, :ClamAV)
|
22
|
+
Object.send(:remove_const, :FileWithVirusCheck)
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
allow(subject).to receive(:warn) # suppress virus warning messages
|
30
|
-
end
|
25
|
+
subject { FileWithVirusCheck.new }
|
26
|
+
let(:file) { Hydra::PCDM::File.new File.join(fixture_path, 'sample-file.pdf') }
|
31
27
|
|
32
|
-
context 'with an infected file' do
|
33
28
|
before do
|
34
|
-
|
29
|
+
allow(subject).to receive(:original_file) { file }
|
30
|
+
allow(subject).to receive(:warn) # suppress virus warning messages
|
35
31
|
end
|
36
|
-
|
37
|
-
|
32
|
+
|
33
|
+
context 'with an infected file' do
|
34
|
+
before do
|
35
|
+
expect(ClamAV.instance).to receive(:scanfile).and_return(1)
|
36
|
+
end
|
37
|
+
it 'fails to save' do
|
38
|
+
expect(subject.save).to eq false
|
39
|
+
end
|
40
|
+
it 'fails to validate' do
|
41
|
+
expect(subject.validate).to eq false
|
42
|
+
end
|
38
43
|
end
|
39
|
-
|
40
|
-
|
44
|
+
|
45
|
+
context 'with a clean file' do
|
46
|
+
before do
|
47
|
+
expect(ClamAV.instance).to receive(:scanfile).and_return(0)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'does not detect viruses' do
|
51
|
+
expect(subject.detect_viruses).to eq true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with a file that responds to :path' do
|
56
|
+
before do
|
57
|
+
allow(file).to receive(:path).and_return('/tmp/file.pdf')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'gets the filename from :path' do
|
61
|
+
expect(subject.send(:local_path_for_file, file)).to eq('/tmp/file.pdf')
|
62
|
+
end
|
41
63
|
end
|
42
64
|
end
|
43
65
|
|
44
|
-
context
|
66
|
+
context "Without ClamAV" do
|
67
|
+
before do
|
68
|
+
class FileWithVirusCheck < ActiveFedora::Base
|
69
|
+
include Hydra::Works::FileSetBehavior
|
70
|
+
include Hydra::Works::VirusCheck
|
71
|
+
end
|
72
|
+
Object.send(:remove_const, :ClamAV) if defined?(ClamAV)
|
73
|
+
end
|
74
|
+
|
75
|
+
subject { FileWithVirusCheck.new }
|
76
|
+
let(:file) { Hydra::PCDM::File.new File.join(fixture_path, 'sample-file.pdf') }
|
77
|
+
|
45
78
|
before do
|
46
|
-
|
79
|
+
allow(subject).to receive(:original_file) { file }
|
47
80
|
end
|
48
81
|
|
49
|
-
it '
|
50
|
-
expect(subject
|
82
|
+
it 'warns if ClamAV is not defined' do
|
83
|
+
expect(subject).to receive(:warning) # .with("Virus checking disabled, sample-file.pdf not checked")
|
84
|
+
expect(subject.detect_viruses).to eq nil
|
51
85
|
end
|
52
86
|
end
|
53
87
|
end
|
@@ -54,4 +54,30 @@ describe Hydra::Works::FileSet do
|
|
54
54
|
.and change { work.reload.ordered_member_proxies.to_a.length }.by(-1)
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
describe 'adding collections to file sets' do
|
59
|
+
let(:collection) { Hydra::Works::Collection.new }
|
60
|
+
let(:exception) { ActiveFedora::AssociationTypeMismatch }
|
61
|
+
let(:error_regex) { /is a Collection and may not be a member of the association/ }
|
62
|
+
context 'with ordered members' do
|
63
|
+
it 'raises AssociationTypeMismatch with a helpful error message' do
|
64
|
+
expect { file_set.ordered_members = [collection] }.to raise_error(exception, error_regex)
|
65
|
+
expect { file_set.ordered_members += [collection] }.to raise_error(exception, error_regex)
|
66
|
+
expect { file_set.ordered_members << collection }.to raise_error(exception, error_regex)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
context 'with unordered members' do
|
70
|
+
it 'raises AssociationTypeMismatch with a helpful error message' do
|
71
|
+
expect { file_set.members = [collection] }.to raise_error(exception, error_regex)
|
72
|
+
expect { file_set.members += [collection] }.to raise_error(exception, error_regex)
|
73
|
+
expect { file_set.members << collection }.to raise_error(exception, error_regex)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#collection?' do
|
79
|
+
it 'is not a collection' do
|
80
|
+
expect(file_set.collection?).to be false
|
81
|
+
end
|
82
|
+
end
|
57
83
|
end
|
@@ -23,7 +23,9 @@ describe Hydra::Works::Work do
|
|
23
23
|
work1.ordered_members << file_set2
|
24
24
|
|
25
25
|
expect(work1.file_set_ids).to eq [file_set1.id, file_set2.id]
|
26
|
-
|
26
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
27
|
+
expect(work1.ordered_file_set_ids).to eq [file_set2.id]
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
@@ -58,7 +60,9 @@ describe Hydra::Works::Work do
|
|
58
60
|
describe '#ordered_file_set_ids' do
|
59
61
|
it 'lists file_set ids' do
|
60
62
|
work1.ordered_members = [file_set1, file_set2]
|
61
|
-
|
63
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
64
|
+
expect(work1.ordered_file_set_ids).to eq [file_set1.id, file_set2.id]
|
65
|
+
end
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
@@ -71,7 +75,9 @@ describe Hydra::Works::Work do
|
|
71
75
|
subject { TestWork.new(ordered_members: [file_set1]) }
|
72
76
|
|
73
77
|
it 'has many file sets' do
|
74
|
-
|
78
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
79
|
+
expect(subject.ordered_file_sets).to eq [file_set1]
|
80
|
+
end
|
75
81
|
end
|
76
82
|
end
|
77
83
|
|
@@ -141,12 +147,14 @@ describe Hydra::Works::Work do
|
|
141
147
|
subject.ordered_members << file_set2
|
142
148
|
end
|
143
149
|
it 'moves file from one work to another' do
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
151
|
+
expect(subject.ordered_file_sets).to eq([file_set1, file_set2])
|
152
|
+
expect(work1.ordered_file_sets).to eq([])
|
153
|
+
subject.ordered_member_proxies.delete_at(0)
|
154
|
+
work1.ordered_members << file_set1
|
155
|
+
expect(subject.ordered_file_sets).to eq([file_set2])
|
156
|
+
expect(work1.ordered_file_sets).to eq([file_set1])
|
157
|
+
end
|
150
158
|
end
|
151
159
|
end
|
152
160
|
|
@@ -154,7 +162,9 @@ describe Hydra::Works::Work do
|
|
154
162
|
it 'returns empty array when only works are aggregated' do
|
155
163
|
subject.ordered_members << work1
|
156
164
|
subject.ordered_members << work2
|
157
|
-
|
165
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
166
|
+
expect(subject.ordered_file_sets).to eq []
|
167
|
+
end
|
158
168
|
end
|
159
169
|
|
160
170
|
context 'with file_sets and works' do
|
@@ -166,7 +176,9 @@ describe Hydra::Works::Work do
|
|
166
176
|
end
|
167
177
|
|
168
178
|
it 'returns only file_sets' do
|
169
|
-
|
179
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
180
|
+
expect(subject.ordered_file_sets).to eq [file_set1, file_set2]
|
181
|
+
end
|
170
182
|
end
|
171
183
|
end
|
172
184
|
end
|
@@ -184,29 +196,57 @@ describe Hydra::Works::Work do
|
|
184
196
|
subject.ordered_members << file_set4
|
185
197
|
subject.ordered_members << work1
|
186
198
|
subject.ordered_members << file_set5
|
187
|
-
|
199
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
200
|
+
expect(subject.ordered_file_sets).to eq [file_set1, file_set2, file_set3, file_set4, file_set5]
|
201
|
+
end
|
188
202
|
end
|
189
203
|
|
190
204
|
it 'removes first collection' do
|
191
205
|
subject.ordered_member_proxies.delete_at(0)
|
192
|
-
|
206
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
207
|
+
expect(subject.ordered_file_sets).to eq [file_set2, file_set3, file_set4, file_set5]
|
208
|
+
end
|
193
209
|
expect(subject.ordered_works).to eq [work2, work1]
|
194
210
|
end
|
195
211
|
|
196
212
|
it 'removes last collection' do
|
197
213
|
subject.ordered_member_proxies.delete_at(6)
|
198
|
-
|
214
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
215
|
+
expect(subject.ordered_file_sets).to eq [file_set1, file_set2, file_set3, file_set4]
|
216
|
+
end
|
199
217
|
expect(subject.ordered_works).to eq [work2, work1]
|
200
218
|
end
|
201
219
|
|
202
220
|
it 'removes middle collection' do
|
203
221
|
subject.ordered_member_proxies.delete_at(3)
|
204
|
-
|
222
|
+
Deprecation.silence Hydra::Works::WorkBehavior do
|
223
|
+
expect(subject.ordered_file_sets).to eq [file_set1, file_set2, file_set4, file_set5]
|
224
|
+
end
|
205
225
|
expect(subject.ordered_works).to eq [work2, work1]
|
206
226
|
end
|
207
227
|
end
|
208
228
|
end
|
209
229
|
|
230
|
+
describe 'adding collections to works' do
|
231
|
+
let(:collection) { Hydra::Works::Collection.new }
|
232
|
+
let(:exception) { ActiveFedora::AssociationTypeMismatch }
|
233
|
+
let(:error_regex) { /is a Collection and may not be a member of the association/ }
|
234
|
+
context 'with ordered members' do
|
235
|
+
it 'raises AssociationTypeMismatch with a helpful error message' do
|
236
|
+
expect { subject.ordered_members = [collection] }.to raise_error(exception, error_regex)
|
237
|
+
expect { subject.ordered_members += [collection] }.to raise_error(exception, error_regex)
|
238
|
+
expect { subject.ordered_members << collection }.to raise_error(exception, error_regex)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
context 'with unordered members' do
|
242
|
+
it 'raises AssociationTypeMismatch with a helpful error message' do
|
243
|
+
expect { subject.members = [collection] }.to raise_error(exception, error_regex)
|
244
|
+
expect { subject.members += [collection] }.to raise_error(exception, error_regex)
|
245
|
+
expect { subject.members << collection }.to raise_error(exception, error_regex)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
210
250
|
describe 'parent work and collection accessors' do
|
211
251
|
let(:collection1) { Hydra::Works::Collection.new }
|
212
252
|
before do
|
@@ -42,6 +42,31 @@ describe Hydra::Works::AddFileToFileSet do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
context 'fall back on :original_filename and application/octet-stream' do
|
46
|
+
before do
|
47
|
+
allow(file).to receive(:original_filename).and_return('original_filename.tif')
|
48
|
+
described_class.call(file_set, file, type)
|
49
|
+
end
|
50
|
+
subject { file_set.filter_files_by_type(type).first }
|
51
|
+
it 'falls back on original_filename' do
|
52
|
+
expect(subject.original_name).to eq('original_filename.tif')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when the file does not support any of the methods' do
|
57
|
+
let(:file3) { double('file') }
|
58
|
+
before do
|
59
|
+
allow(file3).to receive(:read).and_return('')
|
60
|
+
allow(file3).to receive(:size).and_return(0)
|
61
|
+
described_class.call(file_set, file3, type)
|
62
|
+
end
|
63
|
+
subject { file_set.filter_files_by_type(type).first }
|
64
|
+
it 'falls back on "" and "application/octet-stream"' do
|
65
|
+
expect(subject.mime_type).to eq('application/octet-stream')
|
66
|
+
expect(subject.original_name).to eq('')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
45
70
|
context 'file responds to :path but not to :mime_type nor :original_name' do
|
46
71
|
it 'defaults to Hydra::PCDM for mimetype and ::File for basename.' do
|
47
72
|
expect(Hydra::PCDM::GetMimeTypeForFile).to receive(:call).with(file.path)
|
@@ -104,5 +129,9 @@ describe Hydra::Works::AddFileToFileSet do
|
|
104
129
|
it 'converts URI strings to RDF::URI' do
|
105
130
|
expect(subject.send(:type_to_uri, 'http://example.com/CustomURI')).to eq(::RDF::URI('http://example.com/CustomURI'))
|
106
131
|
end
|
132
|
+
|
133
|
+
it 'returns an error for an invalid type' do
|
134
|
+
expect(-> { subject.send(:type_to_uri, 0) }).to raise_error(ArgumentError, 'Invalid file type. You must submit a URI or a symbol.')
|
135
|
+
end
|
107
136
|
end
|
108
137
|
end
|
@@ -31,7 +31,7 @@ describe Hydra::Works::PersistDerivative do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
mock_add_file_to_file_set(file_set, file)
|
34
|
-
|
34
|
+
allow(file).to receive(:mime_type).and_return(mime_type)
|
35
35
|
# Mock .save to permit tests to run without hitting fedora persistence layer
|
36
36
|
allow(file_set).to receive(:save).and_return(file_set)
|
37
37
|
end
|
@@ -116,5 +116,28 @@ describe Hydra::Works::PersistDerivative do
|
|
116
116
|
expect(file_set.thumbnail.mime_type).to eq('image/jpeg')
|
117
117
|
end
|
118
118
|
end
|
119
|
+
|
120
|
+
context 'with a pdf document (.pdf) file' do
|
121
|
+
let(:mime_type) { 'application/pdf' }
|
122
|
+
let(:file_name) { 'sample-file.pdf' }
|
123
|
+
let(:file_set) { Hydra::Works::FileSet.new(id: '01/05') }
|
124
|
+
|
125
|
+
it 'lacks a thumbnail' do
|
126
|
+
expect(file_set.thumbnail).to be_nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'generates a thumbnail on job run', unless: ENV['CI'] do
|
130
|
+
file_set.create_derivatives
|
131
|
+
expect(file_set.thumbnail).to have_content
|
132
|
+
expect(file_set.thumbnail.mime_type).to eq('image/jpeg')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe 'mime type guessing' do
|
138
|
+
it 'has hard-coded mime types for mp4 and webm' do
|
139
|
+
expect(described_class.new_mime_type('mp4')).to eq('video/mp4')
|
140
|
+
expect(described_class.new_mime_type('webm')).to eq('video/webm')
|
141
|
+
end
|
119
142
|
end
|
120
143
|
end
|
@@ -60,6 +60,21 @@ describe Hydra::Works::UploadFileToFileSet do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
context 'with additional services' do
|
64
|
+
let(:dummy_service) { double('service') }
|
65
|
+
before do
|
66
|
+
allow(file).to receive(:mime_type).and_return(mime_type)
|
67
|
+
allow(file).to receive(:original_name).and_return(original_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'additional services' do
|
71
|
+
it 'gets called' do
|
72
|
+
expect(dummy_service).to receive(:call)
|
73
|
+
described_class.call(file_set, file, additional_services: [dummy_service])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
63
78
|
context 'when updating an existing file' do
|
64
79
|
let(:additional_services) { [] }
|
65
80
|
before do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydra-works
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.8'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hydra-pcdm
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: hydra-derivatives
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -214,6 +214,8 @@ files:
|
|
214
214
|
- lib/hydra/works/models/concerns/work_behavior.rb
|
215
215
|
- lib/hydra/works/models/file_set.rb
|
216
216
|
- lib/hydra/works/models/work.rb
|
217
|
+
- lib/hydra/works/not_collection_validator.rb
|
218
|
+
- lib/hydra/works/not_file_set_validator.rb
|
217
219
|
- lib/hydra/works/services/add_file_to_file_set.rb
|
218
220
|
- lib/hydra/works/services/characterization_service.rb
|
219
221
|
- lib/hydra/works/services/persist_derivative.rb
|
@@ -256,6 +258,7 @@ files:
|
|
256
258
|
- spec/fixtures/test5.mp3
|
257
259
|
- spec/fixtures/updated-file.txt
|
258
260
|
- spec/fixtures/world.png
|
261
|
+
- spec/hydra/works/models/characterization/fits_datastream_spec.rb
|
259
262
|
- spec/hydra/works/models/collection_spec.rb
|
260
263
|
- spec/hydra/works/models/concerns/file_set/contained_files_spec.rb
|
261
264
|
- spec/hydra/works/models/concerns/file_set/mime_types_spec.rb
|
@@ -300,7 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
303
|
version: '0'
|
301
304
|
requirements: []
|
302
305
|
rubyforge_project:
|
303
|
-
rubygems_version: 2.5.1
|
306
|
+
rubygems_version: 2.4.5.1
|
304
307
|
signing_key:
|
305
308
|
specification_version: 4
|
306
309
|
summary: Fundamental repository data model for hydra
|
@@ -325,6 +328,7 @@ test_files:
|
|
325
328
|
- spec/fixtures/test5.mp3
|
326
329
|
- spec/fixtures/updated-file.txt
|
327
330
|
- spec/fixtures/world.png
|
331
|
+
- spec/hydra/works/models/characterization/fits_datastream_spec.rb
|
328
332
|
- spec/hydra/works/models/collection_spec.rb
|
329
333
|
- spec/hydra/works/models/concerns/file_set/contained_files_spec.rb
|
330
334
|
- spec/hydra/works/models/concerns/file_set/mime_types_spec.rb
|
@@ -340,4 +344,3 @@ test_files:
|
|
340
344
|
- spec/hydra/works_spec.rb
|
341
345
|
- spec/spec_helper.rb
|
342
346
|
- spec/support/file_set_helper.rb
|
343
|
-
has_rdoc:
|