hyrax 2.1.0.beta2 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODE_OF_CONDUCT.md +5 -5
  3. data/.github/CONTRIBUTING.md +2 -2
  4. data/.rubocop.yml +1 -0
  5. data/.rubocop_fixme.yml +2 -0
  6. data/Gemfile +1 -0
  7. data/README.md +3 -2
  8. data/app/actors/hyrax/actors/collections_membership_actor.rb +3 -0
  9. data/app/actors/hyrax/actors/create_with_remote_files_actor.rb +4 -3
  10. data/app/actors/hyrax/actors/default_admin_set_actor.rb +9 -6
  11. data/app/assets/javascripts/hyrax.js +3 -0
  12. data/app/assets/javascripts/hyrax/app.js.erb +14 -0
  13. data/app/assets/javascripts/hyrax/batch_edit.js +2 -1
  14. data/app/assets/javascripts/hyrax/collection_types.es6 +97 -36
  15. data/app/assets/javascripts/hyrax/collections.js +15 -49
  16. data/app/assets/javascripts/hyrax/collections_utils.es6 +116 -0
  17. data/app/assets/javascripts/hyrax/collections_v2.es6 +57 -0
  18. data/app/assets/javascripts/hyrax/content_blocks.js +1 -13
  19. data/app/assets/javascripts/hyrax/nav_safety.js +41 -0
  20. data/app/assets/javascripts/hyrax/turbolinks_events.js +3 -0
  21. data/app/assets/stylesheets/hyrax/_collection_types.scss +46 -2
  22. data/app/assets/stylesheets/hyrax/_work-show.scss +6 -9
  23. data/app/assets/stylesheets/hyrax/dashboard.scss +2 -0
  24. data/app/assets/stylesheets/hyrax/sidebar.scss +4 -0
  25. data/app/controllers/concerns/hyrax/works_controller_behavior.rb +10 -2
  26. data/app/controllers/hyrax/admin/admin_sets_controller.rb +2 -9
  27. data/app/controllers/hyrax/admin/collection_types_controller.rb +1 -1
  28. data/app/controllers/hyrax/batch_edits_controller.rb +30 -4
  29. data/app/controllers/hyrax/dashboard/collection_members_controller.rb +1 -0
  30. data/app/controllers/hyrax/dashboard/collections_controller.rb +4 -1
  31. data/app/controllers/hyrax/downloads_controller.rb +7 -1
  32. data/app/forms/hyrax/forms/admin/collection_type_form.rb +1 -1
  33. data/app/indexers/hyrax/repository_reindexer.rb +1 -1
  34. data/app/jobs/attach_files_to_work_job.rb +8 -4
  35. data/app/jobs/import_url_job.rb +11 -5
  36. data/app/models/admin_set.rb +25 -3
  37. data/app/models/concerns/hyrax/collection_behavior.rb +23 -11
  38. data/app/models/concerns/hyrax/collection_nesting.rb +22 -3
  39. data/app/models/hyrax/permission_template_access.rb +7 -4
  40. data/app/presenters/hyrax/admin_set_presenter.rb +21 -0
  41. data/app/presenters/hyrax/collection_presenter.rb +23 -1
  42. data/app/presenters/hyrax/dashboard/user_presenter.rb +4 -0
  43. data/app/presenters/hyrax/presents_attributes.rb +6 -2
  44. data/app/presenters/hyrax/work_show_presenter.rb +4 -0
  45. data/app/renderers/hyrax/renderers/attribute_renderer.rb +14 -0
  46. data/app/services/hyrax/adapters/nesting_index_adapter.rb +19 -39
  47. data/app/services/hyrax/admin_set_create_service.rb +1 -1
  48. data/app/services/hyrax/collection_types/create_service.rb +4 -0
  49. data/app/services/hyrax/collections/migration_service.rb +25 -2
  50. data/app/services/hyrax/collections/nested_collection_persistence_service.rb +8 -3
  51. data/app/services/hyrax/collections/nested_collection_query_service.rb +3 -3
  52. data/app/services/hyrax/default_middleware_stack.rb +3 -3
  53. data/app/services/hyrax/multiple_membership_checker.rb +4 -2
  54. data/app/views/catalog/_index_header_list_collection.html.erb +1 -1
  55. data/app/views/catalog/_search_form.html.erb +0 -4
  56. data/app/views/hyrax/admin/admin_sets/_show_actions.html.erb +27 -0
  57. data/app/views/hyrax/admin/admin_sets/show.html.erb +1 -25
  58. data/app/views/hyrax/admin/collection_types/_form.html.erb +17 -6
  59. data/app/views/hyrax/admin/collection_types/_form_appearance.html.erb +5 -0
  60. data/app/views/hyrax/admin/collection_types/_form_participant_table.html.erb +1 -1
  61. data/app/views/hyrax/admin/collection_types/_form_participants.html.erb +56 -52
  62. data/app/views/hyrax/admin/collection_types/edit.html.erb +9 -7
  63. data/app/views/hyrax/admin/collection_types/index.html.erb +1 -1
  64. data/app/views/hyrax/base/_attribute_rows.html.erb +15 -14
  65. data/app/views/hyrax/base/_form.html.erb +1 -0
  66. data/app/views/hyrax/base/_form_collections_error.html.erb +1 -0
  67. data/app/views/hyrax/base/_items.html.erb +3 -2
  68. data/app/views/hyrax/base/_metadata.html.erb +5 -7
  69. data/app/views/hyrax/base/_relationships.html.erb +3 -5
  70. data/app/views/hyrax/base/_relationships_parent_row.html.erb +4 -5
  71. data/app/views/hyrax/base/_relationships_parent_rows.html.erb +2 -1
  72. data/app/views/hyrax/base/_show_actions.html.erb +11 -1
  73. data/app/views/hyrax/batch_edits/edit.html.erb +57 -17
  74. data/app/views/hyrax/collections/_list_collections.html.erb +1 -1
  75. data/app/views/hyrax/collections/show.html.erb +1 -1
  76. data/app/views/hyrax/content_blocks/_form.html.erb +8 -7
  77. data/app/views/hyrax/dashboard/_index_partials/_current_proxy_rights.html.erb +17 -0
  78. data/app/views/hyrax/dashboard/collections/_collection_title.html.erb +1 -3
  79. data/app/views/hyrax/dashboard/collections/_default_group.html.erb +30 -0
  80. data/app/views/hyrax/dashboard/collections/_form_branding.html.erb +2 -2
  81. data/app/views/hyrax/dashboard/collections/_form_for_select_collection.html.erb +1 -1
  82. data/app/views/hyrax/dashboard/collections/_form_share.html.erb +2 -2
  83. data/app/views/hyrax/dashboard/collections/_list_collections.html.erb +13 -2
  84. data/app/views/hyrax/dashboard/show_user.html.erb +10 -9
  85. data/app/views/hyrax/my/collections/_list_collections.html.erb +10 -3
  86. data/app/views/hyrax/my/collections/_modal_add_subcollection.html.erb +1 -1
  87. data/app/views/hyrax/my/collections/_modal_add_to_collection.html.erb +1 -1
  88. data/app/views/hyrax/my/collections/_modal_delete_collections_deny.html.erb +14 -0
  89. data/app/views/hyrax/my/collections/index.html.erb +1 -0
  90. data/app/views/shared/_nav_safety_modal.html.erb +12 -0
  91. data/config/features.rb +4 -0
  92. data/config/initializers/samvera-nesting_indexer_initializer.rb +1 -0
  93. data/config/locales/hyrax.de.yml +26 -11
  94. data/config/locales/hyrax.en.yml +21 -6
  95. data/config/locales/hyrax.es.yml +17 -2
  96. data/config/locales/hyrax.fr.yml +17 -2
  97. data/config/locales/hyrax.it.yml +17 -2
  98. data/config/locales/hyrax.pt-BR.yml +17 -2
  99. data/config/locales/hyrax.zh.yml +17 -2
  100. data/config/locales/simple_form.en.yml +6 -27
  101. data/hyrax.gemspec +2 -2
  102. data/lib/generators/hyrax/assets_generator.rb +4 -0
  103. data/lib/generators/hyrax/install_generator.rb +10 -0
  104. data/lib/generators/hyrax/templates/app/assets/images/unauthorized.png +0 -0
  105. data/lib/generators/hyrax/templates/config/locales/hyrax.en.yml +6 -5
  106. data/lib/generators/hyrax/templates/config/tinymce.yml +12 -7
  107. data/lib/generators/hyrax/templates/db/migrate/20180406202557_add_badge_color_to_collection_types.rb.erb +5 -0
  108. data/lib/hyrax/configuration.rb +1 -1
  109. data/lib/hyrax/version.rb +1 -1
  110. data/spec/actors/hyrax/actors/collections_membership_actor_spec.rb +24 -0
  111. data/spec/actors/hyrax/actors/create_with_remote_files_actor_spec.rb +19 -1
  112. data/spec/actors/hyrax/actors/default_admin_set_actor_spec.rb +41 -8
  113. data/spec/actors/hyrax/actors/file_set_actor_spec.rb +4 -12
  114. data/spec/actors/hyrax/actors/generic_work_actor_spec.rb +3 -7
  115. data/spec/controllers/hyrax/admin/strategies_controller_spec.rb +13 -2
  116. data/spec/controllers/hyrax/batch_edits_controller_spec.rb +83 -8
  117. data/spec/controllers/hyrax/dashboard/collections_controller_spec.rb +3 -0
  118. data/spec/controllers/hyrax/downloads_controller_spec.rb +26 -5
  119. data/spec/controllers/hyrax/file_sets_controller_spec.rb +3 -6
  120. data/spec/controllers/hyrax/generic_works_controller_json_spec.rb +4 -4
  121. data/spec/controllers/hyrax/generic_works_controller_spec.rb +3 -23
  122. data/spec/controllers/hyrax/transfers_controller_spec.rb +1 -1
  123. data/spec/factories/admin_sets_lw.rb +215 -0
  124. data/spec/factories/collections.rb +10 -10
  125. data/spec/factory_tests/adminsets_factory_spec.rb +132 -0
  126. data/spec/factory_tests/collections_factory_spec.rb +3 -3
  127. data/spec/features/batch_create_spec.rb +5 -8
  128. data/spec/features/batch_edit_spec.rb +49 -2
  129. data/spec/features/collection_multi_membership_spec.rb +29 -14
  130. data/spec/features/collection_type_spec.rb +9 -2
  131. data/spec/features/create_work_admin_spec.rb +1 -1
  132. data/spec/features/create_work_spec.rb +1 -1
  133. data/spec/features/dashboard/collection_spec.rb +16 -12
  134. data/spec/features/edit_content_block_admin_spec.rb +29 -12
  135. data/spec/features/embargo_spec.rb +55 -0
  136. data/spec/features/proxy_spec.rb +3 -1
  137. data/spec/features/work_show_spec.rb +20 -4
  138. data/spec/forms/hyrax/forms/admin/collection_type_form_spec.rb +1 -0
  139. data/spec/indexers/hyrax/repository_reindexer_spec.rb +1 -1
  140. data/spec/jobs/attach_files_to_work_job_spec.rb +15 -3
  141. data/spec/jobs/batch_create_job_spec.rb +6 -6
  142. data/spec/jobs/create_work_job_spec.rb +1 -1
  143. data/spec/models/admin_set_spec.rb +10 -8
  144. data/spec/models/collection_spec.rb +1 -1
  145. data/spec/models/concerns/hyrax/collection_nesting_spec.rb +6 -3
  146. data/spec/models/flipflop_spec.rb +8 -0
  147. data/spec/models/hyrax/work_behavior_spec.rb +1 -1
  148. data/spec/presenters/hyrax/admin_set_presenter_spec.rb +70 -0
  149. data/spec/presenters/hyrax/collection_presenter_spec.rb +66 -0
  150. data/spec/renderers/hyrax/renderers/attribute_renderer_spec.rb +19 -0
  151. data/spec/services/hyrax/adapters/nesting_index_adapter_spec.rb +31 -21
  152. data/spec/services/hyrax/collection_types/create_service_spec.rb +7 -4
  153. data/spec/services/hyrax/collections/migration_service_spec.rb +204 -17
  154. data/spec/services/hyrax/collections/nested_collection_persistence_service_spec.rb +1 -1
  155. data/spec/services/hyrax/collections/permissions_create_service_spec.rb +1 -1
  156. data/spec/services/hyrax/collections/permissions_service_spec.rb +4 -0
  157. data/spec/services/hyrax/default_middleware_stack_spec.rb +1 -1
  158. data/spec/services/hyrax/multiple_membership_checker_spec.rb +4 -4
  159. data/spec/services/hyrax/workflow/grant_edit_to_depositor_spec.rb +1 -1
  160. data/spec/services/hyrax/workflow/grant_read_to_depositor_spec.rb +1 -1
  161. data/spec/services/hyrax/workflow/revoke_edit_from_depositor_spec.rb +1 -1
  162. data/spec/spec_helper.rb +35 -2
  163. data/spec/support/features/batch_edit_actions.rb +1 -1
  164. data/spec/support/selectors.rb +15 -0
  165. data/spec/views/hyrax/admin/admin_sets/_show_actions.html.erb_spec.rb +66 -0
  166. data/spec/views/hyrax/admin/admin_sets/show.html.erb_spec.rb +5 -34
  167. data/spec/views/hyrax/admin/collection_types/_form.html.erb_spec.rb +3 -1
  168. data/spec/views/hyrax/admin/collection_types/_form_appearance.html.erb_spec.rb +22 -0
  169. data/spec/views/hyrax/admin/collection_types/_form_participants.html.erb_spec.rb +11 -3
  170. data/spec/views/hyrax/base/_items.html.erb_spec.rb +46 -0
  171. data/spec/views/hyrax/base/_relationships.html.erb_spec.rb +1 -1
  172. data/spec/views/hyrax/base/_show_actions.html.erb_spec.rb +4 -2
  173. data/spec/views/hyrax/dashboard/collections/_default_group.html.erb_spec.rb +43 -0
  174. data/spec/views/hyrax/dashboard/collections/_list_collections.html.erb_spec.rb +51 -0
  175. data/spec/views/hyrax/dashboard/collections/show.html.erb_spec.rb +1 -0
  176. data/spec/views/hyrax/dashboard/show_user_spec.rb +5 -2
  177. data/spec/views/hyrax/my/collections/_list_collections.html.erb_spec.rb +2 -0
  178. data/template.rb +1 -1
  179. metadata +30 -13
  180. data/app/views/hyrax/content_blocks/_modal_content_block.html.erb +0 -15
