curation_concerns 1.0.0.beta9 → 1.0.0.beta10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (21) hide show
  1. checksums.yaml +4 -4
  2. data/app/actors/curation_concerns/actors/add_to_work_actor.rb +1 -1
  3. data/app/connections/curation_concerns/clean_connection.rb +25 -0
  4. data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +9 -0
  5. data/app/presenters/curation_concerns/work_show_presenter.rb +17 -1
  6. data/app/services/curation_concerns/graph_exporter.rb +81 -0
  7. data/app/services/curation_concerns/list_source_exporter.rb +44 -0
  8. data/{lib/generators/curation_concerns/templates/migrations/create_version_committers.rb → db/migrate/20160328222152_create_version_committers.rb} +0 -0
  9. data/{lib/generators/curation_concerns/templates/migrations/create_checksum_audit_logs.rb → db/migrate/20160328222153_create_checksum_audit_logs.rb} +0 -0
  10. data/{lib/generators/curation_concerns/templates/migrations/create_single_use_links.rb → db/migrate/20160328222154_create_single_use_links.rb} +0 -0
  11. data/{lib/generators/curation_concerns/templates/migrations/create_operations.rb → db/migrate/20160427155928_create_operations.rb} +0 -0
  12. data/lib/curation_concerns/configuration.rb +10 -0
  13. data/lib/curation_concerns/engine.rb +2 -2
  14. data/lib/curation_concerns/version.rb +1 -1
  15. data/lib/generators/curation_concerns/models_generator.rb +4 -14
  16. data/spec/actors/curation_concerns/work_actor_spec.rb +37 -0
  17. data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +53 -35
  18. data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +36 -0
  19. data/spec/services/graph_exporter_spec.rb +28 -0
  20. metadata +12 -8
  21. data/lib/generators/curation_concerns/abstract_migration_generator.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 486a45336152e853ee3d6382246df41931f4ee82
4
- data.tar.gz: d2dddd29612f023b7ffd5266d850789e075b9507
3
+ metadata.gz: 72fb3bda363615458c1b666279bbb701ddaa976a
4
+ data.tar.gz: b30167b1ee83c064362de2146dee265a46044ab0
5
5
  SHA512:
6
- metadata.gz: c86cd15261e654d70d97994d71fc9d56f440d351d9e75da8b85e28b2821548c0679d8b6f08ab48d6f5d0aff402b811f17ec43a3de80e753aaa496d9470a4b9da
7
- data.tar.gz: fdf1787db3ee54d7167f5785babd549df3dbc8f846bab7b768edb89d9d04ea1caaa57bfb9fd21123a1caffb9d0afaa4cbc894eb4ba16a634216475c48041399f
6
+ metadata.gz: ab627a66094df0e588350f40d060fe6752de190af34efcd5df2771e85c50808986e8f5f69cd837a00c2d19f60bb35c658871463b865c28f373ad3c817794a76e
7
+ data.tar.gz: 69e0fc0c3854ed43ff8d494db1698610e03b92050702d794576c98321fb2aa0347b59e1d22e6a3f9198e571c6fb4ecfb7d387308fbcc86b9379bce4b4f873244
@@ -14,7 +14,7 @@ module CurationConcerns
14
14
  private
15
15
 
16
16
  def add_to_works(new_work_ids)
17
- return true unless new_work_ids.present?
17
+ return true if new_work_ids.nil?
18
18
  (curation_concern.in_works_ids - new_work_ids).each do |old_id|
19
19
  work = ::ActiveFedora::Base.find(old_id)
20
20
  work.ordered_members.delete(curation_concern)
@@ -0,0 +1,25 @@
1
+ module CurationConcerns
2
+ # This stands in for ActiveFedora::CleanConnection. It behaves the same way,
3
+ # but it doesn't clear the has_model assertion
4
+ class CleanConnection < SimpleDelegator
5
+ def get(*args)
6
+ result = __getobj__.get(*args) do |req|
7
+ prefer_headers = Ldp::PreferHeaders.new(req.headers["Prefer"])
8
+ prefer_headers.omit = prefer_headers.omit | omit_uris
9
+ req.headers["Prefer"] = prefer_headers.to_s
10
+ end
11
+ result
12
+ end
13
+
14
+ private
15
+
16
+ def omit_uris
17
+ [
18
+ ::RDF::Vocab::Fcrepo4.ServerManaged,
19
+ ::RDF::Vocab::LDP.PreferContainment,
20
+ ::RDF::Vocab::LDP.PreferEmptyContainer,
21
+ ::RDF::Vocab::LDP.PreferMembership
22
+ ]
23
+ end
24
+ end
25
+ end
@@ -63,6 +63,15 @@ module CurationConcerns::CurationConcernController
63
63
  render :show, status: :ok
