sufia 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.rubocop.yml +10 -0
  4. data/Gemfile +16 -7
  5. data/History.md +43 -0
  6. data/README.md +26 -19
  7. data/SUFIA_VERSION +1 -1
  8. data/app/assets/javascripts/notifications_check.js.erb +46 -0
  9. data/app/assets/javascripts/sufia.js +1 -2
  10. data/app/assets/javascripts/sufia/uploader.js +3 -3
  11. data/app/assets/stylesheets/sufia/_collections.scss +5 -0
  12. data/app/assets/stylesheets/sufia/_dashboard.scss +6 -1
  13. data/app/assets/stylesheets/sufia/_file-listing.scss +44 -6
  14. data/app/assets/stylesheets/sufia/_file-show.scss +4 -0
  15. data/app/assets/stylesheets/sufia/_settings.scss +3 -0
  16. data/app/controllers/api/items_controller.rb +7 -3
  17. data/app/controllers/concerns/sufia/admin/depositor_stats.rb +1 -1
  18. data/app/controllers/concerns/sufia/admin/stats_behavior.rb +6 -76
  19. data/app/controllers/concerns/sufia/batch_controller_behavior.rb +10 -2
  20. data/app/controllers/concerns/sufia/contact_form_controller_behavior.rb +1 -0
  21. data/app/controllers/concerns/sufia/files_controller_behavior.rb +11 -1
  22. data/app/controllers/concerns/sufia/homepage_controller.rb +1 -1
  23. data/app/controllers/concerns/sufia/my_controller_behavior.rb +2 -0
  24. data/app/controllers/concerns/sufia/users_controller_behavior.rb +2 -2
  25. data/app/helpers/generic_file_helper.rb +8 -5
  26. data/app/jobs/content_delete_event_job.rb +16 -11
  27. data/app/jobs/content_deposit_event_job.rb +4 -16
  28. data/app/jobs/content_depositor_change_event_job.rb +32 -20
  29. data/app/jobs/content_event_job.rb +39 -0
  30. data/app/jobs/content_new_version_event_job.rb +4 -16
  31. data/app/jobs/content_restored_version_event_job.rb +6 -19
  32. data/app/jobs/content_update_event_job.rb +4 -16
  33. data/app/jobs/event_job.rb +48 -4
  34. data/app/jobs/user_edit_profile_event_job.rb +4 -17
  35. data/app/jobs/user_follow_event_job.rb +10 -12
  36. data/app/jobs/user_unfollow_event_job.rb +10 -15
  37. data/app/models/concerns/sufia/solr_document_behavior.rb +11 -1
  38. data/app/models/system_stats.rb +108 -0
  39. data/app/presenters/sufia/admin_stats_presenter.rb +49 -0
  40. data/app/views/_controls.html.erb +1 -1
  41. data/app/views/_footer.html.erb +1 -1
  42. data/app/views/_logo.html.erb +1 -3
  43. data/app/views/admin/stats/_date_form.html.erb +8 -0
  44. data/app/views/admin/stats/_deposits.html.erb +2 -10
  45. data/app/views/admin/stats/_files.html.erb +6 -14
  46. data/app/views/admin/stats/_new_users.html.erb +7 -14
  47. data/app/views/admin/stats/_stats_by_date.html.erb +8 -0
  48. data/app/views/admin/stats/_top_data.html.erb +24 -0
  49. data/app/views/admin/stats/index.html.erb +5 -31
  50. data/app/views/collections/_form_for_select_collection.html.erb +5 -4
  51. data/app/views/collections/_show_actions.html.erb +7 -2
  52. data/app/views/collections/_show_document_list_row.html.erb +1 -9
  53. data/app/views/generic_files/_browse_everything.html.erb +3 -0
  54. data/app/views/generic_files/_descriptions.html.erb +1 -1
  55. data/app/views/generic_files/_generic_file.html.erb +1 -1
  56. data/app/views/generic_files/_local_file_import.html.erb +3 -0
  57. data/app/views/generic_files/_show_actions.html.erb +4 -0
  58. data/app/views/generic_files/upload/_form.html.erb +3 -0
  59. data/app/views/generic_files/upload/_to_collection.html.erb +5 -0
  60. data/app/views/homepage/_recent_document.html.erb +1 -7
  61. data/app/views/my/_index_partials/_default_group.html.erb +1 -1
  62. data/app/views/my/_index_partials/_list_collections.html.erb +3 -10
  63. data/app/views/my/_index_partials/_list_files.html.erb +13 -22
  64. data/app/views/my/_sort_and_per_page.html.erb +3 -3
  65. data/app/views/records/edit_fields/_rights.html.erb +2 -1
  66. data/app/views/static/terms.html.erb +1 -1
  67. data/config/locales/sufia.en.yml +13 -0
  68. data/lib/generators/sufia/templates/catalog_controller.rb +2 -2
  69. data/lib/sufia/version.rb +1 -1
  70. data/spec/actors/generic_file/actor_spec.rb +35 -0
  71. data/spec/controllers/admin_stats_controller_spec.rb +53 -23
  72. data/spec/controllers/api/items_controller_spec.rb +47 -41
  73. data/spec/controllers/batch_controller_spec.rb +1 -0
  74. data/spec/controllers/generic_files_controller_spec.rb +35 -1
  75. data/spec/controllers/my/files_controller_spec.rb +5 -0
  76. data/spec/factories/generic_files.rb +3 -0
  77. data/spec/features/collection_spec.rb +91 -0
  78. data/spec/features/contact_form_spec.rb +1 -0
  79. data/spec/forms/collection_edit_form_spec.rb +3 -3
  80. data/spec/forms/generic_file_edit_form_spec.rb +1 -1
  81. data/spec/jobs/create_derivatives_job_spec.rb +6 -0
  82. data/spec/models/file_content_datastream_spec.rb +1 -1
  83. data/spec/models/file_download_stat_spec.rb +4 -4
  84. data/spec/models/file_usage_spec.rb +2 -2
  85. data/spec/models/file_view_stat_spec.rb +4 -4
  86. data/spec/models/generic_file_spec.rb +15 -3
  87. data/spec/models/geo_names_resource_spec.rb +10 -0
  88. data/spec/models/solr_document_spec.rb +28 -0
  89. data/spec/models/system_stats_spec.rb +184 -0
  90. data/spec/models/user_spec.rb +1 -1
  91. data/spec/models/user_usage_stats_spec.rb +1 -1
  92. data/spec/services/generic_file_csv_service_spec.rb +66 -0
  93. data/spec/services/generic_file_indexing_service_spec.rb +35 -0
  94. data/spec/services/lock_manager_spec.rb +12 -0
  95. data/spec/spec_helper.rb +2 -1
  96. data/spec/views/admin/stats/index.html.erb_spec.rb +11 -10
  97. data/spec/views/catalog/sort_and_per_page.html.erb_spec.rb +1 -1
  98. data/spec/views/collections/_form_for_select_collection.html.erb_spec.rb +51 -0
  99. data/spec/views/generic_file/_browse_everything.html.erb_spec.rb +4 -0
  100. data/spec/views/generic_file/edit.html.erb_spec.rb +31 -24
  101. data/spec/views/generic_file/new.html.erb_spec.rb +70 -0
  102. data/spec/views/generic_file/show.html.erb_spec.rb +23 -0
  103. data/sufia.gemspec +3 -2
  104. data/tasks/sufia-dev.rake +2 -0
  105. metadata +42 -9
  106. data/lib/sufia/role_mapper.rb +0 -7
