hyrax 2.1.0.rc3 → 2.1.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -2
- data/app/assets/javascripts/hyrax/save_work/visibility_component.es6 +4 -4
- data/app/controllers/concerns/hyrax/controller.rb +15 -0
- data/app/controllers/concerns/hyrax/works_controller_behavior.rb +3 -1
- data/app/helpers/hyrax/hyrax_helper_behavior.rb +8 -0
- data/app/jobs/attach_files_to_work_job.rb +1 -1
- data/app/presenters/hyrax/admin_set_presenter.rb +1 -1
- data/app/presenters/hyrax/collection_presenter.rb +1 -1
- data/app/presenters/hyrax/file_set_presenter.rb +10 -6
- data/app/presenters/hyrax/member_presenter_factory.rb +10 -10
- data/app/presenters/hyrax/work_show_presenter.rb +43 -4
- data/app/renderers/hyrax/renderers/faceted_attribute_renderer.rb +1 -1
- data/app/renderers/hyrax/renderers/linked_attribute_renderer.rb +1 -1
- data/app/search_builders/hyrax/catalog_search_builder.rb +14 -1
- data/app/services/hyrax/collections/permissions_service.rb +13 -0
- data/app/views/hyrax/base/_items.html.erb +9 -1
- data/app/views/hyrax/dashboard/collections/_form_for_select_collection.html.erb +4 -3
- data/lib/generators/hyrax/templates/catalog_controller.rb +1 -1
- data/lib/generators/hyrax/templates/config/initializers/hyrax.rb +4 -0
- data/lib/hyrax/configuration.rb +5 -0
- data/lib/hyrax/version.rb +1 -1
- data/spec/features/catalog_search_spec.rb +41 -0
- data/spec/helpers/hyrax_helper_spec.rb +30 -0
- data/spec/lib/hyrax/configuration_spec.rb +1 -0
- data/spec/presenters/hyrax/admin_set_presenter_spec.rb +1 -1
- data/spec/presenters/hyrax/collection_presenter_spec.rb +1 -1
- data/spec/presenters/hyrax/work_show_presenter_spec.rb +79 -4
- data/spec/renderers/hyrax/renderers/faceted_attribute_renderer_spec.rb +3 -3
- data/spec/renderers/hyrax/renderers/linked_attribute_renderer_spec.rb +2 -2
- data/spec/search_builders/hyrax/catalog_search_builder_spec.rb +35 -0
- data/spec/services/hyrax/collections/permissions_service_spec.rb +14 -0
- data/spec/views/hyrax/base/_items.html.erb_spec.rb +18 -24
- data/spec/views/hyrax/my/collections/_list_collections.html.erb_spec.rb +1 -1
- data/template.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf48eeb6b1a64bc4d19de32c47c6c776387ec40d
|
4
|
+
data.tar.gz: f5ee75a59cd3f27fa135d4a623e47430594037d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7699b73766c7b747377e563f16049a02339cefb40cac5b2190795cb1045fce60a64f85d0c4571851fe36ca6ef7f53e16a566faca7711798627cbf15a9746f8e
|
7
|
+
data.tar.gz: b528b5192fc06718fecb1130b4d17b792a4e11b116a7a383091193632b62ccf0d29901004a599f2a4abbf7c9377ef98d8b6230bdc028569b8ccb73b2fe77ba48
|
data/README.md
CHANGED
@@ -63,7 +63,7 @@ The Samvera community is here to help. Please see our [support guide](./.github/
|
|
63
63
|
# Getting started
|
64
64
|
|
65
65
|
This document contains instructions specific to setting up an app with __Hyrax
|
66
|
-
v2.1.0.
|
66
|
+
v2.1.0.rc4__. If you are looking for instructions on installing a different
|
67
67
|
version, be sure to select the appropriate branch or tag from the drop-down
|
68
68
|
menu above.
|
69
69
|
|
@@ -162,7 +162,7 @@ NOTE: The steps need to be done in order to create a new Hyrax based app.
|
|
162
162
|
Generate a new Rails application using the template.
|
163
163
|
|
164
164
|
```
|
165
|
-
rails _5.1.6_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.1.0.
|
165
|
+
rails _5.1.6_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.1.0.rc4/template.rb
|
166
166
|
```
|
167
167
|
|
168
168
|
Generating a new Rails application using Hyrax's template above takes cares of a number of steps for you, including:
|
@@ -188,6 +188,13 @@ Notes:
|
|
188
188
|
* This web server is purely for development purposes. You will want to use a more fully featured [web server](#web-server) for production-like environments.
|
189
189
|
* You have the option to start each of these services individually. More information on [solr_wrapper](https://github.com/cbeer/solr_wrapper) and [fcrepo_wrapper](https://github.com/cbeer/fcrepo_wrapper) will help you set this up. Start rails with `rails s`.
|
190
190
|
|
191
|
+
### Avoid Performance Issues with solr-suggest
|
192
|
+
|
193
|
+
*Recommended for all Hyrax apps.*
|
194
|
+
|
195
|
+
It is strongly suggested that you turn off solr-suggest. Details on why and how to do this are in
|
196
|
+
[Fix performance issue caused by solr-suggest](https://github.com/samvera/hyrax/wiki/Troubleshooting-Migration-from-2.0.x-to-2.1.0#fix-performance-issue-caused-by-solr-suggest-after-200-objects-are-in-the-repository).
|
197
|
+
|
191
198
|
## Start background workers
|
192
199
|
|
193
200
|
Many of the services performed by Hyrax are resource intensive, and therefore are well suited to running as background jobs that can be managed and executed by a message queuing system. Examples include:
|
@@ -8,7 +8,7 @@ export default class VisibilityComponent {
|
|
8
8
|
this.element = element
|
9
9
|
this.adminSetWidget = adminSetWidget
|
10
10
|
this.form = element.closest('form')
|
11
|
-
|
11
|
+
this.element.find('.collapse').collapse({ toggle: false })
|
12
12
|
element.find("[type='radio']").on('change', () => { this.showForm() })
|
13
13
|
// Ensure any disabled options are re-enabled when form submits
|
14
14
|
this.form.on('submit', () => { this.enableAllOptions() })
|
@@ -22,7 +22,7 @@ export default class VisibilityComponent {
|
|
22
22
|
|
23
23
|
// Collapse all Visibility sub-options
|
24
24
|
collapseAll() {
|
25
|
-
|
25
|
+
this.element.find('.collapse').collapse('hide');
|
26
26
|
}
|
27
27
|
|
28
28
|
// Open the selected Visibility's sub-options, collapsing all others
|
@@ -33,8 +33,8 @@ export default class VisibilityComponent {
|
|
33
33
|
|
34
34
|
if(target) {
|
35
35
|
// Show the target suboption and hide all others
|
36
|
-
|
37
|
-
|
36
|
+
this.element.find('.collapse' + target).collapse('show');
|
37
|
+
this.element.find('.collapse:not(' + target + ')').collapse('hide');
|
38
38
|
}
|
39
39
|
else {
|
40
40
|
this.collapseAll()
|
@@ -6,6 +6,7 @@ module Hyrax::Controller
|
|
6
6
|
|
7
7
|
# Adds Hydra behaviors into the application controller
|
8
8
|
include Hydra::Controller::ControllerBehavior
|
9
|
+
helper_method :create_work_presenter
|
9
10
|
before_action :set_locale
|
10
11
|
end
|
11
12
|
|
@@ -14,6 +15,20 @@ module Hyrax::Controller
|
|
14
15
|
hyrax.dashboard_path
|
15
16
|
end
|
16
17
|
|
18
|
+
##
|
19
|
+
# @deprecated this helper is no longer used by Hyrax; if you need access to
|
20
|
+
# this presenter on every page, you may need to readd it manually.
|
21
|
+
#
|
22
|
+
# A presenter for selecting a work type to create this is needed here because
|
23
|
+
# the selector is in the header on every page.
|
24
|
+
def create_work_presenter
|
25
|
+
Deprecation.warn(self, "The `create_work_presenter` helper is deprecated " \
|
26
|
+
"for removal in Hyrax 3.0. The work selector has " \
|
27
|
+
"been removed the masthead in Hyrax 2.1.")
|
28
|
+
|
29
|
+
Hyrax::SelectTypeListPresenter.new(current_user)
|
30
|
+
end
|
31
|
+
|
17
32
|
# Ensure that the locale choice is persistent across requests
|
18
33
|
def default_url_options
|
19
34
|
super.merge(locale: I18n.locale)
|
@@ -192,7 +192,9 @@ module Hyrax
|
|
192
192
|
end
|
193
193
|
|
194
194
|
def curation_concern_from_search_results
|
195
|
-
|
195
|
+
search_params = params
|
196
|
+
search_params.delete :page
|
197
|
+
search_result_document(search_params)
|
196
198
|
end
|
197
199
|
|
198
200
|
# Only returns unsuppressed documents the user has read access to
|
@@ -257,6 +257,14 @@ module Hyrax
|
|
257
257
|
content_tag(:span, "", class: [Hyrax::ModelIcon.css_class_for(Collection), "collection-icon-search"])
|
258
258
|
end
|
259
259
|
|
260
|
+
def collection_title_by_id(id)
|
261
|
+
solr_docs = controller.repository.find(id).docs
|
262
|
+
return nil if solr_docs.empty?
|
263
|
+
solr_field = solr_docs.first[Solrizer.solr_name("title", :stored_searchable)]
|
264
|
+
return nil if solr_field.nil?
|
265
|
+
solr_field.first
|
266
|
+
end
|
267
|
+
|
260
268
|
private
|
261
269
|
|
262
270
|
def user_agent
|
@@ -12,10 +12,10 @@ class AttachFilesToWorkJob < Hyrax::ApplicationJob
|
|
12
12
|
metadata = visibility_attributes(work_attributes)
|
13
13
|
uploaded_files.each do |uploaded_file|
|
14
14
|
actor = Hyrax::Actors::FileSetActor.new(FileSet.create, user)
|
15
|
+
actor.file_set.permissions_attributes = work_permissions
|
15
16
|
actor.create_metadata(metadata)
|
16
17
|
actor.create_content(uploaded_file)
|
17
18
|
actor.attach_to_work(work)
|
18
|
-
actor.file_set.permissions_attributes = work_permissions
|
19
19
|
uploaded_file.update(file_set_uri: actor.file_set.uri)
|
20
20
|
end
|
21
21
|
end
|
@@ -82,12 +82,7 @@ module Hyrax
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def parent
|
85
|
-
|
86
|
-
fl: ActiveFedora.id_field)
|
87
|
-
.map { |x| x.fetch(ActiveFedora.id_field) }
|
88
|
-
@parent_presenter ||= Hyrax::PresenterFactory.build_for(ids: ids,
|
89
|
-
presenter_class: WorkShowPresenter,
|
90
|
-
presenter_args: current_ability).first
|
85
|
+
@parent_presenter ||= fetch_parent_presenter
|
91
86
|
end
|
92
87
|
|
93
88
|
def user_can_perform_any_action?
|
@@ -99,5 +94,14 @@ module Hyrax
|
|
99
94
|
def link_presenter_class
|
100
95
|
SingleUseLinkPresenter
|
101
96
|
end
|
97
|
+
|
98
|
+
def fetch_parent_presenter
|
99
|
+
ids = ActiveFedora::SolrService.query("{!field f=member_ids_ssim}#{id}",
|
100
|
+
fl: ActiveFedora.id_field)
|
101
|
+
.map { |x| x.fetch(ActiveFedora.id_field) }
|
102
|
+
Hyrax::PresenterFactory.build_for(ids: ids,
|
103
|
+
presenter_class: WorkShowPresenter,
|
104
|
+
presenter_args: current_ability).first
|
105
|
+
end
|
102
106
|
end
|
103
107
|
end
|
@@ -36,17 +36,17 @@ module Hyrax
|
|
36
36
|
@work_presenters ||= member_presenters(ordered_ids - file_set_ids, work_presenter_class)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
# TODO: Extract this to ActiveFedora::Aggregations::ListSource
|
40
|
+
def ordered_ids
|
41
|
+
@ordered_ids ||= begin
|
42
|
+
ActiveFedora::SolrService.query("proxy_in_ssi:#{id}",
|
43
|
+
rows: 10_000,
|
44
|
+
fl: "ordered_targets_ssim")
|
45
|
+
.flat_map { |x| x.fetch("ordered_targets_ssim", []) }
|
46
|
+
end
|
47
|
+
end
|
40
48
|
|
41
|
-
|
42
|
-
def ordered_ids
|
43
|
-
@ordered_ids ||= begin
|
44
|
-
ActiveFedora::SolrService.query("proxy_in_ssi:#{id}",
|
45
|
-
rows: 10_000,
|
46
|
-
fl: "ordered_targets_ssim")
|
47
|
-
.flat_map { |x| x.fetch("ordered_targets_ssim", []) }
|
48
|
-
end
|
49
|
-
end
|
49
|
+
private
|
50
50
|
|
51
51
|
# These are the file sets that belong to this work, but not necessarily
|
52
52
|
# in order.
|
@@ -69,7 +69,7 @@ module Hyrax
|
|
69
69
|
return nil if representative_id.blank?
|
70
70
|
@representative_presenter ||=
|
71
71
|
begin
|
72
|
-
result =
|
72
|
+
result = member_presenters_for([representative_id]).first
|
73
73
|
return nil if result.try(:id) == id
|
74
74
|
if result.respond_to?(:representative_presenter)
|
75
75
|
result.representative_presenter
|
@@ -153,10 +153,22 @@ module Hyrax
|
|
153
153
|
solr_document.to_model
|
154
154
|
end
|
155
155
|
|
156
|
-
delegate :member_presenters, :file_set_presenters, :work_presenters, to: :member_presenter_factory
|
156
|
+
delegate :member_presenters, :ordered_ids, :file_set_presenters, :work_presenters, to: :member_presenter_factory
|
157
157
|
|
158
|
-
|
159
|
-
|
158
|
+
# @return [Array] list to display with Kaminari pagination
|
159
|
+
def list_of_item_ids_to_display
|
160
|
+
paginated_item_list(page_array: authorized_item_ids)
|
161
|
+
end
|
162
|
+
|
163
|
+
# @param [Array<String>] ids a list of ids to build presenters for
|
164
|
+
# @return [Array<presenter_class>] presenters for the array of ids (not filtered by class)
|
165
|
+
def member_presenters_for(an_array_of_ids)
|
166
|
+
member_presenters(an_array_of_ids)
|
167
|
+
end
|
168
|
+
|
169
|
+
# @return [Integer] total number of pages of viewable items
|
170
|
+
def total_pages
|
171
|
+
(total_items.to_f / rows_from_params.to_f).ceil
|
160
172
|
end
|
161
173
|
|
162
174
|
def manifest_url
|
@@ -194,6 +206,33 @@ module Hyrax
|
|
194
206
|
|
195
207
|
private
|
196
208
|
|
209
|
+
# list of item ids to display is based on ordered_ids
|
210
|
+
def authorized_item_ids
|
211
|
+
@member_item_list_ids ||= begin
|
212
|
+
items = ordered_ids
|
213
|
+
items.delete_if { |m| !current_ability.can?(:read, m) } if Flipflop.hide_private_items?
|
214
|
+
items
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Uses kaminari to paginate an array to avoid need for solr documents for items here
|
219
|
+
def paginated_item_list(page_array:)
|
220
|
+
Kaminari.paginate_array(page_array, total_count: page_array.size).page(current_page).per(rows_from_params)
|
221
|
+
end
|
222
|
+
|
223
|
+
def total_items
|
224
|
+
authorized_item_ids.size
|
225
|
+
end
|
226
|
+
|
227
|
+
def rows_from_params
|
228
|
+
request.params[:rows].nil? ? Hyrax.config.show_work_item_rows : request.params[:rows].to_i
|
229
|
+
end
|
230
|
+
|
231
|
+
def current_page
|
232
|
+
page = request.params[:page].nil? ? 1 : request.params[:page].to_i
|
233
|
+
page > total_pages ? total_pages : page
|
234
|
+
end
|
235
|
+
|
197
236
|
def manifest_helper
|
198
237
|
@manifest_helper ||= ManifestHelper.new(request.base_url)
|
199
238
|
end
|
@@ -8,7 +8,7 @@ module Hyrax
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def search_path(value)
|
11
|
-
Rails.application.routes.url_helpers.search_catalog_path(:"f[#{search_field}][]" => value)
|
11
|
+
Rails.application.routes.url_helpers.search_catalog_path(:"f[#{search_field}][]" => value, locale: I18n.locale)
|
12
12
|
end
|
13
13
|
|
14
14
|
def search_field
|
@@ -2,7 +2,8 @@ class Hyrax::CatalogSearchBuilder < Hyrax::SearchBuilder
|
|
2
2
|
self.default_processor_chain += [
|
3
3
|
:add_access_controls_to_solr_params,
|
4
4
|
:show_works_or_works_that_contain_files,
|
5
|
-
:show_only_active_records
|
5
|
+
:show_only_active_records,
|
6
|
+
:filter_collection_facet_for_access
|
6
7
|
]
|
7
8
|
|
8
9
|
# show both works that match the query and works that contain files that match the query
|
@@ -19,6 +20,18 @@ class Hyrax::CatalogSearchBuilder < Hyrax::SearchBuilder
|
|
19
20
|
solr_parameters[:fq] << '-suppressed_bsi:true'
|
20
21
|
end
|
21
22
|
|
23
|
+
# only return facet counts for collections that this user has access to see
|
24
|
+
def filter_collection_facet_for_access(solr_parameters)
|
25
|
+
return if current_ability.admin?
|
26
|
+
|
27
|
+
collection_ids = Hyrax::Collections::PermissionsService.collection_ids_for_view(ability: current_ability).map { |id| "^#{id}$" }
|
28
|
+
solr_parameters['f.member_of_collection_ids_ssim.facet.matches'] = if collection_ids.present?
|
29
|
+
collection_ids.join('|')
|
30
|
+
else
|
31
|
+
"^$"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
22
35
|
private
|
23
36
|
|
24
37
|
# the {!lucene} gives us the OR syntax
|
@@ -97,6 +97,19 @@ module Hyrax
|
|
97
97
|
source_ids_for_deposit(ability: ability, source_type: 'collection')
|
98
98
|
end
|
99
99
|
|
100
|
+
# @api public
|
101
|
+
#
|
102
|
+
# IDs of collections which the user can view.
|
103
|
+
#
|
104
|
+
# @param ability [Ability] the ability coming from cancan ability check
|
105
|
+
# @return [Array<String>] IDs of collections into which the user can view
|
106
|
+
# @note Several checks get the user's groups from the user's ability. The same values can be retrieved directly from a passed in ability.
|
107
|
+
def self.collection_ids_for_view(ability:)
|
108
|
+
collection_ids_for_user(ability: ability, access: [Hyrax::PermissionTemplateAccess::MANAGE,
|
109
|
+
Hyrax::PermissionTemplateAccess::DEPOSIT,
|
110
|
+
Hyrax::PermissionTemplateAccess::VIEW])
|
111
|
+
end
|
112
|
+
|
100
113
|
# @api public
|
101
114
|
#
|
102
115
|
# Determine if the given user has permissions to view the admin show page for at least one collection
|
@@ -1,5 +1,6 @@
|
|
1
1
|
<h2><%= t('.header') %></h2>
|
2
|
-
<%
|
2
|
+
<% array_of_ids = presenter.list_of_item_ids_to_display %>
|
3
|
+
<% members = presenter.member_presenters_for(array_of_ids) %>
|
3
4
|
<% if members.present? %>
|
4
5
|
<table class="table table-striped related-files">
|
5
6
|
<thead>
|
@@ -15,6 +16,13 @@
|
|
15
16
|
<%= render partial: 'member', collection: members %>
|
16
17
|
</tbody>
|
17
18
|
</table>
|
19
|
+
<div class="row">
|
20
|
+
<% if presenter.total_pages > 1 %>
|
21
|
+
<div class="row record-padding col-md-9">
|
22
|
+
<%= paginate array_of_ids, outer_window: 2, theme: 'blacklight', param_name: :page, route_set: main_app %>
|
23
|
+
</div><!-- /pager -->
|
24
|
+
<% end %>
|
25
|
+
</div>
|
18
26
|
<% elsif can? :edit, presenter.id %>
|
19
27
|
<div class="alert alert-warning" role="alert"><%= t('.empty', type: presenter.human_readable_type) %></div>
|
20
28
|
<% else %>
|
@@ -33,11 +33,12 @@
|
|
33
33
|
<div class="modal-footer">
|
34
34
|
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t("hyrax.collection.select_form.close") %></button>
|
35
35
|
<% if user_collections.blank? %>
|
36
|
-
|
37
|
-
|
36
|
+
<% # TODO: Uncomment the following line when errors with adding works to a new collection are resolved. See Issue hyrax#3088 %>
|
37
|
+
<% # = render 'hyrax/dashboard/collections/button_create_collection', label: t("hyrax.collection.select_form.create") %>
|
38
38
|
<% else %>
|
39
39
|
<%= render 'hyrax/dashboard/collections/button_for_update_collection', label: t("hyrax.collection.select_form.update"), collection_id: 'collection_replace_id' %>
|
40
|
-
|
40
|
+
<% # TODO: Uncomment the following line when errors with adding works to a new collection are resolved. See Issue hyrax#3088 %>
|
41
|
+
<% # = render 'hyrax/dashboard/collections/button_create_collection', label: t("hyrax.collection.select_form.create_new") %>
|
41
42
|
<% end %>
|
42
43
|
</div>
|
43
44
|
</div><!-- /.modal-content -->
|
@@ -44,7 +44,7 @@ class CatalogController < ApplicationController
|
|
44
44
|
config.add_facet_field solr_name("based_near_label", :facetable), limit: 5
|
45
45
|
config.add_facet_field solr_name("publisher", :facetable), limit: 5
|
46
46
|
config.add_facet_field solr_name("file_format", :facetable), limit: 5
|
47
|
-
config.add_facet_field solr_name('
|
47
|
+
config.add_facet_field solr_name('member_of_collection_ids', :symbol), limit: 5, label: 'Collections', helper_method: :collection_title_by_id
|
48
48
|
|
49
49
|
# The generic_type isn't displayed on the facet list
|
50
50
|
# It's used to give a label to the filter that comes from the user profile
|
@@ -116,6 +116,10 @@ Hyrax.config do |config|
|
|
116
116
|
# The default is true.
|
117
117
|
# config.work_requires_files = true
|
118
118
|
|
119
|
+
# How many rows of items should appear on the work show view?
|
120
|
+
# The default is 10
|
121
|
+
# config.show_work_item_rows = 10
|
122
|
+
|
119
123
|
# Enable IIIF image service. This is required to use the
|
120
124
|
# UniversalViewer-ified show page
|
121
125
|
#
|
data/lib/hyrax/configuration.rb
CHANGED
@@ -340,6 +340,11 @@ module Hyrax
|
|
340
340
|
@work_requires_files
|
341
341
|
end
|
342
342
|
|
343
|
+
attr_writer :show_work_item_rows
|
344
|
+
def show_work_item_rows
|
345
|
+
@show_work_item_rows ||= 10 # rows on show view
|
346
|
+
end
|
347
|
+
|
343
348
|
attr_writer :batch_user_key
|
344
349
|
def batch_user_key
|
345
350
|
@batch_user_key ||= 'batchuser@example.com'
|
data/lib/hyrax/version.rb
CHANGED
@@ -28,4 +28,45 @@ RSpec.describe 'catalog searching', type: :feature do
|
|
28
28
|
expect(page).to have_content(collection.title.first)
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
context 'with public works and private collections', clean_repo: true do
|
33
|
+
let!(:collection) { create(:private_collection) }
|
34
|
+
|
35
|
+
let!(:jills_work) do
|
36
|
+
create(:public_work, title: ["Jill's Research"], keyword: ['jills_keyword'], member_of_collections: [collection])
|
37
|
+
end
|
38
|
+
|
39
|
+
it "hides collection facet values the user doesn't have access to view when performing a search" do
|
40
|
+
within('#search-form-header') do
|
41
|
+
fill_in('search-field-header', with: 'jills_keyword')
|
42
|
+
click_button('Go')
|
43
|
+
end
|
44
|
+
|
45
|
+
expect(page).to have_content('Search Results')
|
46
|
+
expect(page).to have_content(jills_work.title.first)
|
47
|
+
expect(page).not_to have_content(collection.title.first)
|
48
|
+
expect(page).not_to have_css('.blacklight-member_of_collection_ids_ssim')
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'as an admin' do
|
52
|
+
let(:admin_user) { create :admin }
|
53
|
+
|
54
|
+
before do
|
55
|
+
sign_in admin_user
|
56
|
+
visit '/'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "shows collection facet values the user has access to view when performing a search" do
|
60
|
+
within('#search-form-header') do
|
61
|
+
fill_in('search-field-header', with: 'jills_keyword')
|
62
|
+
click_button('Go')
|
63
|
+
end
|
64
|
+
|
65
|
+
expect(page).to have_content('Search Results')
|
66
|
+
expect(page).to have_content(jills_work.title.first)
|
67
|
+
find('.blacklight-member_of_collection_ids_ssim').click
|
68
|
+
expect(page).to have_content(collection.title.first)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
31
72
|
end
|
@@ -366,4 +366,34 @@ RSpec.describe HyraxHelper, type: :helper do
|
|
366
366
|
expect(helper.banner_image).to eq(Hyrax.config.banner_image)
|
367
367
|
end
|
368
368
|
end
|
369
|
+
|
370
|
+
describe "#collection_title_by_id" do
|
371
|
+
let(:solr_doc) { double(id: "abcd12345") }
|
372
|
+
let(:bad_solr_doc) { double(id: "efgh67890") }
|
373
|
+
let(:solr_response) { double(docs: [solr_doc]) }
|
374
|
+
let(:bad_solr_response) { double(docs: [bad_solr_doc]) }
|
375
|
+
let(:empty_solr_response) { double(docs: []) }
|
376
|
+
let(:repository) { double }
|
377
|
+
|
378
|
+
before do
|
379
|
+
allow(controller).to receive(:repository).and_return(repository)
|
380
|
+
allow(solr_doc).to receive(:[]).with("title_tesim").and_return(["Collection of Awesomeness"])
|
381
|
+
allow(bad_solr_doc).to receive(:[]).with("title_tesim").and_return(nil)
|
382
|
+
allow(repository).to receive(:find).with("abcd12345").and_return(solr_response)
|
383
|
+
allow(repository).to receive(:find).with("efgh67890").and_return(bad_solr_response)
|
384
|
+
allow(repository).to receive(:find).with("bad-id").and_return(empty_solr_response)
|
385
|
+
end
|
386
|
+
|
387
|
+
it "returns the first title of the collection" do
|
388
|
+
expect(helper.collection_title_by_id("abcd12345")).to eq "Collection of Awesomeness"
|
389
|
+
end
|
390
|
+
|
391
|
+
it "returns nil if collection doesn't have title_tesim field" do
|
392
|
+
expect(helper.collection_title_by_id("efgh67890")).to eq nil
|
393
|
+
end
|
394
|
+
|
395
|
+
it "returns nil if collection not found" do
|
396
|
+
expect(helper.collection_title_by_id("bad-id")).to eq nil
|
397
|
+
end
|
398
|
+
end
|
369
399
|
end
|
@@ -72,6 +72,7 @@ RSpec.describe Hyrax::Configuration do
|
|
72
72
|
it { is_expected.to respond_to(:rights_statement_service_class=) }
|
73
73
|
it { is_expected.to respond_to(:redis_namespace) }
|
74
74
|
it { is_expected.to respond_to(:subject_prefix) }
|
75
|
+
it { is_expected.to respond_to(:show_work_item_rows) }
|
75
76
|
it { is_expected.to respond_to(:translate_id_to_uri) }
|
76
77
|
it { is_expected.to respond_to(:translate_uri_to_id) }
|
77
78
|
it { is_expected.to respond_to(:upload_path) }
|
@@ -68,7 +68,7 @@ RSpec.describe Hyrax::AdminSetPresenter do
|
|
68
68
|
|
69
69
|
subject { presenter.show_path }
|
70
70
|
|
71
|
-
it { is_expected.to eq "/admin/admin_sets/#{admin_set.id}" }
|
71
|
+
it { is_expected.to eq "/admin/admin_sets/#{admin_set.id}?locale=en" }
|
72
72
|
end
|
73
73
|
|
74
74
|
describe '#managed_access' do
|
@@ -357,7 +357,7 @@ RSpec.describe Hyrax::CollectionPresenter do
|
|
357
357
|
describe '#show_path' do
|
358
358
|
subject { presenter.show_path }
|
359
359
|
|
360
|
-
it { is_expected.to eq "/dashboard/collections/#{solr_doc.id}" }
|
360
|
+
it { is_expected.to eq "/dashboard/collections/#{solr_doc.id}?locale=en" }
|
361
361
|
end
|
362
362
|
|
363
363
|
describe "banner_file" do
|
@@ -30,6 +30,8 @@ RSpec.describe Hyrax::WorkShowPresenter do
|
|
30
30
|
it { is_expected.to delegate_method(:resource_type).to(:solr_document) }
|
31
31
|
it { is_expected.to delegate_method(:keyword).to(:solr_document) }
|
32
32
|
it { is_expected.to delegate_method(:itemtype).to(:solr_document) }
|
33
|
+
it { is_expected.to delegate_method(:member_presenters).to(:member_presenter_factory) }
|
34
|
+
it { is_expected.to delegate_method(:ordered_ids).to(:member_presenter_factory) }
|
33
35
|
|
34
36
|
describe "#model_name" do
|
35
37
|
subject { presenter.model_name }
|
@@ -224,13 +226,86 @@ RSpec.describe Hyrax::WorkShowPresenter do
|
|
224
226
|
end
|
225
227
|
end
|
226
228
|
|
227
|
-
describe "
|
229
|
+
describe "#member_presenters_for" do
|
228
230
|
let(:obj) { create(:work_with_file_and_work) }
|
229
231
|
let(:attributes) { obj.to_solr }
|
230
|
-
let(:
|
232
|
+
let(:items) { presenter.ordered_ids }
|
233
|
+
let(:subject) { presenter.member_presenters_for(items) }
|
231
234
|
|
232
|
-
it
|
233
|
-
expect(
|
235
|
+
it "returns appropriate classes for each item" do
|
236
|
+
expect(subject.size).to eq 2
|
237
|
+
expect(subject.first).to be_instance_of(Hyrax::FileSetPresenter)
|
238
|
+
expect(subject.last).to be_instance_of(described_class)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe "#list_of_item_ids_to_display" do
|
243
|
+
let(:subject) { presenter.list_of_item_ids_to_display }
|
244
|
+
let(:items_list) { ['item0', 'item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8', 'item9'] }
|
245
|
+
let(:rows) { 10 }
|
246
|
+
let(:page) { 1 }
|
247
|
+
let(:ability) { double "Ability" }
|
248
|
+
let(:current_ability) { ability }
|
249
|
+
|
250
|
+
before do
|
251
|
+
allow(presenter).to receive(:ordered_ids).and_return(items_list)
|
252
|
+
allow(current_ability).to receive(:can?).with(:read, 'item0').and_return true
|
253
|
+
allow(current_ability).to receive(:can?).with(:read, 'item1').and_return false
|
254
|
+
allow(current_ability).to receive(:can?).with(:read, 'item2').and_return true
|
255
|
+
allow(current_ability).to receive(:can?).with(:read, 'item3').and_return false
|
256
|
+
allow(current_ability).to receive(:can?).with(:read, 'item4').and_return true
|
257
|
+
allow(current_ability).to receive(:can?).with(:read, 'item5').and_return true
|
258
|
+
allow(current_ability).to receive(:can?).with(:read, 'item6').and_return false
|
259
|
+
allow(current_ability).to receive(:can?).with(:read, 'item7').and_return true
|
260
|
+
allow(current_ability).to receive(:can?).with(:read, 'item8').and_return false
|
261
|
+
allow(current_ability).to receive(:can?).with(:read, 'item9').and_return true
|
262
|
+
allow(presenter).to receive(:rows_from_params).and_return(rows)
|
263
|
+
allow(presenter).to receive(:current_page).and_return(page)
|
264
|
+
allow(Flipflop).to receive(:hide_private_items?).and_return(answer)
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'when hiding private items' do
|
268
|
+
let(:answer) { true }
|
269
|
+
|
270
|
+
it "returns viewable items" do
|
271
|
+
expect(subject.size).to eq 6
|
272
|
+
expect(subject).to be_instance_of(Kaminari::PaginatableArray)
|
273
|
+
expect(subject).to include("item0", "item2", "item4", "item5", "item7", "item9")
|
274
|
+
end
|
275
|
+
end
|
276
|
+
context 'when including private items' do
|
277
|
+
let(:answer) { false }
|
278
|
+
|
279
|
+
it "returns appropriate items" do
|
280
|
+
expect(subject.size).to eq 10
|
281
|
+
expect(subject).to be_instance_of(Kaminari::PaginatableArray)
|
282
|
+
expect(subject).to eq(items_list)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
context 'with pagination' do
|
286
|
+
let(:rows) { 3 }
|
287
|
+
let(:page) { 2 }
|
288
|
+
|
289
|
+
let(:answer) { true }
|
290
|
+
it 'partitions the item list and excluding hidden items' do
|
291
|
+
expect(subject).to eq(['item5', 'item7', 'item9'])
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "#total_pages" do
|
297
|
+
let(:subject) { presenter.total_pages }
|
298
|
+
let(:items) { 17 }
|
299
|
+
let(:rows) { 4 }
|
300
|
+
|
301
|
+
before do
|
302
|
+
allow(Flipflop).to receive(:hide_private_items?).and_return(false)
|
303
|
+
allow(presenter).to receive(:total_items).and_return(items)
|
304
|
+
allow(presenter).to receive(:rows_from_params).and_return(rows)
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'calculates number of pages from items and rows' do
|
308
|
+
expect(subject).to eq(5)
|
234
309
|
end
|
235
310
|
end
|
236
311
|
|
@@ -11,8 +11,8 @@ RSpec.describe Hyrax::Renderers::FacetedAttributeRenderer do
|
|
11
11
|
%(
|
12
12
|
<tr><th>Name</th>
|
13
13
|
<td><ul class='tabular'>
|
14
|
-
<li class="attribute attribute-name"><a href="/catalog?f%5Bname_sim%5D%5B%5D=Bob">Bob</a></li>
|
15
|
-
<li class="attribute attribute-name"><a href="/catalog?f%5Bname_sim%5D%5B%5D=Jessica">Jessica</a></li>
|
14
|
+
<li class="attribute attribute-name"><a href="/catalog?f%5Bname_sim%5D%5B%5D=Bob&locale=en">Bob</a></li>
|
15
|
+
<li class="attribute attribute-name"><a href="/catalog?f%5Bname_sim%5D%5B%5D=Jessica&locale=en">Jessica</a></li>
|
16
16
|
</ul></td></tr>
|
17
17
|
)
|
18
18
|
end
|
@@ -28,7 +28,7 @@ RSpec.describe Hyrax::Renderers::FacetedAttributeRenderer do
|
|
28
28
|
let(:rendered_link_query) { URI.parse(rendered_link['href']).query }
|
29
29
|
|
30
30
|
it "escapes content properly" do
|
31
|
-
expect(rendered_link_query).to eq "#{CGI.escape('f[name_sim][]')}=#{CGI.escape('John & Bob')}"
|
31
|
+
expect(rendered_link_query).to eq "#{CGI.escape('f[name_sim][]')}=#{CGI.escape('John & Bob')}&locale=en"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -10,8 +10,8 @@ RSpec.describe Hyrax::Renderers::LinkedAttributeRenderer do
|
|
10
10
|
let(:tr_content) do
|
11
11
|
"<tr><th>Name</th>\n" \
|
12
12
|
"<td><ul class='tabular'>" \
|
13
|
-
"<li class=\"attribute attribute-name\"><a href=\"/catalog?q=Bob&search_field=name\">Bob</a></li>\n" \
|
14
|
-
"<li class=\"attribute attribute-name\"><a href=\"/catalog?q=Jessica&search_field=name\">Jessica</a></li>\n" \
|
13
|
+
"<li class=\"attribute attribute-name\"><a href=\"/catalog?locale=en&q=Bob&search_field=name\">Bob</a></li>\n" \
|
14
|
+
"<li class=\"attribute attribute-name\"><a href=\"/catalog?locale=en&q=Jessica&search_field=name\">Jessica</a></li>\n" \
|
15
15
|
"</ul></td></tr>"
|
16
16
|
end
|
17
17
|
|
@@ -48,4 +48,39 @@ RSpec.describe Hyrax::CatalogSearchBuilder do
|
|
48
48
|
expect(solr_params[:fq]).to eq ["-suppressed_bsi:true"]
|
49
49
|
end
|
50
50
|
end
|
51
|
+
|
52
|
+
describe "#filter_collection_facet_for_access" do
|
53
|
+
let(:user) { build(:user) }
|
54
|
+
let(:ability) { Ability.new(user) }
|
55
|
+
let(:context) { double(current_ability: ability) }
|
56
|
+
|
57
|
+
subject { builder.filter_collection_facet_for_access(solr_params) }
|
58
|
+
|
59
|
+
context 'with an admin' do
|
60
|
+
let(:user) { build(:admin) }
|
61
|
+
|
62
|
+
it "does nothing if user is an admin" do
|
63
|
+
subject
|
64
|
+
expect(solr_params['f.member_of_collection_ids_ssim.facet.matches']).to be_blank
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when the user has view access to collections' do
|
69
|
+
let(:collection_ids) { ['abcd12345', 'efgh67890'] }
|
70
|
+
|
71
|
+
before do
|
72
|
+
allow(Hyrax::Collections::PermissionsService).to receive(:collection_ids_for_view).with(ability: ability).and_return(collection_ids)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "includes a regex of the ids of collections" do
|
76
|
+
subject
|
77
|
+
expect(solr_params['f.member_of_collection_ids_ssim.facet.matches']).to eq '^abcd12345$|^efgh67890$'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "includes an empty regex when user doesn't have access to view any collections" do
|
82
|
+
subject
|
83
|
+
expect(solr_params['f.member_of_collection_ids_ssim.facet.matches']).to eq '^$'
|
84
|
+
end
|
85
|
+
end
|
51
86
|
end
|
@@ -299,6 +299,20 @@ RSpec.describe Hyrax::Collections::PermissionsService do
|
|
299
299
|
end
|
300
300
|
end
|
301
301
|
|
302
|
+
describe '.collection_ids_for_view' do
|
303
|
+
it 'returns collection ids where user has view access' do
|
304
|
+
expect(described_class.collection_ids_for_view(ability: ability)).to match_array [col_du.id, col_dg.id, col_mu.id, col_mg.id, col_vu.id, col_vg.id]
|
305
|
+
end
|
306
|
+
|
307
|
+
context 'when user has no access' do
|
308
|
+
let(:ability) { Ability.new(user2) }
|
309
|
+
|
310
|
+
it 'returns empty array' do
|
311
|
+
expect(described_class.collection_ids_for_view(ability: ability)).to match_array []
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
302
316
|
describe '.can_manage_any_collection?' do
|
303
317
|
it 'returns true when user has manage access to at least one collection' do
|
304
318
|
expect(described_class.can_manage_any_collection?(ability: ability)).to be true
|
@@ -1,11 +1,17 @@
|
|
1
1
|
RSpec.describe 'hyrax/base/_items.html.erb', type: :view do
|
2
2
|
let(:ability) { double }
|
3
|
-
let(:
|
3
|
+
let(:request) { double "request", params: params }
|
4
|
+
let(:params) { ActionController::Parameters.new(rows: 10) }
|
4
5
|
|
5
6
|
context 'when children are not present' do
|
6
|
-
let(:
|
7
|
+
let(:member_list) { [] }
|
8
|
+
let(:presenter) { double(:presenter, list_of_items_to_display: member_list, member_presenters_for: member_list, id: 'the-id', human_readable_type: 'Thing') }
|
7
9
|
|
8
|
-
|
10
|
+
before do
|
11
|
+
expect(presenter).to receive(:list_of_item_ids_to_display).and_return(member_list)
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'and the current user can edit the presenter' do
|
9
15
|
it 'renders an alert' do
|
10
16
|
expect(view).to receive(:can?).with(:edit, presenter.id).and_return(true)
|
11
17
|
render 'hyrax/base/items', presenter: presenter
|
@@ -25,35 +31,23 @@ RSpec.describe 'hyrax/base/_items.html.erb', type: :view do
|
|
25
31
|
let(:child1) { double('Thing1', id: 'Thing 1', title: 'Title 1') }
|
26
32
|
let(:child2) { double('Thing2', id: 'Thing 2', title: 'Title 2') }
|
27
33
|
let(:child3) { double('Thing3', id: 'Thing 3', title: 'Title 3') }
|
28
|
-
let(:
|
29
|
-
let(:authorized_presenters) { [child1, child3] }
|
34
|
+
let(:member_list) { [child1, child2, child3] }
|
30
35
|
let(:solr_document) { double('Solr Doc', id: 'the-id') }
|
31
36
|
let(:presenter) { Hyrax::WorkShowPresenter.new(solr_document, ability, request) }
|
32
37
|
|
33
38
|
before do
|
34
39
|
stub_template 'hyrax/base/_member.html.erb' => '<%= member %>'
|
35
40
|
expect(Flipflop).to receive(:hide_private_items?).and_return(:flipflop)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
context 'and hide_private_items is on' do
|
43
|
-
let(:flip_flop) { true }
|
44
|
-
|
45
|
-
it "displays only authorized children" do
|
46
|
-
render 'hyrax/base/items', presenter: presenter
|
47
|
-
expect(rendered).to have_css('tbody', text: authorized_presenters.join)
|
48
|
-
end
|
41
|
+
allow(presenter).to receive(:list_of_item_ids_to_display).and_return(member_list)
|
42
|
+
allow(presenter).to receive(:member_presenters_for).with(member_list).and_return(member_list)
|
43
|
+
allow(ability).to receive(:can?).with(:read, child1.id).and_return true
|
44
|
+
allow(ability).to receive(:can?).with(:read, child2.id).and_return false
|
45
|
+
allow(ability).to receive(:can?).with(:read, child3.id).and_return true
|
49
46
|
end
|
50
|
-
context 'and hide_private_items is off' do
|
51
|
-
let(:flip_flop) { false }
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
48
|
+
it "displays children" do
|
49
|
+
render 'hyrax/base/items', presenter: presenter
|
50
|
+
expect(rendered).to have_css('tbody')
|
57
51
|
end
|
58
52
|
end
|
59
53
|
end
|
@@ -45,7 +45,7 @@ RSpec.describe 'hyrax/my/collections/_list_collections.html.erb', type: :view do
|
|
45
45
|
expect(rendered).to have_selector("tr#document_#{id}")
|
46
46
|
check_tr_data_attributes
|
47
47
|
expect(rendered).to have_selector("tr[data-post-delete-url='/dashboard/collections/#{id}']")
|
48
|
-
expect(rendered).to have_link 'Collection Title', href: hyrax.dashboard_collection_path(id)
|
48
|
+
expect(rendered).to have_link 'Collection Title', href: hyrax.dashboard_collection_path(id, locale: I18n.locale)
|
49
49
|
expect(rendered).to have_link 'Edit collection', href: hyrax.edit_dashboard_collection_path(id)
|
50
50
|
expect(rendered).to have_link 'Delete collection'
|
51
51
|
expect(rendered).to have_link 'Add to collection'
|
data/template.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hyrax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.0.
|
4
|
+
version: 2.1.0.rc4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2018-05-
|
17
|
+
date: 2018-05-30 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: rails
|