64
64
  end
65
65
  additional_response_formats(wants)
66
+ wants.ttl do
67
+ render text: presenter.export_as_ttl
68
+ end
69
+ wants.jsonld do
70
+ render text: presenter.export_as_jsonld
71
+ end
72
+ wants.nt do
73
+ render text: presenter.export_as_nt
74
+ end
66
75
  end
67
76
  end
68
77
 
@@ -16,7 +16,7 @@ module CurationConcerns
16
16
  self.work_presenter_class = self
17
17
 
18
18
  # Methods used by blacklight helpers
19
- delegate :has?, :first, :fetch, to: :solr_document
19
+ delegate :has?, :first, :fetch, :export_formats, :export_as, to: :solr_document
20
20
 
21
21
  # @param [SolrDocument] solr_document
22
22
  # @param [Ability] current_ability
@@ -88,8 +88,24 @@ module CurationConcerns
88
88
  current_ability.can?(:read, id) ? to_s : 'File'
89
89
  end
90
90
 
91
+ def export_as_nt
92
+ graph.dump(:ntriples)
93
+ end
94
+
95
+ def export_as_jsonld
96
+ graph.dump(:jsonld, standard_prefixes: true)
97
+ end
98
+
99
+ def export_as_ttl
100
+ graph.dump(:ttl)
101
+ end
102
+
91
103
  private
92
104
 
105
+ def graph
106
+ GraphExporter.new(solr_document, request).fetch
107
+ end
108
+
93
109
  def presenter_factory_arguments
94
110
  [current_ability, request]
95
111
  end