@@ -17,6 +17,7 @@ describe BatchController do
17
17
  it "is successful" do
18
18
  expect(Sufia.queue).to receive(:push).with(batch_update_message).once
19
19
  post :update, id: batch.id, title: { '1' => 'foo' }, visibility: 'open', generic_file: { tag: [""] }
20
+ expect(assigns(:batch_update_job)).to eq(batch_update_message)
20
21
  expect(response).to redirect_to routes.url_helpers.dashboard_files_path
21
22
  expect(flash[:notice]).to include("Your files are being processed")
22
23
  end
@@ -15,6 +15,14 @@ describe GenericFilesController do
15
15
  let(:mock) { GenericFile.new(id: 'test123') }
16
16
  let(:batch) { Batch.create }
17
17
  let(:batch_id) { batch.id }
18
+ let(:collection) {
19
+ Collection.create(title: 'test collection') do |c|
20
+ c.apply_depositor_metadata(user.user_key)
21
+ end
22
+ }
23
+ let(:collection_id) { collection.id }
24
+ let(:collection_noedit) { Collection.create(title: 'test collection - NO EDIT') }
25
+ let(:collection_noedit_id) { collection_noedit.id }
18
26
  let(:file) { fixture_file_upload('/world.png', 'image/png') }
19
27
 
20
28
  before do
@@ -39,10 +47,22 @@ describe GenericFilesController do
39
47
  end
40
48
  end
41
49
 
50
+ context "when user tries to upload to a collection they can't edit" do
51
+ # This shouldn't happen via the UI which will only present to the user collections they can edit.
52
+ it "adds new file but does not put the file in the collection" do
53
+ xhr :post, :create, files: [file], Filename: "The world", batch_id: batch_id, permission: { "group" => { "public" => "read" } }, terms_of_service: "1", collection: collection_noedit_id
54
+ expect(response).to be_success
55
+
56
+ updated_collection = Collection.find(collection_id)
57
+ # This is confirming that the file was NOT added to the collection the user cannot edit
58
+ expect(updated_collection.member_ids).to eq []
59
+ end
60
+ end
61
+
42
62
  context "when everything is perfect" do
