sufia 4.2.0 → 4.3.1

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +21 -0
  3. data/README.md +7 -19
  4. data/SUFIA_VERSION +1 -1
  5. data/app/assets/images/orcid.png +0 -0
  6. data/app/assets/javascripts/sufia.js +6 -1
  7. data/app/assets/javascripts/sufia/permissions.js +2 -26
  8. data/app/assets/stylesheets/sufia.css.scss +6 -0
  9. data/app/assets/stylesheets/sufia/_buttons.scss +6 -1
  10. data/app/assets/stylesheets/sufia/_dashboard.scss +10 -0
  11. data/app/assets/stylesheets/sufia/_file-listing.scss +8 -0
  12. data/app/assets/stylesheets/sufia/_settings.scss +1 -0
  13. data/app/helpers/batch_edits_helper.rb +1 -1
  14. data/app/helpers/sufia/sufia_helper_behavior.rb +11 -0
  15. data/app/models/featured_work_list.rb +4 -1
  16. data/app/views/batch/edit.html.erb +2 -2
  17. data/app/views/batch_edits/_check_all.html.erb +8 -6
  18. data/app/views/collections/_edit_descriptions.html.erb +1 -1
  19. data/app/views/dashboard/_index_partials/_stats.html.erb +10 -1
  20. data/app/views/generic_files/_descriptions.html.erb +1 -1
  21. data/app/views/generic_files/_permission.html.erb +2 -2
  22. data/app/views/generic_files/_permission_form.html.erb +4 -6
  23. data/app/views/generic_files/_versioning.html.erb +2 -2
  24. data/app/views/records/show_fields/_contributor.html.erb +1 -1
  25. data/app/views/records/show_fields/_creator.html.erb +1 -1
  26. data/app/views/users/_profile.html.erb +1 -2
  27. data/app/views/users/_user_info.html.erb +20 -3
  28. data/app/views/users/edit.html.erb +11 -2
  29. data/app/views/users/show.html.erb +1 -1
  30. data/config/locales/sufia.en.yml +5 -0
  31. data/lib/generators/sufia/install_generator.rb +4 -0
  32. data/lib/generators/sufia/templates/catalog_controller.rb +4 -0
  33. data/lib/sufia/version.rb +1 -1
  34. data/spec/controllers/users_controller_spec.rb +18 -10
  35. data/spec/features/browse_files_spec.rb +17 -3
  36. data/spec/features/users_spec.rb +1 -1
  37. data/spec/helpers/batch_edits_helper_spec.rb +7 -1
  38. data/spec/lib/sufia/user_stat_importer_spec.rb +206 -0
  39. data/spec/models/featured_work_list_spec.rb +12 -0
  40. data/spec/models/file_view_stat_spec.rb +6 -2
  41. data/spec/models/user_spec.rb +25 -2
  42. data/spec/models/user_usage_stats_spec.rb +39 -0
  43. data/spec/views/dashboard/index_spec.rb +4 -0
  44. data/spec/views/generic_file/_permission_form.html.erb_spec.rb +19 -0
  45. data/spec/views/generic_file/show.html.erb_spec.rb +2 -2
  46. data/sufia-models/app/models/concerns/sufia/file_stat_utils.rb +3 -3
  47. data/sufia-models/app/models/concerns/sufia/user.rb +27 -10
  48. data/sufia-models/app/models/concerns/sufia/user_usage_stats.rb +15 -0
  49. data/sufia-models/app/models/file_download_stat.rb +2 -2
  50. data/sufia-models/app/models/file_usage.rb +7 -3
  51. data/sufia-models/app/models/file_view_stat.rb +2 -2
  52. data/sufia-models/app/models/sufia/orcid_validator.rb +8 -0
  53. data/sufia-models/app/models/user_stat.rb +2 -0
  54. data/sufia-models/lib/generators/sufia/models/abstract_migration_generator.rb +30 -0
  55. data/sufia-models/lib/generators/sufia/models/cached_stats_generator.rb +2 -31
  56. data/sufia-models/lib/generators/sufia/models/install_generator.rb +11 -31
  57. data/sufia-models/lib/generators/sufia/models/orcid_field_generator.rb +19 -0
  58. data/sufia-models/lib/generators/sufia/models/proxies_generator.rb +2 -31
  59. data/sufia-models/lib/generators/sufia/models/templates/config/sufia.rb +3 -5
  60. data/sufia-models/lib/generators/sufia/models/templates/migrations/add_orcid_to_users.rb +5 -0
  61. data/sufia-models/lib/generators/sufia/models/templates/migrations/create_user_stats.rb +19 -0
  62. data/sufia-models/lib/generators/sufia/models/upgrade400_generator.rb +2 -33
  63. data/sufia-models/lib/generators/sufia/models/user_stats_generator.rb +31 -0
  64. data/sufia-models/lib/sufia/models/stats/user_stat_importer.rb +85 -0
  65. data/sufia-models/lib/sufia/models/version.rb +1 -1
  66. data/sufia-models/lib/tasks/stats_tasks.rake +12 -0
  67. data/sufia.gemspec +0 -1
  68. metadata +21 -19
  69. data/app/views/users/_social_media_info.html.erb +0 -20