@@ -0,0 +1,81 @@
1
+ module CurationConcerns
2
+ # Retrieves the graph for an object with the internal triples removed
3
+ # and the uris translated to external uris.
4
+ class GraphExporter
5
+ # @param [SolrDocument] solr_document idea here is that in the future, ActiveFedora may serialize the object as JSON+LD
6
+ # @param [ActionDispatch::Request] request the http request context
7
+ def initialize(solr_document, request)
8
+ @solr_document = solr_document
9
+ @request = request
10
+ @additional_resources = []
11
+ end
12
+
13
+ attr_reader :solr_document, :request, :additional_resources
14
+
15
+ # @return [RDF::Graph]
16
+ def fetch
17
+ clean_graph_repository.find(solr_document.id).tap do |g|
18
+ additional_resources.uniq.each do |stmt|
19
+ g << stmt
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def clean_graph_repository
27
+ Hydra::ContentNegotiation::CleanGraphRepository.new(connection, replacer)
28
+ end
29
+
30
+ def connection
31
+ @connection ||= CleanConnection.new(ActiveFedora.fedora.connection)
32
+ end
33
+
34
+ # This method is called once for each statement in the graph.
35
+ def replacer
36
+ lambda do |resource_id, graph|
37
+ url = ActiveFedora::Base.id_to_uri(resource_id)
38
+ result = graph.query([RDF::URI(url), ActiveFedora::RDF::Fcrepo::Model.hasModel, nil]).first
39
+ if result
40
+ subject_replacer(result, resource_id)
41
+ elsif resource_id.start_with? solr_document.id
42
+ subresource_replacer(resource_id, graph)
43
+ else
44
+ object_replacer(resource_id, graph)
45
+ end
46
+ end
47
+ end
48
+
49
+ def subresource_replacer(resource_id, graph)
50
+ parent_id, local = resource_id.split('/', 2)
51
+ parent_url = ActiveFedora::Base.id_to_uri(parent_id)
52
+ result = graph.query([RDF::URI(parent_url), ActiveFedora::RDF::Fcrepo::Model.hasModel, nil]).first
53
+
54
+ # OPTIMIZE: we only need to fetch each subresource once.
55
+ additional_resources << ListSourceExporter.new(resource_id, request, subject_replacer(result, parent_id)).fetch
56
+ parent = subject_replacer(result, parent_id)
57
+ "#{parent}/#{local}"
58
+ end
59
+
60
+ def subject_replacer(result, resource_id, anchor = nil)
61
+ klass = result.object.to_s.constantize
62
+ route_key = if CurationConcerns.config.curation_concerns.include?(klass)
63
+ klass.model_name.singular_route_key
64
+ else
65
+ SolrDocument.model_name.singular_route_key
66
+ end
67
+ routes = Rails.application.routes.url_helpers
68
+ builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder
69
+ builder.polymorphic_method routes, route_key, nil, :url, id: resource_id, host: hostname, anchor: anchor
70
+ end
71
+
72
+ def object_replacer(id, _graph)
73
+ id, anchor = id.split('/', 2)
74
+ Rails.application.routes.url_helpers.solr_document_url(id, host: hostname, anchor: anchor)
75
+ end
76
+
77
+ def hostname
78
+ request.host
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,44 @@
1
+ module CurationConcerns
2
+ # Retrieves the graph for an object with the internal triples removed
3
+ # and the uris translated to external uris.
4
+ class ListSourceExporter
5
+ # @param [String] id
6
+ # @param [ActionDispatch::Request] request the http request context
7
+ # @param [String] parent_url
8
+ def initialize(id, request, parent_url)
9
+ @id = id
10
+ @request = request
11
+ @parent_url = parent_url
12
+ end
13
+
14
+ attr_reader :id, :request, :parent_url
15
+
16
+ # @return [RDF::Graph]
17
+ def fetch
18
+ clean_graph_repository.find(id)
19
+ end
20
+
21
+ private
22
+
23
+ def clean_graph_repository
24
+ Hydra::ContentNegotiation::CleanGraphRepository.new(connection, replacer)
25
+ end
26
+
27
+ def connection
28
+ @connection ||= CleanConnection.new(ActiveFedora.fedora.connection)
29
+ end
30
+
31
+ # This method is called once for each statement in the graph.
32
+ def replacer
33
+ lambda do |resource_id, _graph|
34
+ parent_id = ActiveFedora::Base.uri_to_id(parent_url)
35
+ return parent_url + resource_id.sub(parent_id, '') if resource_id.start_with?(parent_id)
36
+ Rails.application.routes.url_helpers.solr_document_url(resource_id, host: hostname)
37
+ end
38
+ end
39
+
40
+ def hostname
41
+ request.host
42
+ end
43
+ end
44
+ end
@@ -80,6 +80,16 @@ module CurationConcerns
80
80
  @enable_noids = true
81
81
  end
82
82
 
83
+ attr_writer :translate_uri_to_id
84
+ def translate_uri_to_id
85
+ @translate_uri_to_id ||= ActiveFedora::Noid.config.translate_uri_to_id
86
+ end
87
+
88
+ attr_writer :translate_id_to_uri
89
+ def translate_id_to_uri
90
+ @translate_id_to_uri ||= ActiveFedora::Noid.config.translate_id_to_uri
91
+ end
92
+
83
93
  attr_writer :noid_template
84
94
  def noid_template
85
95
  @noid_template ||= '.reeddeeddk'
@@ -45,8 +45,8 @@ module CurationConcerns
45
45
  Hydra::Derivatives.fits_path = c.fits_path
46
46
  Hydra::Derivatives.enable_ffmpeg = c.enable_ffmpeg
47
47
 
48
- ActiveFedora::Base.translate_uri_to_id = ActiveFedora::Noid.config.translate_uri_to_id
49
- ActiveFedora::Base.translate_id_to_uri = ActiveFedora::Noid.config.translate_id_to_uri
48
+ ActiveFedora::Base.translate_uri_to_id = c.translate_uri_to_id
49
+ ActiveFedora::Base.translate_id_to_uri = c.translate_id_to_uri
50
50
  ActiveFedora::Noid.config.template = c.noid_template
51
51
  ActiveFedora::Noid.config.statefile = c.minter_statefile
52
52
  end
@@ -1,3 +1,3 @@
1
1
  module CurationConcerns
2
- VERSION = "1.0.0.beta9".freeze
2
+ VERSION = "1.0.0.beta10".freeze
3
3
  end