43
63
  render_views
44
64
  it "spawns a content deposit event job" do
45
- expect_any_instance_of(Sufia::GenericFile::Actor).to receive(:create_content).with(file, 'world.png', 'content', 'image/png').and_return(true)
65
+ expect_any_instance_of(Sufia::GenericFile::Actor).to receive(:create_content).with(file, 'world.png', 'content', 'image/png', nil).and_return(true)
46
66
  xhr :post, :create, files: [file], 'Filename' => 'The world', batch_id: batch_id, permission: { group: { public: 'read' } }, terms_of_service: '1'
47
67
  expect(response.body).to eq '[{"name":null,"size":null,"url":"/files/test123","thumbnail_url":"test123","delete_url":"deleteme","delete_type":"DELETE"}]'
48
68
  expect(flash[:error]).to be_nil
@@ -82,6 +102,20 @@ describe GenericFilesController do
82
102
  expect(saved_file.depositor).to eq 'jilluser@example.com'
83
103
  expect(saved_file.to_solr['depositor_tesim']).to eq ['jilluser@example.com']
84
104
  end
105
+
106
+ it "adds new file when collection is instructions id" do
107
+ xhr :post, :create, files: [file], Filename: "The world", batch_id: batch_id, permission: { "group" => { "public" => "read" } }, terms_of_service: "1", collection: '-1'
108
+ expect(response).to be_success
109
+ end
110
+
111
+ it "adds new file to collection" do
112
+ xhr :post, :create, files: [file], Filename: "The world", batch_id: batch_id, permission: { "group" => { "public" => "read" } }, terms_of_service: "1", collection: collection_id
113
+ expect(response).to be_success
114
+
115
+ updated_collection = Collection.find(collection_id)
116
+ # This is confirming that the file was added to the collection
117
+ expect(updated_collection.member_ids).to eq ['test123']
118
+ end
85
119
  end
86
120
 
87
121
  context "when the file has a virus" do
@@ -87,4 +87,9 @@ describe My::FilesController, type: :controller do
87
87
  expect(assigns(:batches)).to include("ss-" + batch_id2)
88
88
  end
89
89
  end
90
+
91
+ it "sets add_files_to_collection when provided in params" do
92
+ get :index, add_files_to_collection: '12345'
93
+ expect(assigns(:add_files_to_collection)).to eql('12345')
94
+ end
90
95
  end
@@ -25,6 +25,7 @@ FactoryGirl.define do
25
25
  resource_type ["Dissertation"]
26
26
  subject %w(lorem ipsum dolor sit amet)
27
27
  title ["fake_document.pdf"]
28
+ mime_type 'application/pdf'
28
29
  before(:create) do |gf|
29
30
  gf.title = ["Fake PDF Title"]
30
31
  end
@@ -36,6 +37,7 @@ FactoryGirl.define do
36
37
  initialize_with { new(id: id) }
37
38
  subject %w(consectetur adipisicing elit)
38
39
  title ["Test Document MP3.mp3"]
40
+ mime_type 'audio/mpeg'
39
41
  read_groups ["public"]
40
42
  end
41
43
  factory :public_wav do
@@ -46,6 +48,7 @@ FactoryGirl.define do
46
48
  resource_type ["Audio", "Dataset"]
47
49
  read_groups ["public"]
48
50
  title ["Fake Wav File.wav"]
51
+ mime_type 'audio/wav'
49
52
  subject %w(sed do eiusmod tempor incididunt ut labore)
50
53
  end
51
54
  end
@@ -25,6 +25,15 @@ describe 'collection', type: :feature do
25
25
  let(:title2) { "Test Collection 2" }
26
26
  let(:description2) { "Description for collection 2 we are testing." }
27
27
 
28
+ let(:collection1) do
29
+ Collection.create(title: title1, description: description1,
30
+ members: []) { |c| c.apply_depositor_metadata(user.user_key) }
31
+ end
32
+ let(:collection2) do
33
+ Collection.create(title: title2, description: description2,
34
+ members: []) { |c| c.apply_depositor_metadata(user.user_key) }
35
+ end
36
+
28
37
  let(:user) { FactoryGirl.create(:user) }
29
38
 
30
39
  let(:gfs) do
@@ -140,6 +149,88 @@ describe 'collection', type: :feature do
140
149
  end
141
150
  end
142
151
 