@@ -1,5 +1,5 @@
1
1
  <h1>Edit Profile</h1>
2
- <div class="col-xs-12 col-sm-5">
2
+ <div class="col-xs-12 col-sm-5 profile">
3
3
  <div class="well">
4
4
  <%= form_for @user, url: sufia.profile_path(@user.to_param), html: {multipart: true, class: 'form-horizontal' } do |f| %>
5
5
  <div class="form-group">
@@ -29,6 +29,15 @@
29
29
  </div>
30
30
  </div>
31
31
 
32
+ <div class="form-group">
33
+ <%= f.label :orcid, class: 'col-xs-4 control-label' do %>
34
+ <%= orcid_label %>
35
+ <% end %>
36
+ <div class="col-xs-8">
37
+ <%= f.text_field :orcid, class: "form-control" %>
38
+ </div>
39
+ </div><!-- .form-group -->
40
+
32
41
  <div class="form-group">
33
42
  <%= f.label :twitter_handle, '<i class="fa fa-twitter"></i> Twitter Handle'.html_safe, class: 'col-xs-4 control-label' %>
34
43
  <div class="col-xs-8">
@@ -60,7 +69,7 @@
60
69
  </div>
61
70
  </div><!-- .col-xs-5 /well-->
62
71
 
63
- <div class="col-xs-12 col-sm-offset-1 col-sm-6 well">
72
+ <div class="col-xs-12 col-sm-offset-1 col-sm-6 well profile">
64
73
  <h2><i class="glyphicon glyphicon-user"></i> Directory Info (LDAP) <%= link_to 'Edit Instructions', 'http://www.psu.edu/directory/#update', class: 'btn btn-mini btn-primary' %></h3>
65
74
  <%= render partial: 'user_info', locals: {user: @user} %>
66
75
 
@@ -1,7 +1,7 @@
1
1
  <%= javascript_tag do %>
2
2
  <% end %>
3
3
 
4
- <div class="col-xs-12">
4
+ <div class="col-xs-12 profile">
5
5
  <div class="pull-right">
6
6
  <%= render 'profile_actions' %>
7
7
  </div>
@@ -80,6 +80,8 @@ en:
80
80
  stats:
81
81
  heading: "Your Statistics"
82
82
  files: "Files you've deposited"
83
+ file_views: "View"
84
+ file_downloads: "Download"
83
85
  collections: "Collections you've created"
84
86
  following: "People you follow"
85
87
  followers: "People who are following you"
@@ -147,6 +149,9 @@ en:
147
149
  user_profile:
148
150
  no_followers: "No one is following you."
149
151
  no_following: "You are not following anyone."
152
+ orcid:
153
+ alt: "ORCID icon"
154
+ label: "ORCID Profile"
150
155
  batch:
151
156
  help:
152
157
  title: "Filename will be the default title. Please provide a more meaningful title, and filenames will still be preserved by the system."
@@ -23,6 +23,10 @@ module Sufia
23
23
  generate "sufia:models:install"
24
24
  end
25
25
 
26
+ def banner
27
+ say_status("warning", "GENERATING SUFIA", :yellow)
28
+ end
29
+
26
30
  def insert_abilities
27
31
  insert_into_file 'app/models/ability.rb', after: /Hydra::Ability/ do
28
32
  "\n include Sufia::Ability\n"
@@ -30,6 +30,10 @@ class CatalogController < ApplicationController
30
30
  end
31
31
 
32
32
  configure_blacklight do |config|
33
+ #Show gallery view
34
+ config.view.gallery.partials = [:index_header, :index]
35
+ config.view.slideshow.partials = [:index]
36
+
33
37
  ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params
34
38
  config.default_solr_params = {
35
39
  qt: "search",
@@ -1,3 +1,3 @@
1
1
  module Sufia
2
- VERSION = "4.2.0"
2
+ VERSION = "4.3.1"
3
3
  end
@@ -23,10 +23,10 @@ describe UsersController, :type => :controller do
23
23
  end
24
24
 
25
25
  describe "when the user has trophies" do
26
- let(:user) { @user }
27
- let(:file1) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
28
- let(:file2) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
29
- let(:file3) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
26
+ let(:user) { @user }
27
+ let(:file1) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
28
+ let(:file2) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
29
+ let(:file3) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
30
30
  let!(:trophy1) { user.trophies.create!(generic_file_id: file1.noid) }
31
31
  let!(:trophy2) { user.trophies.create!(generic_file_id: file2.noid) }
32
32
  let!(:trophy3) { user.trophies.create!(generic_file_id: file3.noid) }
@@ -105,10 +105,10 @@ describe UsersController, :type => :controller do
105
105
  expect(flash[:alert]).to include("Permission denied: cannot access this page.")
106
106
  end
107
107
  describe "when the user has trophies" do
108
- let(:user) { @user }
109
- let(:file1) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
110
- let(:file2) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
111
- let(:file3) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
108
+ let(:user) { @user }
109
+ let(:file1) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
110
+ let(:file2) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
111
+ let(:file3) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
112
112
  let!(:trophy1) { user.trophies.create!(generic_file_id: file1.noid) }
113
113
  let!(:trophy2) { user.trophies.create!(generic_file_id: file2.noid) }
114
114
  let!(:trophy3) { user.trophies.create!(generic_file_id: file3.noid) }
@@ -182,7 +182,8 @@ describe UsersController, :type => :controller do
182
182
  expect(@user.facebook_handle).to be_blank
183
183
  expect(@user.googleplus_handle).to be_blank
184
184
  expect(@user.linkedin_handle).to be_blank
185
- post :update, id: @user.user_key, user: { twitter_handle: 'twit', facebook_handle: 'face', googleplus_handle: 'goo', linkedin_handle:"link" }
185
+ expect(@user.orcid).to be_blank
186
+ post :update, id: @user.user_key, user: { twitter_handle: 'twit', facebook_handle: 'face', googleplus_handle: 'goo', linkedin_handle: "link", orcid: '0000-0000-1111-2222' }
186
187
  expect(response).to redirect_to(@routes.url_helpers.profile_path(@user.to_param))
187
188
  expect(flash[:notice]).to include("Your profile has been updated")
188
189
  u = User.find_by_user_key(@user.user_key)
@@ -190,11 +191,18 @@ describe UsersController, :type => :controller do
190
191
  expect(u.facebook_handle).to eq 'face'
191
192
  expect(u.googleplus_handle).to eq 'goo'
192
193
  expect(u.linkedin_handle).to eq 'link'
194
+ expect(u.orcid).to eq 'http://orcid.org/0000-0000-1111-2222'
195
+ end
196
+ it 'displays a flash when invalid ORCID is entered' do
197
+ expect(@user.orcid).to be_blank
198
+ post :update, id: @user.user_key, user: { orcid: 'foobar' }
199
+ expect(response).to redirect_to(@routes.url_helpers.edit_profile_path(@user.to_param))
200
+ expect(flash[:alert]).to include('Orcid must be a string of 19 characters, e.g., "0000-0000-0000-0000"')
193
201
  end
194
202
 
195
203
  context "when removing a trophy" do
196
204
  let(:user) { @user }
197
- let(:file) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
205
+ let(:file) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
198
206
  before do
199
207
  user.trophies.create!(generic_file_id: file.noid)
200
208
  end
@@ -7,9 +7,14 @@ describe "Browse files", :type => :feature do
7
7
  @fixtures = find_or_create_file_fixtures
8
8
  @fixtures[0].tag = ["key"]
9
9
  (1..25).each do |i|
10
- @fixtures[0].tag << i
10
+ @fixtures[0].tag << "key_#{i}"
11
11
  end
12
+ @fixtures[1].tag = ["key"]
12
13
  @fixtures[0].save
14
+ (1..20).each do |i|
15
+ @fixtures[1].tag << "key_#{i}"
16
+ end
17
+ @fixtures[1].save
13
18
  end
14
19
 
15
20
  after :all do
@@ -23,21 +28,30 @@ describe "Browse files", :type => :feature do
23
28
  click_button "search-submit-header"
24
29
  click_link "Keyword"
25
30
  click_link "more Keywords»"
31
+ expect(page).to have_css "h3", text: "Keyword"
26
32
  end
27
33
 
28
34
  describe "when not logged in" do
29
35
  it "should let us browse some of the fixtures" do
30
36
  click_link "18"
31
37
  expect(page).to have_content "Search Results"
38
+ expect(page).to have_css "a", text: @fixtures[0].title[0]
32
39
  click_link @fixtures[0].title[0]
33
40
  expect(page).to have_content "Download"
34
41
  expect(page).not_to have_content "Edit"
35
42
  end
36
43
  it "should allow you to click next" do
44
+ expect(page).to have_content "Numerical Sort"
45
+ expect(page).to have_css "a.sort_change", text:"A-Z Sort"
46
+ within(".modal-body") do
47
+ expect(page).to have_content "key_1 "
48
+ expect(page).not_to have_content "key_25 "
49
+ end
37
50
  click_link 'Next »'
51
+ expect(page).to have_css "a.btn-link", text:"« Previous", wait: Capybara.default_wait_time*4
38
52
  within(".modal-body") do
39
- expect(page).to have_content "5"
40
- expect(page).not_to have_content "11"
53
+ expect(page).to have_content "key_25 "
54
+ expect(page).not_to have_content "key_1 "
41
55
  end
42
56
  end
43
57
  end
@@ -30,7 +30,7 @@ describe "User Profile", :type => :feature do
30
30
  click_button 'Save Profile'
31
31
  expect(page).to have_content 'Your profile has been updated'
32
32
  click_link 'Profile'
33
- expect(page).to have_content 'http://twitter.com/curatorOfData'
33
+ expect(page).to have_link('curatorOfData', href: 'http://twitter.com/curatorOfData')
34
34
  end
35
35
  end
36
36
 
@@ -16,6 +16,12 @@ describe BatchEditsHelper, :type => :helper do
16
16
  allow(helper).to receive(:controller_name).and_return("batch_edits")
17
17
  expect(helper.render_check_all).to have_css("span.glyphicon-cog")
18
18
  end
19
+
20
+ it "should show my action menu for my controller" do
21
+ allow(helper).to receive(:params).and_return({ controller: "my" })
22
+ allow(helper).to receive(:controller_name).and_return("my")
23
+ expect(helper.render_check_all).not_to have_content("ABC")
24
+ end
19
25
  end
20
26
 
21
27
  context "with my collections" do
@@ -29,7 +35,7 @@ describe BatchEditsHelper, :type => :helper do
29
35
  it "should not show the check all dropdown" do
30
36
  allow(helper).to receive(:params).and_return({ controller: "foo" })
31
37
  assign(:disable_select_all, true)
32
- expect(helper.render_check_all).to be_nil
38
+ expect(helper.render_check_all).to have_css("input[disabled=disabled]")
33
39
  end
34
40
  end
35
41
 
@@ -0,0 +1,206 @@
1
+ require 'spec_helper'
2
+ require_relative '../../../sufia-models/lib/sufia/models/stats/user_stat_importer'
3
+
4
+ describe Sufia::UserStatImporter do
5
+
6
+ before do
7
+ GenericFile.delete_all
8
+ User.delete_all
9
+
10
+ UserStat.delete_all
11
+ FileViewStat.delete_all
12
+ FileDownloadStat.delete_all
13
+
14
+ allow(Sufia.config).to receive(:analytic_start_date) { dates[0] }
15
+ stub_out_call_to_google_analytics
16
+ end
17
+
18
+ let(:bilbo) { FactoryGirl.create(:user, email: 'bilbo@example.com') }
19
+ let(:frodo) { FactoryGirl.create(:user, email: 'frodo@example.com') }
20
+
21
+ let!(:bilbo_file_1) do
22
+ GenericFile.new(pid: 'bilbo:1').tap do |f|
23
+ f.apply_depositor_metadata(bilbo.email)
24
+ f.save
25
+ end
26
+ end
27
+
28
+ let!(:bilbo_file_2) do
29
+ GenericFile.new(pid: 'bilbo:2').tap do |f|
30
+ f.apply_depositor_metadata(bilbo.email)
31
+ f.save
32
+ end
33
+ end
34
+
35
+ let!(:frodo_file_1) do
36
+ GenericFile.new(pid: 'frodo:1').tap do |f|
37
+ f.apply_depositor_metadata(frodo.email)
38
+ f.save
39
+ end
40
+ end
41
+
42
+ let(:dates) {
43
+ ldates = []
44
+ 4.downto(0) {|idx| ldates << (Date.today-idx.day) }
45
+ ldates
46
+ }
47
+
48
+ let(:date_strs) {
49
+ ldate_strs = []
50
+ dates.each {|date| ldate_strs << date.strftime("%Y%m%d") }
51
+ ldate_strs
52
+ }
53
+
54
+ # This is what the data looks like that's returned from Google Analytics via the Legato gem.
55
+ let(:bilbo_file_1_pageview_stats) {
56
+ [
57
+ OpenStruct.new(date: date_strs[0], pageviews: 1),
58
+ OpenStruct.new(date: date_strs[1], pageviews: 2),
59
+ OpenStruct.new(date: date_strs[2], pageviews: 3),
60
+ OpenStruct.new(date: date_strs[3], pageviews: 4),
61
+ OpenStruct.new(date: date_strs[4], pageviews: 5)
62
+ ]
63
+ }
64
+
65
+ let(:bilbo_file_2_pageview_stats) {
66
+ [
67
+ OpenStruct.new(date: date_strs[0], pageviews: 11),
68
+ OpenStruct.new(date: date_strs[1], pageviews: 12),
69
+ OpenStruct.new(date: date_strs[2], pageviews: 13),
70
+ OpenStruct.new(date: date_strs[3], pageviews: 14),
71
+ OpenStruct.new(date: date_strs[4], pageviews: 15)
72
+ ]
73
+ }
74
+
75
+ let(:frodo_file_1_pageview_stats) {
76
+ [
77
+ OpenStruct.new(date: date_strs[0], pageviews: 2),
78
+ OpenStruct.new(date: date_strs[1], pageviews: 4),
79
+ OpenStruct.new(date: date_strs[2], pageviews: 1),
80
+ OpenStruct.new(date: date_strs[3], pageviews: 1),
81
+ OpenStruct.new(date: date_strs[4], pageviews: 9)
82
+ ]
83
+ }
84
+
85
+ let(:bilbo_file_1_download_stats) {
86
+ [
87
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:1", date: date_strs[0], totalEvents: "2"),
88
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:1", date: date_strs[1], totalEvents: "3"),
89
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:1", date: date_strs[2], totalEvents: "5"),
90
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:1", date: date_strs[3], totalEvents: "3"),
91
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:1", date: date_strs[4], totalEvents: "7"),
92
+ ]
93
+ }
94
+
95
+ let(:bilbo_file_2_download_stats) {
96
+ [
97
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:2", date: date_strs[0], totalEvents: "1"),
98
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:2", date: date_strs[1], totalEvents: "4"),
99
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:2", date: date_strs[2], totalEvents: "3"),
100
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:2", date: date_strs[3], totalEvents: "2"),
101
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "bilbo:2", date: date_strs[4], totalEvents: "3"),
102
+ ]
103
+ }
104
+
105
+ let(:frodo_file_1_download_stats) {
106
+ [
107
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "frodo:1", date: date_strs[0], totalEvents: "5"),
108
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "frodo:1", date: date_strs[1], totalEvents: "4"),
109
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "frodo:1", date: date_strs[2], totalEvents: "2"),
110
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "frodo:1", date: date_strs[3], totalEvents: "1"),
111
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "frodo:1", date: date_strs[4], totalEvents: "6"),
112
+ ]
113
+ }
114
+
115
+
116
+ describe 'with empty cache' do
117
+ it 'for each user it adds one entry per day to the cache' do
118
+ Sufia::UserStatImporter.new.import
119
+
120
+ bilbos_stats = UserStat.where(user_id: bilbo.id).order(date: :asc)
121
+ expect(bilbos_stats.count).to eq 4
122
+
123
+ bilbos_stats.each_with_index do |actual_values, i|
124
+ expected_file_views = bilbo_file_1_pageview_stats[i].pageviews + bilbo_file_2_pageview_stats[i].pageviews
125
+ expected_file_downloads = bilbo_file_1_download_stats[i].totalEvents.to_i + bilbo_file_2_download_stats[i].totalEvents.to_i
126
+ expected_values = { date: dates[i], views: expected_file_views, downloads: expected_file_downloads }
127
+ assert_stats_match(expected_values, actual_values)
128
+ end
129
+
130
+ frodos_stats = UserStat.where(user_id: frodo.id).order(date: :asc)
131
+ expect(frodos_stats.count).to eq 4
132
+
133
+ frodos_stats.each_with_index do |actual_values, i|
134
+ expected_file_views = frodo_file_1_pageview_stats[i].pageviews
135
+ expected_file_downloads = frodo_file_1_download_stats[i].totalEvents.to_i
136
+ expected_values = { date: dates[i], views: expected_file_views, downloads: expected_file_downloads }
137
+ assert_stats_match(expected_values, actual_values)
138
+ end
139
+
140
+ expect(UserStat.count).to eq bilbos_stats.count + frodos_stats.count
141
+ end
142
+ end
143
+
144
+ describe 'with existing data in cache' do
145
+ before do
146
+ [dates[0], dates[1]].each_with_index do |date, i|
147
+ UserStat.create!(user_id: bilbo.id, date: date, file_views: 100 + i, file_downloads: 200 + i)
148
+ end
149
+ UserStat.create!(user_id: frodo.id, date: dates[0], file_views: 300, file_downloads: 400)
150
+ end
151
+
152
+ it "doesn't duplicate entries for existing dates" do
153
+ expect(User.count).to eq 2
154
+ expect(UserStat.count).to eq 3
155
+
156
+ Sufia::UserStatImporter.new.import
157
+
158
+ bilbos_stats = UserStat.where(user_id: bilbo.id).order(date: :asc)
159
+ expect(bilbos_stats.count).to eq 4
160
+
161
+ expect(bilbos_stats[0].file_views).to eq(bilbo_file_1_pageview_stats[0].pageviews + bilbo_file_2_pageview_stats[0].pageviews)
162
+ expect(bilbos_stats[0].file_downloads).to eq(bilbo_file_1_download_stats[0].totalEvents.to_i + bilbo_file_2_download_stats[0].totalEvents.to_i)
163
+
164
+ expect(bilbos_stats[1].file_views).to eq(bilbo_file_1_pageview_stats[1].pageviews + bilbo_file_2_pageview_stats[1].pageviews)
165
+ expect(bilbos_stats[1].file_downloads).to eq(bilbo_file_1_download_stats[1].totalEvents.to_i + bilbo_file_2_download_stats[1].totalEvents.to_i)
166
+
167
+ frodos_stats = UserStat.where(user_id: frodo.id).order(date: :asc)
168
+ expect(frodos_stats.count).to eq 4
169
+
170
+ expect(frodos_stats[0].file_views).to eq(frodo_file_1_pageview_stats[0].pageviews)
171
+
172
+ expect(frodos_stats[0].file_downloads).to eq(frodo_file_1_download_stats[0].totalEvents.to_i)
173
+ end
174
+ end
175
+ end
176
+
177
+
178
+ def stub_out_call_to_google_analytics
179
+ allow(FileViewStat).to receive(:ga_statistics) do |date, file_id|
180
+ case file_id
181
+ when bilbo_file_1.id
182
+ bilbo_file_1_pageview_stats
183
+ when bilbo_file_2.id
184
+ bilbo_file_2_pageview_stats
185
+ else
186
+ frodo_file_1_pageview_stats
187
+ end
188
+ end
189
+
190
+ allow(FileDownloadStat).to receive(:ga_statistics) do |date, file_id|
191
+ case file_id
192
+ when bilbo_file_1.id
193
+ bilbo_file_1_download_stats
194
+ when bilbo_file_2.id
195
+ bilbo_file_2_download_stats
196
+ else
197
+ frodo_file_1_download_stats
198
+ end
199
+ end
200
+ end
201
+
202
+ def assert_stats_match(expected_value, actual_value)
203
+ expect(actual_value.date).to eq expected_value[:date]
204
+ expect(actual_value.file_views).to eq expected_value[:views]
205
+ expect(actual_value.file_downloads).to eq expected_value[:downloads]
206
+ end
@@ -19,4 +19,16 @@ describe FeaturedWorkList, :type => :model do
19
19
  expect(solr_doc.noid).to eq file1.noid
20
20
  end
21
21
  end
22
+
23
+ describe 'file deleted' do
24
+ before do
25
+ file1.destroy
26
+ end
27
+ it 'should be a list of the remaining featured work objects, each with the generic_file\'s solr_doc' do
28
+ expect(subject.featured_works.size).to eq 1
29
+ solr_doc = subject.featured_works.first.generic_file_solr_document
30
+ expect(solr_doc).to be_kind_of SolrDocument
31
+ expect(solr_doc.noid).to eq file2.noid
32
+ end
33
+ end
22
34
  end