ddr-models 3.0.0.beta.10 → 3.0.0.beta.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/attachment.rb +4 -0
  3. data/app/models/collection.rb +4 -0
  4. data/app/models/component.rb +4 -0
  5. data/app/models/item.rb +4 -0
  6. data/app/models/target.rb +4 -0
  7. data/lib/ddr/auth.rb +1 -0
  8. data/lib/ddr/auth/ability.rb +2 -1
  9. data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
  10. data/lib/ddr/auth/permissions.rb +3 -1
  11. data/lib/ddr/derivatives/multires_image.rb +4 -2
  12. data/lib/ddr/derivatives/thumbnail.rb +1 -2
  13. data/lib/ddr/events/event.rb +3 -0
  14. data/lib/ddr/events/fixity_check_event.rb +5 -16
  15. data/lib/ddr/jobs/fixity_check.rb +1 -1
  16. data/lib/ddr/managers/permanent_id_manager.rb +4 -2
  17. data/lib/ddr/managers/workflow_manager.rb +22 -10
  18. data/lib/ddr/models.rb +0 -1
  19. data/lib/ddr/models/base.rb +43 -1
  20. data/lib/ddr/models/file.rb +1 -1
  21. data/lib/ddr/models/has_admin_metadata.rb +1 -1
  22. data/lib/ddr/models/version.rb +1 -1
  23. data/spec/auth/ability_spec.rb +33 -1
  24. data/spec/derivatives/multires_image_spec.rb +8 -2
  25. data/spec/jobs/fixity_check_spec.rb +1 -1
  26. data/spec/managers/derivatives_manager_spec.rb +9 -1
  27. data/spec/models/attachment_spec.rb +1 -0
  28. data/spec/models/collection_spec.rb +1 -0
  29. data/spec/models/component_spec.rb +1 -0
  30. data/spec/models/has_admin_metadata_spec.rb +51 -30
  31. data/spec/models/item_spec.rb +1 -0
  32. data/spec/models/target_spec.rb +1 -0
  33. data/spec/support/shared_examples_for_fixity_checkable_spec.rb +5 -7
  34. data/spec/support/shared_examples_for_publication.rb +43 -0
  35. metadata +5 -7
  36. data/app/helpers/models_helper.rb +0 -7
  37. data/lib/ddr/actions/fixity_check.rb +0 -38
  38. data/lib/ddr/models/fixity_checkable.rb +0 -32
  39. data/spec/helpers/models_helper_spec.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: acfc5ee132f67a3bcd39524c3cb2b3b54e6904a3
4
- data.tar.gz: 8ee6e1cf1e7cbd8cd023d3ccc851b7eea2950803
3
+ metadata.gz: b649796b2ae7a3e6d271ae693967c20ffcaf09c6
4
+ data.tar.gz: a08a5a96113854923916d642994a458f0899edef
5
5
  SHA512:
6
- metadata.gz: 7e470d2d199991ca2d8f8cdcd0300cc8c9c28f5d5339132c18d5f892ede55197577a030adbcbcf5966edfd3f79d72b2825c4e78216902760f0582337d23a0a90
7
- data.tar.gz: 17a7d44df2345a1c740afc6f4f9fb08243858cbb4b9a8bd1a16c8b91c8567b4db633c7a33c661d18bf02b9e148deb3e3a0d7030bda432611b9e9bcca472edae7
6
+ metadata.gz: 92bf5752a52715353c0c6e8bc88a009e0840a1d23caff13383c10c5bb900600dfdce1e30691ff0f2c9dd02e8756806d407e4e785bc67ee9050a9d09dbb40f554
7
+ data.tar.gz: 35f6bc9504c3500b54ec397dc0fc904de3c00a0a6226e52f1438d2698c7016a34e73bf3843a2b3c509a9cd0a9bcf86fed83a9e402f88f7974e8c12d27d0335f6
@@ -11,4 +11,8 @@ class Attachment < Ddr::Models::Base
11
11
  predicate: ::RDF::URI("http://projecthydra.org/ns/relations#isAttachedTo"),
12
12
  class_name: "ActiveFedora::Base"
13
13
 
14
+ def publishable?
15
+ false
16
+ end
17
+
14
18
  end
@@ -54,6 +54,10 @@ class Collection < Ddr::Models::Base
54
54
  scope: Ddr::Auth::Roles::POLICY_SCOPE
55
55
  end
56
56
 
