hyrax 3.3.0 → 3.4.2

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 (255) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +26 -17
  3. data/.dassie/.env +2 -1
  4. data/.dassie/Gemfile +1 -1
  5. data/.dassie/app/forms/collection_resource_form.rb +8 -0
  6. data/.dassie/app/indexers/collection_resource_indexer.rb +8 -0
  7. data/.dassie/app/models/collection_resource.rb +35 -0
  8. data/.dassie/config/initializers/file_services.rb +4 -0
  9. data/.dassie/config/initializers/hyrax.rb +12 -1
  10. data/.dassie/config/metadata/collection_resource.yaml +23 -0
  11. data/.dassie/db/seeds.rb +74 -17
  12. data/.dassie/spec/forms/collection_resource_form_spec.rb +13 -0
  13. data/.dassie/spec/indexers/collection_resource_indexer_spec.rb +14 -0
  14. data/.dassie/spec/models/collection_resource_spec.rb +13 -0
  15. data/.github/release.yml +26 -0
  16. data/.gitignore +3 -0
  17. data/.regen +1 -1
  18. data/.rubocop.yml +1 -1
  19. data/.rubocop_fixme.yml +22 -3
  20. data/CONTAINERS.md +18 -13
  21. data/Dockerfile +4 -3
  22. data/app/actors/hyrax/actors/file_actor.rb +6 -4
  23. data/app/actors/hyrax/actors/transfer_request_actor.rb +3 -7
  24. data/app/assets/javascripts/hyrax/analytics_events.js +8 -2
  25. data/app/assets/javascripts/hyrax/autocomplete/linked_data.es6 +1 -3
  26. data/app/assets/javascripts/hyrax/collections_v2.es6 +13 -0
  27. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +1 -3
  28. data/app/controllers/concerns/hyrax/controller.rb +21 -0
  29. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +83 -59
  30. data/app/controllers/hyrax/admin/admin_sets_controller.rb +105 -19
  31. data/app/controllers/hyrax/admin/permission_template_accesses_controller.rb +12 -19
  32. data/app/controllers/hyrax/batch_edits_controller.rb +12 -3
  33. data/app/controllers/hyrax/batch_uploads_controller.rb +4 -0
  34. data/app/controllers/hyrax/citations_controller.rb +1 -1
  35. data/app/controllers/hyrax/dashboard/collections_controller.rb +176 -83
  36. data/app/controllers/hyrax/single_use_links_viewer_controller.rb +1 -1
  37. data/app/forms/hyrax/forms/administrative_set_form.rb +19 -1
  38. data/app/forms/hyrax/forms/batch_edit_form.rb +1 -1
  39. data/app/forms/hyrax/forms/collection_form.rb +1 -1
  40. data/app/forms/hyrax/forms/dashboard/nest_collection_form.rb +21 -6
  41. data/app/forms/hyrax/forms/pcdm_collection_form.rb +30 -2
  42. data/app/forms/hyrax/forms/permission_template_form.rb +17 -9
  43. data/app/forms/hyrax/forms/resource_form.rb +23 -5
  44. data/app/forms/hyrax/forms/widgets/admin_set_visibility.rb +1 -1
  45. data/app/helpers/hyrax/collections_helper.rb +14 -0
  46. data/app/helpers/hyrax/membership_helper.rb +1 -1
  47. data/app/helpers/hyrax/trophy_helper.rb +1 -1
  48. data/app/helpers/hyrax/url_helper.rb +1 -1
  49. data/app/indexers/hyrax/administrative_set_indexer.rb +8 -2
  50. data/app/indexers/hyrax/deep_indexing_service.rb +1 -1
  51. data/app/indexers/hyrax/file_set_indexer.rb +1 -0
  52. data/app/indexers/hyrax/pcdm_collection_indexer.rb +3 -2
  53. data/app/indexers/hyrax/thumbnail_indexer.rb +31 -0
  54. data/app/indexers/hyrax/valkyrie_file_set_indexer.rb +6 -6
  55. data/app/indexers/hyrax/valkyrie_indexer.rb +4 -2
  56. data/app/indexers/hyrax/valkyrie_work_indexer.rb +13 -0
  57. data/app/inputs/controlled_vocabulary_input.rb +2 -0
  58. data/app/jobs/change_depositor_event_job.rb +47 -0
  59. data/app/jobs/characterize_job.rb +43 -3
  60. data/app/jobs/concerns/hyrax/members_permission_job_behavior.rb +1 -1
  61. data/app/jobs/content_depositor_change_event_job.rb +2 -1
  62. data/app/jobs/hyrax/propagate_change_depositor_job.rb +32 -0
  63. data/app/jobs/import_url_job.rb +4 -6
  64. data/app/jobs/inherit_permissions_job.rb +1 -1
  65. data/app/jobs/valkyrie_create_derivatives_job.rb +25 -0
  66. data/app/jobs/valkyrie_ingest_job.rb +41 -35
  67. data/app/models/admin_set.rb +10 -2
  68. data/app/models/collection_branding_info.rb +8 -6
  69. data/app/models/concerns/hyrax/collection_behavior.rb +3 -3
  70. data/app/models/concerns/hyrax/file_set/characterization.rb +7 -1
  71. data/app/models/concerns/hyrax/solr_document/metadata.rb +1 -0
  72. data/app/models/concerns/hyrax/solr_document_behavior.rb +9 -3
  73. data/app/models/concerns/hyrax/user.rb +11 -0
  74. data/app/models/concerns/hyrax/work_behavior.rb +1 -1
  75. data/app/models/featured_work_list.rb +0 -1
  76. data/app/models/hyrax/administrative_set.rb +36 -1
  77. data/app/models/hyrax/collection_type.rb +2 -2
  78. data/app/models/hyrax/file_metadata.rb +37 -3
  79. data/app/models/hyrax/file_set.rb +43 -4
  80. data/app/models/hyrax/group.rb +19 -0
  81. data/app/models/hyrax/pcdm_collection.rb +56 -1
  82. data/app/models/hyrax/permission_template.rb +11 -5
  83. data/app/models/hyrax/work.rb +91 -0
  84. data/app/models/job_io_wrapper.rb +1 -1
  85. data/app/models/proxy_deposit_request.rb +1 -1
  86. data/app/presenters/hyrax/admin_set_presenter.rb +2 -2
  87. data/app/presenters/hyrax/member_presenter_factory.rb +2 -4
  88. data/app/presenters/hyrax/pcdm_member_presenter_factory.rb +2 -2
  89. data/app/presenters/hyrax/work_show_presenter.rb +10 -6
  90. data/app/search_builders/hyrax/dashboard/collections_search_builder.rb +2 -2
  91. data/app/search_builders/hyrax/dashboard/managed_search_filters.rb +44 -4
  92. data/app/search_builders/hyrax/dashboard/nested_collections_search_builder.rb +2 -2
  93. data/app/search_builders/hyrax/my/collections_search_builder.rb +11 -4
  94. data/app/services/hyrax/access_control_list.rb +20 -6
  95. data/app/services/hyrax/adapters/nesting_index_adapter.rb +3 -3
  96. data/app/services/hyrax/admin_set_create_service.rb +21 -37
  97. data/app/services/hyrax/change_content_depositor_service.rb +2 -2
  98. data/app/services/hyrax/change_depositor_service.rb +70 -0
  99. data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +4 -6
  100. data/app/services/hyrax/collections/collection_member_service.rb +3 -5
  101. data/app/services/hyrax/collections/nested_collection_query_service.rb +24 -12
  102. data/app/services/hyrax/custom_queries/navigators/child_file_sets_navigator.rb +45 -0
  103. data/app/services/hyrax/custom_queries/navigators/child_filesets_navigator.rb +7 -2
  104. data/app/services/hyrax/custom_queries/navigators/parent_work_navigator.rb +54 -0
  105. data/app/services/hyrax/default_middleware_stack.rb +3 -0
  106. data/app/services/hyrax/file_set_derivatives_service.rb +21 -2
  107. data/app/services/hyrax/file_set_type_service.rb +2 -5
  108. data/app/services/hyrax/listeners/file_metadata_listener.rb +31 -1
  109. data/app/services/hyrax/listeners/member_cleanup_listener.rb +27 -11
  110. data/app/services/hyrax/listeners/metadata_index_listener.rb +39 -0
  111. data/app/services/hyrax/listeners/proxy_deposit_listener.rb +14 -8
  112. data/app/services/hyrax/location_service.rb +33 -0
  113. data/app/services/hyrax/multiple_membership_checker.rb +46 -1
  114. data/app/services/hyrax/resource_visibility_propagator.rb +1 -1
  115. data/app/services/hyrax/simple_schema_loader.rb +5 -1
  116. data/app/services/hyrax/solr_query_service.rb +12 -7
  117. data/app/services/hyrax/thumbnail_path_service.rb +1 -1
  118. data/app/services/hyrax/valkyrie_persist_derivatives.rb +50 -0
  119. data/app/services/hyrax/valkyrie_upload.rb +94 -0
  120. data/app/services/hyrax/work_uploads_handler.rb +0 -10
  121. data/app/services/hyrax/workflow/workflow_importer.rb +7 -9
  122. data/app/services/hyrax/workflow/workflow_schema.rb +3 -5
  123. data/app/strategies/hyrax/strategies/yaml_strategy.rb +4 -6
  124. data/app/uploaders/hyrax/uploaded_file_uploader.rb +4 -4
  125. data/app/utils/hyrax/data_destroyers/collection_branding_destroyer.rb +29 -0
  126. data/app/utils/hyrax/data_destroyers/collection_types_destroyer.rb +26 -0
  127. data/app/utils/hyrax/data_destroyers/default_admin_set_id_cache_destroyer.rb +26 -0
  128. data/app/utils/hyrax/data_destroyers/featured_works_destroyer.rb +27 -0
  129. data/app/utils/hyrax/data_destroyers/permission_templates_destroyer.rb +30 -0
  130. data/app/utils/hyrax/data_destroyers/repository_metadata_destroyer.rb +42 -0
  131. data/app/utils/hyrax/data_destroyers/stats_destroyer.rb +33 -0
  132. data/app/utils/hyrax/data_maintenance.rb +51 -0
  133. data/app/utils/hyrax/required_data_seeder.rb +21 -0
  134. data/app/utils/hyrax/required_data_seeders/collection_seeder.rb +26 -0
  135. data/app/utils/hyrax/required_data_seeders/collection_type_seeder.rb +36 -0
  136. data/app/utils/hyrax/test_data_seeder.rb +24 -0
  137. data/app/utils/hyrax/test_data_seeders/collection_seeder.rb +91 -0
  138. data/app/utils/hyrax/test_data_seeders/collection_type_seeder.rb +72 -0
  139. data/app/utils/hyrax/test_data_seeders/user_seeder.rb +52 -0
  140. data/app/validators/hyrax/collection_membership_validator.rb +39 -0
  141. data/app/views/catalog/_index_header_list_default.html.erb +8 -1
  142. data/app/views/catalog/_thumbnail_list_default.html.erb +8 -3
  143. data/app/views/collections/edit_fields/_based_near.html.erb +7 -7
  144. data/app/views/hyrax/admin/admin_sets/_form_participant_table.html.erb +2 -2
  145. data/app/views/hyrax/admin/admin_sets/_form_participants.html.erb +2 -2
  146. data/app/views/hyrax/admin/admin_sets/_form_visibility.html.erb +2 -2
  147. data/app/views/hyrax/admin/admin_sets/_form_workflow.erb +1 -1
  148. data/app/views/hyrax/admin/collection_types/index.html.erb +1 -1
  149. data/app/views/hyrax/base/_form.html.erb +1 -1
  150. data/app/views/hyrax/base/_form_child_work_relationships.html.erb +1 -1
  151. data/app/views/hyrax/dashboard/collections/_default_group.html.erb +2 -2
  152. data/app/views/hyrax/dashboard/collections/_form.html.erb +24 -17
  153. data/app/views/hyrax/dashboard/collections/_form_branding.html.erb +1 -0
  154. data/app/views/hyrax/dashboard/collections/_form_discovery.html.erb +6 -3
  155. data/app/views/hyrax/dashboard/collections/_form_share.html.erb +2 -2
  156. data/app/views/hyrax/dashboard/collections/_form_share_table.html.erb +3 -3
  157. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +2 -2
  158. data/app/views/hyrax/dashboard/sidebar/_activity.html.erb +1 -1
  159. data/app/views/hyrax/dashboard/works/_default_group.html.erb +1 -1
  160. data/app/views/hyrax/dashboard/works/_list_works.html.erb +1 -1
  161. data/app/views/hyrax/file_sets/_actions.html.erb +2 -2
  162. data/app/views/hyrax/my/_facet_pagination.html.erb +12 -9
  163. data/app/views/hyrax/my/_work_action_menu.html.erb +8 -9
  164. data/app/views/hyrax/my/collections/_default_group.html.erb +2 -2
  165. data/app/views/hyrax/my/collections/_list_collections.html.erb +2 -2
  166. data/app/views/hyrax/my/collections/index.html.erb +3 -2
  167. data/app/views/hyrax/my/works/_default_group.html.erb +1 -1
  168. data/app/views/hyrax/my/works/_list_works.html.erb +1 -2
  169. data/app/views/hyrax/my/works/_tabs.html.erb +6 -1
  170. data/app/views/hyrax/my/works/index.html.erb +4 -2
  171. data/chart/hyrax/Chart.yaml +11 -7
  172. data/chart/hyrax/README.md +22 -1
  173. data/chart/hyrax/templates/_helpers.tpl +4 -0
  174. data/chart/hyrax/templates/cron-embargo.yaml +5 -0
  175. data/chart/hyrax/templates/cron-lease.yaml +5 -0
  176. data/chart/hyrax/templates/deployment-worker.yaml +11 -0
  177. data/chart/hyrax/templates/ingress.yaml +7 -6
  178. data/chart/hyrax/values.yaml +152 -0
  179. data/config/features.rb +48 -50
  180. data/config/initializers/listeners.rb +0 -1
  181. data/config/initializers/{valkryrie_storage.rb → storage_adapter_initializer.rb} +5 -0
  182. data/config/locales/hyrax.de.yml +18 -17
  183. data/config/locales/hyrax.en.yml +30 -28
  184. data/config/locales/hyrax.es.yml +10 -9
  185. data/config/locales/hyrax.fr.yml +2 -1
  186. data/config/locales/hyrax.it.yml +3 -2
  187. data/config/locales/hyrax.pt-BR.yml +2 -1
  188. data/config/locales/hyrax.zh.yml +2 -1
  189. data/config/metadata/basic_metadata.yaml +2 -0
  190. data/config/metadata/core_metadata.yaml +1 -1
  191. data/docker-compose.yml +47 -42
  192. data/documentation/developing-your-hyrax-based-app.md +1 -1
  193. data/documentation/legacyREADME.md +1 -1
  194. data/hyrax.gemspec +5 -3
  195. data/lib/generators/hyrax/collection_resource/USAGE +20 -0
  196. data/lib/generators/hyrax/collection_resource/collection_resource_generator.rb +133 -0
  197. data/lib/generators/hyrax/collection_resource/templates/collection.rb.erb +34 -0
  198. data/lib/generators/hyrax/collection_resource/templates/collection_form.rb.erb +7 -0
  199. data/lib/generators/hyrax/collection_resource/templates/collection_form_spec.rb.erb +13 -0
  200. data/lib/generators/hyrax/collection_resource/templates/collection_indexer.rb.erb +7 -0
  201. data/lib/generators/hyrax/collection_resource/templates/collection_indexer_spec.rb.erb +13 -0
  202. data/lib/generators/hyrax/collection_resource/templates/collection_metadata.yaml +22 -0
  203. data/lib/generators/hyrax/collection_resource/templates/collection_spec.rb.erb +12 -0
  204. data/lib/generators/hyrax/install_generator.rb +9 -0
  205. data/lib/hyrax/administrative_set_name.rb +18 -0
  206. data/lib/hyrax/collection_name.rb +2 -0
  207. data/lib/hyrax/configuration.rb +22 -0
  208. data/lib/hyrax/controlled_vocabularies/location.rb +9 -2
  209. data/lib/hyrax/controlled_vocabularies/resource_label_caching.rb +42 -0
  210. data/lib/hyrax/controlled_vocabularies.rb +1 -0
  211. data/lib/hyrax/publisher.rb +49 -0
  212. data/lib/hyrax/schema.rb +16 -13
  213. data/lib/hyrax/specs/capybara.rb +1 -1
  214. data/lib/hyrax/specs/shared_specs/hydra_works.rb +11 -5
  215. data/lib/hyrax/specs/shared_specs/indexers.rb +117 -3
  216. data/lib/hyrax/transactions/admin_set_create.rb +2 -1
  217. data/lib/hyrax/transactions/admin_set_destroy.rb +22 -0
  218. data/lib/hyrax/transactions/admin_set_update.rb +21 -0
  219. data/lib/hyrax/transactions/collection_destroy.rb +22 -0
  220. data/lib/hyrax/transactions/collection_update.rb +5 -2
  221. data/lib/hyrax/transactions/container.rb +97 -23
  222. data/lib/hyrax/transactions/create_work.rb +3 -0
  223. data/lib/hyrax/transactions/destroy_work.rb +3 -0
  224. data/lib/hyrax/transactions/steps/apply_collection_permission_template.rb +2 -0
  225. data/lib/hyrax/transactions/steps/apply_permission_template.rb +2 -0
  226. data/lib/hyrax/transactions/steps/apply_visibility.rb +2 -0
  227. data/lib/hyrax/transactions/steps/change_depositor.rb +46 -0
  228. data/lib/hyrax/transactions/steps/check_for_empty_admin_set.rb +36 -0
  229. data/lib/hyrax/transactions/steps/delete_access_control.rb +32 -0
  230. data/lib/hyrax/transactions/steps/delete_resource.rb +19 -3
  231. data/lib/hyrax/transactions/steps/destroy_work.rb +3 -1
  232. data/lib/hyrax/transactions/steps/ensure_permission_template.rb +2 -0
  233. data/lib/hyrax/transactions/steps/save.rb +24 -6
  234. data/lib/hyrax/transactions/steps/save_access_control.rb +2 -2
  235. data/lib/hyrax/transactions/steps/save_collection_banner.rb +59 -0
  236. data/lib/hyrax/transactions/steps/save_collection_logo.rb +109 -0
  237. data/lib/hyrax/transactions/steps/save_work.rb +3 -0
  238. data/lib/hyrax/transactions/steps/set_user_as_creator.rb +41 -0
  239. data/lib/hyrax/transactions/steps/update_work_members.rb +51 -0
  240. data/lib/hyrax/transactions/update_work.rb +4 -3
  241. data/lib/hyrax/transactions/work_create.rb +1 -1
  242. data/lib/hyrax/transactions/work_destroy.rb +2 -1
  243. data/lib/hyrax/transactions/work_update.rb +19 -0
  244. data/lib/hyrax/version.rb +1 -1
  245. data/lib/wings/active_fedora_converter/file_metadata_node.rb +48 -0
  246. data/lib/wings/active_fedora_converter/instance_builder.rb +68 -0
  247. data/lib/wings/active_fedora_converter.rb +3 -3
  248. data/lib/wings/attribute_transformer.rb +5 -1
  249. data/lib/wings/services/custom_queries/find_file_metadata.rb +19 -8
  250. data/lib/wings/setup.rb +3 -1
  251. data/lib/wings/valkyrie/persister.rb +2 -0
  252. data/lib/wings/valkyrie/query_service.rb +6 -7
  253. data/lib/wings/valkyrie/storage.rb +7 -1
  254. data/template.rb +1 -1
  255. metadata +99 -12