152
+ describe 'collection sorting' do
153
+ before do
154
+ collection1 # create the collections by referencing them
155
+ sleep(1) # make sure the timestamps aren't equal
156
+ collection2
157
+ sleep(1)
158
+ collection1.title += 'changed'
159
+ collection1.save
160
+ # collection 1 is now earlier when sorting by create date but later
161
+ # when sorting by modified date
162
+
163
+ sign_in user
164
+ visit '/dashboard/collections'
165
+ end
166
+
167
+ it "has creation date for collections" do
168
+ expect(page).to have_content(collection1.create_date.to_date.to_formatted_s(:standard))
169
+ end
170
+
171
+ it "allows changing sort order" do
172
+ find(:xpath, "//select[@id='sort']/option[contains(., 'date modified')][contains(@value, 'asc')]") \
173
+ .select_option
174
+ click_button('Refresh')
175
+ expect(page).to have_css("#document_#{collection1.id}")
176
+ expect(page).to have_css("#document_#{collection2.id}")
177
+ expect(page.body.index("id=\"document_#{collection1.id}")).to be > page.body.index("id=\"document_#{collection2.id}")
178
+
179
+ find(:xpath, "//select[@id='sort']/option[contains(., 'date modified')][contains(@value, 'desc')]") \
180
+ .select_option
181
+ click_button('Refresh')
182
+ expect(page).to have_css("#document_#{collection1.id}")
183
+ expect(page).to have_css("#document_#{collection2.id}")
184
+ expect(page.body.index("id=\"document_#{collection1.id}")).to be < page.body.index("id=\"document_#{collection2.id}")
185
+ end
186
+ end
187
+
188
+ describe 'add files to collection' do
189
+ let!(:gf1) { gfs[0] }
190
+ let!(:gf2) { gfs[1] }
191
+
192
+ before do
193
+ collection1 # create collections by referencing them
194
+ collection2
195
+ sign_in user
196
+ end
197
+
198
+ it "preselects the collection we are adding files to" do
199
+ visit "/collections/#{collection1.id}"
200
+ click_link 'Add files'
201
+ first('input#check_all').click
202
+ click_button "Add to Collection"
203
+ expect(page).to have_css("input#id_#{collection1.id}[checked='checked']")
204
+ expect(page).not_to have_css("input#id_#{collection2.id}[checked='checked']")
205
+
206
+ visit "/collections/#{collection2.id}"
207
+ click_link 'Add files'
208
+ first('input#check_all').click
209
+ click_button "Add to Collection"
210
+ expect(page).not_to have_css("input#id_#{collection1.id}[checked='checked']")
211
+ expect(page).to have_css("input#id_#{collection2.id}[checked='checked']")
212
+ end
213
+ end
214
+
215
+ describe 'upload files to collection' do
216
+ let(:upload_to_collection) { true }
217
+ let!(:gf1) { gfs[0] }
218
+ let!(:gf2) { gfs[1] }
219
+
220
+ before do
221
+ Sufia.config.upload_to_collection = upload_to_collection
222
+ collection1 # create collections by referencing them
223
+ collection2
224
+ sign_in user
225
+ end
226
+
227
+ it "preselects the collection we are uploading files to" do
228
+ visit "/collections/#{collection1.id}"
229
+ click_link 'Upload files'
230
+ expect(page).to have_select('collection', selected: title1)
231
+ end
232
+ end
233
+
143
234
  describe 'edit collection' do
144
235
  let!(:collection) do
145
236
  Collection.create(title: 'collection title', description: 'collection description',
@@ -17,6 +17,7 @@ describe "Sending an email via the contact form", type: :feature do
17
17
  select "Depositing content", from: "contact_form_category"
18
18
  click_button "Send"
19
19
  expect(page).to have_content "Thank you"
20
+ expect(page).not_to have_content "I am contacting you regarding ScholarSphere."
20
21
  # this step allows the delivery to go back to normal
21
22
  allow_any_instance_of(ContactForm).to receive(:deliver).and_call_original
22
23
  end
@@ -11,10 +11,10 @@ describe Sufia::Forms::CollectionEditForm do
11
11
  :identifier, :based_near, :related_url] }
12
12
  end
13
13
 
14
- describe "unique?" do
14
+ describe "multiple?" do
15
15
  context "with :title" do
16
- subject { described_class.unique?(:title) }
17
- it { is_expected.to be true }
16
+ subject { described_class.multiple?(:title) }
17
+ it { is_expected.to be false }
18
18
  end
19
19
  end
20
20
  end
@@ -23,7 +23,7 @@ describe Sufia::Forms::GenericFileEditForm do
23
23
  let(:params) { ActionController::Parameters.new(title: ['foo'], description: [''], "permissions_attributes" => { "2" => { "access" => "edit", "_destroy" => "true", "id" => "a987551e-b87f-427a-8721-3e5942273125" } }) }
24
24
  subject { described_class.model_attributes(params) }
25
25
 
26
- it "onlies change title" do
26
+ it "only changes title" do
27
27
  expect(subject['title']).to eq ["foo"]