57
+ def publishable?
58
+ true
59
+ end
60
+
57
61
  private
58
62
 
59
63
  def set_admin_policy
@@ -25,4 +25,8 @@ class Component < Ddr::Models::Base
25
25
  collection.id rescue nil
26
26
  end
27
27
 
28
+ def publishable?
29
+ parent.present? && parent.published?
30
+ end
31
+
28
32
  end
@@ -17,4 +17,8 @@ class Item < Ddr::Models::Base
17
17
  predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection,
18
18
  class_name: "Collection"
19
19
 
20
+ def publishable?
21
+ parent.present? && parent.published?
22
+ end
23
+
20
24
  end
@@ -17,4 +17,8 @@ class Target < Ddr::Models::Base
17
17
  predicate: ::RDF::URI("http://www.loc.gov/mix/v20/externalTarget#isExternalTargetFor"),
18
18
  class_name: "Collection"
19
19
 
20
+ def publishable?
21
+ false
22
+ end
23
+
20
24
  end
@@ -38,6 +38,7 @@ module Ddr
38
38
  autoload :DatastreamAbilityDefinitions
39
39
  autoload :EventAbilityDefinitions
40
40
  autoload :ItemAbilityDefinitions
41
+ autoload :PublicationAbilityDefinitions
41
42
  autoload :RoleBasedAbilityDefinitions
42
43
  autoload :SuperuserAbilityDefinitions
43
44
  end
@@ -9,7 +9,8 @@ module Ddr
9
9
  AttachmentAbilityDefinitions,
10
10
  RoleBasedAbilityDefinitions,
11
11
  DatastreamAbilityDefinitions,
12
- EventAbilityDefinitions ]
12
+ EventAbilityDefinitions,
13
+ PublicationAbilityDefinitions ]
13
14
 
14
15
  end
15
16
  end
@@ -0,0 +1,16 @@
1
+ module Ddr
2
+ module Auth
3
+ class PublicationAbilityDefinitions < AbilityDefinitions
4
+
5
+ def call
6
+ can :publish, Ddr::Models::Base do |obj|
7
+ !obj.published? && obj.publishable?
8
+ end
9
+ can :unpublish, Ddr::Models::Base do |obj|
10
+ obj.published?
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -7,10 +7,12 @@ module Ddr::Auth
7
7
  UPDATE = :update
8
8
  REPLACE = :replace
9
9
  ARRANGE = :arrange
10
+ PUBLISH = :publish
11
+ UNPUBLISH = :unpublish
10
12
  AUDIT = :audit
11
13
  GRANT = :grant
12
14
 
13
- ALL = [ READ, DOWNLOAD, ADD_CHILDREN, UPDATE, REPLACE, ARRANGE, AUDIT, GRANT ]
15
+ ALL = [ READ, DOWNLOAD, ADD_CHILDREN, UPDATE, REPLACE, ARRANGE, PUBLISH, UNPUBLISH, AUDIT, GRANT ]
14
16
 
15
17
  end
16
18
  end
@@ -2,7 +2,9 @@ module Ddr::Derivatives
2
2
  class MultiresImage < Derivative
3
3
 
4
4
  def self.generatable?(object)
5
- object.can_have_multires_image? && object.has_content? && object.content_type == "image/tiff"
5
+ object.can_have_multires_image? &&
6
+ object.has_content? &&
7
+ (object.content_type == "image/tiff" || object.content_type == "image/jpeg")
6
8
  end
7
9
 
8
10
  def self.has_derivative?(object)
@@ -56,4 +58,4 @@ module Ddr::Derivatives
56
58
  end
57
59
 
58
60
  end
59
- end
61
+ end
@@ -21,8 +21,7 @@ module Ddr::Derivatives
21
21
  end
22
22
 
23
23
  def output_file_name(object)
24
- basename = object.content.original_name.present? ? File.basename(object.content.original_name, '.*') : "thumbnail"
25
- "#{basename}.#{generator.class.output_extension}"
24
+ "thumbnail.#{generator.class.output_extension}"
26
25
  end
27
26
 
28
27
  def store(object, output_path)
@@ -39,6 +39,9 @@ module Ddr
39
39
  # Receive message sent by ActiveSupport::Notifications
40
40
  def self.call(*args)
41
41
  notification = ActiveSupport::Notifications::Event.new(*args)
42
+ if block_given?
43
+ yield notification.payload
44
+ end
42
45
  create(notification.payload)