@@ -39,6 +39,9 @@ RSpec.describe Hyrax::Dashboard::CollectionsController, :clean_repo do
39
39
  post :create, params: {
40
40
  collection: collection_attrs.merge(
41
41
  visibility: 'open',
42
+ # TODO: Tests with old approach to sharing a collection which is deprecated and
43
+ # will be removed in 3.0. New approach creates a PermissionTemplate with
44
+ # source_id = the collection's id.
42
45
  permissions_attributes: [{ type: 'person',
43
46
  name: 'archivist1',
44
47
  access: 'edit' }]
@@ -19,16 +19,37 @@ RSpec.describe Hyrax::DownloadsController do
19
19
 
20
20
  before { sign_in another_user }
21
21
 
22
- it 'redirects to the default image' do
22
+ it 'returns :unauthorized status with image content' do
23
23
  get :show, params: { id: file_set.to_param }
24
- expect(response).to redirect_to default_image
24
+ expect(response).to have_http_status(:unauthorized)
25
+ expect(response).not_to redirect_to default_image
26
+ expect(response.content_type).to eq 'image/png'
25
27
  end
26
28
  end
27
29
 
28
30
  context "when user isn't logged in" do
29
- it 'redirects to the default image' do
30
- get :show, params: { id: file_set.to_param }
31
- expect(response).to redirect_to default_image
31
+ context "and the unauthorized image exists" do
32
+ before do
33
+ allow(File).to receive(:exist?).and_return(true)
34
+ end
35
+
36
+ it 'returns :unauthorized status with image content' do
37
+ get :show, params: { id: file_set.to_param }
38
+ expect(response).to have_http_status(:unauthorized)
39
+ expect(response).not_to redirect_to default_image
40
+ expect(response.content_type).to eq 'image/png'
41
+ end
42
+ end
43
+
44
+ context "and the unauthorized image doesn't exist" do
45
+ before do
46
+ allow(File).to receive(:exist?).and_return(false)
47
+ end
48
+
49
+ it 'redirects to the default image' do
50
+ get :show, params: { id: file_set.to_param }
51
+ expect(response).to redirect_to default_image
52
+ end
32
53
  end
33
54
 
34
55
  it 'authorizes the resource using only the id' do
@@ -6,10 +6,6 @@ RSpec.describe Hyrax::FileSetsController do
6
6
  context "when signed in" do
7
7
  before do
8
8
  sign_in user
9
- # allow_any_instance_of(User).to receive(:groups).and_return([])
10
- # prevents characterization and derivative creation
11
- allow(CharacterizeJob).to receive(:perform_later)
12
- allow(CreateDerivativesJob).to receive(:perform_later)
13
9
  end
14
10
 
15
11
  describe "#destroy" do
@@ -100,7 +96,7 @@ RSpec.describe Hyrax::FileSetsController do
100
96
  allow(Hyrax::Actors::FileActor).to receive(:new).and_return(actor)
101
97
  end
102
98
 
103
- it "spawns a ContentNewVersionEventJob" do
99
+ it "spawns a ContentNewVersionEventJob", perform_enqueued: [IngestJob] do
104
100
  expect(ContentNewVersionEventJob).to receive(:perform_later).with(file_set, user)
105
101
  expect(actor).to receive(:ingest_file).with(JobIoWrapper).and_return(true)
106
102
  file = fixture_file_upload('/world.png', 'image/png')
@@ -109,7 +105,7 @@ RSpec.describe Hyrax::FileSetsController do
109
105
  end
110
106
  end
111
107
 
112
- context "with two existing versions from different users" do
108
+ context "with two existing versions from different users", :perform_enqueued do
113
109
  let(:file1) { "world.png" }
114
110
  let(:file2) { "image.jpg" }
115
111
  let(:second_user) { create(:user) }
@@ -118,6 +114,7 @@ RSpec.describe Hyrax::FileSetsController do
118
114
  let(:actor2) { Hyrax::Actors::FileSetActor.new(file_set, second_user) }
119
115
 
120
116
  before do
117
+ ActiveJob::Base.queue_adapter.filter = [IngestJob]
121
118
  actor1.create_content(fixture_file_upload(file1))
122
119
  actor2.create_content(fixture_file_upload(file2))
123
120
  end
@@ -8,7 +8,9 @@ RSpec.describe Hyrax::GenericWorksController do
8
8
  before { sign_in user }
9
9
 
10
10
  context "JSON" do
11
- let(:resource) { create(:private_generic_work, user: user) }
11
+ let(:admin_set) { create(:admin_set, id: 'admin_set_1', with_permission_template: { with_active_workflow: true }) }
12
+
13
+ let(:resource) { create(:private_generic_work, user: user, admin_set_id: admin_set.id) }
12
14
  let(:resource_request) { get :show, params: { id: resource, format: :json } }
13
15
 
14
16
  subject { response }
@@ -81,9 +83,7 @@ RSpec.describe Hyrax::GenericWorksController do
81
83
  end
82
84
 
83
85
  describe 'failed update' do
84
- before do
85
- post :update, params: { id: resource, generic_work: { title: [''] }, format: :json }
86
- end
86
+ before { post :update, params: { id: resource, generic_work: { title: [''] }, format: :json } }
87
87
  it "returns 422 and the errors" do
88
88
  expect(response).to respond_unprocessable_entity(errors: { title: ["Your work must have a title."] })
89
89
  end
@@ -68,6 +68,7 @@ RSpec.describe Hyrax::GenericWorksController do
68
68
  end
69
69
 
70
70
  it "sets breadcrumbs to authorized pages" do
71
+ expect(controller).to receive(:add_breadcrumb).with('Home', main_app.root_path(locale: 'en'))
71
72
  expect(controller).not_to receive(:add_breadcrumb).with('Dashboard', hyrax.dashboard_path(locale: 'en'))
72
73
  expect(controller).not_to receive(:add_breadcrumb).with('Your Works', hyrax.my_works_path(locale: 'en'))
73
74
  expect(controller).to receive(:add_breadcrumb).with('public thing', main_app.hyrax_generic_work_path(work.id, locale: 'en'))
@@ -169,10 +170,12 @@ RSpec.describe Hyrax::GenericWorksController do
169
170
  before do
170
171
  allow(controller).to receive(:presenter).and_return(presenter)
171
172
  allow(presenter).to receive(:export_as_ttl).and_return("ttl graph")
173
+ allow(presenter).to receive(:editor?).and_return(true)
172
174
  end
173
175
 
174
176
  it 'renders a turtle file' do
175
177
  get :show, params: { id: '99999999', format: :ttl }
178
+
176
179
  expect(response).to be_successful
177
180
  expect(response.body).to eq "ttl graph"
178
181
  expect(response.content_type).to eq 'text/turtle'
@@ -260,20 +263,9 @@ RSpec.describe Hyrax::GenericWorksController do
260
263
  context 'when create fails' do
261
264
  let(:work) { create(:work) }
262
265
  let(:create_status) { false }
263
- let(:errors) { double }
264
- let(:messages) { double }
265
- let(:error_messages) { ['Error: foo bar'] }
266
-
267
- before do
268
- allow(controller).to receive(:curation_concern).and_return(work)
269
- allow(work).to receive(:errors).and_return(errors)
270
- allow(errors).to receive(:messages).and_return(messages)
271
- allow(messages).to receive(:[]).with(:collections).and_return(error_messages)
272
- end
273
266
 
274
267
  it 'draws the form again' do
275
268
  post :create, params: { generic_work: { title: ['a title'] } }
276
- expect(flash[:error]).to eq error_messages.to_sentence
277
269
  expect(response.status).to eq 422
278
270
  expect(assigns[:form]).to be_kind_of Hyrax::GenericWorkForm
279
271
  expect(response).to render_template 'new'
@@ -493,21 +485,9 @@ RSpec.describe Hyrax::GenericWorksController do
493
485
 
494
486
  describe 'update failed' do
495
487
  let(:actor) { double(update: false) }
496
- let(:work) { create(:work) }
497
- let(:errors) { double }
498
- let(:messages) { double }
499
- let(:error_messages) { ['Error: foo bar'] }
500
-
501
- before do
502
- allow(controller).to receive(:curation_concern).and_return(work)
503
- allow(work).to receive(:errors).and_return(errors)
504
- allow(errors).to receive(:messages).and_return(messages)
505
- allow(messages).to receive(:[]).with(:collections).and_return(error_messages)
506
- end
507
488
 
508
489
  it 'renders the form' do
509
490
  patch :update, params: { id: work, generic_work: {} }
510
- expect(flash[:error]).to eq error_messages.to_sentence
511
491
  expect(assigns[:form]).to be_kind_of Hyrax::GenericWorkForm
512
492
  expect(response).to render_template('edit')
513
493
  end
@@ -78,7 +78,7 @@ RSpec.describe Hyrax::TransfersController, type: :controller do
78
78
  end
79
79
  end
80
80
 
81
- describe "#accept" do
81
+ describe "#accept", perform_enqueued: [ContentDepositorChangeEventJob] do
82
82
  context "when I am the receiver" do
83
83
  let!(:incoming_work) do
84
84
  GenericWork.new(title: ['incoming']) do |w|
@@ -0,0 +1,215 @@
1
+ FactoryBot.define do
2
+ # Tests that create a Fedora Object are very slow. This factory lets you control which parts of the object ecosystem
3
+ # get built.
4
+ #
5
+ # PREFERRED: Use build whenever possible. You can control the creation of the permission template and solr document
6
+ # by passing parameters to the build(:admin_set_lw) method. That way you can build only the parts needed
7
+ # for a specific test.
8
+ #
9
+ # AVOID: Do not use create unless absolutely necessary. It will create everything including the Fedora object.
10
+ #
11
+ # @example Simple build of an admin set with no additional parts created. Lightest weight.
12
+ # NOTE: A user is automatically created as the owner of the admin set.
13
+ # let(:adminset) { build(:adminset_lw) }
14
+ #
15
+ # @example Simple build of an admin set with no additional parts created. User is the owner of the admin set. Lightest weight.
16
+ # let(:adminset) { build(:adminset_lw, user:) }
17
+ #
18
+ # @example Simple build of an admin set with only solr-document. Owner is given edit-access in solr-document. Light weight.
19
+ # let(:adminset) { build(:adminset_lw, with_solr_document: true) }
20
+ #
21
+ # @example Simple build of an admin set with only a permission template created. Owner is set as a manager. Light weight.
22
+ # let(:adminset) { build(:adminset_lw, with_permission_template: true) }
23
+ #
24
+ # @example Build an admin set with only a permission template created. Permissions are set based on
25
+ # attributes set for `with_permission_template`. Middle weight.
26
+ # # permissions passed thru `with_permission_template` can be any of the following in any combination
27
+ # let(:permissions) { { manage_users: [user.user_key], # multiple users can be listed
28
+ # deposit_users: [user.user_key],
29
+ # view_users: [user.user_key],
30
+ # manage_groups: [group_name], # multiple groups can be listed
31
+ # deposit_groups: [group_name],
32
+ # view_groups: [group_name], } }
33
+ # let(:adminset) { build(:adminset_lw, user: , with_permission_template: permissions) }
34
+ #
35
+ # @example Build an admin set with permission template and solr-document created. Permissions are set based on
36
+ # attributes set for `with_permission_template`. Solr-document includes read/edit access defined based
37
+ # on attributes passed thru `with_permission_template`. Middle weight.
38
+ # # permissions passed thru `with_permission_template` can be any of the following in any combination
39
+ # let(:permissions) { { manage_users: [user.user_key], # multiple users can be listed
40
+ # deposit_users: [user.user_key],
41
+ # view_users: [user.user_key],
42
+ # manage_groups: [group_name], # multiple groups can be listed
43
+ # deposit_groups: [group_name],
44
+ # view_groups: [group_name], } }
45
+ # let(:adminset) { build(:adminset_lw, user: , with_permission_template: permissions, with_solr_document: true) }
46
+ #
47
+ # @example Create an admin set with everything. Extreme heavy weight. This is very slow and should be avoided.
48
+ # NOTE: Everything gets created.
49
+ # NOTE: Build options effect created admin sets as follows...
50
+ # * `with_permission_template` can specify user/group permissions. A permission template is always created.
51
+ # * `with_solr_document` is ignored. A solr document is always created.
52
+ # let(:adminset) { create(:adminset_lw) }
53
+ #
54
+ # @example Build the default admin set with permission template, solr doc, and default adminset's metadata.
55
+ # let(:default_adminset) { build(:default_adminset) }
56
+
57
+ factory :adminset_lw, class: AdminSet do
58
+ transient do
59
+ user { create(:user) }
60
+
61
+ with_permission_template false
62
+ with_solr_document false
63
+ end
64
+ sequence(:title) { |n| ["Collection Title #{n}"] }
65
+
66
+ after(:build) do |adminset, evaluator|
67
+ adminset.creator = [evaluator.user.user_key]
68
+
69
+ AdminSetFactoryHelper.process_with_permission_template(adminset, evaluator)
70
+ AdminSetFactoryHelper.process_with_solr_document(adminset, evaluator)
71
+ end
72
+
73
+ before(:create) do |adminset, evaluator|
74
+ # force create a permission template if it doesn't exist for the newly created admin set
75
+ AdminSetFactoryHelper.process_with_permission_template(adminset, evaluator, true) unless evaluator.with_permission_template
76
+ end
77
+
78
+ after(:create) do |adminset, _evaluator|
79
+ adminset.reset_access_controls!
80
+ end
81
+
82
+ factory :default_adminset, class: AdminSet do
83
+ transient do
84
+ with_permission_template do
85
+ {
86
+ deposit_groups: [::Ability.registered_group_name],
87
+ manage_groups: [::Ability.admin_group_name]
88
+ }
89
+ end
90
+ with_solr_document true
91
+ end
92
+ id AdminSet::DEFAULT_ID
93
+ title AdminSet::DEFAULT_TITLE
94
+ end
95
+ end
96
+
97
+ factory :no_solr_grants_adminset, class: AdminSet do
98
+ # Builds a pre-Hyrax 2.1.0 adminset without edit/view grants on the admin set.
99
+ # Do not use with create because the save will cause the solr grants to be created.
100
+ transient do
101
+ user { create(:user) }
102
+ with_permission_template true
103
+ with_solr_document true
104
+ end
105
+
106
+ sequence(:title) { |n| ["No Solr Grant Admin Set Title #{n}"] }
107
+
108
+ after(:build) do |adminset, evaluator|
109
+ adminset.creator = [evaluator.user.user_key]
110
+ AdminSetFactoryHelper.process_with_permission_template(adminset, evaluator, true)
111
+ AdminSetFactoryHelper.process_with_solr_document(adminset, evaluator, true)
112
+ end
113
+ end
114
+
115
+ class AdminSetFactoryHelper
116
+ # @returns array of user keys
117
+ def self.permission_from_template(permission_template_attributes, permission_key)
118
+ permissions = []
119
+ return permissions if permission_template_attributes.blank?
120
+ return permissions unless permission_template_attributes.is_a? Hash
121
+ return permissions unless permission_template_attributes.key?(permission_key)
122
+ permission_template_attributes[permission_key]
123
+ end
124
+ private_class_method :permission_from_template
125
+
126
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
127
+ # @parem [String] creator_user is the user who created the new admin set
128
+ # @param [Boolean] include_creator, when true, adds the creator_user as a manager
129
+ # @returns array of user keys
130
+ def self.user_managers(permission_template_attributes, creator_user)
131
+ managers = permission_from_template(permission_template_attributes, :manage_users)
132
+ managers << creator_user
133
+ managers.uniq
134
+ end
135
+
136
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
137
+ # @returns array of user keys
138
+ def self.group_managers(permission_template_attributes)
139
+ permission_from_template(permission_template_attributes, :manage_groups).uniq
140
+ end
141
+
142
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
143
+ # @returns array of user keys
144
+ def self.user_depositors(permission_template_attributes)
145
+ permission_from_template(permission_template_attributes, :deposit_users).uniq
146
+ end
147
+
148
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
149
+ # @returns array of user keys
150
+ def self.group_depositors(permission_template_attributes)
151
+ permission_from_template(permission_template_attributes, :deposit_groups).uniq
152
+ end
153
+
154
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
155
+ # @returns array of user keys
156
+ def self.user_viewers(permission_template_attributes)
157
+ permission_from_template(permission_template_attributes, :view_users).uniq
158
+ end
159
+
160
+ # @param [Hash] permission_template_attributes where names identify the role and value are the user keys for that role
161
+ # @returns array of user keys
162
+ def self.group_viewers(permission_template_attributes)
163
+ permission_from_template(permission_template_attributes, :view_groups).uniq
164
+ end
165
+
166
+ # Process the with_permission_template transient property such that...
167
+ # * a permission template is created for the admin set
168
+ # * a permission template access is created for the admin set creator
169
+ # * additional permission template accesses are created for each user/group identified in the attributes
170
+ # of with_permission_template (created by the permission_template factory)
171
+ # @param [AdminSet] admin set object being built/created by the factory
172
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
173
+ # @param [Boolean] if true, force the permission template to be created
174
+ def self.process_with_permission_template(adminset, evaluator, force = false)
175
+ return unless force || evaluator.with_permission_template
176
+ adminset.id ||= FactoryBot.generate(:object_id)
177
+ attributes = { source_id: adminset.id }
178
+ attributes[:manage_users] = user_managers(evaluator.with_permission_template, evaluator.user)
179
+ attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge)
180
+ FactoryBot.create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: adminset.id)
181
+ end
182
+
183
+ # Process the with_solr_document transient property such that...
184
+ # * a solr document is created for the admin set
185
+ # * permissions identified by with_permission_template, if any, are added to the solr fields
186
+ # @param [AdminSet] adminset object being built/created by the factory
187
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
188
+ def self.process_with_solr_document(adminset, evaluator, creator_only = false)
189
+ return unless creator_only || evaluator.with_solr_document
190
+ ActiveFedora::SolrService.add(solr_document_with_permissions(adminset, evaluator, creator_only), commit: true)
191
+ end
192
+
193
+ # Return the admin set's solr document with permissions added, such that...
194
+ # * permissions identified by with_permission_template, if any, are added to the solr fields
195
+ # @param [AdminSet] adminset object being built/created by the factory
196
+ # @param [Class] evaluator holding the transient properties for the current build/creation process
197
+ # @returns the admin set's solr document with permissions added
198
+ def self.solr_document_with_permissions(adminset, evaluator, creator_only)
199
+ adminset.id ||= FactoryBot.generate(:object_id)
200
+ if creator_only
201
+ adminset.edit_users = [evaluator.user]
202
+ else
203
+ adminset.edit_users = user_managers(evaluator.with_permission_template, evaluator.user)
204
+ adminset.edit_groups = group_managers(evaluator.with_permission_template)
205
+ adminset.read_users = user_viewers(evaluator.with_permission_template) +
206
+ user_depositors(evaluator.with_permission_template)
207
+ adminset.read_groups = group_viewers(evaluator.with_permission_template) +
208
+ group_depositors(evaluator.with_permission_template) -
209
+ [::Ability.registered_group_name, ::Ability.public_group_name]
210
+ end
211
+ adminset.to_solr
212
+ end
213
+ private_class_method :solr_document_with_permissions
214
+ end
215
+ end
@@ -10,16 +10,16 @@ FactoryBot.define do
10
10
  #
