curation_concerns 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +1 -2
  5. data/README.md +1 -1
  6. data/Rakefile +1 -1
  7. data/VERSION +1 -1
  8. data/app/assets/javascripts/curation_concerns/curation_concerns.js +2 -0
  9. data/app/assets/javascripts/curation_concerns/uploader.js +4 -4
  10. data/app/assets/stylesheets/curation_concerns/_modules.scss +1 -0
  11. data/app/assets/stylesheets/curation_concerns/_positioning.scss +3 -0
  12. data/app/assets/stylesheets/curation_concerns/modules/icons.scss +11 -0
  13. data/app/controllers/concerns/curation_concerns/api.rb +1 -12
  14. data/app/controllers/concerns/curation_concerns/application_controller_behavior.rb +20 -6
  15. data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +44 -25
  16. data/app/controllers/concerns/curation_concerns/file_sets_controller_behavior.rb +32 -23
  17. data/app/controllers/concerns/curation_concerns/parent_container.rb +0 -11
  18. data/app/controllers/concerns/curation_concerns/single_use_links_controller_behavior.rb +1 -1
  19. data/app/controllers/concerns/curation_concerns/single_use_links_viewer_controller_behavior.rb +7 -1
  20. data/app/controllers/concerns/curation_concerns/upload_sets_controller_behavior.rb +19 -7
  21. data/app/controllers/curation_concerns/permissions_controller.rb +1 -1
  22. data/app/forms/curation_concerns/forms/collection_edit_form.rb +6 -2
  23. data/app/forms/curation_concerns/forms/work_form.rb +14 -3
  24. data/app/forms/curation_concerns/upload_set_form.rb +43 -0
  25. data/app/helpers/curation_concerns/ability_helper.rb +12 -18
  26. data/app/helpers/curation_concerns/file_set_helper.rb +1 -1
  27. data/app/helpers/curation_concerns/main_app_helpers.rb +1 -0
  28. data/app/helpers/curation_concerns/permissions_helper.rb +20 -0
  29. data/app/helpers/curation_concerns/url_helper.rb +3 -11
  30. data/app/inputs/multi_value_with_help_input.rb +8 -0
  31. data/app/inputs/select_with_help_input.rb +3 -0
  32. data/app/inputs/select_with_modal_help_input.rb +36 -0
  33. data/app/inputs/with_help_icon.rb +34 -0
  34. data/app/presenters/curation_concerns/collection_presenter.rb +9 -0
  35. data/app/presenters/curation_concerns/file_set_presenter.rb +2 -1
  36. data/app/presenters/curation_concerns/presents_attributes.rb +16 -0
  37. data/app/presenters/curation_concerns/work_show_presenter.rb +3 -2
  38. data/app/renderers/curation_concerns/attribute_renderer.rb +22 -4
  39. data/app/renderers/curation_concerns/configured_microdata.rb +40 -0
  40. data/app/services/curation_concerns/parent_service.rb +1 -1
  41. data/app/views/catalog/_action_menu_partials/_default.html.erb +2 -2
  42. data/app/views/collections/_form.html.erb +8 -9
  43. data/app/views/collections/_sort_and_per_page.html.erb +25 -23
  44. data/app/views/collections/show.html.erb +1 -1
  45. data/app/views/curation_concerns/base/_attributes.html.erb +1 -1
  46. data/app/views/curation_concerns/base/_form.html.erb +6 -7
  47. data/app/views/curation_concerns/base/_form_permission.html.erb +3 -0
  48. data/app/views/curation_concerns/base/_multiple_upload.html.erb +3 -0
  49. data/app/views/curation_concerns/base/_show_actions.html.erb +2 -2
  50. data/app/views/curation_concerns/base/_versioning.html.erb +1 -1
  51. data/app/views/curation_concerns/base/_visibility.html.erb +17 -0
  52. data/app/views/curation_concerns/base/show.html.erb +1 -1
  53. data/app/views/curation_concerns/classify_concerns/new.html.erb +1 -1
  54. data/app/views/curation_concerns/file_sets/_actions.html.erb +2 -2
  55. data/app/views/curation_concerns/file_sets/_form.html.erb +1 -1
  56. data/app/views/curation_concerns/file_sets/_rights_modal.html.erb +41 -0
  57. data/app/views/curation_concerns/file_sets/media_display/_default.html.erb +4 -1
  58. data/app/views/curation_concerns/file_sets/media_display/_image.html.erb +9 -8
  59. data/app/views/curation_concerns/file_sets/media_display/_office_document.html.erb +9 -7
  60. data/app/views/curation_concerns/file_sets/media_display/_pdf.html.erb +7 -5
  61. data/app/views/curation_concerns/file_sets/show.html.erb +2 -2
  62. data/app/views/curation_concerns/file_sets/upload/_alerts.html.erb +3 -3
  63. data/app/views/curation_concerns/file_sets/upload/_form.html.erb +1 -1
  64. data/app/views/curation_concerns/file_sets/upload/_script_templates.html.erb +1 -1
  65. data/app/views/curation_concerns/permissions/confirm.html.erb +1 -1
  66. data/app/views/curation_concerns/single_use_links_viewer/show.html.erb +1 -1
  67. data/app/views/embargoes/edit.html.erb +4 -4
  68. data/app/views/layouts/curation_concerns.html.erb +1 -1
  69. data/app/views/leases/edit.html.erb +3 -3
  70. data/app/views/shared/_add_works.html.erb +6 -3
  71. data/app/views/upload_sets/_base_metadata.html.erb +12 -0
  72. data/app/views/upload_sets/_metadata.html.erb +3 -13
  73. data/app/views/upload_sets/edit.html.erb +1 -1
  74. data/config/locales/curation_concerns.en.yml +46 -0
  75. data/curation_concerns.gemspec +5 -4
  76. data/lib/curation_concerns/engine.rb +5 -0
  77. data/lib/curation_concerns/form_builder.rb +16 -0
  78. data/lib/curation_concerns/rails/routes.rb +7 -5
  79. data/lib/generators/curation_concerns/install_generator.rb +1 -1
  80. data/lib/generators/curation_concerns/work/work_generator.rb +1 -1
  81. data/spec/actors/curation_concerns/file_set_actor_spec.rb +26 -16
  82. data/spec/controllers/curation_concerns/file_sets_controller_json_spec.rb +14 -4
  83. data/spec/controllers/curation_concerns/file_sets_controller_spec.rb +3 -3
  84. data/spec/controllers/curation_concerns/generic_works_controller_json_spec.rb +4 -4
  85. data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +21 -0
  86. data/spec/controllers/curation_concerns/single_use_links_controller_spec.rb +2 -2
  87. data/spec/controllers/curation_concerns/single_use_links_viewer_controller_spec.rb +1 -1
  88. data/spec/controllers/upload_sets_controller_spec.rb +20 -27
  89. data/spec/factories/file_sets.rb +1 -0
  90. data/spec/factories/generic_works.rb +1 -0
  91. data/spec/factories/users.rb +0 -12
  92. data/spec/features/collection_spec.rb +1 -3
  93. data/spec/forms/collection_edit_form_spec.rb +16 -1
  94. data/spec/forms/upload_set_form_spec.rb +55 -0
  95. data/spec/forms/work_form_spec.rb +68 -3
  96. data/spec/helpers/curation_concerns/ability_helper_spec.rb +45 -0
  97. data/spec/helpers/curation_concerns/permissions_helper_spec.rb +12 -0
  98. data/spec/helpers/url_helper_spec.rb +0 -3
  99. data/spec/indexers/collection_indexer_spec.rb +5 -0
  100. data/spec/indexers/{file_set_indexing_service_spec.rb → file_set_indexer_spec.rb} +40 -2
  101. data/spec/indexers/{generic_work_indexing_service_spec.rb → work_indexer_spec.rb} +1 -1
  102. data/spec/inputs/multi_value_with_help_input_spec.rb +32 -0
  103. data/spec/inputs/select_with_help_input_spec.rb +43 -0
  104. data/spec/inputs/select_with_modal_help_input_spec.rb +21 -0
  105. data/spec/jobs/import_url_job_spec.rb +33 -1
  106. data/spec/jobs/ingest_file_job_spec.rb +29 -16
  107. data/spec/jobs/upload_set_update_job_spec.rb +24 -11
  108. data/spec/lib/curation_concerns/messages_spec.rb +2 -2
  109. data/spec/lib/curation_concerns/name_spec.rb +20 -0
  110. data/spec/lib/curation_concerns/null_logger_spec.rb +10 -0
  111. data/spec/models/curation_concerns/collection_behavior_spec.rb +41 -10
  112. data/spec/models/curation_concerns/work_behavior_spec.rb +1 -13
  113. data/spec/models/file_set_spec.rb +19 -4
  114. data/spec/models/generic_work_spec.rb +7 -2
  115. data/spec/models/quick_classification_query_spec.rb +35 -0
  116. data/spec/models/upload_set_spec.rb +5 -7
  117. data/spec/presenters/curation_concerns/collection_presenter_spec.rb +20 -0
  118. data/spec/presenters/curation_concerns/file_set_presenter_spec.rb +10 -3
  119. data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +13 -1
  120. data/spec/renderers/curation_concerns/attribute_renderer_spec.rb +41 -8
  121. data/spec/routing/curation_concerns/routes_spec.rb +2 -2
  122. data/spec/routing/route_spec.rb +1 -1
  123. data/spec/services/file_set_audit_service_spec.rb +46 -4
  124. data/spec/spec_helper.rb +5 -7
  125. data/spec/views/collections/_sort_and_per_page.html.erb_spec.rb +32 -0
  126. data/spec/views/curation_concerns/base/_attributes.html.erb_spec.rb +8 -1
  127. data/spec/views/curation_concerns/base/show.html.erb_spec.rb +36 -2
  128. data/spec/views/curation_concerns/file_sets/_file_set.html.erb_spec.rb +3 -2
  129. data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +56 -0
  130. data/spec/views/curation_concerns/single_use_links_viewer/show.html.erb_spec.rb +19 -0
  131. data/spec/views/shared/_add_content.html.erb_spec.rb +3 -3
  132. data/spec/views/single_use_links/new_download.html.erb_spec.rb +1 -1
  133. data/spec/views/upload_sets/_metadata.html.erb_spec.rb +28 -0
  134. metadata +80 -50
  135. data/app/assets/stylesheets/curation_concerns/help_requests.scss +0 -3
  136. data/app/controllers/concerns/curation_concerns/without_namespace.rb +0 -16
  137. data/app/controllers/registrations_controller.rb +0 -19
  138. data/app/controllers/sessions_controller.rb +0 -4
  139. data/app/views/curation_concerns/file_sets/_multiple_upload.html.erb +0 -3
  140. data/spec/fixtures/Example.ogg +0 -0
  141. data/spec/fixtures/charter.docx +0 -0
  142. data/spec/fixtures/countdown.avi +0 -0
  143. data/spec/fixtures/curation_concerns_generic_stub.txt +0 -1
  144. data/spec/fixtures/empty_file.txt +0 -0
  145. data/spec/fixtures/files/image.png +0 -0
  146. data/spec/fixtures/image.jp2 +0 -0
  147. data/spec/fixtures/image.jpg +0 -0
  148. data/spec/fixtures/piano_note.wav +0 -0
  149. data/spec/fixtures/sample_mpeg4.mp4 +0 -0
  150. data/spec/fixtures/small_file.txt +0 -1
  151. data/spec/fixtures/spoken-text.m4a +0 -0
  152. data/spec/fixtures/test.pdf +0 -0
  153. data/spec/fixtures/test4.pdf +0 -0
  154. data/spec/fixtures/test5.mp3 +0 -0
  155. data/spec/fixtures/world.png +0 -0
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe CurationConcerns::FileSetIndexingService do
3
+ describe CurationConcerns::FileSetIndexer do
4
4
  let(:file_set) do
