curation_concerns 0.12.0.pre1 → 0.12.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +24 -16
  3. data/Gemfile +0 -4
  4. data/README.md +14 -0
  5. data/RELEASING.md +2 -2
  6. data/Rakefile +2 -0
  7. data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +28 -0
  8. data/app/actors/curation_concerns/abstract_actor.rb +28 -0
  9. data/app/actors/curation_concerns/add_to_collection_actor.rb +38 -0
  10. data/app/actors/curation_concerns/apply_order_actor.rb +24 -0
  11. data/app/actors/curation_concerns/assign_identifier_actor.rb +7 -0
  12. data/app/actors/curation_concerns/assign_representative_actor.rb +18 -0
  13. data/app/actors/curation_concerns/attach_files_actor.rb +39 -0
  14. data/app/actors/curation_concerns/base_actor.rb +71 -0
  15. data/app/actors/curation_concerns/embargo_actor.rb +19 -0
  16. data/app/actors/curation_concerns/file_actor.rb +79 -0
  17. data/app/actors/curation_concerns/file_set_actor.rb +146 -0
  18. data/app/actors/curation_concerns/interpret_visibility_actor.rb +123 -0
  19. data/app/actors/curation_concerns/lease_actor.rb +19 -0
  20. data/app/actors/curation_concerns/root_actor.rb +17 -0
  21. data/app/actors/curation_concerns/work_actor_behavior.rb +8 -0
  22. data/app/assets/javascripts/curation_concerns/batch_select.js +42 -0
  23. data/app/assets/javascripts/curation_concerns/collections.js +13 -0
  24. data/app/assets/javascripts/curation_concerns/curation_concerns.js +2 -0
  25. data/app/assets/stylesheets/curation_concerns/_curation_concerns.scss +0 -3
  26. data/app/assets/stylesheets/curation_concerns/_modules.scss +1 -1
  27. data/app/assets/stylesheets/curation_concerns/_positioning.scss +3 -6
  28. data/app/assets/stylesheets/curation_concerns/_theme.scss +0 -39
  29. data/app/assets/stylesheets/curation_concerns/_typography.scss +0 -69
  30. data/app/assets/stylesheets/curation_concerns/modules/classify_work.scss +0 -2
  31. data/app/assets/stylesheets/curation_concerns/modules/collections.scss +4 -0
  32. data/app/assets/stylesheets/curation_concerns/modules/forms.scss +0 -4
  33. data/app/assets/stylesheets/curation_concerns/modules/site_actions.scss +34 -29
  34. data/app/assets/stylesheets/curation_concerns/modules/site_search.scss +0 -46
  35. data/app/assets/stylesheets/curation_concerns.scss +4 -0
  36. data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +166 -21
  37. data/app/controllers/concerns/curation_concerns/embargoes_controller_behavior.rb +1 -1
  38. data/app/controllers/concerns/curation_concerns/leases_controller_behavior.rb +1 -1
  39. data/app/controllers/concerns/curation_concerns/selects_collections.rb +65 -0
  40. data/app/forms/curation_concerns/forms/collection_edit_form.rb +0 -29
  41. data/app/forms/curation_concerns/forms/work_form.rb +2 -1
  42. data/app/helpers/batch_select_helper.rb +23 -0
  43. data/app/helpers/collections_helper.rb +4 -0
  44. data/app/helpers/curation_concerns/collections_helper.rb +2 -2
  45. data/app/helpers/curation_concerns/collections_helper_behavior.rb +56 -0
  46. data/app/helpers/curation_concerns/render_constraints_helper.rb +14 -35
  47. data/app/helpers/curation_concerns/title_helper.rb +4 -0
  48. data/app/indexers/curation_concerns/collection_indexer.rb +16 -0
  49. data/app/indexers/curation_concerns/file_set_indexer.rb +46 -0
  50. data/app/indexers/curation_concerns/work_indexer.rb +15 -0
  51. data/app/jobs/audit_job.rb +49 -0
  52. data/app/jobs/characterize_job.rb +11 -0
  53. data/app/jobs/create_derivatives_job.rb +21 -0
  54. data/app/jobs/import_url_job.rb +48 -0
  55. data/app/jobs/ingest_file_job.rb +30 -0
  56. data/app/jobs/ingest_local_file_job.rb +20 -0
  57. data/app/jobs/resolrize_job.rb +7 -0
  58. data/app/models/checksum_audit_log.rb +20 -0
  59. data/app/models/collection.rb +6 -0
  60. data/app/models/concerns/curation_concerns/ability.rb +49 -0
  61. data/app/models/concerns/curation_concerns/basic_metadata.rb +64 -0
  62. data/app/models/concerns/curation_concerns/collection.rb +16 -0
  63. data/app/models/concerns/curation_concerns/collection_behavior.rb +62 -0
  64. data/app/models/concerns/curation_concerns/file_set/belongs_to_works.rb +47 -0
  65. data/app/models/concerns/curation_concerns/file_set/derivatives.rb +65 -0
  66. data/app/models/concerns/curation_concerns/file_set/full_text_indexing.rb +11 -0
  67. data/app/models/concerns/curation_concerns/file_set/indexing.rb +14 -0
  68. data/app/models/concerns/curation_concerns/file_set/querying.rb +17 -0
  69. data/app/models/concerns/curation_concerns/file_set_behavior.rb +36 -0
  70. data/app/models/concerns/curation_concerns/has_representative.rb +13 -0
  71. data/app/models/concerns/curation_concerns/human_readable_type.rb +17 -0
  72. data/app/models/concerns/curation_concerns/naming.rb +17 -0
  73. data/app/models/concerns/curation_concerns/permissions/readable.rb +18 -0
  74. data/app/models/concerns/curation_concerns/permissions/writable.rb +34 -0
  75. data/app/models/concerns/curation_concerns/permissions.rb +7 -0
  76. data/app/models/concerns/curation_concerns/required_metadata.rb +30 -0
  77. data/app/models/concerns/curation_concerns/serializers.rb +13 -0
  78. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +147 -0
  79. data/app/models/concerns/curation_concerns/user.rb +18 -0
  80. data/app/models/concerns/curation_concerns/with_file_sets.rb +37 -0
  81. data/app/models/concerns/curation_concerns/work_behavior.rb +45 -0
  82. data/app/models/curation_concerns/classify_concern.rb +49 -0
  83. data/app/models/curation_concerns/quick_classification_query.rb +38 -0
  84. data/app/models/single_use_link.rb +34 -0
  85. data/app/models/version_committer.rb +2 -0
  86. data/app/search_builders/curation_concerns/collection_member_search_builder.rb +1 -1
  87. data/app/search_builders/curation_concerns/collection_search_builder.rb +33 -0
  88. data/app/search_builders/curation_concerns/member_search_builder.rb +17 -0
  89. data/app/services/curation_concerns/derivative_path.rb +49 -0
  90. data/app/services/curation_concerns/file_set_audit_service.rb +105 -0
  91. data/app/services/curation_concerns/indexes_thumbnails.rb +30 -0
  92. data/app/services/curation_concerns/local_file_service.rb +10 -0
  93. data/app/services/curation_concerns/lock_manager.rb +39 -0
  94. data/app/services/curation_concerns/lockable.rb +16 -0
  95. data/app/services/curation_concerns/noid.rb +23 -0
  96. data/app/services/curation_concerns/persist_derivatives.rb +33 -0
  97. data/app/services/curation_concerns/persist_directly_contained_output_file_service.rb +26 -0
  98. data/app/services/curation_concerns/repository_audit_service.rb +7 -0
  99. data/app/services/curation_concerns/thumbnail_path_service.rb +46 -0
  100. data/app/services/curation_concerns/time_service.rb +7 -0
  101. data/app/services/curation_concerns/versioning_service.rb +26 -0
  102. data/app/validators/has_one_title_validator.rb +8 -0
  103. data/app/views/batch_select/_add_button.html.erb +3 -0
  104. data/app/views/batch_select/_check_all.html.erb +4 -0
  105. data/app/views/batch_select/_tools.html.erb +10 -0
  106. data/app/views/catalog/_action_menu_partials/_collection.html.erb +3 -3
  107. data/app/views/catalog/_action_menu_partials/_default.html.erb +1 -1
  108. data/app/views/catalog/_document_list.html.erb +1 -1
  109. data/app/views/collections/_bookmark_control.html.erb +2 -0
  110. data/app/views/collections/_button_create_collection.html.erb +2 -0
  111. data/app/views/collections/_button_for_creating_empty_collection.html.erb +1 -1
  112. data/app/views/collections/_button_for_delete_collection.html.erb +4 -0
  113. data/app/views/collections/_button_for_remove_selected_from_collection.html.erb +8 -0
  114. data/app/views/collections/_button_for_update_collection.html.erb +4 -0
  115. data/app/views/collections/_button_remove_from_collection.html.erb +4 -0
  116. data/app/views/collections/_document_header.html.erb +9 -0
  117. data/app/views/collections/_edit_actions.html.erb +1 -1
  118. data/app/views/collections/_edit_descriptions.html.erb +1 -1
  119. data/app/views/collections/_form.html.erb +2 -2
  120. data/app/views/collections/_form_for_select_destination_collection.html.erb +21 -0
  121. data/app/views/collections/_form_to_add_member.html.erb +1 -1
  122. data/app/views/collections/_index_default.html.erb +2 -0
  123. data/app/views/collections/_index_header_default.html.erb +2 -0
  124. data/app/views/collections/_media_display.html.erb +1 -1
  125. data/app/views/collections/_paginate.html.erb +1 -1
  126. data/app/views/collections/_paginate_compact.html.erb +1 -0
  127. data/app/views/collections/_results_pagination.html.erb +9 -0
  128. data/app/views/collections/_search_collection_dashboard_form.html.erb +1 -1
  129. data/app/views/collections/_search_form.html.erb +1 -1
  130. data/app/views/collections/_search_results.html.erb +23 -0
  131. data/app/views/collections/_show_actions.html.erb +1 -1
  132. data/app/views/collections/_sort_and_per_page.html.erb +1 -1
  133. data/app/views/collections/_view_type_group.html.erb +1 -1
  134. data/app/views/collections/index.html.erb +9 -0
  135. data/app/views/collections/new.html.erb +3 -0
  136. data/app/views/curation_concerns/base/_form_permission.html.erb +10 -11
  137. data/app/views/curation_concerns/base/_form_permission_embargo.html.erb +1 -1
  138. data/app/views/curation_concerns/base/_form_permission_lease.html.erb +1 -1
  139. data/app/views/curation_concerns/base/_legally_binding_text.html.erb +7 -7
  140. data/app/views/curation_concerns/base/_related_files.html.erb +1 -1
  141. data/app/views/curation_concerns/base/_visibility.html.erb +2 -2
  142. data/app/views/curation_concerns/file_sets/_actions.html.erb +1 -1
  143. data/app/views/embargoes/_list_expired_active_embargoes.html.erb +1 -1
  144. data/app/views/error/single_use_error.html.erb +1 -1
  145. data/app/views/shared/_add_content.html.erb +17 -15
  146. data/app/views/shared/_brand_bar.html.erb +19 -10
  147. data/app/views/shared/_header.html.erb +2 -6
  148. data/app/views/shared/_my_actions.html.erb +28 -27
  149. data/app/views/shared/_site_actions.html.erb +5 -1
  150. data/app/views/shared/_site_search.html.erb +3 -2
  151. data/app/views/shared/_title_bar.html.erb +7 -16
  152. data/app/views/welcome/index.html.erb +2 -2
  153. data/config/locales/curation_concerns.en.yml +25 -1
  154. data/curation_concerns.gemspec +21 -5
  155. data/lib/curation_concerns/collections/accepts_batches.rb +53 -0
  156. data/lib/curation_concerns/collections/search_service.rb +57 -0
  157. data/lib/curation_concerns/collections.rb +10 -0
  158. data/lib/curation_concerns/configuration.rb +167 -0
  159. data/lib/curation_concerns/engine.rb +22 -1
  160. data/lib/curation_concerns/messages.rb +68 -0
  161. data/lib/curation_concerns/models.rb +42 -0
  162. data/lib/curation_concerns/name.rb +20 -0
  163. data/lib/curation_concerns/null_logger.rb +10 -0
  164. data/lib/curation_concerns/rails/routes.rb +1 -3
  165. data/lib/curation_concerns/version.rb +1 -1
  166. data/lib/curation_concerns.rb +2 -0
  167. data/lib/generators/curation_concerns/abstract_migration_generator.rb +31 -0
  168. data/lib/generators/curation_concerns/clamav_generator.rb +19 -0
  169. data/lib/generators/curation_concerns/collection_generator.rb +15 -0
  170. data/lib/generators/curation_concerns/install_generator.rb +1 -2
  171. data/lib/generators/curation_concerns/models_generator.rb +62 -0
  172. data/lib/generators/curation_concerns/templates/app/models/collection.rb +6 -0
  173. data/lib/generators/curation_concerns/templates/app/models/file_set.rb +4 -0
  174. data/lib/generators/curation_concerns/templates/config/clamav.rb +1 -0
  175. data/lib/generators/curation_concerns/templates/config/curation_concerns.rb +61 -0
  176. data/lib/generators/curation_concerns/templates/config/mime_types.rb +6 -0
  177. data/lib/generators/curation_concerns/templates/config/redis.yml +9 -0
  178. data/lib/generators/curation_concerns/templates/config/redis_config.rb +29 -0
  179. data/lib/generators/curation_concerns/templates/config/resque-pool.yml +1 -0
  180. data/lib/generators/curation_concerns/templates/config/resque_config.rb +6 -0
  181. data/lib/generators/curation_concerns/templates/curation_concerns.scss +3 -2
  182. data/lib/generators/curation_concerns/templates/migrations/create_checksum_audit_logs.rb +19 -0
  183. data/lib/generators/curation_concerns/templates/migrations/create_single_use_links.rb +12 -0
  184. data/lib/generators/curation_concerns/templates/migrations/create_version_committers.rb +15 -0
  185. data/lib/tasks/migrate.rake +11 -0
  186. data/lib/tasks/resque.rake +14 -0
  187. data/lib/tasks/solr_reindex.rake +8 -0
  188. data/spec/actors/curation_concerns/file_set_actor_spec.rb +31 -0
  189. data/spec/controllers/accepts_batches_controller_spec.rb +65 -0
  190. data/spec/controllers/collections_controller_spec.rb +272 -0
  191. data/spec/controllers/curation_concerns/collections_controller_spec.rb +1 -2
  192. data/spec/controllers/selects_collections_controller_spec.rb +109 -0
  193. data/spec/features/create_work_spec.rb +1 -1
  194. data/spec/features/work_generator_spec.rb +1 -1
  195. data/spec/forms/collection_edit_form_spec.rb +2 -9
  196. data/spec/forms/work_form_spec.rb +5 -0
  197. data/spec/helpers/collections_helper_spec.rb +129 -0
  198. data/spec/helpers/curation_concerns/collections_helper_spec.rb +2 -2
  199. data/spec/helpers/render_constraints_helper_spec.rb +23 -1
  200. data/spec/lib/curation_concerns/collections/search_service_spec.rb +33 -0
  201. data/spec/models/collection_spec.rb +165 -0
  202. data/spec/tasks/rake_spec.rb +1 -1
  203. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  204. data/spec/views/curation_concerns/base/_form_permission.html.erb_spec.rb +4 -1
  205. data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +1 -0
  206. data/spec/views/shared/_add_content.html.erb_spec.rb +3 -3
  207. metadata +341 -24
  208. data/VERSION +0 -1
  209. data/app/assets/stylesheets/curation_concerns/_global-variables.scss +0 -5
  210. data/app/assets/stylesheets/curation_concerns/modules/multi_value_fields.scss +0 -52
  211. data/app/views/collections/_form_required_information.html.erb +0 -11
  212. data/tasks/release.rake +0 -93