@@ -85,6 +85,27 @@ RSpec.shared_examples 'a visibility indexer' do
85
85
  end
86
86
  end
87
87
 
88
+ RSpec.shared_examples 'a thumbnail indexer' do
89
+ before do
90
+ raise 'indexer_class must be set with `let(:indexer_class)`' unless defined? indexer_class
91
+ raise 'resource must be set with `let(:resource)` and is expected to be a kind of Hyrax::Resource' unless defined?(resource) && resource.kind_of?(Hyrax::Resource)
92
+ # optionally can pass in default_visibility by setting it with a let statement if your application changes the default; Hyrax defines this as 'restricted'
93
+ # See samvera/hyrda-head hydra-access-controls/app/models/concerns/hydra/access_controls/access_rights.rb for possible VISIBILITY_TEXT_VALUE_...'
94
+ end
95
+ subject(:indexer) { indexer_class.new(resource: resource) }
96
+ let(:thumbnail_path) { '/downloads/foo12345?file=thumbnail' }
97
+
98
+ before do
99
+ allow(indexer.thumbnail_path_service).to receive(:call).and_return(thumbnail_path)
100
+ end
101
+
102
+ describe '#to_solr' do
103
+ it 'indexes a thumbnail path' do
104
+ expect(indexer.to_solr).to include(thumbnail_path_ss: thumbnail_path)
105
+ end
106
+ end
107
+ end
108
+
88
109
  RSpec.shared_examples 'a Core metadata indexer' do