43
46
  end
44
47
 
@@ -6,26 +6,15 @@ module Ddr
6
6
  include ReindexObjectAfterSave
7
7
 
8
8
  self.preservation_event_type = :fix
9
- self.description = "Validation of datastream checksums"
10
-
11
- DETAIL_PREAMBLE = "Datastream checksum validation results:"
12
- DETAIL_TEMPLATE = "%{dsid} ... %{validation}"
9
+ self.description = "Fixity check of attached files".freeze
13
10
 
14
11
  # Message sent by ActiveSupport::Notifications
15
12
  def self.call(*args)
16
- notification = ActiveSupport::Notifications::Event.new(*args)
17
- result = notification.payload[:result] # FixityCheck::Result instance
18
- detail = [DETAIL_PREAMBLE]
19
- result.results.each do |dsid, dsProfile|
20
- # validation = dsProfile["dsChecksumValid"] ? VALID : INVALID
21
- validation = dsProfile["checksum_valid"] ? VALID : INVALID
22
- detail << DETAIL_TEMPLATE % {dsid: dsid, validation: validation}
13
+ super do |payload|
14
+ results = payload.delete(:results)
15
+ payload[:outcome] = results.values.all? ? SUCCESS : FAILURE
16
+ payload[:detail] = "Fixity check results:\n\n#{results}"
23
17
  end
24
- create(pid: result.id,
25
- event_date_time: notification.time,
26
- outcome: result.success ? SUCCESS : FAILURE,
27
- detail: detail.join("\n")
28
- )
29
18
  end
30
19
 
31
20
  def to_solr
@@ -6,7 +6,7 @@ module Ddr::Jobs
6
6
 
7
7
  def self.perform(id)
8
8
  obj = ActiveFedora::Base.find(id)
9
- obj.fixity_check
9
+ obj.check_fixity
10
10
  end
11
11
 
12
12
  end
@@ -13,6 +13,7 @@ module Ddr
13
13
  PERMANENT_URL_BASE = "http://id.library.duke.edu/"
14
14
  ASSIGN_EVENT_SUMMARY = "Permanent ID assignment"
15
15
  SOFTWARE = Ezid::Client.version
16
+ FCREPO3_PID = "fcrepo3.pid"
16
17
 
17
18
  attr_reader :object
18
19
 
@@ -53,8 +54,9 @@ EZID Metadata:
53
54
  end
54
55
 
55
56
  def default_metadata