@@ -0,0 +1,109 @@
1
+ require "spec_helper"
2
+
3
+ class SelectsCollectionsController < ApplicationController
4
+ include Blacklight::Catalog
5
+ include Hydra::Controller::ControllerBehavior
6
+ include CurationConcerns::SelectsCollections
7
+ end
8
+
9
+ describe SelectsCollectionsController, type: :controller do
10
+ describe "#find_collections" do
11
+ it "uses the search builder" do
12
+ expect(subject.collections_search_builder_class.default_processor_chain).to eq [:default_solr_parameters, :add_query_to_solr, :add_access_controls_to_solr_params, :add_collection_filter, :some_rows, :sort_by_title]
13
+ expect(CurationConcerns::CollectionSearchBuilder).to receive(:new).with(subject).and_call_original
14
+ subject.find_collections
15
+ end
16
+ end
17
+
18
+ describe "Select Collections" do
19
+ let(:user) { FactoryGirl.create(:user) }
20
+ let!(:collection) { FactoryGirl.create(:collection, read_groups: ['public'], user: user) }
21
+ let!(:collection2) { FactoryGirl.create(:collection, read_users: [user.user_key]) }
22
+ let!(:collection3) { FactoryGirl.create(:collection, edit_users: [user.user_key]) }
23
+ let!(:collection4) { FactoryGirl.create(:collection) }
24
+ # # collection = Collection.new title:"Test Public"
25
+ # # collection.apply_depositor_metadata(@user.user_key)
26
+ # # collection.read_groups = ["public"]
27
+ # # collection.save
28
+ # collection2 = Collection.new title:"Test Read"
29
+ # collection2.apply_depositor_metadata('abc123@test.com')
30
+ # collection2.read_users = [@user.user_key]
31
+ # collection2.save
32
+ # collection3 = Collection.new title:"Test Edit"
33
+ # collection3.apply_depositor_metadata('abc123@test.com')
34
+ # collection3.edit_users = [@user.user_key]
35
+ # collection3.save
36
+ # collection4 = Collection.new title:"Test No Access"
37
+ # collection4.apply_depositor_metadata('abc123@test.com')
38
+ # collection4.save
39
+
40
+ describe "Public Access" do
41
+ it "only returns public collections" do
42
+ subject.find_collections
43
+ expect(assigns[:user_collections].map(&:id)).to match_array [collection.id]
44
+ end
45
+
46
+ context "when there are more than 10" do
47
+ before do
48
+ 11.times do
49
+ FactoryGirl.create(:collection, read_groups: ["public"], user: user)
50
+ end
51
+ end
52
+
53
+ it "returns all public collections" do
54
+ subject.find_collections
55
+ expect(assigns[:user_collections].count).to eq(12)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe "Read Access" do
61
+ describe "not signed in" do
62
+ it "errors if the user is not signed in" do
63
+ expect { subject.find_collections_with_read_access }.to raise_error
64
+ end
65
+ end
66
+ describe "signed in" do
67
+ before { sign_in user }
68
+
69
+ it "only returns public and read access (edit access implies read) collections" do
70
+ subject.find_collections_with_read_access
71
+ expect(assigns[:user_collections].map(&:id)).to match_array [collection.id, collection2.id, collection3.id]
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "Edit Access" do
77
+ describe "not signed in" do
78
+ it "errors if the user is not signed in" do
79
+ expect { subject.find_collections_with_edit_access }.to raise_error
80
+ end
81
+ end
82
+
83
+ describe "signed in" do
84
+ before { sign_in user }
85
+
86
+ it "only returns public or editable collections" do
87
+ subject.find_collections_with_edit_access
88
+ expect(assigns[:user_collections].map(&:id)).to match_array [collection.id, collection3.id]
89
+ end
90
+
91
+ it "only returns public or editable collections & instructions" do
92
+ subject.find_collections_with_edit_access(true)
93
+ expect(assigns[:user_collections].map(&:id)).to match_array [-1, collection.id, collection3.id]
94
+ end
95
+
96
+ context "after querying for read access" do
97
+ before do
98
+ subject.find_collections
99
+ subject.find_collections_with_edit_access
100
+ end
101
+
102
+ it "returns collections with edit access" do
103
+ expect(assigns[:user_collections].map(&:id)).to match_array [collection.id, collection3.id]
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -25,7 +25,7 @@ feature 'Creating a new Work' do
25
25
  within('form.new_generic_work') do