11
11
  # @example Simple build of a collection with no additional parts created. Lightest weight.
12
12
  # NOTE: A user is automatically created as the owner of the collection.
13
- # let(:collection) { build(:collection_lw)
13
+ # let(:collection) { build(:collection_lw) }
14
14
  #
15
15
  # @example Simple build of a collection with no additional parts created. User is the owner of the collection. Lightest weight.
16
- # let(:collection) { build(:collection_lw, user:)
16
+ # let(:collection) { build(:collection_lw, user:) }
17
17
  #
18
18
  # @example Simple build of a collection with only solr-document. Owner is given edit-access in solr-document. Light weight.
19
- # let(:collection) { build(:collection_lw, with_solr_document: true)
19
+ # let(:collection) { build(:collection_lw, with_solr_document: true) }
20
20
  #
21
21
  # @example Simple build of a collection with only a permission template created. Owner is set as a manager. Light weight.
22
- # let(:collection) { build(:collection_lw, with_permission_template: true)
22
+ # let(:collection) { build(:collection_lw, with_permission_template: true) }
23
23
  #
24
24
  # @example Build a collection with only a permission template created. Permissions are set based on
25
25
  # attributes set for `with_permission_template`. Middle weight.
@@ -30,7 +30,7 @@ FactoryBot.define do
30
30
  # manage_groups: [group_name], # multiple groups can be listed