28
28
  expect(subject['description']).to be_empty
29
29
  expect(subject['permissions_attributes']).to eq("2" => { "access" => "edit", "id" => "a987551e-b87f-427a-8721-3e5942273125", "_destroy" => "true" })
@@ -171,4 +171,10 @@ describe CreateDerivativesJob do
171
171
  end
172
172
  end
173
173
  end
174
+
175
+ describe 'minimagick setup' do
176
+ it 'uses posix-spawn' do
177
+ expect(MiniMagick.shell_api).to eq('posix-spawn')
178
+ end
179
+ end
174
180
  end
@@ -45,7 +45,7 @@ describe FileContentDatastream, type: :model do
45
45
  @generic_file.apply_depositor_metadata('mjg36')
46
46
  end
47
47
 
48
- it "onlies return true when the datastream has actually changed" do
48
+ it "only returns true when the datastream has actually changed" do
49
49
  @generic_file.add_file(File.open(fixture_path + '/world.png', 'rb'), path: 'content', original_name: 'world.png')
50
50
  expect(@generic_file.content).to be_changed
51
51
  @generic_file.save!
@@ -46,7 +46,7 @@ RSpec.describe FileDownloadStat, type: :model do
46
46
  describe "cache empty" do
47
47
  let(:stats) do
48
48
  expect(described_class).to receive(:ga_statistics).and_return(sample_download_statistics)
49
- described_class.statistics(file_id, Date.today - 4.day)
49
+ described_class.statistics(file_id, Date.today - 4.days)
50
50
  end
51
51
 
52
52
  it "includes cached ga data" do
@@ -59,17 +59,17 @@ RSpec.describe FileDownloadStat, type: :model do
59
59
  # at this point all data should be cached
60
60
  allow(described_class).to receive(:ga_statistics).with(Date.today, file_id).and_raise("We should not call Google Analytics All data should be cached!")
61
61
 
62
- stats2 = described_class.statistics(file_id, Date.today - 4.day)
62
+ stats2 = described_class.statistics(file_id, Date.today - 4.days)
63
63
  expect(described_class.to_flots stats2).to include(*download_output)
64
64
  end
65
65
  end
66
66
 
67
67
  describe "cache loaded" do
68
- let!(:file_download_stat) { described_class.create(date: (Date.today - 5.day).to_datetime, file_id: file_id, downloads: "25") }
68
+ let!(:file_download_stat) { described_class.create(date: (Date.today - 5.days).to_datetime, file_id: file_id, downloads: "25") }
69
69
 
70
70
  let(:stats) do
71
71
  expect(described_class).to receive(:ga_statistics).and_return(sample_download_statistics)
72
- described_class.statistics(file_id, Date.today - 5.day)
72
+ described_class.statistics(file_id, Date.today - 5.days)
73
73
  end
74
74
 
75
75
  it "includes cached data" do
@@ -55,7 +55,7 @@ describe FileUsage, type: :model do
55
55
  end
56
56
 
57
57
  let(:usage) do
58
- allow_any_instance_of(GenericFile).to receive(:create_date).and_return((Date.today - 4.day).to_s)
58
+ allow_any_instance_of(GenericFile).to receive(:create_date).and_return((Date.today - 4.days).to_s)
59
59
  expect(FileDownloadStat).to receive(:ga_statistics).and_return(sample_download_statistics)
60
60
  expect(FileViewStat).to receive(:ga_statistics).and_return(sample_pageview_statistics)
61
61
  described_class.new(file.id)
@@ -123,7 +123,7 @@ describe FileUsage, type: :model do
123
123
 
124
124
  describe "create date after earliest" do
125
125
  let(:usage) do
126
- allow_any_instance_of(GenericFile).to receive(:create_date).and_return((Date.today - 4.day).to_s)
126
+ allow_any_instance_of(GenericFile).to receive(:create_date).and_return((Date.today - 4.days).to_s)
127
127
  expect(FileDownloadStat).to receive(:ga_statistics).and_return(sample_download_statistics)
128
128
  expect(FileViewStat).to receive(:ga_statistics).and_return(sample_pageview_statistics)
129
129
  Sufia.config.analytic_start_date = earliest
@@ -47,7 +47,7 @@ RSpec.describe FileViewStat, type: :model do
47
47
  describe "cache empty" do
48
48
  let(:stats) do
49
49
  expect(described_class).to receive(:ga_statistics).and_return(sample_pageview_statistics)
50
- described_class.statistics(file_id, Date.today - 4.day, user_id)
50
+ described_class.statistics(file_id, Date.today - 4.days, user_id)
51
51
  end
52
52
 
53
53
  it "includes cached ga data" do
@@ -61,17 +61,17 @@ RSpec.describe FileViewStat, type: :model do
61
61
  # at this point all data should be cached