89
110
  before do
90
111
  raise 'indexer_class must be set with `let(:indexer_class)`' unless defined? indexer_class
@@ -144,6 +165,53 @@ RSpec.shared_examples 'a Basic metadata indexer' do
144
165
  end
145
166
  end
146
167
 
168
+ RSpec.shared_examples 'a File Set indexer' do
169
+ before do
170
+ raise 'indexer_class must be set with `let(:indexer_class)`' unless defined? indexer_class
171
+ # NOTE: resource must be persisted for permission tests to pass
172
+ raise 'resource must be set with `let(:resource)` and is expected to be a kind of Hyrax::FileSet' unless defined?(resource) && resource.kind_of?(Hyrax::FileSet)
173
+ # optionally can pass in default_visibility by setting it with a let statement if your application changes the default; Hyrax defines this as 'restricted'
174
+ # See samvera/hyrda-head hydra-access-controls/app/models/concerns/hydra/access_controls/access_rights.rb for possible VISIBILITY_TEXT_VALUE_...'
175
+ end
176
+ subject(:indexer) { indexer_class.new(resource: resource) }
177
+ let(:file_ids) { ['fileid1', 'fileid2'] }
178
+
179
+ it_behaves_like 'a Hyrax::Resource indexer'
180
+ it_behaves_like 'a Core metadata indexer'
181
+ it_behaves_like 'a Basic metadata indexer'
182
+ it_behaves_like 'a permission indexer'
183
+ it_behaves_like 'a visibility indexer'
184
+ it_behaves_like 'a thumbnail indexer'
185
+
186
+ describe '#to_solr' do
187
+ it 'indexes generic type' do
188
+ expect(indexer.to_solr)
189
+ .to include(generic_type_sim: a_collection_containing_exactly('FileSet'))
190
+ end
191
+
192
+ it 'indexed file ids' do
193
+ expect(indexer.to_solr)
194
+ .to include(file_ids_ssim: a_collection_containing_exactly(*ids))
195
+ end
196
+
197
+ it 'indexes representative id' do
198
+ expect(indexer.to_solr)
199
+ .to include(hasRelatedMediaFragment_ssim: a_collection_containing_exactly(an_instance_of(String)))
200
+ end
201
+
202
+ it 'indexes thumbnail id' do
203
+ expect(indexer.to_solr)
204
+ .to include(hasRelatedImage_ssim: a_collection_containing_exactly(an_instance_of(String)))
205
+ end
206
+
207
+ it 'indexes depositor' do
208
+ expect(indexer.to_solr)
209
+ .to include(depositor_ssim: [resource.depositor],
210
+ depositor_tesim: [resource.depositor])
211
+ end
212
+ end
213
+ end
214
+
147
215
  RSpec.shared_examples 'a Work indexer' do