@@ -1,13 +1,10 @@
1
- require_relative 'abstract_migration_generator'
2
-
3
- class CurationConcerns::ModelsGenerator < CurationConcerns::AbstractMigrationGenerator
1
+ class CurationConcerns::ModelsGenerator < Rails::Generators::Base
4
2
  source_root File.expand_path('../templates', __FILE__)
5
3
  argument :model_name, type: :string, default: 'user'
6
4
  desc '
7
5
  This generator makes the following changes to your application:
8
- 1. Creates several database migrations if they do not exist in /db/migrate
9
- 2. Creates the curation_concerns.rb configuration file and several others
10
- 3. Creates the file_set.rb and collection.rb models
6
+ 1. Creates the curation_concerns.rb configuration file and several others
7
+ 2. Creates the file_set.rb and collection.rb models
11
8
  '
12
9
  def banner
13
10
  say_status('warning', 'GENERATING CURATION_CONCERNS MODELS', :yellow)
@@ -15,14 +12,7 @@ This generator makes the following changes to your application:
15
12
 
16
13
  # Setup the database migrations
17
14
  def copy_migrations
18
- [
19
- 'create_version_committers.rb',
20
- 'create_checksum_audit_logs.rb',
21
- 'create_single_use_links.rb',
22
- 'create_operations.rb'
23
- ].each do |file|
24
- better_migration_template file
25
- end
15
+ rake 'curation_concerns:install:migrations'
26
16
  end
27
17
 
28
18
  # Add behaviors to the user model
@@ -204,6 +204,43 @@ describe CurationConcerns::Actors::GenericWorkActor do
204
204
  expect(old_parent.reload.members).to eq []
205
205
  end
206
206
  end
207
+ context 'without in_works_ids' do
208
+ let(:old_parent) { FactoryGirl.create(:generic_work) }
209
+ let(:attributes) do
210
+ FactoryGirl.attributes_for(:generic_work).merge(
211
+ in_works_ids: []
212
+ )
213
+ end
214
+ before do
215
+ curation_concern.apply_depositor_metadata(user.user_key)
216
+ curation_concern.save!
217
+ old_parent.ordered_members << curation_concern
218
+ old_parent.save!
219
+ end
220
+ it "removes the old parent" do
221
+ expect(subject.update(attributes)).to be true
222
+ expect(curation_concern.in_works).to eq []
223
+ expect(old_parent.reload.members).to eq []
224
+ end
225
+ end
226
+ context 'with nil in_works_ids' do
227
+ let(:parent) { FactoryGirl.create(:generic_work) }
228
+ let(:attributes) do
229
+ FactoryGirl.attributes_for(:generic_work).merge(
230
+ in_works_ids: nil
231
+ )
232
+ end
233
+ before do
234
+ curation_concern.apply_depositor_metadata(user.user_key)
235
+ curation_concern.save!
236
+ parent.ordered_members << curation_concern
237
+ parent.save!
238
+ end
239
+ it "does nothing" do
240
+ expect(subject.update(attributes)).to be true
241
+ expect(curation_concern.in_works).to eq [parent]
242
+ end
243
+ end
207
244
  context 'adding to collections' do
208
245
  let!(:collection1) { create(:collection, user: user) }
209
246
  let!(:collection2) { create(:collection, user: user) }
@@ -8,16 +8,17 @@ describe CurationConcerns::GenericWorksController do
8
8
 
9
9
  describe '#show' do
10
10
  context 'my own private work' do
11
- let(:a_work) { create(:private_generic_work, user: user) }
11
+ let(:work) { create(:private_generic_work, user: user) }
12
12
  it 'shows me the page' do
13
- get :show, id: a_work
13
+ get :show, id: work
14
14
  expect(response).to be_success
15
15
  end
16
+
16
17
  context "with a parent work" do
17
18
  render_views
18
19
  it "renders a breadcrumb" do
19
- parent = create(:generic_work, title: ['Parent Work'], user: user, ordered_members: [a_work])
20
- get :show, id: a_work, parent_id: parent
20
+ parent = create(:generic_work, title: ['Parent Work'], user: user, ordered_members: [work])
21
+ get :show, id: work, parent_id: parent
21
22
 
22
23
  expect(response.body).to have_content "Parent Work"
23
24
  end
@@ -25,28 +26,45 @@ describe CurationConcerns::GenericWorksController do
25
26
  end
