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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cefb87e089349c82c73439d52e233d4bb75a7d3
4
- data.tar.gz: db102c0181dbb73a50e18980d97567466446bd8b
3
+ metadata.gz: 028f44443d1d3bdcfbff713b15bc1b59cffb8e2c
4
+ data.tar.gz: 401c0b9112abc87e79319fe6ba0a3bf2849be4db
5
5
  SHA512:
6
- metadata.gz: 020a75d61769ec1ec016b6a08faab106c620684f3648836cf70d2764b447a754ea1127259f4eaca6fe36dea5ac219d423caf61f4898adc39aa6bd18b7fcb03c8
7
- data.tar.gz: 10995a20095c6b0690c957b4fa31fbf3f9ce90b62f2107a90666db92fc98cbef43a97323bccb64f1eb8a1ab63632aa65cff9868b91e29da350753c8378f8a8c5
6
+ metadata.gz: 93b2a91ae3c98474558c00d1b23d9cc006028aa13f6691adc5850d28ca7efa39a15fdfca577852b3633eabaf259f0d7cc22c0b7964b40c32a32ce5f6f0ed9634
7
+ data.tar.gz: f0bc3421b8a91e55c20f815b0b6fb2600c2aee1bf287de7e36aca8fe204a3ebe104d10468360018a1ce35792c1d48875285f3cd5b1323598f4365fa4947c362c
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ gemspec
6
6
  gem 'slop', '~> 3.6' # For byebug
7
7
 
8
8
  group :development, :test do
9
- gem 'rubocop', require: false
9
+ gem 'rubocop', '~> 0.37.2', require: false
10
10
  gem 'rubocop-rspec', require: false
11
11
  gem 'pry' unless ENV['CI']