148
216
  before do
149
217
  raise 'indexer_class must be set with `let(:indexer_class)`' unless defined? indexer_class
@@ -158,6 +226,19 @@ RSpec.shared_examples 'a Work indexer' do
158
226
  it_behaves_like 'a Core metadata indexer'
159
227
  it_behaves_like 'a permission indexer'
160
228
  it_behaves_like 'a visibility indexer'
229
+ it_behaves_like 'a thumbnail indexer'
230
+
231
+ describe '#to_solr' do
232
+ it 'indexes representative id' do
233
+ expect(indexer.to_solr)
234
+ .to include('hasRelatedMediaFragment_ssim': a_collection_containing_exactly(an_instance_of(String)))
235
+ end
236
+
237
+ it 'indexes thumbnail id' do
238
+ expect(indexer.to_solr)
239
+ .to include('hasRelatedImage_ssim': a_collection_containing_exactly(an_instance_of(String)))
240
+ end
241
+ end
161
242
  end
162
243
 
163
244
  RSpec.shared_examples 'a Collection indexer' do
@@ -172,6 +253,7 @@ RSpec.shared_examples 'a Collection indexer' do
172
253
  it_behaves_like 'a Core metadata indexer'
173
254
  it_behaves_like 'a permission indexer'
174
255
  it_behaves_like 'a visibility indexer'
