hydra-works 0.7.1 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![API Docs](http://img.shields.io/badge/API-docs-blue.svg)](http://rubydoc.info/gems/hydra-works)
|
10
10
|
[![Stories in Ready](https://badge.waffle.io/projecthydra-labs/hydra-works.png?source=projecthydra-labs%2Fhydra-works&label=ready&title=Ready)](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:
|