31
31
  # deposit_groups: [group_name],
32
32
  # view_groups: [group_name], } }
33
- # let(:collection) { build(:collection_lw, user: , with_permission_template: permissions)
33
+ # let(:collection) { build(:collection_lw, user: , with_permission_template: permissions) }
34
34
  #
35
35
  # @example Build a collection with permission template and solr-document created. Permissions are set based on
36
36
  # attributes set for `with_permission_template`. Solr-document includes read/edit access defined based
@@ -42,7 +42,7 @@ FactoryBot.define do
42
42
  # manage_groups: [group_name], # multiple groups can be listed
43
43
  # deposit_groups: [group_name],
44
44
  # view_groups: [group_name], } }
45
- # let(:collection) { build(:collection_lw, user: , with_permission_template: permissions, with_solr_document: true)
45
+ # let(:collection) { build(:collection_lw, user: , with_permission_template: permissions, with_solr_document: true) }
46
46
  #
47
47
  # @example Build a collection generating its collection type with specific settings. Light Weight.
48
48
  # NOTE: Do not use this approach if you need access to the collection type in the test.
@@ -68,8 +68,8 @@ FactoryBot.define do
68
68
  # :sharable, # OR :not_sharable OR :sharable_no_work_permissions
69
69
  # :allow_multiple_membership, # OR :not_allow_multiple_membership