256
+ it_behaves_like 'a thumbnail indexer'
175
257
 
176
258
  describe '#to_solr' do
177
259
  it 'indexes collection type gid' do
@@ -184,15 +266,47 @@ RSpec.shared_examples 'a Collection indexer' do
184
266
  .to include(generic_type_sim: a_collection_containing_exactly('Collection'))
185
267
  end
186
268
 
269
+ it 'indexes depositor' do
270
+ expect(indexer.to_solr)
271
+ .to include(depositor_ssim: [resource.depositor],
272
+ depositor_tesim: [resource.depositor])
273
+ end
274
+ end
275
+ end
276
+
277
+ RSpec.shared_examples 'an Administrative Set indexer' do
278
+ before do
279
+ raise 'indexer_class must be set with `let(:indexer_class)`' unless defined? indexer_class
280
+ # NOTE: resource must be persisted for permission tests to pass
281
+ raise 'resource must be set with `let(:resource)` and is expected to be a kind of Hyrax::AdministrativeSet' unless defined?(resource) && resource.kind_of?(Hyrax::AdministrativeSet)
282
+ end
283
+ subject(:indexer) { indexer_class.new(resource: resource) }
284
+
285
+ it_behaves_like 'a Hyrax::Resource indexer'
286
+ it_behaves_like 'a Core metadata indexer'
287
+ it_behaves_like 'a permission indexer'
288
+ it_behaves_like 'a visibility indexer'
289
+
290
+ describe '#to_solr' do
291
+ it 'indexes collection type gid' do
292
+ expect(indexer.to_solr)
293
+ .to include(collection_type_gid_ssim: a_collection_containing_exactly(an_instance_of(String)))
294
+ end
295
+
296
+ it 'indexes generic type' do
297
+ expect(indexer.to_solr)
298
+ .to include(generic_type_sim: a_collection_containing_exactly('Admin Set'))
299
+ end
300
+
187
301
  it 'indexes thumbnail' do
188
302
  expect(indexer.to_solr)
189
303
  .to include(thumbnail_path_ss: include('assets/collection', '.png'))
190
304
  end
191
305
 
192
- it 'indexes depositor' do
306
+ it 'indexes creator' do
193
307
  expect(indexer.to_solr)
194
- .to include(depositor_ssim: [resource.depositor],
195
- depositor_tesim: [resource.depositor])
308
+ .to include(creator_ssim: [resource.creator],
309
+ creator_tesim: [resource.creator])
196
310
  end
197
311
  end
198
312
  end
@@ -8,7 +8,8 @@ module Hyrax
8
8
  #
9
9
  # @since 3.2.0
10
10
  class AdminSetCreate < Transaction