26
27
 
27
28
  context 'someone elses private work' do
28
- let(:a_work) { create(:private_generic_work) }
29
+ let(:work) { create(:private_generic_work) }
29
30
  it 'shows unauthorized message' do
30
- get :show, id: a_work
31
+ get :show, id: work
31
32
  expect(response.code).to eq '401'
32
33
  expect(response).to render_template(:unauthorized)
33
34
  end
34
35
  end
35
36
 
36
37
  context 'someone elses public work' do
37
- let(:a_work) { create(:public_generic_work) }
38
- it 'shows me the page' do
39
- expect(controller). to receive(:additional_response_formats).with(ActionController::MimeResponds::Collector)
40
- get :show, id: a_work
41
- expect(response).to be_success
38
+ let(:work) { create(:public_generic_work) }
39
+ context "html" do
40
+ it 'shows me the page' do
41
+ expect(controller). to receive(:additional_response_formats).with(ActionController::MimeResponds::Collector)
42
+ get :show, id: work
43
+ expect(response).to be_success
44
+ end
45
+ end
46
+
47
+ context "ttl" do
48
+ let(:presenter) { double }
49
+ before do
50
+ allow(controller).to receive(:presenter).and_return(presenter)
51
+ allow(presenter).to receive(:export_as_ttl).and_return("ttl graph")
52
+ end
53
+
54
+ it 'renders an turtle file' do
55
+ get :show, id: '99999999', format: :ttl
56
+ expect(response).to be_successful
57
+ expect(response.body).to eq "ttl graph"
58
+ expect(response.content_type).to eq 'text/turtle'
59
+ end
42
60
  end
43
61
  end
44
62
 
45
63
  context 'when I am a repository manager' do
46
64
  before { allow_any_instance_of(User).to receive(:groups).and_return(['admin']) }
47
- let(:a_work) { create(:private_generic_work) }
65
+ let(:work) { create(:private_generic_work) }
48
66
  it 'someone elses private work should show me the page' do
49
- get :show, id: a_work
67
+ get :show, id: work
50
68
  expect(response).to be_success
51
69
  end
52
70
  end
@@ -109,9 +127,9 @@ describe CurationConcerns::GenericWorksController do
109
127
 
110
128
  describe '#edit' do
111
129
  context 'my own private work' do
112
- let(:a_work) { create(:private_generic_work, user: user) }
130
+ let(:work) { create(:private_generic_work, user: user) }
113
131
  it 'shows me the page' do
114
- get :edit, id: a_work
132
+ get :edit, id: work
115
133
  expect(assigns[:form]).to be_kind_of CurationConcerns::GenericWorkForm
116
134
  expect(response).to be_success
117
135
  end
@@ -119,18 +137,18 @@ describe CurationConcerns::GenericWorksController do
119
137
 
120
138
  context 'someone elses private work' do
121
139
  routes { Rails.application.class.routes }
122
- let(:a_work) { create(:private_generic_work) }
140
+ let(:work) { create(:private_generic_work) }
123
141
  it 'shows the unauthorized message' do
124
- get :edit, id: a_work
142
+ get :edit, id: work
125
143
  expect(response.code).to eq '401'
126
144
  expect(response).to render_template(:unauthorized)
127
145
  end
128
146
  end
129
147
 
130
148
  context 'someone elses public work' do
131
- let(:a_work) { create(:public_generic_work) }
149
+ let(:work) { create(:public_generic_work) }
132
150
  it 'shows the unauthorized message' do
133
- get :edit, id: a_work
151
+ get :edit, id: work
134
152
  expect(response.code).to eq '401'
135
153
  expect(response).to render_template(:unauthorized)
136
154
  end
@@ -138,16 +156,16 @@ describe CurationConcerns::GenericWorksController do
138
156
 
139
157
  context 'when I am a repository manager' do
140
158
  before { allow_any_instance_of(User).to receive(:groups).and_return(['admin']) }
141
- let(:a_work) { create(:private_generic_work) }
159
+ let(:work) { create(:private_generic_work) }
142
160
  it 'someone elses private work should show me the page' do
143
- get :edit, id: a_work
161
+ get :edit, id: work
144
162
  expect(response).to be_success
145
163
  end
146
164
  end
147
165
  end
148
166
 
149
167
  describe '#update' do