70
70
  # ] }
71
- # let(:collection_type) { create(:collection_lw_type, settings)}
72
- # let(:collection) { build(:collection_lw, collection_type_gid: collection_type.gid)}
71
+ # let(:collection_type) { create(:collection_lw_type, settings) }
72
+ # let(:collection) { build(:collection_lw, collection_type_gid: collection_type.gid) }
73
73
  #
74
74
  # @example Build a collection with nesting fields set in the solr document. Light weight.
75
75
  # NOTE: The property `with_nesting_attributes` is only supported for building collections. The attributes will
@@ -77,7 +77,7 @@ FactoryBot.define do
77
77
  # let(:collection) { build(:collection_lw, with_nesting_attributes: { ancestors: ['Parent_1'],
78
78
  # parent_ids: ['Parent_1'],
79
79
  # pathnames: ['Parent_1/Collection123'],
80
- # depth: 2 })
80
+ # depth: 2 }) }
81
81
  #
82
82
  # @example Create a collection with everything. Extreme heavy weight. This is very slow and should be avoided.
83
83
  # NOTE: Everything gets created.
@@ -87,7 +87,7 @@ FactoryBot.define do
87
87
  # * `with_solr_document` is ignored. A solr document is always created.
88
88
  # * `with_nested_attributes` is ignored.
89
89
  # NOTE: Additional process is required for testing nested collections with Fedora objects. See next example.
90
- # let(:collection) { create(:collection_lw)
90
+ # let(:collection) { create(:collection_lw) }
91
91
  #
92
92
  # @example Create collections for use with nested collection index testing.
93
93
  # NOTE: For light weight nested collection testing using solr documents only, see `with_nested_attributes` above