5
5
  FileSet.new(
6
6
  id: 'foo123',
@@ -28,12 +28,21 @@ describe CurationConcerns::FileSetIndexingService do
28
28
  end
29
29
  end
30
30
 
31
+ let(:mock_file) do
32
+ mock_model("MockFile",
33
+ content: "asdf",
34
+ digest: ["urn:sha1:f794b23c0c6fe1083d0ca8b58261a078cd968967"]
35
+ )
36
+ end
37
+ let(:indexer) { described_class.new(file_set) }
38
+
31
39
  describe '#generate_solr_document' do
32
40
  before do
33
41
  allow(file_set).to receive(:label).and_return('CastoriaAd.tiff')
34
42
  allow(CurationConcerns::ThumbnailPathService).to receive(:call).and_return('/downloads/foo123?file=thumbnail')
43
+ allow(file_set).to receive(:original_file).and_return(mock_file)
35
44
  end
36
- subject { described_class.new(file_set).generate_solr_document }
45
+ subject { indexer.generate_solr_document }
37
46
 
38
47
  it 'has fields' do
39
48
  expect(subject[Solrizer.solr_name('hasRelatedMediaFragment', :symbol)]).to eq 'foo123'
@@ -64,6 +73,35 @@ describe CurationConcerns::FileSetIndexingService do
64
73
  expect(subject['all_text_timv']).to eq('abcxyz')
65
74
  expect(subject['height_is']).to eq 500
66
75
  expect(subject['width_is']).to eq 600
76
+ expect(subject[Solrizer.solr_name('digest', :symbol)]).to eq 'urn:sha1:f794b23c0c6fe1083d0ca8b58261a078cd968967'
77
+ end
78
+ end
79
+
80
+ describe '#file_format' do
81
+ subject { indexer.send(:file_format) }
82
+
83
+ context 'when both mime and format_label are present' do
84
+ before do
85
+ allow(file_set).to receive(:mime_type).and_return('image/png')
86
+ allow(file_set).to receive(:format_label).and_return(['Portable Network Graphics'])
87
+ end
88
+ it { is_expected.to eq 'png (Portable Network Graphics)' }
89
+ end
90
+
91
+ context 'when just mime type is present' do
92
+ before do
93
+ allow(file_set).to receive(:mime_type).and_return('image/png')
94
+ allow(file_set).to receive(:format_label).and_return([])
95
+ end
96
+ it { is_expected.to eq 'png' }
97
+ end
98
+
99
+ context 'when just format_label is present' do
100
+ before do
101
+ allow(file_set).to receive(:mime_type).and_return('')
102
+ allow(file_set).to receive(:format_label).and_return(['Portable Network Graphics'])
103
+ end
104
+ it { is_expected.to eq ['Portable Network Graphics'] }
67
105
  end
68
106
  end
69
107
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe CurationConcerns::WorkIndexingService do
3
+ describe CurationConcerns::WorkIndexer do
4
4
  # TODO: file_set_ids returns an empty set unless you persist the work
5
5
  let(:user) { create(:user) }
6
6
  let!(:generic_work) { create(:work_with_one_file, user: user) }
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'MultiValueWithHelpInput', type: :input do
4
+ subject { input_for file, field, as: :multi_value_with_help, required: true }
5
+ let(:file) { FileSet.new }
6
+
7
+ context "when the field has a translation" do
8
+ let(:field) { :language }
9
+ before do
10
+ allow_any_instance_of(MultiValueWithHelpInput).to receive(:raw_label_text).and_return('Language')
11
+ allow_any_instance_of(MultiValueWithHelpInput).to receive(:translate_from_namespace).and_return('default translation')
12
+ allow_any_instance_of(MultiValueWithHelpInput).to receive(:translate_from_namespace).with(:metadata_help).and_return(
13
+ 'The language of the file content.'
14
+ )
15
+ end
16
+
17
+ it 'renders help icon' do
18
+ expect(subject).to have_selector('a[data-toggle=popover][data-original-title=Language]')
19
+ expect(subject).to have_selector('a[data-toggle=popover][data-content="The language of the file content."]')
20
+ expect(subject).to have_selector('i.help-icon')
21
+ end
22
+ end
23
+
24
+ context "when the field doesn't have a translation" do
25
+ let(:field) { :date_modified }
26
+ it 'renders help icon' do
27
+ expect(subject).to have_selector('a[data-toggle=popover][data-original-title="Date modified"]')
28
+ expect(subject).to have_selector('a[data-toggle=popover][data-content="Date modified"]')
29
+ expect(subject).to have_selector('i.help-icon')
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'SelectWithHelpInput', type: :input do
4
+ subject { input_for form, :resource_type, options }
5
+ let(:file) { FileSet.new }
6
+ let(:form_class) do
7
+ Class.new do
8
+ include HydraEditor::Form
9
+ self.model_class = FileSet
10
+ self.terms = [:resource_type]
11
+ end
12
+ end
13
+ let(:form) { form_class.new(FileSet.new) }
14
+ let(:collection) { CurationConcerns.config.resource_types }
15
+ let(:base_options) do
16
+ { as: :select_with_help, collection: collection,
17
+ input_html: { class: 'form-control', multiple: true } }
18
+ end
19
+ let(:options) { base_options }
20
+
21
+ it "does not be required by default" do
22
+ expect(subject).to have_selector 'select'
23
+ expect(subject).not_to match(/required/)
24
+ end
25
+
26
+ context 'with File Edit' do
27
+ let(:user) { create(:user) }
28
+ let(:file) { FileSet.create(label: 'f1') { |f| f.apply_depositor_metadata(user) } }
29
+ let(:form) { CurationConcerns::Forms::FileSetEditForm.new(file) }
30
+ let(:base_options) do
31
+ { as: :select_with_help, collection: collection,
32
+ input_html: { class: 'form-control', multiple: true } }
33
+ end
34
+ let(:options) { base_options }
35
+
36
+ subject { input_for form, :resource_type, options }
37
+
38
+ it "is not required by default" do
39
+ expect(subject).to have_selector 'select'
40
+ expect(subject).not_to match(/required/)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'SelectWithModalHelpInput', type: :input do
4
+ subject { input_for file, :rights, options }
5
+ let(:file) { FileSet.new }
6
+ let(:base_options) { { as: :select_with_modal_help, required: true, collection: RightsService.select_options } }
7
+ let(:options) { base_options }
8
+
9
+ context "when a blank is requested" do
10
+ let(:options) { base_options.merge(include_blank: true) }
11
+ it 'renders a blank option' do
12
+ expect(subject).to have_selector 'select option[value=""]'
13
+ end
14
+ end
15
+
16
+ context "when a blank is not requested" do
17
+ it 'has no blanks' do
18
+ expect(subject).to have_selector 'select option:first-child', text: 'Attribution 3.0 United States'
19
+ end
20
+ end
21
+ end
@@ -13,7 +13,6 @@ describe ImportUrlJob do
13
13
  end
14
14
 
15
15
  let(:file_set_id) { 'abc123' }
16
- let(:actor) { double }
17
16
 
18
17
  let(:mock_response) do
19
18
  double('response').tap do |http_res|
@@ -24,8 +23,10 @@ describe ImportUrlJob do
24
23
  end
25
24
 
26
25
  context 'after running the job' do
26
+ let(:actor) { double }
27
27
  before do
28
28
  allow(ActiveFedora::Base).to receive(:find).with(file_set_id).and_return(file_set)
29
+ allow(file_set).to receive(:reload)
29
30
  allow(CurationConcerns::FileSetActor).to receive(:new).with(file_set, user).and_return(actor)
30
31
  end
31
32
 
@@ -35,4 +36,35 @@ describe ImportUrlJob do
35
36
  described_class.perform_now(file_set_id)
36
37
  end
37
38
  end
39
+
40
+ context "when a batch update job is running too" do
41
+ let(:title) { { file_set.id => ['File One'] } }
42
+ let(:metadata) { {} }
43
+ let(:visibility) { nil }
44
+
45
+ let(:upload_set) { UploadSet.create }
46
+ let(:upload_set_job) { UploadSetUpdateJob.perform_now(user.user_key, upload_set.id, title, metadata, visibility) }
47
+ let(:file_set_id) { file_set.id }
48
+
49
+ before do
50
+ file_set.save!
51
+ allow(ActiveFedora::Base).to receive(:find).and_call_original
52
+ allow(ActiveFedora::Base).to receive(:find).with(file_set_id).and_return(file_set)
53
+ allow_any_instance_of(CurationConcerns::FileSetActor).to receive(:create_content)
54
+ allow_any_instance_of(Ability).to receive(:can?).and_return(true)
55
+ expect_any_instance_of(Net::HTTP).to receive(:request_get).with(file_hash).and_yield(mock_response)
56
+ end
57
+
58
+ it "does not kill all the metadata set by other processes" do
59
+ # run the batch job to set the title
60
+ file_set.update(title: ['File One'])
61
+
62
+ # run the import job
63
+ described_class.perform_now(file_set_id)
64
+
65
+ # import job should not override the title set another process
66
+ file = FileSet.find(file_set_id)
67
+ expect(file.title).to eq(['File One'])
68
+ end
69
+ end
38
70
  end
@@ -3,24 +3,34 @@ require 'spec_helper'
3
3
  describe IngestFileJob do
4
4
  let(:file_set) { create(:file_set) }
5
5
  let(:filename) { fixture_file_path('/world.png') }
6
+ let(:user) { create(:user) }
6
7
 
7
- it 'uses the provided mime_type' do
8
- described_class.perform_now(file_set.id, filename, 'image/png', 'bob')
9
- expect(file_set.reload.original_file.mime_type).to eq 'image/png'
8
+ context 'when givin a mime_type' do
9
+ it 'uses a provided mime_type' do
10
+ described_class.perform_now(file_set.id, filename, 'image/png', 'bob')
11
+ expect(file_set.reload.original_file.mime_type).to eq 'image/png'
12
+ end
10
13
  end
11
14
 
12
- context 'with two existing versions from different users' do
13
- let(:file1) { fixture_file_path 'world.png' }
14
- let(:file2) { fixture_file_path 'small_file.txt' }
15
- let(:actor1) { described_class.new(file_set, user) }
16
- let(:actor2) { described_class.new(file_set, second_user) }
15
+ context 'when not given a mime_type' do
16
+ it 'does not decorate File when not given mime_type' do
17
+ # Mocking CC Versioning here as it will be the versioning machinery called by the job.
18
+ # The parameter versioning: false instructs the machinery in Hydra::Works NOT to do versioning. So it can be handled later on.
19
+ allow(CurationConcerns::VersioningService).to receive(:create)
20
+ expect(Hydra::Works::AddFileToFileSet).to receive(:call).with(file_set, instance_of(::File), :original_file, versioning: false)
21
+ described_class.perform_now(file_set.id, filename, nil, 'bob')
22
+ end
23
+ end
17
24
 
18
- let(:second_user) { create(:user) }
25
+ context 'with two existing versions from different users' do
26
+ let(:file1) { fixture_file_path 'world.png' }
27
+ let(:file2) { fixture_file_path 'small_file.txt' }
19
28
  let(:versions) { file_set.reload.original_file.versions }
29
+ let(:user2) { create(:user) }
20
30
 
21
31
  before do
22
- described_class.perform_now(file_set.id, file1, 'image/png', 'bob')
23
- described_class.perform_now(file_set.id, file2, 'text/plain', 'bess')
32
+ described_class.perform_now(file_set.id, file1, 'image/png', user.user_key)
33
+ described_class.perform_now(file_set.id, file2, 'text/plain', user2.user_key)
24
34
  end
25
35
 
26
36
  it 'has two versions' do
@@ -33,13 +43,16 @@ describe IngestFileJob do
33
43
  expect(file_set.original_file.original_name).to eq 'small_file.txt'
34
44
 
35
45
  # the user for each version
36
- expect(VersionCommitter.where(version_id: versions.first.uri).pluck(:committer_login)).to eq ['bob']
37
- expect(VersionCommitter.where(version_id: versions.last.uri).pluck(:committer_login)).to eq ['bess']
46
+ expect(VersionCommitter.where(version_id: versions.first.uri).pluck(:committer_login)).to eq [user.user_key]
47
+ expect(VersionCommitter.where(version_id: versions.last.uri).pluck(:committer_login)).to eq [user2.user_key]
38
48
  end
39
49
  end
40
50
 
41
- it 'runs the after_create_content callback with file_set and user arguments' do
42
- expect(CurationConcerns.config.callback).to receive(:run).with(:after_create_content, file_set, 'bob').exactly(1).times
43
- described_class.perform_now(file_set.id, filename, 'image/png', 'bob')
51
+ describe "the after_create_contentcallback" do
52
+ subject { CurationConcerns.config.callback }
53
+ it 'runs with file_set and user arguments' do
54
+ expect(subject).to receive(:run).with(:after_create_content, file_set, user)
55
+ described_class.perform_now(file_set.id, filename, 'image/png', user.user_key)
56
+ end
44
57
  end
45
58
  end
@@ -4,27 +4,40 @@ describe UploadSetUpdateJob do
4
4
  let(:user) { create(:user) }
5
5
  let(:upload_set) { UploadSet.create }
6
6
 
7
- let!(:file) { create(:file_set, user: user, upload_set: upload_set) }
8
- let!(:file2) { create(:file_set, user: user, upload_set: upload_set) }
7
+ let(:work) { create(:work, user: user, upload_set: upload_set) }
8
+ let(:work2) { create(:work, user: user, upload_set: upload_set) }
9
+
10
+ before do
11
+ allow(CurationConcerns.config.callback).to receive(:run)
12
+ allow(CurationConcerns.config.callback).to receive(:set?)
13
+ .with(:after_upload_set_update_success)
14
+ .and_return(true)
15
+ allow(CurationConcerns.config.callback).to receive(:set?)
16
+ .with(:after_upload_set_update_failure)
17
+ .and_return(true)
18
+ end
9
19
 
10
20
  describe "#perform" do
11
- let(:title) { { file.id => ['File One'], file2.id => ['File Two'] } }
21
+ let(:title) { { work.id => ['File One'], work2.id => ['File Two'] } }
12
22
  let(:metadata) { { tag: [''] } }
13
23
  let(:visibility) { nil }
14
24
 
15
25
  subject { described_class.perform_now(user.user_key, upload_set.id, title, metadata, visibility) }
16
26
 
17
- it "updates file metadata" do
18
- expect(subject).to be true
19
- expect(file.reload.title).to eq ['File One']
27
+ it "updates work metadata" do
28
+ expect(CurationConcerns.config.callback).to receive(:run).with(:after_upload_set_update_success, user, upload_set)
29
+ subject
30
+ expect(work.reload.title).to eq ['File One']
31
+ expect(work2.reload.title).to eq ['File Two']
20
32
  end
21
33
 
22
- context "when user does not have permission to edit all of the files" do
23
- before do
24
- expect_any_instance_of(User).to receive(:can?).with(:edit, file).and_return(true)
25
- expect_any_instance_of(User).to receive(:can?).with(:edit, file2).and_return(false)
34
+ context "when user does not have permission to edit all of the works" do
35
+ it "sends the failure message" do
36
+ expect_any_instance_of(User).to receive(:can?).with(:edit, work).and_return(true)
37
+ expect_any_instance_of(User).to receive(:can?).with(:edit, work2).and_return(false)
38
+ expect(CurationConcerns.config.callback).to receive(:run).with(:after_upload_set_update_failure, user, upload_set)
39
+ subject
26
40
  end
27
- it { is_expected.to be false }
28
41
  end
29
42
  end
30
43
  end
@@ -41,7 +41,7 @@ describe CurationConcerns::Messages do
41
41
  it 'renders a success message for multiple files' do
42
42
  node = Capybara::Node::Simple.new(message.multiple_success(upload_set_id, multiple))
43
43
  expect(node).to have_selector("span[id=\"ss-1\"]", text: 'These files have been saved.')
44
- expect(node).to have_selector("a[data-content=\"#{file_list}\"][rel=\"popover\"][data-title=\"Files uploaded successfully\"]")
44
+ expect(node).to have_selector("a[data-content=\"#{file_list}\"][data-toggle=\"popover\"][data-title=\"Files uploaded successfully\"]")
45
45
  end
46
46
  end
47
47
 
@@ -57,7 +57,7 @@ describe CurationConcerns::Messages do
57
57
  it 'renders a failure message for multiple files' do
58
58
  node = Capybara::Node::Simple.new(message.multiple_failure(upload_set_id, multiple))
59
59
  expect(node).to have_selector("span[id=\"ss-1\"]", text: 'These files could not be updated. You do not have sufficient privileges to edit them.')
60
- expect(node).to have_selector("a[data-content=\"#{file_list}\"][rel=\"popover\"][data-title=\"Files failed\"]")
60
+ expect(node).to have_selector("a[data-content=\"#{file_list}\"][data-toggle=\"popover\"][data-title=\"Files failed\"]")
61
61
  end
62
62
  end
63
63
 
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::Name do
4
+ let(:name) { described_class.new(GenericWork) }
5
+
6
+ describe "route_key" do
7
+ subject { name.route_key }
8
+ it { is_expected.to eq 'curation_concerns_generic_works' }
9
+ end
10
+
11
+ describe "singular_route_key" do
12
+ subject { name.singular_route_key }
13
+ it { is_expected.to eq 'curation_concerns_generic_work' }
14
+ end
15
+
16
+ describe "param_key" do
17
+ subject { name.param_key }
18
+ it { is_expected.to eq 'generic_work' }
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::NullLogger do
4
+ subject { described_class.new }
5
+ its(:debug) { is_expected.to be_nil }
6
+ its(:info) { is_expected.to be_nil }
7
+ its(:warn) { is_expected.to be_nil }
8
+ its(:error) { is_expected.to be_nil }
9
+ its(:fatal) { is_expected.to be_nil }
10
+ end
@@ -17,19 +17,49 @@ describe CurationConcerns::CollectionBehavior do
17
17
  it { is_expected.to eq CurationConcerns::CollectionIndexer }
18
18
  end
19
19
 
20
- describe '::bytes' do
20
+ describe '.bytes' do
21
21
  subject { collection.bytes }
22
22
 
23
23
  context 'with no items' do
24
24
  before { collection.save }
25
- it { is_expected.to eq 0 }
25
+ it "gets zero without querying solr" do
26
+ expect(ActiveFedora::SolrService).not_to receive(:query)
27
+ is_expected.to eq 0
28
+ end
26
29
  end
27
30
 
28
- context 'with two 50 byte files' do
29
- let(:bitstream) { double('content', size: '50') }
30
- let(:file) { mock_model ::FileSet, content: bitstream }
31
- before { allow(collection).to receive(:members).and_return([file, file]) }
32
- it { is_expected.to eq 100 }
31
+ # Calculating the size of the Collection should only hit Solr.
32
+ # This base case querries solr in an integration test
33
+ context 'with indexed Works and FileSets', :integration do
34
+ let(:file1) { FactoryGirl.build(:file_set, file_size: ['100']) }
35
+ let(:file2) { FactoryGirl.build(:file_set, file_size: ['100']) }
36
+ let(:file3) { FactoryGirl.build(:file_set, file_size: ['9000'], id: 'fumid') }
37
+ let(:work1) { FactoryGirl.build(:generic_work) }
38
+ let(:work2) { FactoryGirl.build(:generic_work) }
39
+ let(:work3) { FactoryGirl.build(:generic_work, id: 'dumid') }
40
+ before do
41
+ # Save collection to get ids
42
+ collection.save
43
+ # Create relationships so member_ids are created
44
+ collection.members = [work1, work2]
45
+ work1.members = [file1]
46
+ work2.members = [file2]
47
+ # Create a relatinship not in the collection.
48
+ work3.members = [file3]
49
+
50
+ # Manually Call Indexing to put the data in Solr
51
+ ActiveFedora::SolrService.add(collection.to_solr)
52
+ ActiveFedora::SolrService.add(work1.to_solr, softCommit: true)
53
+ ActiveFedora::SolrService.add(work2.to_solr, softCommit: true)
54
+ ActiveFedora::SolrService.add(work3.to_solr, softCommit: true)
55
+ ActiveFedora::SolrService.add(file1.to_solr, softCommit: true)
56
+ ActiveFedora::SolrService.add(file2.to_solr, softCommit: true)
57
+ ActiveFedora::SolrService.add(file3.to_solr, softCommit: true)
58
+ end
59
+
60
+ it "is the correct aggregate size" do
61
+ is_expected.to eq 200
62
+ end
33
63
  end
34
64
  end
35
65
 
@@ -46,7 +76,7 @@ describe CurationConcerns::CollectionBehavior do
46
76
  end
47
77
 
48
78
  context 'with itself' do
49
- it 'does not add it to the collection\'s members' do
79
+ it 'does not add it to the collection members' do
50
80
  expect do
51
81
  subject.add_member(subject)
52
82
  end.to_not change { subject.members.size }
@@ -75,7 +105,7 @@ describe CurationConcerns::CollectionBehavior do
75
105
  end
76
106
  end
77
107
 
78
- context 'is a pcdm:Collection instance' do
108
+ describe 'intrinsic properties' do
79
109
  let(:collection1) { FactoryGirl.build(:collection) }
80
110
  let(:work1) { FactoryGirl.build(:work) }
81
111
 
@@ -83,7 +113,8 @@ describe CurationConcerns::CollectionBehavior do
83
113
  expect(subject.pcdm_collection?).to be true
84
114
  expect(subject.type).to include Hydra::PCDM::Vocab::PCDMTerms.Collection
85
115
  end
86
- it 'does not be a pcdm:Object' do
116
+
117
+ it 'is not a pcdm:Object' do
87
118
  expect(subject.pcdm_object?).to be false
88
119
  expect(subject.type).to_not include Hydra::PCDM::Vocab::PCDMTerms.Object
89
120
  end
@@ -4,7 +4,6 @@ describe CurationConcerns::WorkBehavior do
4
4
  before do
5
5
  class EssentialWork < ActiveFedora::Base
6
6
  include CurationConcerns::WorkBehavior
7
- include CurationConcerns::BasicMetadata
8
7
  end
9
8
  end
10
9
  after do
@@ -23,19 +22,8 @@ describe CurationConcerns::WorkBehavior do
23
22
  subject.title = %w(Hello World)
24
23
  expect(subject.to_s).to eq('Hello | World')
25
24
  end
26
-
27
- it 'falls back on label if no titles are given' do
28
- subject.title = []
29
- subject.label = 'Spam'
30
- expect(subject.to_s).to eq('Spam')
31
- end
32
-
33
- it 'with no label or titles it is "No Title"' do
34
- subject.title = []
35
- subject.label = nil
36
- expect(subject.to_s).to eq('No Title')
37
- end
38
25
  end
26
+
39
27
  describe 'human_readable_type' do
40
28
  it 'has a default' do
41
29
  expect(subject.human_readable_type).to eq 'Essential Work'
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  # It includes the CurationConcerns::FileSetBehavior module and nothing else
5
5
  # So this test covers both the FileSetBehavior module and the generated FileSet model
6
6
  describe FileSet do
7
- let(:user) { FactoryGirl.find_or_create(:jill) }
7
+ let(:user) { create(:user) }
8
8
 
9
9
  describe 'rdf type' do
10
10
  subject { described_class.new.type }
@@ -147,7 +147,7 @@ describe FileSet do
147
147
 
148
148
  describe '#indexer' do
149
149
  subject { described_class.indexer }
150
- it { is_expected.to eq CurationConcerns::FileSetIndexingService }
150
+ it { is_expected.to eq CurationConcerns::FileSetIndexer }
151
151
  end
152
152
 
153
153
  it 'supports multi-valued fields in solr' do
@@ -361,10 +361,25 @@ describe FileSet do
361
361
  end
362
362
  end
363
363
 
364
+ describe '#where_digest_is' do
365
+ let(:file) { create(:file_set) }
366
+ let(:file_path) { fixture_path + '/small_file.txt' }
367
+ let(:digest_string) { '88fb4e88c15682c18e8b19b8a7b6eaf8770d33cf' }
368
+ before do
369
+ allow(file).to receive(:warn) # suppress virus warnings
370
+ of = file.build_original_file
371
+ of.content = File.open(file_path)
372
+ file.save
373
+ file.update_index
374
+ end
375
+ subject { described_class.where_digest_is(digest_string).first }
376
+ it { is_expected.to eq(file) }
377
+ end
378
+
364
379
  describe 'to_solr' do
365
380
  let(:indexer) { double(generate_solr_document: {}) }
366
381
  before do
367
- allow(CurationConcerns::FileSetIndexingService).to receive(:new)
382
+ allow(CurationConcerns::FileSetIndexer).to receive(:new)
368
383
  .with(subject).and_return(indexer)
369
384
  end
370
385
 
@@ -374,7 +389,7 @@ describe FileSet do
374
389
  end
375
390
 
376
391
  it 'has human readable type' do
377
- expect(subject.to_solr.fetch('human_readable_type_tesim')).to eq 'File Set'
392
+ expect(subject.to_solr.fetch('human_readable_type_tesim')).to eq 'File'
378
393
  end
379
394
  end
380
395
 
@@ -9,6 +9,11 @@ describe GenericWork do
9
9
  expect(subject.title).to eq ['foo']
10
10
  end
11
11
 
12
+ describe '.model_name' do
13
+ subject { described_class.model_name.singular_route_key }
14
+ it { is_expected.to eq 'curation_concerns_generic_work' }
15
+ end
16
+
12
17
  context 'with attached files' do
13
18
  subject { FactoryGirl.create(:work_with_files) }
14
19
 
@@ -20,7 +25,7 @@ describe GenericWork do
20
25
 
21
26
  describe '#indexer' do
22
27
  subject { described_class.indexer }
23
- it { is_expected.to eq CurationConcerns::WorkIndexingService }
28
+ it { is_expected.to eq CurationConcerns::WorkIndexer }
24
29
  end
25
30
 
26
31
  describe 'to_solr' do
@@ -39,6 +44,6 @@ describe GenericWork do
39
44
  describe '#to_partial_path' do
40
45
  let(:work) { described_class.new }
41
46
  subject { work.to_partial_path }
42
- it { is_expected.to eq 'curation_concerns/generic_works/generic_work' }
47
+ it { is_expected.to eq 'generic_works/generic_work' }
43
48
  end
44
49
  end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::QuickClassificationQuery do
4
+ let(:user) { create(:user) }
5
+
6
+ context "with no options" do
7
+ let(:query) { described_class.new(user) }
8
+ describe "#all?" do
9
+ subject { query.all? }
10
+ it { is_expected.to be true }
11
+ end
12
+
13
+ describe '#each' do
14
+ let(:thing) { double }
15
+ before do
16
+ # Ensure that no other test has altered the configuration:
17
+ allow(CurationConcerns.config).to receive(:registered_curation_concern_types).and_return(['GenericWork'])
18
+ end
19
+ it "calls the block once for every model" do
20
+ expect(thing).to receive(:test).with(GenericWork)
21
+ query.each do |f|
22
+ thing.test(f)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ context "with models" do
29
+ let(:query) { described_class.new(user, models: ['dataset']) }
30
+ describe "#all?" do
31
+ subject { query.all? }
32
+ it { is_expected.to be false }
33
+ end
34
+ end
35
+ end