150
- let(:a_work) { create(:private_generic_work, user: user) }
168
+ let(:work) { create(:private_generic_work, user: user) }
151
169
  before do
152
170
  allow(CurationConcerns::CurationConcern).to receive(:actor).and_return(actor)
153
171
  allow_any_instance_of(GenericWork).to receive(:visibility_changed?).and_return(visibility_changed)
@@ -156,12 +174,12 @@ describe CurationConcerns::GenericWorksController do
156
174
  let(:actor) { double(update: true) }
157
175
 
158
176
  it 'updates the work' do
159
- patch :update, id: a_work, generic_work: {}
160
- expect(response).to redirect_to main_app.curation_concerns_generic_work_path(a_work)
177
+ patch :update, id: work, generic_work: {}
178
+ expect(response).to redirect_to main_app.curation_concerns_generic_work_path(work)
161
179
  end
162
180
 
163
181
  it "can update file membership" do
164
- patch :update, id: a_work, generic_work: { ordered_member_ids: ['foo_123'] }
182
+ patch :update, id: work, generic_work: { ordered_member_ids: ['foo_123'] }
165
183
  expect(actor).to have_received(:update).with(ordered_member_ids: ['foo_123'])
166
184
  end
167
185
 
@@ -170,18 +188,18 @@ describe CurationConcerns::GenericWorksController do
170
188
  let(:actor) { double(update: true) }
171
189
 
172
190
  context 'when there are children' do
173
- let(:a_work) { create(:work_with_one_file, user: user) }
191
+ let(:work) { create(:work_with_one_file, user: user) }
174
192
 
175
193
  it 'prompts to change the files access' do
176
- patch :update, id: a_work, generic_work: {}
194
+ patch :update, id: work, generic_work: {}
177
195
  expect(response).to redirect_to main_app.confirm_curation_concerns_permission_path(controller.curation_concern)
178
196
  end
179
197
  end
180
198
 
181
199
  context 'without children' do
182
200
  it "doesn't prompt to change the files access" do
183
- patch :update, id: a_work, generic_work: {}
184
- expect(response).to redirect_to main_app.curation_concerns_generic_work_path(a_work)
201
+ patch :update, id: work, generic_work: {}
202
+ expect(response).to redirect_to main_app.curation_concerns_generic_work_path(work)
185
203
  end
186
204
  end
187
205
  end
@@ -190,16 +208,16 @@ describe CurationConcerns::GenericWorksController do
190
208
  let(:actor) { double(update: false) }
191
209
 
192
210
  it 'renders the form' do
193
- patch :update, id: a_work, generic_work: {}
211
+ patch :update, id: work, generic_work: {}
194
212
  expect(assigns[:form]).to be_kind_of CurationConcerns::GenericWorkForm
195
213
  expect(response).to render_template('edit')
196
214
  end
197
215
  end
198
216
 
199
217
  context 'someone elses public work' do
200
- let(:a_work) { create(:public_generic_work) }
218
+ let(:work) { create(:public_generic_work) }
201
219
  it 'shows the unauthorized message' do
202
- get :update, id: a_work
220
+ get :update, id: work
203
221
  expect(response.code).to eq '401'
204
222
  expect(response).to render_template(:unauthorized)
205
223
  end
@@ -207,10 +225,10 @@ describe CurationConcerns::GenericWorksController do
207
225
 
208
226
  context 'when I am a repository manager' do
209
227
  before { allow_any_instance_of(User).to receive(:groups).and_return(['admin']) }
210
- let(:a_work) { create(:private_generic_work) }
228
+ let(:work) { create(:private_generic_work) }
211
229
  it 'someone elses private work should update the work' do
212
- patch :update, id: a_work, generic_work: {}
213
- expect(response).to redirect_to main_app.curation_concerns_generic_work_path(a_work)
230
+ patch :update, id: work, generic_work: {}
231
+ expect(response).to redirect_to main_app.curation_concerns_generic_work_path(work)
214
232
  end
215
233
  end
216
234
  end
@@ -177,4 +177,40 @@ describe CurationConcerns::WorkShowPresenter do
177
177
  end
178
178
  end
179
179
  end