26
26
  fill_in('Title', with: work_title)
27
27
  attach_file('Upload a file', fixture_file_path('files/image.png'))
28
- choose('visibility_open')
28
+ choose('generic_work_visibility_open')
29
29
  click_on('Create Generic work')
30
30
  end
31
31
  within '.related_files' do
@@ -42,7 +42,7 @@ feature 'Creating a new Work' do
42
42
  within('form.new_catapult') do
43
43
  fill_in('Title', with: catapult_title)
44
44
  attach_file('Upload a file', fixture_file_path('files/image.png'))
45
- choose('visibility_open')
45
+ choose('catapult_visibility_open')
46
46
  click_on('Create Catapult')
47
47
  end
48
48
  click_on('Edit This Catapult')
@@ -29,10 +29,10 @@ describe CurationConcerns::Forms::CollectionEditForm do
29
29
  describe ".build_permitted_params" do
30
30
  subject { described_class.build_permitted_params }
31
31
  it { is_expected.to eq [{ resource_type: [] },
32
- :title,
32
+ { title: [] },
33
33
  { creator: [] },
34
34
  { contributor: [] },
35
- :description,
35
+ { description: [] },
36
36
  { tag: [] },
37
37
  { rights: [] },
38
38
  { publisher: [] },
@@ -47,13 +47,6 @@ describe CurationConcerns::Forms::CollectionEditForm do
47
47
  :visibility] }
