sufia 4.2.0 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
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