180
+
181
+ describe "graph export methods" do
182
+ let(:graph) do
183
+ RDF::Graph.new.tap do |g|
184
+ g << [RDF::URI('http://example.com/1'), RDF::Vocab::DC.title, 'Test title']
185
+ end
186
+ end
187
+
188
+ let(:exporter) { double }
189
+
190
+ before do
191
+ allow(CurationConcerns::GraphExporter).to receive(:new).and_return(exporter)
192
+ allow(exporter).to receive(:fetch).and_return(graph)
193
+ end
194
+
195
+ describe "#export_as_nt" do
196
+ subject { presenter.export_as_nt }
197
+ it { is_expected.to eq "<http://example.com/1> <http://purl.org/dc/terms/title> \"Test title\" .\n" }
198
+ end
199
+
200
+ describe "#export_as_ttl" do
201
+ subject { presenter.export_as_ttl }
202
+ it { is_expected.to eq "\n<http://example.com/1> <http://purl.org/dc/terms/title> \"Test title\" .\n" }
203
+ end
204
+
205
+ describe "#export_as_jsonld" do
206
+ subject { presenter.export_as_jsonld }
207
+ it { is_expected.to eq '{
208
+ "@context": {
209
+ "dc": "http://purl.org/dc/terms/"
210
+ },
211
+ "@id": "http://example.com/1",
212
+ "dc:title": "Test title"
213
+ }' }
214
+ end
215
+ end
180
216
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe CurationConcerns::GraphExporter do
4
+ let(:work) { create(:work_with_one_file, visibility: 'open') }
5
+ let(:document) { double(id: work.id) }
6
+ let(:request) { double(host: 'localhost') }
7
+ let(:service) { described_class.new(document, request) }
8
+
9
+ describe "fetch" do
10
+ subject { service.fetch }
11
+ let(:ttl) { subject.dump(:ttl) }
12
+ it "transforms suburis to hashcodes" do
13
+ expect(ttl).to match %r{<http://localhost/concern/generic_works/#{work.id}> a <http://projecthydra\.org/works/models#Work>,}
14
+ expect(ttl).to match %r{<http://purl\.org/dc/terms/title> "Test title";}
15
+ expect(ttl).to match %r{<http://www\.w3\.org/ns/auth/acl#accessControl> <http://localhost/catalog/}
16
+
17
+ query = subject.query([RDF::URI("http://localhost/concern/generic_works/#{work.id}"),
18
+ RDF::URI("http://www.iana.org/assignments/relation/first"),
19
+ nil])
20
+ proxy = query.to_a.first.object
21
+
22
+ expect(proxy.to_s).to match %r{http://localhost/concern/generic_works/#{work.id}/list_source#g\d+}
23
+
24
+ # It includes the list nodes on the graph
25
+ expect(subject.query([proxy, nil, nil]).count).to eq 2
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curation_concerns
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta9
4
+ version: 1.0.0.beta10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-06-10 00:00:00.000000000 Z
13
+ date: 2016-06-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hydra-head
@@ -669,6 +669,7 @@ files:
669
669
  - app/assets/stylesheets/curation_concerns/modules/search_results.scss
670
670
  - app/assets/stylesheets/curation_concerns/modules/site_actions.scss
671
671
  - app/assets/stylesheets/curation_concerns/modules/site_search.scss
672
+ - app/connections/curation_concerns/clean_connection.rb
672
673
  - app/controllers/collections_controller.rb
673
674
  - app/controllers/concerns/curation_concerns/api.rb
674
675
  - app/controllers/concerns/curation_concerns/application_controller_behavior.rb
@@ -801,8 +802,10 @@ files:
801
802
  - app/services/curation_concerns/derivative_path.rb
802
803
  - app/services/curation_concerns/embargo_service.rb
803
804
  - app/services/curation_concerns/file_set_audit_service.rb
805
+ - app/services/curation_concerns/graph_exporter.rb
804
806
  - app/services/curation_concerns/indexes_thumbnails.rb
805
807
  - app/services/curation_concerns/lease_service.rb
808
+ - app/services/curation_concerns/list_source_exporter.rb
806
809
  - app/services/curation_concerns/local_file_service.rb
807
810
  - app/services/curation_concerns/lock_manager.rb
808
811
  - app/services/curation_concerns/lockable.rb
@@ -975,6 +978,10 @@ files:
975
978
  - config/locales/curation_concerns.en.yml
976
979
  - config/routes.rb
977
980
  - curation_concerns.gemspec
981
+ - db/migrate/20160328222152_create_version_committers.rb
982
+ - db/migrate/20160328222153_create_checksum_audit_logs.rb
983
+ - db/migrate/20160328222154_create_single_use_links.rb
984
+ - db/migrate/20160427155928_create_operations.rb
978
985
  - lib/curation_concerns.rb
979
986
  - lib/curation_concerns/callbacks.rb
980
987
  - lib/curation_concerns/callbacks/registry.rb
@@ -990,7 +997,6 @@ files:
990
997
  - lib/curation_concerns/single_use_error.rb
991
998
  - lib/curation_concerns/spec_support.rb
992
999
  - lib/curation_concerns/version.rb
993
- - lib/generators/curation_concerns/abstract_migration_generator.rb
994
1000
  - lib/generators/curation_concerns/assets_generator.rb
995
1001
  - lib/generators/curation_concerns/clamav_generator.rb
996
1002
  - lib/generators/curation_concerns/collection_generator.rb
@@ -1011,10 +1017,6 @@ files:
1011
1017
  - lib/generators/curation_concerns/templates/curation_concerns.js
1012
1018
  - lib/generators/curation_concerns/templates/curation_concerns.scss
1013
1019
  - lib/generators/curation_concerns/templates/curation_concerns_helper.rb
1014
- - lib/generators/curation_concerns/templates/migrations/create_checksum_audit_logs.rb
1015
- - lib/generators/curation_concerns/templates/migrations/create_operations.rb
1016
- - lib/generators/curation_concerns/templates/migrations/create_single_use_links.rb
1017
- - lib/generators/curation_concerns/templates/migrations/create_version_committers.rb
1018
1020
  - lib/generators/curation_concerns/work/USAGE
1019
1021
  - lib/generators/curation_concerns/work/templates/README
1020
1022
  - lib/generators/curation_concerns/work/templates/actor.rb.erb
@@ -1170,6 +1172,7 @@ files:
1170
1172
  - spec/services/derivative_path_spec.rb
1171
1173
  - spec/services/embargo_service_spec.rb
1172
1174
  - spec/services/file_set_audit_service_spec.rb
1175
+ - spec/services/graph_exporter_spec.rb
1173
1176
  - spec/services/lease_service_spec.rb
1174
1177
  - spec/services/lock_manager_spec.rb
1175
1178
  - spec/services/parent_service_spec.rb
@@ -1243,7 +1246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1243
1246
  version: 1.3.1
1244
1247
  requirements: []
1245
1248
  rubyforge_project:
1246
- rubygems_version: 2.6.4
1249
+ rubygems_version: 2.5.1
1247
1250
  signing_key:
1248
1251
  specification_version: 4
1249
1252
  summary: A Rails Engine that allows an application to CRUD CurationConcern objects
@@ -1374,6 +1377,7 @@ test_files:
1374
1377
  - spec/services/derivative_path_spec.rb
1375
1378
  - spec/services/embargo_service_spec.rb
1376
1379
  - spec/services/file_set_audit_service_spec.rb
1380
+ - spec/services/graph_exporter_spec.rb
1377
1381
  - spec/services/lease_service_spec.rb
1378
1382
  - spec/services/lock_manager_spec.rb
1379
1383
  - spec/services/parent_service_spec.rb
@@ -1,31 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'rails/generators'
3
- require 'rails/generators/migration'
4
-
5
- class CurationConcerns::AbstractMigrationGenerator < Rails::Generators::Base
6
- include Rails::Generators::Migration
7
-
8
- # Implement the required interface for Rails::Generators::Migration.
9
- # taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
10
- def self.next_migration_number(path)
11
- if @prev_migration_nr
12
- @prev_migration_nr += 1
13
- else
14
- last_migration = Dir[File.join(path, '*.rb')].sort.last
15
- @prev_migration_nr = if last_migration
16
- last_migration.sub(File.join(path, '/'), '').to_i + 1
17
- else
18
- Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
19
- end
20
- end
21
- @prev_migration_nr.to_s
22
- end
23
-
24
- protected
25
-
26
- def better_migration_template(file)
27
- migration_template "migrations/#{file}", "db/migrate/#{file}"
28
- rescue Rails::Generators::Error => e
29
- say_status('warning', e.message, :yellow)
30
- end
31
- end