48
48
  end
49
49
 
50
- describe 'multiple?' do
51
- context 'with :title' do
52
- subject { described_class.multiple?(:title) }
53
- it { is_expected.to be false }
54
- end
55
- end
56
-
57
50
  describe '#select_files' do
58
51
  context 'without any works/files attached' do
59
52
  subject { form.select_files }
@@ -75,6 +75,11 @@ describe CurationConcerns::Forms::WorkForm do
75
75
  end
76
76
  end
77
77
 
78
+ describe '#visibility' do
79
+ subject { form.visibility }
80
+ it { is_expected.to eq 'restricted' }
81
+ end
82
+
78
83
  describe '#human_readable_type' do
79
84
  subject { form.human_readable_type }
80
85
  it { is_expected.to eq 'Generic Work' }
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe CollectionsHelper, type: :helper do
4
+ describe "has_collection_search_parameters?" do
5
+ subject { helper }
6
+
7
+ context "when cq is set" do
8
+ before { allow(helper).to receive(:params).and_return(cq: 'foo') }
9
+ it { is_expected.to have_collection_search_parameters }
10
+ end
11
+
12
+ context "when cq is not set" do
13
+ before { allow(helper).to receive(:params).and_return(cq: '') }
14
+ it { is_expected.not_to have_collection_search_parameters }
15
+ end
16
+ end
17
+
18
+ describe "button_for_create_collection" do
19
+ it "creates a button to the collections new path" do
20
+ str = String.new(helper.button_for_create_collection)
21
+ doc = Nokogiri::HTML(str)
22
+ form = doc.xpath('//form').first
23
+ expect(form.attr('action')).to eq(new_collection_path.to_s)
24
+ i = form.xpath('.//input').first
25
+ expect(i.attr('type')).to eq('submit')
26
+ end
27
+
28
+ it "creates a button with my text" do
29
+ str = String.new(helper.button_for_create_collection("Create My Button"))
30
+ doc = Nokogiri::HTML(str)
31
+ form = doc.xpath('//form').first
32
+ expect(form.attr('action')).to eq(new_collection_path.to_s)
33
+ i = form.xpath('.//input').first
34
+ expect(i.attr('value')).to eq('Create My Button')
35
+ end
36
+ end
37
+
38
+ describe "button_for_delete_collection" do
39
+ let(:collection) { FactoryGirl.create(:collection) }
40
+
41
+ it "creates a button to the collections delete path" do
42
+ str = button_for_delete_collection collection
43
+ doc = Nokogiri::HTML(str)
44
+ form = doc.xpath('//form').first
45
+ expect(form.attr('action')).to eq collection_path(collection)
46
+ i = form.xpath('.//input')[1]
47
+ expect(i.attr('type')).to eq('submit')
48
+ end
49
+ it "creates a button with my text" do
50
+ str = button_for_delete_collection collection, "Delete My Button"
51
+ doc = Nokogiri::HTML(str)
52
+ form = doc.xpath('//form').first
53
+ expect(form.attr('action')).to eq collection_path(collection)
54
+ i = form.xpath('.//input')[1]
55
+ expect(i.attr('value')).to eq("Delete My Button")
56
+ end
57
+ end
58
+
59
+ describe "button_for_remove_from_collection" do
60
+ let(:item) { double(id: 'changeme:123') }
61
+ let(:collection) { FactoryGirl.create(:collection) }
62
+
63
+ it "generates a form that can remove the item" do
64
+ str = button_for_remove_from_collection collection, item
65
+ doc = Nokogiri::HTML(str)
66
+ form = doc.xpath('//form').first
67
+ expect(form.attr('action')).to eq collection_path(collection)
68
+ expect(form.css('input#collection_members[type="hidden"][value="remove"]')).not_to be_empty
69
+ expect(form.css('input[type="hidden"][name="batch_document_ids[]"][value="changeme:123"]')).not_to be_empty
70
+ end
71
+
72
+ describe "for a collection of another name" do
73
+ before(:all) do
74
+ class OtherCollection < ActiveFedora::Base
75
+ include CurationConcerns::Collection
76
+ include Hydra::Works::WorkBehavior
77
+ end
78
+ end
79
+
80
+ let!(:collection) { OtherCollection.create! }
81
+
82
+ after(:all) do
83
+ Object.send(:remove_const, :OtherCollection)
84
+ end
85
+
86
+ it "generates a form that can remove the item" do
87
+ str = button_for_remove_from_collection collection, item
88
+ doc = Nokogiri::HTML(str)
89
+ form = doc.xpath('//form').first
90
+ expect(form.attr('action')).to eq collection_path(collection)
91
+ expect(form.css('input#collection_members[type="hidden"][value="remove"]')).not_to be_empty
92
+ expect(form.css('input[type="hidden"][name="batch_document_ids[]"][value="changeme:123"]')).not_to be_empty
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "button_for_remove_selected_from_collection" do
98
+ let(:collection) { FactoryGirl.create(:collection) }
99
+
100
+ it "creates a button to the collections delete path" do
101
+ str = button_for_remove_selected_from_collection collection
102
+ doc = Nokogiri::HTML(str)
103
+ form = doc.xpath('//form').first
104
+ expect(form.attr('action')).to eq collection_path(collection)
105
+ i = form.xpath('.//input')[2]
106
+ expect(i.attr('value')).to eq("remove")
107
+ expect(i.attr('name')).to eq("collection[members]")
108
+ end
109
+
110
+ it "creates a button with my text" do
111
+ str = button_for_remove_selected_from_collection collection, "Remove My Button"
112
+ doc = Nokogiri::HTML(str)
113
+ form = doc.css('form').first
114
+ expect(form.attr('action')).to eq collection_path(collection)
115
+ expect(form.css('input[type="submit"]').attr('value').value).to eq "Remove My Button"
116
+ end
117
+ end
118
+
119
+ describe "hidden_collection_members" do
120
+ before { helper.params[:batch_document_ids] = ['foo:12', 'foo:23'] }
121
+ it "makes hidden fields" do
122
+ doc = Nokogiri::HTML(hidden_collection_members)
123
+ inputs = doc.xpath('//input[@type="hidden"][@name="batch_document_ids[]"]')
124
+ expect(inputs.length).to eq(2)
125
+ expect(inputs[0].attr('value')).to eq('foo:12')
126
+ expect(inputs[1].attr('value')).to eq('foo:23')
127
+ end
128
+ end
129
+ end
@@ -26,8 +26,8 @@ describe CurationConcerns::CollectionsHelper do
26
26
  it 'has a form that routes to remove the collectible' do