11
- DEFAULT_STEPS = ['change_set.apply',
11
+ DEFAULT_STEPS = ['change_set.set_user_as_creator',
12
+ 'change_set.apply',
12
13
  'admin_set_resource.apply_collection_type_permissions',
13
14
  'admin_set_resource.save_acl'].freeze
14
15
 
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ require 'hyrax/transactions/transaction'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ ##
7
+ # Destroys a {Hyraxe::AdministrativeSet}
8
+ #
9
+ # @since 3.4.0
10
+ class AdminSetDestroy < Transaction
11
+ DEFAULT_STEPS = ['admin_set_resource.check_empty',
12
+ 'admin_set_resource.delete',
13
+ 'admin_set_resource.delete_acl'].freeze
14
+
15
+ ##
16
+ # @see Hyrax::Transactions::Transaction
17
+ def initialize(container: Container, steps: DEFAULT_STEPS)
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ require 'hyrax/transactions/transaction'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ ##
7
+ # Updates a {Hyrax::AdministrativeSet} from a ChangeSet
8
+ #
9
+ # @since 3.4.0
10
+ class AdminSetUpdate < Transaction
11
+ DEFAULT_STEPS = ['change_set.apply',
12
+ 'admin_set_resource.save_acl'].freeze
13
+
14
+ ##
15
+ # @see Hyrax::Transactions::Transaction
16
+ def initialize(container: Container, steps: DEFAULT_STEPS)
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ require 'hyrax/transactions/transaction'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ ##
7
+ # Destroys a {Hyrax::PcdmCollection}
8
+ #
9
+ # @since 3.4.0
10
+ class CollectionDestroy < Transaction
11
+ # TODO: Add step that checks if collection is empty for collections of types that require it
12
+ DEFAULT_STEPS = ['collection_resource.delete',
13
+ 'collection_resource.delete_acl'].freeze
14
+
15
+ ##
16
+ # @see Hyrax::Transactions::Transaction
17
+ def initialize(container: Container, steps: DEFAULT_STEPS)
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
@@ -4,11 +4,14 @@ require 'hyrax/transactions/transaction'
4
4
  module Hyrax
5
5
  module Transactions
6
6
  ##
7
- # Creates a Collection from a ChangeSet
7
+ # Updates a Collection from a ChangeSet
8
8
  #
9
9
  # @since 3.2.0
10
10
  class CollectionUpdate < Transaction
11
- DEFAULT_STEPS = ['change_set.apply'].freeze
11
+ DEFAULT_STEPS = ['change_set.apply',
12
+ 'collection_resource.save_collection_banner',
13
+ 'collection_resource.save_collection_logo',
14
+ 'collection_resource.save_acl'].freeze
12
15
 
13
16
  ##
14
17
  # @see Hyrax::Transactions::Transaction
@@ -10,51 +10,64 @@ module Hyrax
10
10
  #
11
11
  # In advanced use, the container could provide runtime dependency injection
12
12
  # for particular step code. For the basic case, users can consider it as
13
- # providing namespaceing and resolution for steps (as used in
14
- # `Hyrax::Transaction::CreateWork`; e.g.
15
- # `step :save_work, with: 'work.save_work'`).
13
+ # providing namespacing and resolution for steps (as used in
14
+ # `Hyrax::Transaction::WorkCreate`; e.g.
15
+ # `step :save, with: 'work_resource.save'`).
16
16
  #
17
17
  # @since 2.4.0
18
18
  #
19
19
  # @see https://dry-rb.org/gems/dry-container/
20
20
  class Container # rubocop:disable Metrics/ClassLength
21
21
  require 'hyrax/transactions/admin_set_create'
22
+ require 'hyrax/transactions/admin_set_destroy'
23
+ require 'hyrax/transactions/admin_set_update'
22
24
  require 'hyrax/transactions/apply_change_set'
23
25
  require 'hyrax/transactions/collection_create'
26
+ require 'hyrax/transactions/collection_destroy'
24
27
  require 'hyrax/transactions/collection_update'
25
- require 'hyrax/transactions/create_work'
26
- require 'hyrax/transactions/destroy_work'
27
28
  require 'hyrax/transactions/file_set_destroy'
28
29
  require 'hyrax/transactions/work_create'
29
30
  require 'hyrax/transactions/work_destroy'
30
- require 'hyrax/transactions/update_work'
31
+ require 'hyrax/transactions/work_update'
31
32
  require 'hyrax/transactions/steps/add_file_sets'
32
33
  require 'hyrax/transactions/steps/add_to_collections'
33
34
  require 'hyrax/transactions/steps/add_to_parent'
34
- require 'hyrax/transactions/steps/apply_collection_permission_template'
35
35
  require 'hyrax/transactions/steps/apply_collection_type_permissions'
36
- require 'hyrax/transactions/steps/apply_permission_template'
37
- require 'hyrax/transactions/steps/apply_visibility'
36
+ require 'hyrax/transactions/steps/change_depositor'
37
+ require 'hyrax/transactions/steps/check_for_empty_admin_set'
38
+ require 'hyrax/transactions/steps/delete_access_control'
38
39
  require 'hyrax/transactions/steps/delete_resource'
39
- require 'hyrax/transactions/steps/destroy_work'
40
40
  require 'hyrax/transactions/steps/ensure_admin_set'
41
41
  require 'hyrax/transactions/steps/set_collection_type_gid'
42
- require 'hyrax/transactions/steps/ensure_permission_template'
43
42
  require 'hyrax/transactions/steps/remove_file_set_from_work'
44
43
  require 'hyrax/transactions/steps/save'
45
- require 'hyrax/transactions/steps/save_work'
46
44
  require 'hyrax/transactions/steps/save_access_control'
45
+ require 'hyrax/transactions/steps/save_collection_banner'
46
+ require 'hyrax/transactions/steps/save_collection_logo'
47
47
  require 'hyrax/transactions/steps/set_default_admin_set'
48
48
  require 'hyrax/transactions/steps/set_modified_date'
49
49
  require 'hyrax/transactions/steps/set_uploaded_date_unless_present'
50
+ require 'hyrax/transactions/steps/set_user_as_creator'
50
51
  require 'hyrax/transactions/steps/set_user_as_depositor'
52
+ require 'hyrax/transactions/steps/update_work_members'
51
53
  require 'hyrax/transactions/steps/validate'
52
54
 
55
+ # The following transactions and steps are deprecated.
56
+ require 'hyrax/transactions/create_work'
57
+ require 'hyrax/transactions/destroy_work'
58
+ require 'hyrax/transactions/update_work'
59
+ require 'hyrax/transactions/steps/apply_collection_permission_template'
60
+ require 'hyrax/transactions/steps/apply_permission_template'
61
+ require 'hyrax/transactions/steps/apply_visibility'
62
+ require 'hyrax/transactions/steps/destroy_work'
63
+ require 'hyrax/transactions/steps/ensure_permission_template'
64
+ require 'hyrax/transactions/steps/save_work'
65
+
53
66
  extend Dry::Container::Mixin
54
67
 
55
68
  # Disable BlockLength rule for DSL code
56
69
  # rubocop:disable Metrics/BlockLength
57
- namespace 'change_set' do |ops|
70
+ namespace 'change_set' do |ops| # Hyrax::ChangeSet
58
71
  ops.register 'add_to_collections' do
59
72
  Steps::AddToCollections.new
60
73
  end
@@ -63,12 +76,12 @@ module Hyrax
63
76
  ApplyChangeSet.new
64
77
  end
65
78
 
66
- ops.register 'create_collection' do
67
- CollectionCreate.new
79
+ ops.register 'create_admin_set' do
80
+ AdminSetCreate.new
68
81
  end
69
82
 
70
- ops.register 'update_collection' do
71
- CollectionUpdate.new
83
+ ops.register 'create_collection' do
84
+ CollectionCreate.new
72
85
  end
73
86
 
74
87
  ops.register 'create_work' do
@@ -99,12 +112,20 @@ module Hyrax
99
112
  Steps::SetUploadedDateUnlessPresent.new
100
113
  end
101
114
 
115
+ ops.register 'set_user_as_creator' do
116
+ Steps::SetUserAsCreator.new
117
+ end
118
+
102
119
  ops.register 'set_user_as_depositor' do
103
120
  Steps::SetUserAsDepositor.new
104
121
  end
105
122
 
123
+ ops.register 'update_collection' do
124
+ CollectionUpdate.new
125
+ end
126
+
106
127
  ops.register 'update_work' do
107
- UpdateWork.new
128
+ WorkUpdate.new
108
129
  end
109
130
 
110
131
  ops.register 'validate' do
@@ -112,7 +133,7 @@ module Hyrax
112
133
  end
113
134
  end
114
135
 
115
- namespace 'file_set' do |ops| # Hyrax::FileSet
136
+ namespace 'file_set' do |ops| # Hyrax::FileSet resource
116
137
  ops.register 'delete' do
117
138
  Steps::DeleteResource.new
118
139
  end
@@ -126,27 +147,67 @@ module Hyrax
126
147
  end
127
148
  end
128
149
 
129
- namespace 'admin_set_resource' do |ops| # valkyrie administrative set
150
+ namespace 'admin_set_resource' do |ops| # Hyrax::AdministrativeSet resource
151
+ ops.register 'check_empty' do
152
+ Steps::CheckForEmptyAdminSet.new
153
+ end
154
+
155
+ ops.register 'delete' do
156
+ Steps::DeleteResource.new
157
+ end
158
+
159
+ ops.register 'destroy' do
160
+ AdminSetDestroy.new
161
+ end
162
+
163
+ ops.register 'update' do
164
+ AdminSetUpdate.new
165
+ end
166
+
130
167
  ops.register 'apply_collection_type_permissions' do
131
168
  Steps::ApplyCollectionTypePermissions.new
132
169
  end
133
170
 
171
+ ops.register 'delete_acl' do
172
+ Steps::DeleteAccessControl.new
173
+ end
174
+
134
175
  ops.register 'save_acl' do
135
176
  Steps::SaveAccessControl.new
136
177
  end
137
178
  end
138
179
 
139
- namespace 'collection_resource' do |ops| # valkyrie collection
180
+ namespace 'collection_resource' do |ops| # Hyrax::PcdmCollection resource
140
181
  ops.register 'apply_collection_type_permissions' do
141
182
  Steps::ApplyCollectionTypePermissions.new
142
183
  end
143
184
 
185
+ ops.register 'delete' do
186
+ Steps::DeleteResource.new
187
+ end
188
+
189
+ ops.register 'destroy' do
190
+ CollectionDestroy.new
191
+ end
192
+
193
+ ops.register 'delete_acl' do
194
+ Steps::DeleteAccessControl.new
195
+ end
196
+
144
197
  ops.register 'save_acl' do
145
198
  Steps::SaveAccessControl.new
146
199
  end
200
+
201
+ ops.register 'save_collection_banner' do
202
+ Steps::SaveCollectionBanner.new
203
+ end
204
+
205
+ ops.register 'save_collection_logo' do
206
+ Steps::SaveCollectionLogo.new
207
+ end
147
208
  end
148
209
 
149
- namespace 'work_resource' do |ops| # valkyrie works
210
+ namespace 'work_resource' do |ops| # Hyrax::Work resource
150
211
  ops.register 'add_file_sets' do
151
212
  Steps::AddFileSets.new
152
213
  end
@@ -155,6 +216,10 @@ module Hyrax
155
216
  Steps::AddToParent.new
156
217
  end
157
218
 
219
+ ops.register 'change_depositor' do
220
+ Steps::ChangeDepositor.new
221
+ end
222
+
158
223
  ops.register 'delete' do
159
224
  Steps::DeleteResource.new
160
225
  end
@@ -163,12 +228,21 @@ module Hyrax
163
228
  WorkDestroy.new
164
229
  end
165
230
 
231
+ ops.register 'delete_acl' do
232
+ Steps::DeleteAccessControl.new
233
+ end
234
+
166
235
  ops.register 'save_acl' do
167
236
  Steps::SaveAccessControl.new
168
237
  end
238
+
239
+ ops.register 'update_work_members' do
240
+ Steps::UpdateWorkMembers.new
241
+ end
169
242
  end
170
243
 
171
- namespace 'work' do |ops| # legacy AF works
244
+ # legacy AF works processing by transactions is deprecated
245
+ namespace 'work' do |ops|
172
246
  ops.register 'apply_collection_permission_template' do
173
247
  Steps::ApplyCollectionPermissionTemplate.new
174
248
  end
@@ -46,9 +46,12 @@ module Hyrax
46
46
  # @deprecated Development on Dry::Transaction has been discontinued, we're
47
47
  # removing existing transactions and replacing them with Dry::Monad-based
48
48
  # valkyrie versions.
49
+ # @see Hyrax::Transactions::WorkCreate
49
50
  class CreateWork
50
51
  include Dry::Transaction(container: Hyrax::Transactions::Container)
51
52
 
53
+ # DO NOT USE - This class is deprecated. See Hyrax::Transactions::WorkCreate for resource works.
54
+
52
55
  step :set_default_admin_set, with: 'work.set_default_admin_set'
53
56
  step :ensure_admin_set, with: 'work.ensure_admin_set'
54
57
  step :apply_permission_template, with: 'work.apply_permission_template'
@@ -16,9 +16,12 @@ module Hyrax
16
16
  # @deprecated Development on Dry::Transaction has been discontinued, we're
17
17
  # removing existing transactions and replacing them with Dry::Monad-based
18
18
  # valkyrie versions.
19
+ # @see Hyrax::Transactions::WorkDestroy
19
20
  class DestroyWork
20
21
  include Dry::Transaction(container: Hyrax::Transactions::Container)
21
22
 
23
+ # DO NOT USE - This class is deprecated. See Hyrax::Transactions::WorkDestroy for resource works.
24
+
22
25
  step :destroy_work, with: 'work.destroy_work'
23
26
  end
24
27
  end
@@ -7,6 +7,8 @@ module Hyrax
7
7
  # collections on a given work.
8
8
  #
9
9
  # @since 3.0.0
10
+ # @deprecated This is part of the legacy AF set of transaction steps for works.
11
+ # Transactions are not being used with AF works. This will be removed in 4.0.
10
12
  class ApplyCollectionPermissionTemplate
11
13
  include Dry::Transaction::Operation
12
14
 
@@ -7,6 +7,8 @@ module Hyrax
7
7
  # work's AdminSet.
8
8
  #
9
9
  # @since 2.4.0
10
+ # @deprecated This is part of the legacy AF set of transaction steps for works.
11
+ # Transactions are not being used with AF works. This will be removed in 4.0.
10
12
  class ApplyPermissionTemplate
11
13
  include Dry::Transaction::Operation
12
14
 
@@ -7,6 +7,8 @@ module Hyrax
7
7
  # passed arguments.
8
8
  #
9
9
  # @since 3.0.0
10
+ # @deprecated This is part of the legacy AF set of transaction steps for works.
11
+ # Transactions are not being used with AF works. This will be removed in 4.0.
10
12
  class ApplyVisibility
11
13
  include Dry::Transaction::Operation
12
14
 
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+ require 'dry/monads'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ module Steps
7
+ ##
8
+ # Add a given `::User` as the `#depositor`
9
+ # Move the previous value of that property to `#proxy_depositor`
10
+ #
11
+ #
12
+ # If no user is given, simply passes as a `Success`.
13
+ #
14
+ # @since 3.4.0
15
+ class ChangeDepositor
16
+ include Dry::Monads[:result]
17
+
18
+ ##
19
+ # @param [Hyrax::Work] obj
20
+ # @param user [User] the user that will "become" the depositor of
21
+ # the given work
22
+ #
23
+ # @return [Dry::Monads::Result]
24
+ def call(obj, user: NullUser.new, reset: false)
25
+ return Success(obj) unless user&.user_key
26
+
27
+ obj = Hyrax::ChangeDepositorService.call(obj, user, reset)
28
+
29
+ Success(obj)
30
+ rescue StandardError => err
31
+ Failure([err.message, obj])
32
+ end
33
+
34
+ ##
35
+ # @api private
36
+ class NullUser
37
+ ##
38
+ # @return [nil]
39
+ def user_key
40
+ nil
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ require 'dry/monads'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ module Steps
7
+ ##
8
+ # Validates emptiness of the {Hyrax::AdministrativeSet}; gives `Success`
9
+ # when empty and `Failure` otherwise.
10
+ #
11
+ # Use this step to guard against destroying AdminSets with member objects.
12
+ class CheckForEmptyAdminSet
13
+ include Dry::Monads[:result]
14
+
15
+ ##
16
+ # @param [#find_inverse_references_by] query_service
17
+ def initialize(query_service: Hyrax.query_service)
18
+ @query_service = query_service
19
+ end
20
+
21
+ ##
22
+ # @param [Hyrax::AdministrativeSet] admin_set
23
+ #
24
+ # @return [Dry::Monads::Result]
25
+ def call(admin_set)
26
+ members = @query_service
27
+ .find_inverse_references_by(property: :admin_set_id,
28
+ resource: admin_set)
29
+ return Failure[:admin_set_has_members, members] if members.any?
30
+
31
+ Success(admin_set)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require 'dry/monads'
3
+
4
+ module Hyrax
5
+ module Transactions
6
+ module Steps
7
+ ##
8
+ # Deletes the Hyrax::AccessControlList for any resource with a `#permission_manager`.
9
+ # If `#permission_manager` is undefined, succeeds.
10
+ #
11
+ # @see https://dry-rb.org/gems/dry-monads/1.0/result/
12
+ class DeleteAccessControl
13
+ include Dry::Monads[:result]
14
+
15
+ ##
16
+ # @param [Valkyrie::Resource] obj
17
+ #
18
+ # @return [Dry::Monads::Result]
19
+ def call(obj)
20
+ return Success(obj) unless obj.respond_to?(:permission_manager)
21
+
22
+ acl = obj.permission_manager&.acl
23
+ return Success(obj) if acl.nil?
24
+
25
+ acl.destroy || (return Failure[:failed_to_delete_acl, acl])
26
+
27
+ Success(obj)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end