62
62
  allow(described_class).to receive(:ga_statistics).with(Date.today, file_id).and_raise("We should not call Google Analytics All data should be cached!")
63
63
 
64
- stats2 = described_class.statistics(file_id, Date.today - 5.day)
64
+ stats2 = described_class.statistics(file_id, Date.today - 5.days)
65
65
  expect(described_class.to_flots stats2).to include(*view_output)
66
66
  end
67
67
  end
68
68
 
69
69
  describe "cache loaded" do
70
- let!(:file_view_stat) { described_class.create(date: (Date.today - 5.day).to_datetime, file_id: file_id, views: "25") }
70
+ let!(:file_view_stat) { described_class.create(date: (Date.today - 5.days).to_datetime, file_id: file_id, views: "25") }
71
71
 
72
72
  let(:stats) do
73
73
  expect(described_class).to receive(:ga_statistics).and_return(sample_pageview_statistics)
74
- described_class.statistics(file_id, Date.today - 5.day)
74
+ described_class.statistics(file_id, Date.today - 5.days)
75
75
  end
76
76
 
77
77
  it "includes cached data" do
@@ -491,7 +491,7 @@ describe GenericFile, type: :model do
491
491
  expect(subject.edit_users).to eq ['jcoyne']
492
492
  end
493
493
 
494
- it "onlies revoke eligible groups" do
494
+ it "only revokes eligible groups" do
495
495
  subject.set_read_groups(['group-2', 'group-3'], ['group-6'])
496
496
  # 'group-7' is not eligible to be revoked
497
497
  expect(subject.read_groups).to match_array ['group-2', 'group-3', 'group-7']
@@ -643,7 +643,7 @@ describe GenericFile, type: :model do
643
643
  end
644
644
 
645
645
  context "with no end date" do
646
- let(:start_date) { 1.days.ago }
646
+ let(:start_date) { 1.day.ago }
647
647
  let(:end_date) { nil }
648
648
  before do
649
649
  @file.save
@@ -652,7 +652,7 @@ describe GenericFile, type: :model do
652
652
  end
653
653
 
654
654
  context "with an end date" do
655
- let(:start_date) { 1.days.ago }
655
+ let(:start_date) { 1.day.ago }
656
656
  let(:end_date) { DateTime.now }
657
657
  before do
658
658
  @file.save
@@ -661,6 +661,18 @@ describe GenericFile, type: :model do
661
661
  end
662
662
  end
663
663
 
664
+ describe '#where_digest_is' do
665
+ subject { described_class.where_digest_is digest_string }
666
+ let(:digest_string) { 'f794b23c0c6fe1083d0ca8b58261a078cd968967' }
667
+ before do
668
+ @file.add_file(File.open(fixture_path + '/world.png'), path: 'content', original_name: 'world.png')
669
+ @file.save
670
+ end
671
+ it 'returns a list of files' do
672
+ expect(subject).to eq [@file]
673
+ end
674
+ end
675
+
664
676
  describe "where_access_is" do
665
677
  subject { described_class.where_access_is access_level }
666
678
  before do
@@ -1,6 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe GeoNamesResource, type: :model do
4
+ before do
5
+ state = {
6
+ "totalResultsCount" => 1, "geonames" => [{
7
+ "countryId" => "1327865", "adminCode1" => "11", "countryName" => "Myanmar [Burma]", "fclName" => "country, state, region,...", "countryCode" => "MM", "lng" => "98", "fcodeName" => "first-order administrative division", "toponymName" => "Shan State", "fcl" => "A", "name" => "Shan State", "fcode" => "ADM1", "geonameId" => 1_297_099, "lat" => "22", "adminName1" => "Shan", "population" => 5_815_384
8
+ }]
9
+ }
10
+ ActiveResource::HttpMock.respond_to do |mock|
11
+ mock.get "/searchJSON?maxRows=10&q=State&username=", {}, state.to_json
12
+ end
13
+ end
4
14
  it "finds locations" do
5
15
  hits = described_class.find_location("State")
6
16
  expect(hits).not_to be_nil
@@ -8,6 +8,34 @@ describe SolrDocument, type: :model do
8
8
  it "is a date" do
9
9
  expect(subject.date_uploaded).to eq '03/14/2013'
10
10
  end