27
27
  expect(subject).to have_selector 'a[data-method=put]'
28
28
  expect(subject).to have_link 'Remove From Collection',
29
- href: collections.collection_path('123', collection: { members: 'remove' },
30
- batch_document_ids: ['456'])
29
+ href: collection_path('123', collection: { members: 'remove' },
30
+ batch_document_ids: ['456'])
31
31
  end
32
32
  end
33
33
 
@@ -1,6 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CurationConcernsHelper do
4
+ let(:search_params) do
5
+ ActionController::Parameters.new(q: 'Simon',
6
+ search_field: 'publisher',
7
+ controller: 'catalog')
8
+ end
4
9
  describe 'render_constraints_query' do
5
10
  before do
6
11
  # Stub methods from Blacklight::SearchFields
@@ -8,12 +13,29 @@ describe CurationConcernsHelper do
8
13
  allow(helper).to receive(:label_for_search_field).and_return('Foo')
9
14
  end
10
15
 
11
- let(:search_params) { { q: 'Simon', search_field: 'publisher', controller: 'catalog' } }
12
16
  subject { helper.render_constraints_query(search_params) }
13
17
 
14
18
  it 'removes search_field' do
15
19
  node = Capybara::Node::Simple.new(subject)
16
20
  expect(node).to have_link 'Remove constraint Foo: Simon', href: search_catalog_path