12
12
  gem 'pry-byebug' unless ENV['CI']
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 provides a set of [Portland Common Data Model](https://github.com/duraspace/pcdm/wiki)-compliant ActiveFedora models and associated behaviors around the broad concept of multi-file "works", the need for which was expressed by a variety of [community use cases](https://github.com/projecthydra-labs/hydra-works/tree/master/use-cases). The Hydra::Works domain model includes:
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
- * **FileSet**: a *Hydra::PCDM::Object* that encapsulates one or more directly related *Hydra::PCDM::Files*, such as a PDF document, its derivatives, and extracted full-text
15
- * **Work**: a *Hydra::PCDM::Object* that holds zero or more **FileSets** and zero or more **Works** (often you won't use Work directly, but instead write your own class that mixes in `Hydra::Works::WorkBehavior`)
16
- * **Collection**: a *Hydra::PCDM::Collection* that indirectly contains zero or more **Works** and zero or more **Collection**s
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
- View [a diagram of the domain model](https://docs.google.com/drawings/d/1-NkkRPpGpZGoTimEpYTaGM1uUPRaT0SamuWDITvtG_8/edit).
18
+ Behaviors included in the model include:
19
19
 
20
- Checkout the readme for [hydra-derivatives](https://github.com/projecthydra/hydra-derivatives#dependencies) for additional dependencies.
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
- To set up for running the test suite, you need a copy of jetty
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
- $ rake jetty:clean
96
- $ rake hydra_works:jetty:config
110
+ If you want to run the tests manually, follow these instructions:
97
111
 
98
- To run the test suite, generate the test app (which goes into spec/internal) and start jetty (if it's not already running)
112
+ ```bash
113
+ solr_wrapper -d solr/config/
114
+ ```
99
115
 
100
- $ rake jetty:start
101
- $ rake spec
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.4'
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
@@ -23,6 +23,8 @@ module Hydra
23
23
  end
24
24
 
25
25
  autoload :Characterization
26
+ autoload :NotFileSetValidator
27
+ autoload :NotCollectionValidator
26
28
 
27
29
  autoload_under 'models' do
28
30
  autoload :Collection
@@ -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
- include Hydra::PCDM::ObjectBehavior
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
@@ -0,0 +1,9 @@
1
+ module Hydra::Works
2
+ class NotFileSetValidator
3
+ def self.validate!(_association, record)
4
+ if record.try(:file_set?)
5
+ raise ActiveFedora::AssociationTypeMismatch, "#{record} is a FileSet 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
- file.mime_type
61
- elsif file.respond_to? :content_type
62
- file.content_type
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. It's necessary because the default behavior in Hydra::Derivatives assumes that you're using LDP Basic Containment. Hydra::Works::FileSets use IndirectContainment. This Service handles that case.
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
@@ -1,5 +1,5 @@
1
1
  module Hydra
2
2
  module Works
3
- VERSION = '0.7.1'.freeze
3
+ VERSION = '0.8'.freeze
4
4
  end
5
5
  end
@@ -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
- before do
5
- class FileWithVirusCheck < ActiveFedora::Base
6
- include Hydra::Works::FileSetBehavior
7
- include Hydra::Works::VirusCheck
8
- end
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
- def scanfile(path)
15
- puts "scanfile: #{path}"
15
+ def scanfile(path)
16
+ puts "scanfile: #{path}"
17
+ end
16
18
  end
17
19
  end
18
- end
19
- after do
20
- Object.send(:remove_const, :ClamAV)
21
- Object.send(:remove_const, :FileWithVirusCheck)
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
- before do
28
- allow(subject).to receive(:original_file) { file }
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
- expect(ClamAV.instance).to receive(:scanfile).and_return(1)
29
+ allow(subject).to receive(:original_file) { file }
30
+ allow(subject).to receive(:warn) # suppress virus warning messages
35
31
  end
36
- it 'fails to save' do
37
- expect(subject.save).to eq false
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
- it 'fails to validate' do
40
- expect(subject.validate).to eq false
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 'with a clean file' do
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
- expect(ClamAV.instance).to receive(:scanfile).and_return(0)
79
+ allow(subject).to receive(:original_file) { file }
47
80
  end
48
81
 
49
- it 'does not detect viruses' do
50
- expect(subject.detect_viruses).to eq true
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
@@ -9,4 +9,8 @@ describe Hydra::Works::FileSetBehavior do
9
9
  it 'ensures that objects will be recognized as file_sets' do
10
10
  expect(subject).to be_file_set
11
11
  end
12
+
13
+ it 'ensures that objects will not be collections' do
14
+ expect(subject.collection?).to be false
15
+ end
12
16
  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
- expect(work1.ordered_file_set_ids).to eq [file_set2.id]
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
- expect(work1.ordered_file_set_ids).to eq [file_set1.id, file_set2.id]
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
- expect(subject.ordered_file_sets).to eq [file_set1]
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
- expect(subject.ordered_file_sets).to eq([file_set1, file_set2])
145
- expect(work1.ordered_file_sets).to eq([])
146
- subject.ordered_member_proxies.delete_at(0)
147
- work1.ordered_members << file_set1
148
- expect(subject.ordered_file_sets).to eq([file_set2])
149
- expect(work1.ordered_file_sets).to eq([file_set1])
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
- expect(subject.ordered_file_sets).to eq []
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
- expect(subject.ordered_file_sets).to eq [file_set1, file_set2]
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
- expect(subject.ordered_file_sets).to eq [file_set1, file_set2, file_set3, file_set4, file_set5]
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
- expect(subject.ordered_file_sets).to eq [file_set2, file_set3, file_set4, file_set5]
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
- expect(subject.ordered_file_sets).to eq [file_set1, file_set2, file_set3, file_set4]
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
- expect(subject.ordered_file_sets).to eq [file_set1, file_set2, file_set4, file_set5]
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
- allow_any_instance_of(Hydra::Works::FileSet).to receive(:mime_type).and_return(mime_type)
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.7.1
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-02-24 00:00:00.000000000 Z
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.4'
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.4'
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: