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

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