17
21
  end
22
+
23
+ it 'calls remove_constraint_url' do
24
+ expect(helper).to receive(:remove_constraint_url).and_return('/hello')
25
+ expect(subject).to include 'href="/hello"'
26
+ end
27
+ end
28
+
29
+ describe 'remove_constraint_url' do
30
+ subject { helper.remove_constraint_url(search_params) }
31
+ it 'calls fields_to_exclude_from_constraint_element' do
32
+ expect(helper).to receive(:fields_to_exclude_from_constraint_element).and_return([])
33
+ expect(subject).to eq "/catalog?search_field=publisher"
34
+ end
35
+ end
36
+
37
+ describe 'fields_to_exclude_from_constraint_element' do
38
+ subject { helper.fields_to_exclude_from_constraint_element }
39
+ it { is_expected.to eq [:search_field] }
18
40
  end
19
41
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::Collections::SearchService do
4
+ before do
5
+ @login = 'vanessa'
6
+ @session = { history: [17, 14, 12, 9] }
7
+ @service = described_class.new(@session, @login)
8
+ end
9
+
10
+ it "gets the documents for the first history entry" do
11
+ expect(Search).to receive(:find).with(17).and_return(Search.new(query_params: { q: "World Peace" }))
12
+ expect(@service).to receive(:get_search_results).and_return([:one, [:doc1, :doc2]])
13
+ expect(@service.last_search_documents).to eq([:doc1, :doc2])
14
+ end
15
+
16
+ describe 'apply_gated_search' do
17
+ before(:each) do
18
+ allow(RoleMapper).to receive(:roles).with(@login).and_return(['umg/test.group.1'])
19
+ params = @service.apply_gated_search({}, {})
20
+ @group_query = params[:fq].first.split(' OR ')[1]
21
+ end
22
+ it "escapes slashes in groups" do
23
+ expect(@group_query).to eq('edit_access_group_ssim:umg\/test.group.1')
24
+ end
25
+ it "allows overriding Solr's access control suffix" do
26
+ allow_any_instance_of(described_class).to receive(:solr_access_control_suffix).and_return("edit_group_customfield")
27
+ @service = described_class.new({}, '')
28
+ params = @service.apply_gated_search({}, {})
29
+ @public_query = params[:fq].first.split(' OR ')[0]
30
+ expect(@public_query).to eq('edit_group_customfield:public')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ describe Collection, type: :model do
4
+ let(:gf1) { create(:generic_work, user: user) }
5
+ let(:gf2) { create(:generic_work, user: user) }
6
+ let(:gf3) { create(:generic_work, user: user) }
7
+
8
+ let(:user) { FactoryGirl.create(:user) }
9
+
10
+ before do
11
+ subject.title = ['Some title']
12
+ subject.apply_depositor_metadata(user)
13
+ end
14
+
15
+ describe "#to_solr" do
16
+ let(:collection) { FactoryGirl.build(:collection, user: user, title: ['A good title']) }
17
+
18
+ let(:solr_document) { collection.to_solr }
19
+
20
+ it "has title information" do
21
+ expect(solr_document).to include 'title_tesim' => ['A good title'],
22
+ 'title_sim' => ['A good title']
23
+ end
24
+
25
+ it "has depositor information" do
26
+ expect(solr_document).to include 'depositor_tesim' => [user.user_key],
27
+ 'depositor_ssim' => [user.user_key]
28
+ end
29
+
30
+ context "with members" do
31
+ before do
32
+ collection.members << gf1
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#depositor" do
38
+ before do
39
+ subject.apply_depositor_metadata(user)
40
+ end
41
+
42
+ it "has a depositor" do
43
+ expect(subject.depositor).to eq(user.user_key)
44
+ end
45
+ end
46
+
47
+ describe "the ability" do
48
+ let(:collection) { described_class.create(title: ['Some title']) { |c| c.apply_depositor_metadata(user) } }
49
+
50
+ let(:ability) { Ability.new(user) }
51
+
52
+ it "allows the depositor to edit and read" do
53
+ expect(ability.can?(:read, collection)).to be true
54
+ expect(ability.can?(:edit, collection)).to be true
55
+ end
56
+ end
57
+
58
+ describe "#members" do
59
+ it "is empty by default" do
60
+ expect(subject.members).to be_empty
61
+ end
62
+
63
+ context "adding members" do
64
+ context "using assignment" do
65
+ subject { described_class.create!(title: ['Some title'], members: [gf1, gf2]) { |c| c.apply_depositor_metadata(user) } }
66
+
67
+ it "has many files" do
68
+ expect(subject.reload.members).to eq [gf1, gf2]
69
+ end
70
+ end
71
+
72
+ context "using append" do
73
+ before do
74
+ subject.members = [gf1]
75
+ subject.save
76
+ end
77
+ it "allows new files to be added" do
78
+ subject.reload
79
+ subject.members << gf2
80
+ subject.save
81
+ expect(subject.reload.members).to eq [gf1, gf2]
82
+ end
83
+
84
+ it "allows multiple files to be added" do
85
+ subject.reload
86
+ subject.add_members [gf2.id, gf3.id]
87
+ subject.save
88
+ expect(subject.reload.members).to eq [gf1, gf2, gf3]
89
+ end
90
+ end
91
+ end
92
+
93
+ context "removing members" do
94
+ before do
95
+ subject.members = [gf1, gf2]
96
+ subject.save!
97
+ end
98
+
99
+ it "allows files to be removed" do
100
+ # force the "in_collections" to be cached:
101
+ expect(gf1.in_collections).to eq [subject]
102
+
103
+ # We need to ensure that deleting causes the collection to be flushed.
104
+ subject.reload.members.delete(gf1)
105
+ subject.save
106
+ expect(subject.reload.members).to eq [gf2]
107
+ end
108
+ end
109
+ end
110
+
111
+ it "has a title" do
112
+ subject.title = ["title"]
113
+ subject.save
114
+ expect(subject.reload.title).to eq ["title"]
115
+ end
116
+
117
+ it "has a description" do
118
+ subject.title = ["title"]
119
+ subject.description = ["description"]
120
+ subject.save
121
+ expect(subject.reload.description).to eq ["description"]
122
+ end
123
+
124
+ describe "#destroy" do
125
+ before do
126
+ subject.members = [gf1, gf2]
127
+ subject.save
128
+ subject.destroy
129
+ end
130
+
131
+ it "does not delete member files when deleted" do
132
+ expect(GenericWork.exists?(gf1.id)).to be true
133
+ expect(GenericWork.exists?(gf2.id)).to be true
134
+ end
135
+ end
136
+
137
+ describe "Collection by another name" do
138
+ before do
139
+ class OtherCollection < ActiveFedora::Base
140
+ include CurationConcerns::Collection
141
+ end
142
+
143
+ class Member < ActiveFedora::Base
144
+ include Hydra::Works::WorkBehavior
145
+ end
146
+ end
147
+ after do
148
+ Object.send(:remove_const, :OtherCollection)
149
+ Object.send(:remove_const, :Member)
150
+ end
151
+
152
+ let(:member) { Member.create }
153
+ let(:collection) { OtherCollection.new }
154
+
155
+ before do
156
+ collection.members << member
157
+ collection.save
158
+ end
159
+
160
+ it "have members that know about the collection" do
161
+ member.reload
162
+ expect(member.in_collections).to eq [collection]
163
+ end
164
+ end
165
+ end
@@ -6,7 +6,7 @@ describe 'Rake tasks' do
6
6
  let(:namespaced_id) { 'curation_concerns:123' }
7
7
  let(:corrected_id) { '123' }
8
8
  before do
9
- load File.expand_path('../../../curation_concerns-models/lib/tasks/migrate.rake', __FILE__)
9
+ load File.expand_path('../../../lib/tasks/migrate.rake', __FILE__)
10
10
  Rake::Task.define_task(:environment)
11
11
  end
12
12
 
@@ -1,7 +1,7 @@
1
1
  require 'rails/generators'
2
2
 
3
3
  class TestAppGenerator < Rails::Generators::Base
4
- source_root '../../spec/test_app_templates'
4
+ source_root File.expand_path("../../../../spec/test_app_templates", __FILE__)
5
5
 
6
6
  def install_engine
7
7
  generate 'curation_concerns:install', '-f'
@@ -3,7 +3,10 @@ require 'spec_helper'
3
3
  describe 'curation_concerns/base/_form_permission.html.erb' do
4
4
  let(:curation_concern) { GenericWork.new }
5
5
  before do
6
- f = double('form', object: curation_concern, object_name: nil, input: nil)
6
+ f = double('form', object: curation_concern,
7
+ object_name: nil,
8
+ input: nil,
9
+ radio_button: nil)
7
10
  render partial: "curation_concerns/base/form_permission", locals: { f: f }
8
11
  end
