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 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: