sufia 6.3.0 → 6.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -2
- data/.rubocop.yml +10 -0
- data/Gemfile +16 -7
- data/History.md +43 -0
- data/README.md +26 -19
- data/SUFIA_VERSION +1 -1
- data/app/assets/javascripts/notifications_check.js.erb +46 -0
- data/app/assets/javascripts/sufia.js +1 -2
- data/app/assets/javascripts/sufia/uploader.js +3 -3
- data/app/assets/stylesheets/sufia/_collections.scss +5 -0
- data/app/assets/stylesheets/sufia/_dashboard.scss +6 -1
- data/app/assets/stylesheets/sufia/_file-listing.scss +44 -6
- data/app/assets/stylesheets/sufia/_file-show.scss +4 -0
- data/app/assets/stylesheets/sufia/_settings.scss +3 -0
- data/app/controllers/api/items_controller.rb +7 -3
- data/app/controllers/concerns/sufia/admin/depositor_stats.rb +1 -1
- data/app/controllers/concerns/sufia/admin/stats_behavior.rb +6 -76
- data/app/controllers/concerns/sufia/batch_controller_behavior.rb +10 -2
- data/app/controllers/concerns/sufia/contact_form_controller_behavior.rb +1 -0
- data/app/controllers/concerns/sufia/files_controller_behavior.rb +11 -1
- data/app/controllers/concerns/sufia/homepage_controller.rb +1 -1
- data/app/controllers/concerns/sufia/my_controller_behavior.rb +2 -0
- data/app/controllers/concerns/sufia/users_controller_behavior.rb +2 -2
- data/app/helpers/generic_file_helper.rb +8 -5
- data/app/jobs/content_delete_event_job.rb +16 -11
- data/app/jobs/content_deposit_event_job.rb +4 -16
- data/app/jobs/content_depositor_change_event_job.rb +32 -20
- data/app/jobs/content_event_job.rb +39 -0
- data/app/jobs/content_new_version_event_job.rb +4 -16
- data/app/jobs/content_restored_version_event_job.rb +6 -19
- data/app/jobs/content_update_event_job.rb +4 -16
- data/app/jobs/event_job.rb +48 -4
- data/app/jobs/user_edit_profile_event_job.rb +4 -17
- data/app/jobs/user_follow_event_job.rb +10 -12
- data/app/jobs/user_unfollow_event_job.rb +10 -15
- data/app/models/concerns/sufia/solr_document_behavior.rb +11 -1
- data/app/models/system_stats.rb +108 -0
- data/app/presenters/sufia/admin_stats_presenter.rb +49 -0
- data/app/views/_controls.html.erb +1 -1
- data/app/views/_footer.html.erb +1 -1
- data/app/views/_logo.html.erb +1 -3
- data/app/views/admin/stats/_date_form.html.erb +8 -0
- data/app/views/admin/stats/_deposits.html.erb +2 -10
- data/app/views/admin/stats/_files.html.erb +6 -14
- data/app/views/admin/stats/_new_users.html.erb +7 -14
- data/app/views/admin/stats/_stats_by_date.html.erb +8 -0
- data/app/views/admin/stats/_top_data.html.erb +24 -0
- data/app/views/admin/stats/index.html.erb +5 -31
- data/app/views/collections/_form_for_select_collection.html.erb +5 -4
- data/app/views/collections/_show_actions.html.erb +7 -2
- data/app/views/collections/_show_document_list_row.html.erb +1 -9
- data/app/views/generic_files/_browse_everything.html.erb +3 -0
- data/app/views/generic_files/_descriptions.html.erb +1 -1
- data/app/views/generic_files/_generic_file.html.erb +1 -1
- data/app/views/generic_files/_local_file_import.html.erb +3 -0
- data/app/views/generic_files/_show_actions.html.erb +4 -0
- data/app/views/generic_files/upload/_form.html.erb +3 -0
- data/app/views/generic_files/upload/_to_collection.html.erb +5 -0
- data/app/views/homepage/_recent_document.html.erb +1 -7
- data/app/views/my/_index_partials/_default_group.html.erb +1 -1
- data/app/views/my/_index_partials/_list_collections.html.erb +3 -10
- data/app/views/my/_index_partials/_list_files.html.erb +13 -22
- data/app/views/my/_sort_and_per_page.html.erb +3 -3
- data/app/views/records/edit_fields/_rights.html.erb +2 -1
- data/app/views/static/terms.html.erb +1 -1
- data/config/locales/sufia.en.yml +13 -0
- data/lib/generators/sufia/templates/catalog_controller.rb +2 -2
- data/lib/sufia/version.rb +1 -1
- data/spec/actors/generic_file/actor_spec.rb +35 -0
- data/spec/controllers/admin_stats_controller_spec.rb +53 -23
- data/spec/controllers/api/items_controller_spec.rb +47 -41
- data/spec/controllers/batch_controller_spec.rb +1 -0
- data/spec/controllers/generic_files_controller_spec.rb +35 -1
- data/spec/controllers/my/files_controller_spec.rb +5 -0
- data/spec/factories/generic_files.rb +3 -0
- data/spec/features/collection_spec.rb +91 -0
- data/spec/features/contact_form_spec.rb +1 -0
- data/spec/forms/collection_edit_form_spec.rb +3 -3
- data/spec/forms/generic_file_edit_form_spec.rb +1 -1
- data/spec/jobs/create_derivatives_job_spec.rb +6 -0
- data/spec/models/file_content_datastream_spec.rb +1 -1
- data/spec/models/file_download_stat_spec.rb +4 -4
- data/spec/models/file_usage_spec.rb +2 -2
- data/spec/models/file_view_stat_spec.rb +4 -4
- data/spec/models/generic_file_spec.rb +15 -3
- data/spec/models/geo_names_resource_spec.rb +10 -0
- data/spec/models/solr_document_spec.rb +28 -0
- data/spec/models/system_stats_spec.rb +184 -0
- data/spec/models/user_spec.rb +1 -1
- data/spec/models/user_usage_stats_spec.rb +1 -1
- data/spec/services/generic_file_csv_service_spec.rb +66 -0
- data/spec/services/generic_file_indexing_service_spec.rb +35 -0
- data/spec/services/lock_manager_spec.rb +12 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/views/admin/stats/index.html.erb_spec.rb +11 -10
- data/spec/views/catalog/sort_and_per_page.html.erb_spec.rb +1 -1
- data/spec/views/collections/_form_for_select_collection.html.erb_spec.rb +51 -0
- data/spec/views/generic_file/_browse_everything.html.erb_spec.rb +4 -0
- data/spec/views/generic_file/edit.html.erb_spec.rb +31 -24
- data/spec/views/generic_file/new.html.erb_spec.rb +70 -0
- data/spec/views/generic_file/show.html.erb_spec.rb +23 -0
- data/sufia.gemspec +3 -2
- data/tasks/sufia-dev.rake +2 -0
- metadata +42 -9
- 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 "
|
14
|
+
describe "multiple?" do
|
15
15
|
context "with :title" do
|
16
|
-
subject { described_class.
|
17
|
-
it { is_expected.to be
|
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 "
|
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" })
|
@@ -45,7 +45,7 @@ describe FileContentDatastream, type: :model do
|
|
45
45
|
@generic_file.apply_depositor_metadata('mjg36')
|
46
46
|
end
|
47
47
|
|
48
|
-
it "
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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 "
|
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.
|
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.
|
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
|