9
12
 
@@ -38,6 +38,7 @@ describe 'curation_concerns/file_sets/show.html.erb', type: :view do
38
38
 
39
39
  describe 'title heading' do
40
40
  before do
41
+ stub_template 'shared/_brand_bar.html.erb' => 'Brand Bar'
41
42
  stub_template 'shared/_title_bar.html.erb' => 'Title Bar'
42
43
  render template: 'curation_concerns/file_sets/show.html.erb', layout: 'layouts/curation_concerns'
43
44
  end
@@ -16,7 +16,7 @@ describe 'shared/_add_content.html.erb' do
16
16
  CurationConcerns.config.curation_concerns.each do |curation_concern_type|
17
17
  expect(rendered).to have_link("New #{curation_concern_type.human_readable_type}", href: new_polymorphic_path(curation_concern_type))
18
18
  end
19
- expect(rendered).to have_link('Add a Collection', href: collections.new_collection_path)
19
+ expect(rendered).to have_link('Add a Collection', href: new_collection_path)
20
20
  end
21
21
  end
22
22
 
@@ -32,7 +32,7 @@ describe 'shared/_add_content.html.erb' do
32
32
  CurationConcerns.config.curation_concerns.each do |curation_concern_type|
33
33
  expect(rendered).not_to have_link("New #{curation_concern_type.human_readable_type}", href: new_polymorphic_path(curation_concern_type))
34
34
  end
35
- expect(rendered).to have_link('Add a Collection', href: collections.new_collection_path)
35
+ expect(rendered).to have_link('Add a Collection', href: new_collection_path)
36
36
  end
37
37
  end
38
38
 
@@ -49,7 +49,7 @@ describe 'shared/_add_content.html.erb' do
49
49
  CurationConcerns.config.curation_concerns.each do |curation_concern_type|
50
50
  expect(rendered).not_to have_link("New #{curation_concern_type.human_readable_type}", href: new_polymorphic_path(curation_concern_type))
51
51
  end
52
- expect(rendered).not_to have_link('Add a Collection', href: collections.new_collection_path)
52
+ expect(rendered).not_to have_link('Add a Collection', href: new_collection_path)
53
53
  end
54
54
  end
55
55
  end