11
+ it "logs parse errors" do
12
+ expect(ActiveFedora::Base.logger).to receive(:info).with(/Unable to parse date.*/)
13
+ subject['date_uploaded_dtsi'] = 'Test'
14
+ subject.date_uploaded
15
+ end
16
+ end
17
+
18
+ describe "create_date" do
19
+ before do
20
+ subject['system_create_dtsi'] = '2013-03-14T00:00:00Z'
21
+ end
22
+ it "is a date" do
23
+ expect(subject.create_date).to eq '03/14/2013'
24
+ end
25
+ it "logs parse errors" do
26
+ expect(ActiveFedora::Base.logger).to receive(:info).with(/Unable to parse date.*/)
27
+ subject['system_create_dtsi'] = 'Test'
28
+ subject.create_date
29
+ end
30
+ end
31
+
32
+ describe "resource_type" do
33
+ before do
34
+ subject['resource_type_tesim'] = ['Image']
35
+ end
36
+ it "returns the resource type" do
37
+ expect(subject.resource_type).to eq ['Image']
38
+ end
11
39
  end
12
40
 
13
41
  describe '#to_param' do
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ describe ::SystemStats, type: :model do
4
+ let(:user1) { FactoryGirl.find_or_create(:user) }
5
+ let(:morning_two_days_ago) { 2.days.ago.to_date.to_datetime.to_s }
6
+ let(:yesterday) { 1.day.ago.to_datetime.to_s }
7
+ let(:this_morning) { 0.days.ago.to_date.to_datetime.to_s }
8
+
9
+ let(:stats) { described_class.new(depositor_count, user_stats[:start_date], user_stats[:end_date]) }
10
+
11
+ describe "#top_depositors" do
12
+ let(:user_stats) { {} }
13
+
14
+ context "when requested count is withing bounds" do
15
+ let!(:user2) { FactoryGirl.find_or_create(:archivist) }
16
+ let(:depositor_count) { 15 }
17
+
18
+ # I am specifically creating objects in this test
19
+ # I am doing this for one test to make sure that the full loop works
20
+ before do
21
+ GenericFile.new(id: "abc123") do |gf|
22
+ gf.apply_depositor_metadata(user1)
23
+ gf.update_index
24
+ end
25
+ GenericFile.new(id: "def123") do |gf|
26
+ gf.apply_depositor_metadata(user2)
27
+ gf.update_index
28
+ end
29
+ GenericFile.new(id: "zzz123") do |gf|
30
+ gf.create_date = [2.days.ago]
31
+ gf.apply_depositor_metadata(user1)
32
+ gf.update_index
33
+ end
34
+ Collection.new(id: "ccc123") do |c|
35
+ c.apply_depositor_metadata(user1)
36
+ c.update_index
37
+ end
38
+ end
39
+
40
+ it "queries for the data" do
41
+ expect(stats.top_depositors).to include(display_name(user1) => 3, display_name(user2) => 1)
42
+ end
43
+ end
44
+
45
+ context "when requested count is too small" do
46
+ let(:depositor_count) { 3 }
47
+ let(:actual_count) { 5 }
48
+ it "queries for 5 items" do
49
+ expect(stats).to receive(:open).with("http://127.0.0.1:8983/solr/test/terms?terms.fl=depositor_tesim&terms.sort=count&terms.limit=#{actual_count}&wt=json&omitHeader=true").and_return(StringIO.new('{"terms":{"depositor_tesim":["example.com",4,"user2",3,"archivist1",1]}}'))
50
+ stats.top_depositors
51
+ end
52
+ end
53
+
54
+ context "when requested count is too big" do
55
+ let(:depositor_count) { 99 }
56
+ let(:actual_count) { 20 }
57
+ it "queries for 20 items" do
58
+ expect(stats).to receive(:open).with("http://127.0.0.1:8983/solr/test/terms?terms.fl=depositor_tesim&terms.sort=count&terms.limit=#{actual_count}&wt=json&omitHeader=true").and_return(StringIO.new('{"terms":{"depositor_tesim":["example.com",4,"user2",3,"archivist1",1]}}'))
59
+ stats.top_depositors
60
+ end
61
+ end
62
+ end
63
+
64
+ def display_name(user)
65
+ user.user_key.split('@')[0]
66
+ end
67
+
68
+ describe "#document_by_permission" do
69
+ let(:user_stats) { {} }
70
+ let(:depositor_count) { nil }
71
+
72
+ before do
73
+ FactoryGirl.build(:public_pdf, depositor: user1, id: "pdf1223").update_index
74
+ FactoryGirl.build(:public_wav, depositor: user1, id: "wav1223").update_index
75
+ FactoryGirl.build(:public_mp3, depositor: user1, id: "mp31223", create_date: [2.days.ago]).update_index
76
+ FactoryGirl.build(:registered_file, depositor: user1, id: "reg1223").update_index
77
+ FactoryGirl.build(:generic_file, depositor: user1, id: "private1223").update_index
78
+ Collection.new(id: "ccc123") do |c|
79
+ c.apply_depositor_metadata(user1)
80
+ c.update_index
81
+ end
82
+ end
83
+ it "get all documents by permissions" do
84
+ expect(stats.document_by_permission).to include(public: 3, private: 1, registered: 1, total: 5)
85
+ end
86
+
87
+ context "when passing a start date" do
88
+ let(:user_stats) { { start_date: yesterday } }
89
+ it "get documents after date by permissions" do
90
+ expect(stats.document_by_permission).to include(public: 2, private: 1, registered: 1, total: 4)
91
+ end
92
+
93
+ context "when passing an end date" do
94
+ let(:user_stats) { { start_date: morning_two_days_ago, end_date: yesterday } }
95
+ it "get documents between dates by permissions" do
96
+ expect(stats.document_by_permission).to include(public: 1, private: 0, registered: 0, total: 1)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "#top_formats" do
103
+ let(:user_stats) { {} }
104
+ let(:depositor_count) { nil }
105
+
106
+ before do
107
+ FactoryGirl.build(:public_pdf, depositor: user1, id: "pdf1111").update_index
108
+ FactoryGirl.build(:public_wav, depositor: user1, id: "wav1111").update_index
109
+ FactoryGirl.build(:public_mp3, depositor: user1, id: "mp31111", create_date: [2.days.ago]).update_index
110
+ FactoryGirl.build(:registered_file, depositor: user1, id: "word1111", mime_type: "application/vnd.ms-word.document").update_index
111
+ end
112
+
113
+ subject { stats.top_formats }
114
+
115
+ it { is_expected.to include("mpeg" => 1, "pdf" => 1, "wav" => 1, "vnd.ms-word.document" => 1) }
116
+
117
+ context "when more than 5 formats available" do
118
+ before do
119
+ FactoryGirl.build(:public_pdf, depositor: user1, id: "pdf2222").update_index
120
+ FactoryGirl.build(:public_wav, depositor: user1, id: "wav2222").update_index
121
+ FactoryGirl.build(:public_mp3, depositor: user1, id: "mp32222", create_date: [2.days.ago]).update_index
122
+ FactoryGirl.build(:registered_file, depositor: user1, id: "reg2222", mime_type: "application/vnd.ms-word.document").update_index
123
+ FactoryGirl.build(:generic_file, depositor: user1, id: "png1111", mime_type: "image/png").update_index
124
+ FactoryGirl.build(:generic_file, depositor: user1, id: "png2222", mime_type: "image/png").update_index
125
+ FactoryGirl.build(:generic_file, depositor: user1, id: "jpeg2222", mime_type: "image/jpeg").update_index
126
+ end
127
+
128
+ it do
129
+ is_expected.to include("mpeg" => 2, "pdf" => 2, "wav" => 2, "vnd.ms-word.document" => 2, "png" => 2)
130
+ is_expected.not_to include("jpeg" => 1)
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "#recent_users" do
136
+ let!(:user2) { FactoryGirl.find_or_create(:archivist) }
137
+
138
+ let(:one_day_ago_date) { 1.day.ago.to_datetime }
139
+ let(:two_days_ago_date) { 2.days.ago.to_datetime.end_of_day }
140
+ let(:one_day_ago) { one_day_ago_date.strftime("%Y-%m-%d") }
141
+ let(:two_days_ago) { two_days_ago_date.strftime("%Y-%m-%d") }
142
+ let(:depositor_count) { nil }
143
+
144
+ subject { stats.recent_users }
145
+
146
+ context "without dates" do
147
+ let(:user_stats) { {} }
148
+ let(:mock_order) { double }
149
+ let(:mock_limit) { double }
150
+ it "defaults to latest 5 users" do
151
+ expect(mock_order).to receive(:limit).with(5).and_return(mock_limit)
152
+ expect(User).to receive(:order).with('created_at DESC').and_return(mock_order)
153
+ is_expected.to eq mock_limit
154
+ end
155
+ end
156
+
157
+ context "with start date" do
158
+ let(:user_stats) { { start_date: one_day_ago } }
159
+
160
+ it "allows queries against user_stats without an end date " do
161
+ expect(User).to receive(:recent_users).with(one_day_ago_date, nil).and_return([user2])
162
+ is_expected.to eq([user2])
163
+ end
164
+ end
165
+ context "with start date and end date" do
166
+ let(:user_stats) { { start_date: two_days_ago, end_date: one_day_ago } }
167
+ it "queries" do
168
+ expect(User).to receive(:recent_users).with(two_days_ago_date, one_day_ago_date).and_return([user2])
169
+ is_expected.to eq([user2])
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "#users_count" do
175
+ let(:user_stats) { {} }
176
+ let(:depositor_count) { nil }
177
+ let!(:user1) { FactoryGirl.find_or_create(:user) }
178
+ let!(:user2) { FactoryGirl.find_or_create(:archivist) }
179
+
180
+ subject { stats.users_count }
181
+
182
+ it { is_expected.to eq 2 }
183
+ end
184
+ end