56
- { profile: "dc",
57
- export: "no"
57
+ { :profile => "dc",
58
+ :export => "no",
59
+ FCREPO3_PID => object.pid
58
60
  }
59
61
  end
60
62
 
@@ -9,22 +9,34 @@ module Ddr
9
9
  object.workflow_state == PUBLISHED
10
10
  end
11
11
 
12
- def publish
13
- object.workflow_state = PUBLISHED
12
+ def publish!(include_descendants: true)
13
+ unless published?
14
+ publish
15
+ object.save
16
+ end
17
+ if include_descendants && object.respond_to?(:children)
18
+ object.children.each { |child| child.publish!(include_descendants: include_descendants) }
19
+ end
14
20
  end
15
21
 
16
- def publish!
17
- publish
18
- object.save
22
+ def unpublish!
23
+ if published?
24
+ unpublish
25
+ object.save
26
+ end
27
+ if object.respond_to?(:children)
28
+ object.children.each { |child| child.unpublish! }
29
+ end
19
30
  end
20
31
 
21
- def unpublish
22
- object.workflow_state = UNPUBLISHED
32
+ private
33
+
34
+ def publish
35
+ object.workflow_state = PUBLISHED
23
36
  end
24
37
 
25
- def unpublish!
26
- unpublish
27
- object.save
38
+ def unpublish
39
+ object.workflow_state = UNPUBLISHED
28
40
  end
29
41
 
30
42
  end
@@ -39,7 +39,6 @@ module Ddr
39
39
  autoload :FileCharacterization
40
40
  autoload :FileManagement
41
41
  autoload :FindingAid
42
- autoload :FixityCheckable
43
42
  autoload :Governable
44
43
  autoload :HasAdminMetadata
45
44
  autoload :HasAttachments
@@ -6,7 +6,6 @@ module Ddr::Models
6
6
  include Governable
7
7
  include HasThumbnail
8
8
  include EventLoggable
9
- include FixityCheckable
10
9
  include FileManagement
11
10
  include Indexing
12
11
  include Hydra::Validations
@@ -116,5 +115,48 @@ module Ddr::Models
116
115
  self
117
116
  end
118
117
 
118
+ def datastreams_to_validate
119
+ Deprecation.warn(FixityCheckable, "`datastreams_to_validate` is deprecated." \
120
+ " Use `attached_files_having_content` instead.")
121
+ attached_files_having_content
122
+ end
123
+
124
+ def attached_files_having_content
125
+ Hash.new.tap do |h|
126
+ attached_files.each do |file_id, file|
127
+ h[file_id] = file if file.has_content?
128
+ end
129
+ end
130
+ end
131
+
132
+ def fixity_checks
133
+ Ddr::Events::FixityCheckEvent.for_object(self)
134
+ end
135
+
136
+ def check_fixity
137
+ results = attached_files_having_content.each_with_object({}) do |(file_id, file), memo|
138
+ memo[file_id] = !!file.check_fixity
139
+ end
140
+ notify_event(:fixity_check, results: results)
141
+ end
142
+ alias_method :fixity_check, :check_fixity
143
+ deprecation_deprecate :fixity_check
144
+
145
+ def last_fixity_check
146
+ fixity_checks.last
147
+ end
148
+
149
+ def last_fixity_check_on
150
+ last_fixity_check && last_fixity_check.event_date_time
151
+ end
152
+
153
+ def last_fixity_check_outcome
154
+ last_fixity_check && last_fixity_check.outcome
155
+ end
156
+
157
+ def publishable?
158
+ raise NotImplementedError, "Must be implemented by subclasses"
159
+ end
160
+
119
161
  end
120
162
  end
@@ -44,7 +44,7 @@ module Ddr::Models
44
44
  end
45
45
 
46
46
  def create_date_string
47
- dsCreateDate.strftime(STRFTIME_FORMAT) if dsCreateDate
47
+ create_date.strftime(STRFTIME_FORMAT) if create_date
48
48
  end
49
49
 
50
50
  def content_digest(algorithm)
@@ -61,7 +61,7 @@ module Ddr::Models
61
61
  predicate: Ddr::Vocab::Asset.workflowState,
62
62
  multiple: false
63
63
 
64
- delegate :publish, :publish!, :unpublish, :unpublish!, :published?, to: :workflow
64
+ delegate :publish!, :unpublish!, :published?, to: :workflow
65
65
 
66
66
  after_create :assign_permanent_id!, if: "Ddr::Models.auto_assign_permanent_ids"
67
67
  around_destroy :update_permanent_id_on_destroy, if: "permanent_id.present?"
@@ -1,5 +1,5 @@
1
1
  module Ddr
2
2
  module Models
3
- VERSION = "3.0.0.beta.10"
3
+ VERSION = "3.0.0.beta.11"
4
4
  end
5
5
  end
@@ -2,7 +2,7 @@ module Ddr::Auth
2
2
  RSpec.describe Ability, type: :model, abilities: true do
3
3
 
4
4
  subject { described_class.new(auth_context) }
5
-
5
+
6
6
  let(:auth_context) { FactoryGirl.build(:auth_context) }
7
7
 
8
8
  describe "aliases" do
@@ -144,6 +144,38 @@ module Ddr::Auth
144
144
  end
145
145
  end
146
146
 
147
+ describe "publication abilities" do
148
+ let(:obj) { Ddr::Models::Base.new }
149
+
150
+ describe "publish" do
151
+ describe "when the object is published" do
152
+ before { allow(obj).to receive(:published?) { true } }
153
+ it { should_not be_able_to(:publish, obj) }
154
+ end
155
+ describe "when the object is not published" do
156
+ describe "when the object is publishable" do
157
+ before { allow(obj).to receive(:publishable?) { true } }
158
+ it { should be_able_to(:publish, obj) }
159
+ end
160
+ describe "when the object is not publishable" do
161
+ before { allow(obj).to receive(:publishable?) { false } }
162
+ it { should_not be_able_to(:publish, obj) }
163
+ end
164
+ end
165
+ end
166
+
167
+ describe "unpublish" do
168
+ describe "when the object is published" do
169
+ before { allow(obj).to receive(:published?) { true } }
170
+ it { should be_able_to(:unpublish, obj) }
171
+ end
172
+ describe "when the object is not published" do
173
+ it { should_not be_able_to(:unpublish, obj) }
174
+ end
175
+ end
176
+
177
+ end
178
+
147
179
  describe "role based abilities" do
148
180
  shared_examples "it has role based abilities" do
149
181
  describe "when permissions are cached" do
@@ -21,8 +21,14 @@ module Ddr::Derivatives
21
21
  expect(subject.generatable?(object)).to be_truthy
22
22
  end
23
23
  end
24
- context 'content is not a tiff image' do
24
+ context 'content is a jpeg image' do
25
25
  before { allow(object).to receive(:content_type) { 'image/jpeg' } }
26
+ it "should be generatable" do
27
+ expect(subject.generatable?(object)).to be_truthy
28
+ end
29
+ end
30
+ context 'content is neither a tiff nor a jpeg image' do
31
+ before { allow(object).to receive(:content_type) { 'image/gif' } }
26
32
  it "should not be generatable" do
27
33
  expect(subject.generatable?(object)).to be_falsey
28
34
  end
@@ -45,4 +51,4 @@ module Ddr::Derivatives
45
51
 
46
52
  end
47
53
  end
48
- end
54
+ end
@@ -13,7 +13,7 @@ module Ddr::Jobs
13
13
  allow(ActiveFedora::Base).to receive(:find).with("test:1") { obj }
14
14
  end
15
15
  it "should call `fixity_check` on the object" do
16
- expect(obj).to receive(:fixity_check)
16
+ expect(obj).to receive(:check_fixity)
17
17
  described_class.perform("test:1")
18
18
  end
19
19
  end
@@ -55,8 +55,16 @@ module Ddr
55
55
  object.derivatives.update_derivatives(:now)
56
56
  end
57
57
  end
58
- context "content is not tiff image" do
58
+ context "content is a jpeg image" do
59
59
  let(:file) { fixture_file_upload("bird.jpg", "image/jpeg") }
60
+ it "should generate a thumbnail and a ptif" do
61
+ expect(object.derivatives).to receive(:generate_derivative).with(Ddr::Derivatives::DERIVATIVES[:thumbnail])
62
+ expect(object.derivatives).to receive(:generate_derivative).with(Ddr::Derivatives::DERIVATIVES[:multires_image])
63
+ object.derivatives.update_derivatives(:now)
64
+ end
65
+ end
66
+ context "content is neither a tiff nor a jpeg image" do
67
+ let(:file) { fixture_file_upload("arrow1rightred_e0.gif", "image/gif") }
60
68
  it "should generate a thumbnail but not a ptif" do
61
69
  expect(object.derivatives).to receive(:generate_derivative).with(Ddr::Derivatives::DERIVATIVES[:thumbnail])
62
70
  expect(object.derivatives).to_not receive(:generate_derivative).with(Ddr::Derivatives::DERIVATIVES[:multires_image])
@@ -5,5 +5,6 @@ RSpec.describe Attachment, type: :model, attachments: true do
5
5
  it_behaves_like "a DDR model"
6
6
  it_behaves_like "an object that can have content"
7
7
  it_behaves_like "a non-collection model"
8
+ it_behaves_like "an unpublishable object"
8
9
 
9
10
  end
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  RSpec.describe Collection, type: :model do
4
4
 
5
5
  it_behaves_like "a DDR model"
6
+ it_behaves_like "a publishable object"
6
7
 
7
8
  describe "#components_from_solr" do
8
9
  subject { Collection.new(id: 'test-1') }
@@ -5,6 +5,7 @@ RSpec.describe Component, type: :model, components: true do
5
5
  it_behaves_like "a DDR model"
6
6
  it_behaves_like "an object that can have content"
7
7
  it_behaves_like "a non-collection model"
8
+ it_behaves_like "a potentially publishable object"
8
9
 
9
10
  describe "indexing" do
10
11
  subject { FactoryGirl.build(:component) }
@@ -49,15 +49,29 @@ module Ddr::Models
49
49
  end
50
50
 
51
51
  describe "lifecycle" do
52
- let!(:identifier) { Ezid::MockIdentifier.new(id: "ark:/99999/fk4zzz", status: "public") }
52
+ subject { FactoryGirl.create(:item) }
53
+ let!(:identifier) {
54
+ Ezid::MockIdentifier.create(subject.permanent_id_manager.default_metadata)
55
+ }
53
56
  before do
54
57
  allow(Ddr::Models).to receive(:auto_assign_permanent_ids) { false }
55
- allow(Ezid::Identifier).to receive(:find).with("ark:/99999/fk4zzz") { identifier }
56
- subject.permanent_id = "ark:/99999/fk4zzz"
58
+ allow(Ezid::Identifier).to receive(:find).with(identifier.id) { identifier }
59
+ subject.permanent_id = identifier.id
57
60
  subject.save!
58
61
  end
59
- it "should update the status of the identifier when the object is destroyed" do
60
- expect { subject.destroy }.to change(identifier, :status).from("public").to("unavailable | deleted")
62
+ describe "identifier creation" do
63
+ it "sets default metadata" do
64
+ expect(identifier.profile).to eq("dc")
65
+ expect(identifier.export).to eq("no")
66
+ expect(identifier["fcrepo3.pid"]).to eq(subject.pid)
67
+ end
68
+ end
69
+ describe "object destruction" do
70
+ it "marks the identifier as unavailable" do
71
+ expect { subject.destroy }
72
+ .to change(identifier, :status)
73
+ .to("unavailable | deleted")
74
+ end
61
75
  end
62
76
  end
63
77
 
@@ -90,50 +104,57 @@ module Ddr::Models
90
104
 
91
105
  describe "workflow" do
92
106
 
93
- subject { FactoryGirl.build(:item) }
107
+ let(:collection) { FactoryGirl.create(:collection) }
108
+ let(:item) { FactoryGirl.create(:item) }
109
+ let(:component) { FactoryGirl.create(:component) }
110
+ before do
111
+ item.parent = collection
112
+ item.save!
113
+ component.parent = item
114
+ component.save!
115
+ end
94
116
 
95
117
  describe "#published?" do
96
118
  context "object is published" do
97
- before { allow(subject).to receive(:workflow_state) { Ddr::Managers::WorkflowManager::PUBLISHED } }
119
+ before { allow(collection).to receive(:workflow_state) { Ddr::Managers::WorkflowManager::PUBLISHED } }
98
120
  it "should return true" do
99
- expect(subject).to be_published
121
+ expect(collection).to be_published
100
122
  end
101
123
  end
102
124
  context "object is not published" do
103
- before { allow(subject).to receive(:workflow_state) { nil } }
125
+ before { allow(collection).to receive(:workflow_state) { nil } }
104
126
  it "should return false" do
105
- expect(subject).not_to be_published
127
+ expect(collection).not_to be_published
106
128
  end
107
129
  end
108
130
  end
109
131
 
110
- describe "#publish" do
111
- it "should publish the object" do
112
- subject.publish
113
- expect(subject).to be_published
114
- end
115
- end
116
-
117
132
  describe "#publish!" do
118
- it "should publish and persist the object" do
119
- subject.publish!
120
- expect(subject.reload).to be_published
133
+ context "do not include descendants" do
134
+ it "should publish and persist the object" do
135
+ collection.publish!(include_descendants: false)
136
+ expect(collection.reload).to be_published
137
+ expect(item.reload).not_to be_published
138
+ expect(component.reload).not_to be_published
139
+ end
121
140
  end
122
- end
123
-
124
- describe "#unpublish" do
125
- before { subject.publish }
126
- it "should unpublish the object" do
127
- subject.unpublish
128
- expect(subject).not_to be_published
141
+ context "do include descendants" do
142
+ it "should publish and persist the object and descendants" do
143
+ collection.publish!
144
+ expect(collection.reload).to be_published
145
+ expect(item.reload).to be_published
146
+ expect(component.reload).to be_published
147
+ end
129
148
  end
130
149
  end
131
150
 
132
151
  describe "#unpublish!" do
133
- before { subject.publish! }
152
+ before { collection.publish! }
134
153
  it "should unpublish and persist the object" do
135
- subject.unpublish!
136
- expect(subject.reload).not_to be_published
154
+ collection.unpublish!
155
+ expect(collection.reload).not_to be_published
156
+ expect(item.reload).not_to be_published
157
+ expect(component.reload).not_to be_published
137
158
  end
138
159
  end
139
160
  end
@@ -4,5 +4,6 @@ RSpec.describe Item, type: :model do
4
4
 
5
5
  it_behaves_like "a DDR model"
6
6
  it_behaves_like "a non-collection model"
7
+ it_behaves_like "a potentially publishable object"
7
8
 
8
9
  end
@@ -5,5 +5,6 @@ RSpec.describe Target, type: :model, targets: true do
5
5
  it_behaves_like "a DDR model"
6
6
  it_behaves_like "an object that can have content"
7
7
  it_behaves_like "a non-collection model"
8
+ it_behaves_like "an unpublishable object"
8
9
 
9
10
  end
@@ -1,15 +1,13 @@
1
1
  RSpec.shared_examples "a fixity checkable object" do
2
2
 
3
- let(:object) { described_class.new }
4
-
5
3
  describe "fixity check" do
6
4
  before do
7
- object.thumbnail.content = '1234567890'
8
- object.save(validate: false)
5
+ subject.thumbnail.content = '1234567890'
6
+ subject.save(validate: false)
9
7
  end
10
- it "should be able to perform a fixity check" do
11
- expect(Ddr::Actions::FixityCheck.execute(object)).to_not be_nil
8
+ it "can check fixity" do
9
+ expect { subject.check_fixity }.to change(subject.fixity_checks, :count).from(0).to(1)
12
10
  end
13
11
  end
14
12
 
15
- end
13
+ end
@@ -0,0 +1,43 @@
1
+ RSpec.shared_examples 'a publishable object' do
2
+ describe '#publishable?' do
3
+ let(:object) { described_class.new }
4
+ it 'should be publishable' do
5
+ expect(object.publishable?).to be true
6
+ end
7
+ end
8
+ end
9
+
10
+ RSpec.shared_examples 'an unpublishable object' do
11
+ describe '#publishable?' do
12
+ let(:object) { described_class.new }
13
+ it 'should not be publishable' do
14
+ expect(object.publishable?).to be false
15
+ end
16
+ end
17
+ end
18
+
19
+ RSpec.shared_examples 'a potentially publishable object' do
20
+ describe "#publishable?" do
21
+ let(:object) { described_class.new }
22
+ context "has parent" do
23
+ before { allow(object).to receive(:parent) { parent } }
24
+ context "parent is published" do
25
+ let(:parent) { double(published?: true) }
26
+ it "should be publishable" do
27
+ expect(object.publishable?).to be true
28
+ end
29
+ end
30
+ context "parent is not published" do
31
+ let(:parent) { double(published?: false) }
32
+ it "should not be publishable" do
33
+ expect(object.publishable?).to be false
34
+ end
35
+ end
36
+ end
37
+ context "does not have parent" do
38
+ it "should not be publishable" do
39
+ expect(object.publishable?).to be false
40
+ end
41
+ end
42
+ end
43
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddr-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.10
4
+ version: 3.0.0.beta.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Coble
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-02-12 00:00:00.000000000 Z
12
+ date: 2016-02-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -389,7 +389,6 @@ files:
389
389
  - Rakefile
390
390
  - app/controllers/users/omniauth_callbacks_controller.rb
391
391
  - app/controllers/users/sessions_controller.rb
392
- - app/helpers/models_helper.rb
393
392
  - app/models/.keep
394
393
  - app/models/attachment.rb
395
394
  - app/models/collection.rb
@@ -420,7 +419,6 @@ files:
420
419
  - ddr-models.gemspec
421
420
  - lib/ddr-models.rb
422
421
  - lib/ddr/actions.rb
423
- - lib/ddr/actions/fixity_check.rb
424
422
  - lib/ddr/actions/virus_check.rb
425
423
  - lib/ddr/auth.rb
426
424
  - lib/ddr/auth/ability.rb
@@ -432,6 +430,7 @@ files:
432
430
  - lib/ddr/auth/ability_definitions/datastream_ability_definitions.rb
433
431
  - lib/ddr/auth/ability_definitions/event_ability_definitions.rb
434
432
  - lib/ddr/auth/ability_definitions/item_ability_definitions.rb
433
+ - lib/ddr/auth/ability_definitions/publication_ability_definitions.rb
435
434
  - lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb
436
435
  - lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb
437
436
  - lib/ddr/auth/ability_factory.rb
@@ -538,7 +537,6 @@ files:
538
537
  - lib/ddr/models/files/fits_xml_file.rb
539
538
  - lib/ddr/models/files/structural_metadata_file.rb
540
539
  - lib/ddr/models/finding_aid.rb
541
- - lib/ddr/models/fixity_checkable.rb
542
540
  - lib/ddr/models/governable.rb
543
541
  - lib/ddr/models/has_admin_metadata.rb
544
542
  - lib/ddr/models/has_attachments.rb
@@ -676,7 +674,6 @@ files:
676
674
  - spec/fixtures/sample.docx
677
675
  - spec/fixtures/sample.pdf
678
676
  - spec/fixtures/target.png
679
- - spec/helpers/models_helper_spec.rb
680
677
  - spec/index/fields_spec.rb
681
678
  - spec/index/filter_spec.rb
682
679
  - spec/index/query_builder_spec.rb
@@ -728,6 +725,7 @@ files:
728
725
  - spec/support/shared_examples_for_has_content.rb
729
726
  - spec/support/shared_examples_for_indexing.rb
730
727
  - spec/support/shared_examples_for_non_collection_models.rb
728
+ - spec/support/shared_examples_for_publication.rb
731
729
  - spec/support/shared_examples_for_role_sets.rb
732
730
  - spec/support/structural_metadata_helper.rb
733
731
  - spec/utils_spec.rb
@@ -850,7 +848,6 @@ test_files:
850
848
  - spec/fixtures/sample.docx
851
849
  - spec/fixtures/sample.pdf
852
850
  - spec/fixtures/target.png
853
- - spec/helpers/models_helper_spec.rb
854
851
  - spec/index/fields_spec.rb
855
852
  - spec/index/filter_spec.rb
856
853
  - spec/index/query_builder_spec.rb
@@ -902,6 +899,7 @@ test_files:
902
899
  - spec/support/shared_examples_for_has_content.rb
903
900
  - spec/support/shared_examples_for_indexing.rb
904
901
  - spec/support/shared_examples_for_non_collection_models.rb
902
+ - spec/support/shared_examples_for_publication.rb
905
903
  - spec/support/shared_examples_for_role_sets.rb
906
904
  - spec/support/structural_metadata_helper.rb
907
905
  - spec/utils_spec.rb
@@ -1,7 +0,0 @@
1
- module ModelsHelper
2
-
3
- def admin_set_full_name(slug)
4
- I18n.t("ddr.admin_set.#{slug}")
5
- end
6
-
7
- end
@@ -1,38 +0,0 @@
1
- module Ddr
2
- module Actions
3
- class FixityCheck
4
-
5
- # Return result of fixity check - wrapped by a notifier
6
- def self.execute(object)
7
- ActiveSupport::Notifications.instrument(Ddr::Notifications::FIXITY_CHECK) do |payload|
8
- payload[:result] = _execute(object)
9
- end
10
- end
11
-
12
- # Return result of fixity check
13
- def self._execute(object)
14
- Result.new(id: object.id).tap do |r|
15
- object.datastreams_to_validate.each do |dsid, ds|
16
- # r.success &&= ds.dsChecksumValid
17
- # r.results[dsid] = ds.profile
18
- checksum_valid = ds.check_fixity
19
- r.success &&= checksum_valid
20
- r.results[dsid] = { 'checksum_valid' => checksum_valid }
21
- end
22
- end
23
- end
24
-
25
- class Result
26
- attr_accessor :id, :success, :results, :checked_at
27
-
28
- def initialize(args={})
29
- @id = args[:id]
30
- @success = args[:success] || true
31
- @results = args[:results] || {}
32
- @checked_at = args[:checked_at] || Time.now.utc
33
- end
34
- end
35
-
36
- end
37
- end
38
- end
@@ -1,32 +0,0 @@
1
- module Ddr
2
- module Models
3
- module FixityCheckable
4
-
5
- def datastreams_to_validate
6
- datastreams.select { |dsid, ds| ds.has_content? }
7
- end
8
-
9
- def fixity_checks
10
- Ddr::Events::FixityCheckEvent.for_object(self)
11
- end
12
-
13
- # Returns a Ddr::Actions::FixityCheck::Result for the object
14
- def fixity_check
15
- Ddr::Actions::FixityCheck.execute(self)
16
- end
17
-
18
- def last_fixity_check
19
- fixity_checks.last
20
- end
21
-
22
- def last_fixity_check_on
23
- last_fixity_check && last_fixity_check.event_date_time
24
- end
25
-
26
- def last_fixity_check_outcome
27
- last_fixity_check && last_fixity_check.outcome
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe ModelsHelper, type: :helper do
4
-
5
- describe 'admin_set_full_name' do
6
- it "should call I18n to translate the slug" do
7
- expect(I18n).to receive(:t).with('ddr.admin_set.foo')
8
- helper.admin_set_full_name('foo')
9
- end
10
- end
11
- end