sufia 6.1.0 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: afe7739c6421450db9e6d2f9651152c8d4ff0624
4
- data.tar.gz: 08b718c691ae8e6813f928d57efaeb3d2265151b
3
+ metadata.gz: d5983e2ea047b6ee6b08ef678cb233a8f20b68a3
4
+ data.tar.gz: 73adb6f66582d0b1021d0addba02efb4e15ee8ca
5
5
  SHA512:
6
- metadata.gz: a5e5252d70908e42cdd09137947531a696f05bc4b7ab23989cf47774e25597415566c649333efdbb1e65d9f981f08206cb9a1ce68ca7c2199754cf7e910ef78f
7
- data.tar.gz: ba76310232b867f0e7bc6bba3dcc16ec1282b7d912b940e2f206cac7b068a38a43b4c8d8b1008aa6639e7a3dff86b3e757bf2be1f1fe0e37f385c9f1fb327701
6
+ metadata.gz: e378ea0a2b5e17b0f86ab170c276d92863a8933468c4b5af31e472b2d226a096f9f9475e51a41ce3f9f9523df83f069c0605f24a08973888f79b425943cf0db7
7
+ data.tar.gz: b4e5438fbd558768b324b336a5c1d9b0194c44c56360c66069bfee3d38bac696998d1115160194a150e9832cd9ee3297f1ec18bbfc3a43bb0ea9282693724938
data/History.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # History of Sufia releases
2
2
 
3
+ ## 6.2.0
4
+
5
+ * Check to make sure Zotero integration is enabled before asking user instances if they have a Zotero user ID. Fixes #1235 [Michael J. Giarlo]
6
+ * Make my controller retrieve only user's own collections. [Olli Lyytinen]
7
+ * Adding date range queries for deposited files. fixes #1189 [Carolyn Cole]
8
+ * Allowing the second input to also auto complete. fixes #1222 [Carolyn Cole]
9
+ * Removing any calls to the sort! method [Carolyn Cole]
10
+ * Adding recent users query end date so a range can be queried. fixes #1187 [Carolyn Cole]
11
+ * Don't calculate coverage of code found in spec/ directory [Michael J. Giarlo]
12
+ * Refactoring feature test to make it more efficient [Carolyn Cole]
13
+
3
14
  ## 6.1.0
4
15
 
5
16
  * Making the image thumbnail alt tag empty for better accessibility, since there is more information about title and description in the result. [Michael Tribone]
@@ -68,7 +79,6 @@
68
79
  * Noid service extracted out into its own gem [Michael J. Giarlo]
69
80
  * Correct version of Sufia in README [Michael J. Giarlo]
70
81
 
71
-
72
82
  ## 6.0.0
73
83
 
74
84
  * Replace pid with id in config [Adam Wead]
@@ -1 +1 @@
1
- 6.1.0
1
+ 6.2.0
@@ -45,7 +45,7 @@ Blacklight.onLoad(function() {
45
45
  },
46
46
  minLength: 2
47
47
  };
48
- $("#generic_file_based_near").autocomplete(get_autocomplete_opts("location"));
48
+ $("input.generic_file_based_near").autocomplete(get_autocomplete_opts("location"));
49
49
 
50
50
  var autocomplete_vocab = new Object();
51
51
 
@@ -57,7 +57,7 @@ Blacklight.onLoad(function() {
57
57
  for (var i=0; i < autocomplete_vocab.url_var.length; i++) {
58
58
  autocomplete_vocab.field_name.push('generic_file_' + autocomplete_vocab.url_var[i]);
59
59
  // autocompletes
60
- $("#" + autocomplete_vocab.field_name[i])
60
+ $("input." + autocomplete_vocab.field_name[i])
61
61
  // don't navigate away from the field on tab when selecting an item
62
62
  .bind( "keydown", function( event ) {
63
63
  if ( event.keyCode === $.ui.keyCode.TAB &&
@@ -29,10 +29,23 @@ class Admin::StatsController < ApplicationController
29
29
  end
30
30
 
31
31
  def document_by_permission
32
+ return document_by_date_by_permission if @users_stats[:file_start_date]
33
+
32
34
  files_count = {}
33
35
  files_count[:total] = GenericFile.count
34
- files_count[:public] = GenericFile.where(Solrizer.solr_name('read_access_group', :symbol) => 'public').count
35
- files_count[:registered] = GenericFile.where(Solrizer.solr_name('read_access_group', :symbol) =>'registered').count
36
+ files_count[:public] = GenericFile.where_public.count
37
+ files_count[:registered] = GenericFile.where_registered.count
38
+ files_count[:private] = files_count[:total] - (files_count[:registered] + files_count[:public])
39
+ files_count
40
+ end
41
+
42
+ def document_by_date_by_permission
43
+ start_date = DateTime.parse(@users_stats[:file_start_date])
44
+ end_date = DateTime.parse(@users_stats[:file_end_date]).end_of_day unless @users_stats[:file_end_date].blank?
45
+ files_count = {}
46
+ files_count[:total] = GenericFile.find_by_date_created(start_date, end_date).count
47
+ files_count[:public] = GenericFile.find_by_date_created(start_date, end_date).merge(GenericFile.where_public).count
48
+ files_count[:registered] = GenericFile.find_by_date_created(start_date, end_date).merge(GenericFile.where_registered).count
36
49
  files_count[:private] = files_count[:total] - (files_count[:registered] + files_count[:public])
37
50
  files_count
38
51
  end
@@ -57,12 +70,11 @@ class Admin::StatsController < ApplicationController
57
70
  end
58
71
 
59
72
  def recent_users
60
- # users since date
61
- if @users_stats[:start_date]
62
- return User.where('created_at >= ?', @users_stats[:start_date])
63
- end
73
+ # no dates return the top 5
74
+ return User.order('created_at DESC').limit(5) if @users_stats[:start_date].blank?
64
75
 
65
- # 5 most recent
66
- User.order('created_at DESC').limit(5)
76
+ start_date = DateTime.parse @users_stats[:start_date]
77
+ end_date = DateTime.parse(@users_stats[:end_date]).end_of_day unless @users_stats[:end_date].blank?
78
+ User.recent_users start_date, end_date
67
79
  end
68
80
  end
@@ -6,17 +6,17 @@ module Sufia
6
6
  include Hydra::Catalog
7
7
  include Hydra::BatchEditBehavior
8
8
  include Hydra::Collections::SelectsCollections
9
-
9
+
10
10
  included do
11
11
  include Blacklight::Configurable
12
12
 
13
13
  self.copy_blacklight_config_from(CatalogController)
14
14
  self.blacklight_config.search_builder_class = Sufia::MySearchBuilder
15
-
15
+
16
16
  before_filter :authenticate_user!
17
17
  before_filter :enforce_show_permissions, only: :show
18
18
  before_filter :enforce_viewing_context_for_show_requests, only: :show
19
- before_filter :find_collections, only: :index
19
+ before_filter :find_collections_with_edit_access, only: :index
20
20
 
21
21
  self.search_params_logic += [:add_access_controls_to_solr_params, :add_advanced_parse_q_to_solr]
22
22
 
@@ -0,0 +1,16 @@
1
+ <h2>File Statistics</h2>
2
+ <%= form_for "users_stats", url: sufia.admin_stats_path, method: "GET" do |f| %>
3
+ <%= f.label "#{ t("sufia.admin.stats.deposited_form.heading") } #{ t("sufia.admin.stats.deposited_form.start_label") }" %>
4
+ <input type="date" name="users_stats[file_start_date]" value="<%= @users_stats[:file_start_date] %>"></input>
5
+ <%= f.label t("sufia.admin.stats.deposited_form.end_label") %>
6
+ <input type="date" name="users_stats[file_end_date]" value="<%= @users_stats[:file_end_date] %>"></input>
7
+ <%= f.submit "Load Stats" %>
8
+ <h3>Total Files: <%= @files_count[:total] %> </h3>
9
+ <br/>
10
+ <%- end %>
11
+ <h3>Totals by Visibility</h3>
12
+ <ul>
13
+ <li>Open Access <span class="count">(<%= @files_count[:public] %>)</span></li>
14
+ <li><%= t("sufia.admin.stats.registered") %> <span class="count">(<%= @files_count[:registered] %>)</span></li>
15
+ <li>Private <span class="count">(<%= @files_count[:private] %>)</span></li>
16
+ </ul>
@@ -0,0 +1,30 @@
1
+ <h3>Newest Users</h3>
2
+ <%= form_for "users_stats", url: sufia.admin_stats_path, method: "GET" do |f| %>
3
+ <%= f.label "Display users registered: Start" %>
4
+ <input type="date" name="users_stats[start_date]" value="<%= @users_stats[:start_date] %>"></input>
5
+ <%= f.label "end [defaults to now]" %>
6
+ <input type="date" name="users_stats[end_date]" value="<%= @users_stats[:end_date] %>"></input>
7
+ <%= f.submit "Load Stats" %>
8
+ <%- end %>
9
+
10
+ <%- if @users_stats[:start_date] %>
11
+ <div>Total: <%= @recent_users.count %></div>
12
+ <%- else %>
13
+ Five most recent users:
14
+ <%- end %>
15
+
16
+ <ul>
17
+ <% @recent_users.each do |usr| %>
18
+ <li>
19
+ <a href="<%= sufia.profile_path(usr.user_key) %>" title="View user's profile"><%= usr.name %></a>
20
+ <%- if usr.department %>
21
+ of <%= usr.department %>
22
+ <%- end %>
23
+ registered
24
+ <span class="date">
25
+ <%= usr.created_at.to_time.strftime("%m/%d/%Y") %>
26
+ </span>
27
+ </li>
28
+ <% end %>
29
+ </ul>
30
+
@@ -3,14 +3,7 @@
3
3
  <%= Sufia::VERSION %></h1>
4
4
  <br/>
5
5
 
6
- <h2>Total Files: <%= @files_count[:total] %> </h2>
7
- <br/>
8
- <h3>Totals by Visibility</h3>
9
- <ul>
10
- <li>Open Access <span class="count">(<%= @files_count[:public] %>)</span></li>
11
- <li><%= t("sufia.admin.stats.registered") %> <span class="count">(<%= @files_count[:registered] %>)</span></li>
12
- <li>Private <span class="count">(<%= @files_count[:private] %>)</span></li>
13
- </ul>
6
+ <%= render "admin/stats/files" %>
14
7
 
15
8
  <h3>Top File Formats</h3>
16
9
  <ul>
@@ -24,34 +17,7 @@
24
17
  <h2>Total <%= application_name %> Users:&nbsp; <%= @users_count %> </h2>
25
18
  <br/>
26
19
 
27
- <h3>Newest Users</h3>
28
- <%= form_for "users_stats", url: sufia.admin_stats_path, method: "GET" do |f| %>
29
- <%= f.label "Display users registered since" %>
30
- <input type="date" name="users_stats[start_date]" value="<%= @users_stats[:start_date] %>"></input>
31
- <%= f.submit "Load Stats" %>
32
- <%- end %>
33
-
34
- <%- if @users_stats[:start_date] %>
35
- <div>Total: <%= @recent_users.count %></div>
36
- <%- else %>
37
- Five most recent users:
38
- <%- end %>
39
-
40
- <ul>
41
- <% @recent_users.each do |usr| %>
42
- <li>
43
- <a href="<%= sufia.profile_path(usr.user_key) %>" title="View user's profile"><%= usr.name %></a>
44
- <%- if usr.department %>
45
- of <%= usr.department %>
46
- <%- end %>
47
- registered
48
- <span class="date">
49
- <%= usr.created_at.to_time.strftime("%m/%d/%Y") %>
50
- </span>
51
- </li>
52
- <% end %>
53
- </ul>
54
-
20
+ <%= render "admin/stats/new_users" %>
55
21
 
56
22
  <br/>
57
23
  <h3>Most Active Users (top <%= @active_users.count %>)</h3>
@@ -4,7 +4,7 @@
4
4
  <div class="col-sm-8">
5
5
  <h3>Applies to individual files uploaded</h3>
6
6
  <%= content_tag :p, t('sufia.batch.help.title'), class: "help-block" %>
7
- <% @batch.generic_files.sort! { |a,b| a.label.downcase <=> b.label.downcase }.each_with_index do |gen_f, index| %>
7
+ <% @batch.generic_files.sort { |a,b| a.label.downcase <=> b.label.downcase }.each_with_index do |gen_f, index| %>
8
8
  <div class="form-group">
9
9
  <%= f.input_label :title, as: :multi_value_with_help, label: "Title #{index + 1}" %>
10
10
  <div id="additional_title_clone">
@@ -13,8 +13,7 @@
13
13
  <fieldset>
14
14
  <legend><%= t("sufia.collection.select_form.select_heading") %></legend>
15
15
  <ul>
16
- <% user_collections.sort! { |c1,c2| c1['date_modified_dtsi'] <=> c2['date_modified_dtsi'] } %>
17
- <% user_collections.each do |collection| %>
16
+ <% user_collections.sort { |c1,c2| c1['date_modified_dtsi'] <=> c2['date_modified_dtsi'] }.each do |collection| %>
18
17
  <li> <label for="id_<%= collection.id %>" class="sr-only">Add to <%=collection.title%></label>
19
18
  <%= radio_button_tag(:id, collection.id, true, class: "collection-selector") %>
20
19
  <%= label_tag(:collection, collection.title, "aria-hidden" =>true) %>
@@ -5,7 +5,7 @@
5
5
  <dd class="col-xs-7"><%= link_to user.orcid, user.orcid, { target: '_blank' } %></dd>
6
6
  <% end %>
7
7
 
8
- <% if user.zotero_userid.present? %>
8
+ <% if Sufia.config.arkivo_api && user.zotero_userid.present? %>
9
9
  <dt class="col-xs-5"><%= zotero_label(html_class: 'profile') %></dt>
10
10
  <dd class="col-xs-7"><%= link_to zotero_profile_url(user.zotero_userid), zotero_profile_url(user.zotero_userid), { target: '_blank' } %></dd>
11
11
  <% end %>
@@ -172,6 +172,10 @@ en:
172
172
  admin:
173
173
  stats:
174
174
  registered: "Registered"
175
+ deposited_form:
176
+ heading: "Display Files Deposited:"
177
+ start_label: "Start"
178
+ end_label: "end [defaults to now]"
175
179
 
176
180
  simple_form:
177
181
  labels:
@@ -1,3 +1,3 @@
1
1
  module Sufia
2
- VERSION = "6.1.0"
2
+ VERSION = "6.2.0"
3
3
  end
@@ -23,14 +23,24 @@ describe Admin::StatsController, type: :controller do
23
23
  end
24
24
 
25
25
  describe "querying user_stats" do
26
+ let(:one_day_ago_date) { 1.days.ago.to_datetime }
27
+ let(:two_days_ago_date) { 2.days.ago.to_datetime.end_of_day }
28
+ let(:one_day_ago) { one_day_ago_date.strftime("%Y-%m-%d") }
29
+ let(:two_days_ago) { two_days_ago_date.strftime("%Y-%m-%d") }
30
+
26
31
  it "defaults to latest 5 users" do
27
32
  get :index
28
33
  expect(assigns[:recent_users]).to eq(User.order('created_at DESC').limit(5))
29
34
  end
30
- it "allows queries against user_stats" do
35
+ it "allows queries against user_stats without an end date " do
31
36
  expect(User).to receive(:where).with('id' => user1.id).once.and_return([user1])
32
- expect(User).to receive(:where).with('created_at >= ?', 1.days.ago.strftime("%Y-%m-%d")).and_return([user2])
33
- get :index, users_stats: {start_date:1.days.ago.strftime("%Y-%m-%d")}
37
+ expect(User).to receive(:recent_users).with(one_day_ago_date, nil).and_return([user2])
38
+ get :index, users_stats: { start_date: one_day_ago }
39
+ expect(assigns[:recent_users]).to eq([user2])
40
+ end
41
+ it "allows queries against user_stats with an end date" do
42
+ expect(User).to receive(:recent_users).with(two_days_ago_date, one_day_ago_date).and_return([user2])
43
+ get :index, users_stats: { start_date: two_days_ago, end_date: one_day_ago }
34
44
  expect(assigns[:recent_users]).to eq([user2])
35
45
  end
36
46
  end
@@ -51,21 +61,40 @@ describe Admin::StatsController, type: :controller do
51
61
  end
52
62
 
53
63
  describe "counts" do
54
- before do
55
- FactoryGirl.create(:generic_file, depositor: user1)
56
- FactoryGirl.create(:public_file, depositor: user1)
57
- FactoryGirl.create(:registered_file, depositor: user1)
58
- Collection.create(title: "test").tap do |c|
59
- c.apply_depositor_metadata(user1.user_key)
64
+ context "when date range not set" do
65
+ before do
66
+ FactoryGirl.create(:generic_file, depositor: user1)
67
+ FactoryGirl.create(:public_file, depositor: user1)
68
+ FactoryGirl.create(:registered_file, depositor: user1)
69
+ Collection.create(title: "test") do |c|
70
+ c.apply_depositor_metadata(user1.user_key)
71
+ end
72
+ end
73
+ it "includes files but not collections" do
74
+ get :index
75
+ expect(assigns[:files_count][:total]).to eq(3)
76
+ expect(assigns[:files_count][:public]).to eq(1)
77
+ expect(assigns[:files_count][:registered]).to eq(1)
78
+ expect(assigns[:files_count][:private]).to eq(1)
60
79
  end
61
80
  end
62
81
 
63
- it "includes files but not collections" do
64
- get :index
65
- expect(assigns[:files_count][:total]).to eq(3)
66
- expect(assigns[:files_count][:public]).to eq(1)
67
- expect(assigns[:files_count][:registered]).to eq(1)
68
- expect(assigns[:files_count][:private]).to eq(1)
82
+ context "when start date set" do
83
+ it "queries by start date" do
84
+ expect(GenericFile).to receive(:find_by_date_created).exactly(3).times.with(1.days.ago.to_datetime, nil).and_call_original
85
+ expect(GenericFile).to receive(:where_public).and_call_original
86
+ expect(GenericFile).to receive(:where_registered).and_call_original
87
+ get :index, users_stats: { file_start_date: 1.days.ago.strftime("%Y-%m-%d") }
88
+ end
89
+ end
90
+
91
+ context "when date range set" do
92
+ it "queries by start and date" do
93
+ expect(GenericFile).to receive(:find_by_date_created).exactly(3).times.with(1.days.ago.to_datetime, 0.days.ago.to_datetime.end_of_day).and_call_original
94
+ expect(GenericFile).to receive(:where_public).and_call_original
95
+ expect(GenericFile).to receive(:where_registered).and_call_original
96
+ get :index, users_stats: { file_start_date: 1.days.ago.strftime("%Y-%m-%d"), file_end_date: 0.days.ago.strftime("%Y-%m-%d") }
97
+ end
69
98
  end
70
99
  end
71
100
 
@@ -3,9 +3,14 @@ require 'spec_helper'
3
3
  describe My::FilesController, :type => :controller do
4
4
 
5
5
  let(:my_collection) do
6
- Collection.new(title: 'test collection').tap do |c|
6
+ Collection.create(title: 'test collection') do |c|
7
7
  c.apply_depositor_metadata(user.user_key)
8
- c.save!
8
+ end
9
+ end
10
+
11
+ let(:other_collection) do
12
+ Collection.create(title: 'other test collection') do |c|
13
+ c.apply_depositor_metadata(another_user.user_key)
9
14
  end
10
15
  end
11
16
 
@@ -19,10 +24,13 @@ describe My::FilesController, :type => :controller do
19
24
 
20
25
  let(:user) { FactoryGirl.find_or_create(:archivist) }
21
26
 
27
+ let(:another_user) { FactoryGirl.find_or_create(:jill) }
28
+
22
29
  before do
23
30
  sign_in user
24
31
  @my_file = FactoryGirl.create(:generic_file, depositor: user)
25
32
  @my_collection = my_collection
33
+ @other_collection = other_collection
26
34
  @shared_file = shared_file
27
35
  @unrelated_file = FactoryGirl.create(:generic_file, depositor: FactoryGirl.create(:user))
28
36
  @wrong_type = Batch.create
@@ -56,6 +64,12 @@ describe My::FilesController, :type => :controller do
56
64
  expect(assigns[:document_list].map(&:id)).to_not include(@wrong_type.id)
57
65
  end
58
66
 
67
+ it "has the correct collections" do
68
+ get :index
69
+ expect(assigns[:user_collections].map(&:id)).to include(@my_collection.id)
70
+ expect(assigns[:user_collections].map(&:id)).to_not include(@other_collection.id)
71
+ end
72
+
59
73
  describe "batch processing" do
60
74
  include Sufia::Messages
61
75
  let(:batch_id) {"batch_id"}
@@ -2,17 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe "Browse Dashboard", type: :feature do
4
4
  let(:user) { FactoryGirl.create(:user) }
5
- let!(:fixtures) { create_file_fixtures(user.user_key) }
5
+ let!(:fixtures) { create_file_fixtures(user.user_key, handles) }
6
6
 
7
7
  before do
8
8
  sign_in user
9
9
  end
10
10
 
11
- it "should search your files by default" do
12
- visit "/dashboard"
13
- fill_in "q", with: "PDF"
14
- click_button "search-submit-header"
15
- expect(page).to have_content("Fake PDF Title")
11
+ context "within dashboard" do
12
+ let(:handles) { [:public_pdf] }
13
+
14
+ it "should search your files by default" do
15
+ visit "/dashboard"
16
+ fill_in "q", with: "PDF"
17
+ click_button "search-submit-header"
18
+ expect(page).to have_content("Fake PDF Title")
19
+ end
16
20
  end
17
21
 
18
22
  context "within my files page" do
@@ -21,78 +25,93 @@ describe "Browse Dashboard", type: :feature do
21
25
  visit "/dashboard/files"
22
26
  end
23
27
 
24
- it "should display all the necessary information" do
25
- # TODO this would make a good view test.
26
- within("#document_#{fixtures.first.id}") do
27
- click_button("Select an action")
28
- end
29
- expect(page).to have_content("Edit File")
30
- expect(page).to have_content("Download File")
31
- expect(page).to_not have_content("Is part of:")
32
- first(".label-success") do
33
- expect(page).to have_content("Open Access")
34
- end
35
- expect(page).to have_link("Create Collection")
36
- expect(page).to have_link("Upload")
37
- end
28
+ context "no files" do
29
+ let(:handles) { [ ] }
38
30
 
39
- it "should allow you to search your own files and remove constraints" do
40
- fill_in "q", with: "PDF"
41
- click_button "search-submit-header"
42
- expect(page).to have_content("Fake PDF Title")
43
- within(".constraints-container") do
44
- expect(page).to have_content("You searched for:")
45
- expect(page).to have_css("span.glyphicon-remove")
46
- find(".dropdown-toggle").click
31
+ it "should link to my other tabs" do
32
+ # TODO this would make a good view test.
33
+ ["My Collections", "My Highlights", "Files Shared with Me"].each do |tab|
34
+ within("#my_nav") do
35
+ click_link(tab)
36
+ end
37
+ expect(page).to have_content(tab)
38
+ end
47
39
  end
48
- expect(page).to have_content("Fake Wav File")
49
40
  end
50
41
 
51
- it "should allow you to browse facets" do
52
- click_link "Subject"
53
- click_link "more Subjects"
54
- click_link "consectetur"
55
- within("#document_#{fixtures[1].id}") do
56
- click_link "Display all details of Test Document MP3.mp3"
57
- end
58
- expect(page).to have_content("File Details")
59
- end
42
+ context "with one file" do
43
+ let(:handles) { [ :public_pdf ] }
60
44
 
61
- it "should allow me to edit files (from the fixtures)" do
62
- # TODO this would make a good view test.
63
- fill_in "q", with: "Wav"
64
- click_button "search-submit-header"
65
- click_button "Select an action"
66
- click_link "Edit File"
67
- expect(page).to have_content("Edit Fake Wav File.wav")
68
- end
69
-
70
- it "should refresh the page of files" do
71
- # TODO this would make a good view test.
72
- click_button "Refresh"
73
- within("#document_#{fixtures.first.id}") do
74
- click_button("Select an action")
45
+ it "should display all the necessary information" do
46
+ # TODO this would make a good view test.
47
+ within("#document_#{fixtures.first.id}") do
48
+ click_button("Select an action")
49
+ end
75
50
  expect(page).to have_content("Edit File")
76
51
  expect(page).to have_content("Download File")
52
+ expect(page).to_not have_content("Is part of:")
53
+ first(".label-success") do
54
+ expect(page).to have_content("Open Access")
55
+ end
56
+ expect(page).to have_link("Create Collection")
57
+ expect(page).to have_link("Upload")
77
58
  end
78
59
  end
79
60
 
80
- it "should allow me to edit files in batches" do
81
- first('input#check_all').click
82
- click_button('Edit Selected')
83
- expect(page).to have_content('3 files')
84
- end
61
+ context "with three files" do
62
+ let(:handles) { [:public_pdf, :public_mp3, :public_wav] }
85
63
 
86
- it "should link to my other tabs" do
87
- # TODO this would make a good view test.
88
- ["My Collections", "My Highlights", "Files Shared with Me"].each do |tab|
89
- within("#my_nav") do
90
- click_link(tab)
64
+ it "allows you to interact your own files" do
65
+
66
+ #refreshes the page of files
67
+ # TODO this would make a good view test.
68
+ click_button "Refresh"
69
+ within("#document_#{fixtures.first.id}") do
70
+ click_button("Select an action")
71
+ expect(page).to have_content("Edit File")
72
+ expect(page).to have_content("Download File")
73
+ end
74
+
75
+ # allows you to search your own files and remove constraints
76
+ fill_in "q", with: "PDF"
77
+ click_button "search-submit-header"
78
+ expect(page).to have_content("Fake PDF Title")
79
+ within(".constraints-container") do
80
+ expect(page).to have_content("You searched for:")
81
+ expect(page).to have_css("span.glyphicon-remove")
82
+ find(".dropdown-toggle").click
91
83
  end
92
- expect(page).to have_content(tab)
84
+ expect(page).to have_content("Fake Wav File")
85
+
86
+ # allows you to browse facets
87
+ visit "/dashboard/files"
88
+ click_link "Subject"
89
+ click_link "more Subjects"
90
+ click_link "consectetur"
91
+ within("#document_#{fixtures[1].id}") do
92
+ click_link "Display all details of Test Document MP3.mp3"
93
+ end
94
+ expect(page).to have_content("File Details")
95
+
96
+ # allows me to edit files (from the fixtures)
97
+ # TODO this would make a good view test.
98
+ visit "/dashboard/files"
99
+
100
+ fill_in "q", with: "Wav"
101
+ click_button "search-submit-header"
102
+ click_button "Select an action"
103
+ click_link "Edit File"
104
+ expect(page).to have_content("Edit Fake Wav File.wav")
105
+
106
+ # allows me to edit files in batches"
107
+ visit "/dashboard/files"
108
+
109
+ first('input#check_all').click
110
+ click_button('Edit Selected')
111
+ expect(page).to have_content('3 files')
112
+
93
113
  end
94
114
  end
95
-
96
115
  end
97
116
 
98
117
  end
@@ -0,0 +1,137 @@
1
+ describe "auto complete", ->
2
+ beforeEach ->
3
+ # set up the spy to see in the autocomplete is called
4
+ resp = [{"uri":"http://lexvo.org/id/iso639-3/fra","label":"French"},{"uri":"http://lexvo.org/id/iso639-3/fsl","label":"French Sign Language"}]
5
+ @spy_on_json = spyOn($, 'getJSON').and.returnValue resp
6
+
7
+ #set up a key down event to trigger the auto complete
8
+ @typeEvent = $.Event( 'keydown' )
9
+ @typeEvent.keyCode = 70 # lower case f
10
+
11
+ #define the jasmine clock so we can control time
12
+ jasmine.clock().install()
13
+
14
+ afterEach ->
15
+ #undefine the jasmine clock so time goes back to normal
16
+ jasmine.clock().uninstall()
17
+
18
+ describe "language", ->
19
+ beforeEach ->
20
+ # setup two inputs for us to attach auto complete to
21
+ setFixtures '<input class="generic_file_language" value="" id="generic_file_language" type="text" >
22
+ <input class="generic_file_language" value="" type="text">'
23
+
24
+ # run all Blacklight.onload functions
25
+ Blacklight.activate()
26
+
27
+ describe "first input", ->
28
+
29
+ # field triggers auto complete
30
+ it "auto completes on typing", ->
31
+ # send a key stroke to the target input to activate the auto complete
32
+ target = $($("input.generic_file_language")[0])
33
+ target.val('fre')
34
+ target.trigger(@typeEvent)
35
+
36
+ # move time along so that events have a chance to happen
37
+ jasmine.clock().tick(800);
38
+
39
+ # verify that the ajax call was made
40
+ expect(@spy_on_json).toHaveBeenCalled()
41
+
42
+
43
+ describe "second input", ->
44
+
45
+ # field triggers auto complete
46
+ it "auto completes on typing", ->
47
+ # send a key stroke to the target input to activate the auto complete
48
+ target = $($("input.generic_file_language")[1])
49
+ target.val('fre')
50
+ target.trigger(@typeEvent)
51
+
52
+ # move time along so that events have a chance to happen
53
+ jasmine.clock().tick(800);
54
+
55
+ # verify that the ajax call was made
56
+ expect(@spy_on_json).toHaveBeenCalled()
57
+
58
+ describe "subject", ->
59
+ beforeEach ->
60
+ # setup two inputs for us to attach auto complete to
61
+ setFixtures '<input class="generic_file_subject" value="" id="generic_file_subject" type="text" >
62
+ <input class="generic_file_subject" value="" type="text">'
63
+
64
+ # run all Blacklight.onload functions
65
+ Blacklight.activate()
66
+
67
+ describe "first input", ->
68
+
69
+ # field triggers auto complete
70
+ it "auto completes on typing", ->
71
+ # send a key stroke to the target input to activate the auto complete
72
+ target = $($("input.generic_file_subject")[0])
73
+ target.val('fre')
74
+ target.trigger(@typeEvent)
75
+
76
+ # move time along so that events have a chance to happen
77
+ jasmine.clock().tick(800);
78
+
79
+ # verify that the ajax call was made
80
+ expect(@spy_on_json).toHaveBeenCalled()
81
+
82
+
83
+ describe "second input", ->
84
+
85
+ # field triggers auto complete
86
+ it "auto completes on typing", ->
87
+ # send a key stroke to the target input to activate the auto complete
88
+ target = $($("input.generic_file_subject")[1])
89
+ target.val('fre')
90
+ target.trigger(@typeEvent)
91
+
92
+ # move time along so that events have a chance to happen
93
+ jasmine.clock().tick(800);
94
+
95
+ # verify that the ajax call was made
96
+ expect(@spy_on_json).toHaveBeenCalled()
97
+
98
+
99
+ describe "location", ->
100
+ beforeEach ->
101
+ # setup two inputs for us to attach auto complete to
102
+ setFixtures '<input class="generic_file_based_near" value="" id="generic_file_based_near" type="text" >
103
+ <input class="generic_file_based_near" value="" type="text">'
104
+
105
+ # run all Blacklight.onload functions
106
+ Blacklight.activate()
107
+
108
+ describe "first input", ->
109
+
110
+ # field triggers auto complete
111
+ it "auto completes on typing", ->
112
+ # send a key stroke to the target input to activate the auto complete
113
+ target = $($("input.generic_file_based_near")[0])
114
+ target.val('fre')
115
+ target.trigger(@typeEvent)
116
+
117
+ # move time along so that events have a chance to happen
118
+ jasmine.clock().tick(800);
119
+
120
+ # verify that the ajax call was made
121
+ expect(@spy_on_json).toHaveBeenCalled()
122
+
123
+
124
+ describe "second input", ->
125
+
126
+ # field triggers auto complete
127
+ it "auto completes on typing", ->
128
+ # send a key stroke to the target input to activate the auto complete
129
+ target = $($("input.generic_file_based_near")[1])
130
+ target.val('fre')
131
+ target.trigger(@typeEvent)
132
+
133
+ # move time along so that events have a chance to happen
134
+ jasmine.clock().tick(800);
135
+
136
+ # verify that the ajax call was made
137
+ expect(@spy_on_json).toHaveBeenCalled()
@@ -634,4 +634,104 @@ describe GenericFile, :type => :model do
634
634
  it { is_expected.not_to be_public }
635
635
  end
636
636
  end
637
+
638
+ describe "find_by_date_created" do
639
+ subject { GenericFile.find_by_date_created(start_date, end_date) }
640
+
641
+ context "with no start date" do
642
+ let(:start_date) { nil }
643
+ let(:end_date) { nil }
644
+ it { is_expected.to eq [] }
645
+ end
646
+
647
+ context "with no end date" do
648
+ let(:start_date) {1.days.ago}
649
+ let(:end_date) {nil}
650
+ before do
651
+ @file.save
652
+ end
653
+ it { is_expected.to eq [@file] }
654
+ end
655
+
656
+ context "with an end date" do
657
+ let(:start_date) { 1.days.ago }
658
+ let(:end_date) { DateTime.now }
659
+ before do
660
+ @file.save
661
+ end
662
+ it { is_expected.to eq [@file] }
663
+ end
664
+ end
665
+
666
+ describe "where_access_is" do
667
+ subject { GenericFile.where_access_is access_level }
668
+ before do
669
+ @file.read_groups = read_groups
670
+ @file.save
671
+ end
672
+
673
+ context "when file is private" do
674
+ let(:read_groups) { ["private"] }
675
+ context "when access level is private" do
676
+ let(:access_level) { 'private' }
677
+ it { is_expected.to eq [@file]}
678
+ end
679
+ context "when access level is public" do
680
+ let(:access_level) { 'public' }
681
+ it { is_expected.to eq []}
682
+ end
683
+ context "when access level is registered" do
684
+ let(:access_level) { 'registered' }
685
+ it { is_expected.to eq []}
686
+ end
687
+ end
688
+ context "when file is public" do
689
+ let(:read_groups) { ["public"] }
690
+ context "when access level is private" do
691
+ let(:access_level) { 'private' }
692
+ it { is_expected.to eq []}
693
+ end
694
+ context "when access level is public" do
695
+ let(:access_level) { 'public' }
696
+ it { is_expected.to eq [@file]}
697
+ end
698
+ context "when access level is registered" do
699
+ let(:access_level) { 'registered' }
700
+ it { is_expected.to eq []}
701
+ end
702
+ end
703
+ context "when file is registered" do
704
+ let(:read_groups) { ["registered"] }
705
+ context "when access level is private" do
706
+ let(:access_level) { 'private' }
707
+ it { is_expected.to eq []}
708
+ end
709
+ context "when access level is public" do
710
+ let(:access_level) {'public'}
711
+ it { is_expected.to eq []}
712
+ end
713
+ context "when access level is registered" do
714
+ let(:access_level) { 'registered' }
715
+ it { is_expected.to eq [@file]}
716
+ end
717
+ end
718
+ end
719
+ describe "where_private" do
720
+ it "calls where_access_is with private" do
721
+ expect(GenericFile).to receive(:where_access_is).with('private')
722
+ GenericFile.where_private
723
+ end
724
+ end
725
+ describe "where_registered" do
726
+ it "calls where_access_is with registered" do
727
+ expect(GenericFile).to receive(:where_access_is).with('registered')
728
+ GenericFile.where_registered
729
+ end
730
+ end
731
+ describe "where_public" do
732
+ it "calls where_access_is with public" do
733
+ expect(GenericFile).to receive(:where_access_is).with('public')
734
+ GenericFile.where_public
735
+ end
736
+ end
637
737
  end
@@ -172,4 +172,31 @@ describe User, :type => :model do
172
172
  expect(another_user.can_receive_deposits_from.to_a).to eq [@subject]
173
173
  end
174
174
  end
175
+ describe "class methods" do
176
+ describe "recent_users" do
177
+ let(:new_users) { User.all.order(created_at: :desc) }
178
+
179
+ before do
180
+ (1..3).each {|i| User.create(email: "abc#{i}@blah.frg", password: "blarg1234", created_at:DateTime.now - i.days) }
181
+ end
182
+
183
+ context "when has a start date" do
184
+ subject { User.recent_users(Date.today - 2.days) }
185
+ it "returns valid data" do
186
+ expect(subject.count).to eq 2
187
+ is_expected.to include(new_users[0],new_users[1])
188
+ is_expected.not_to include(new_users[2])
189
+ end
190
+ end
191
+
192
+ context "when has start and end date" do
193
+ subject { User.recent_users(Date.today - 2.days, Date.today - 1.days) }
194
+ it "returns valid data" do
195
+ expect(subject.count).to eq 1
196
+ is_expected.to include(new_users[1])
197
+ is_expected.not_to include(new_users[2], new_users[0])
198
+ end
199
+ end
200
+ end
201
+ end
175
202
  end
@@ -25,10 +25,14 @@ require 'support/rake'
25
25
  require 'support/input_support'
26
26
  require 'byebug' unless ENV['TRAVIS']
27
27
 
28
- if ENV['COVERAGE']
28
+ if ENV['COVERAGE'] || ENV['TRAVIS']
29
29
  require 'simplecov'
30
- SimpleCov.start 'rails'
31
- SimpleCov.command_name "spec"
30
+ SimpleCov.root(File.expand_path('../..', __FILE__))
31
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
32
+ SimpleCov.start('rails') do
33
+ add_filter '/spec'
34
+ end
35
+ SimpleCov.command_name 'spec'
32
36
  end
33
37
 
34
38
  Capybara.default_driver = :rack_test # This is a faster driver
@@ -1,7 +1,6 @@
1
1
  # spec/support/fixture_helpers.rb
2
2
  module FixtureHelpers
3
- def create_file_fixtures(depositor = 'archivist1@example.com')
4
- handles = [:public_pdf, :public_mp3, :public_wav]
3
+ def create_file_fixtures(depositor = 'archivist1@example.com', handles = [:public_pdf, :public_mp3, :public_wav])
5
4
  handles.map { |handle| FactoryGirl.create(handle, depositor: depositor) }
6
5
  end
7
6
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'users/_user_info.html.erb', type: :view do
4
+ let(:user) { stub_model(User, user_key: 'jdoe42') }
5
+
6
+ context 'with Zotero disabled' do
7
+ before do
8
+ allow(Sufia.config).to receive(:arkivo_api) { false }
9
+ allow(user).to receive(:zotero_userid).and_raise(NoMethodError)
10
+ render "users/user_info", user: user
11
+ end
12
+
13
+ it 'does not display a Zotero profile link' do
14
+ expect(rendered).not_to match(/Zotero Profile/)
15
+ end
16
+ end
17
+
18
+ context 'with Zotero enabled' do
19
+ before do
20
+ allow(Sufia.config).to receive(:arkivo_api) { true }
21
+ allow(user).to receive(:zotero_userid) { 'jdoe42zotero' }
22
+ render "users/user_info", user: user
23
+ end
24
+
25
+ it 'displays a Zotero profile link' do
26
+ expect(rendered).to match(/Zotero Profile/)
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sufia
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-07-02 00:00:00.000000000 Z
12
+ date: 2015-07-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sufia-models
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 6.1.0
20
+ version: 6.2.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 6.1.0
27
+ version: 6.2.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: blacklight_advanced_search
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -683,6 +683,8 @@ files:
683
683
  - app/views/_logo.html.erb
684
684
  - app/views/_masthead.html.erb
685
685
  - app/views/_user_util_links.html.erb
686
+ - app/views/admin/stats/_files.html.erb
687
+ - app/views/admin/stats/_new_users.html.erb
686
688
  - app/views/admin/stats/index.html.erb
687
689
  - app/views/advanced/_advanced_search_facets.html.erb
688
690
  - app/views/advanced/_advanced_search_fields.html.erb
@@ -1031,6 +1033,7 @@ files:
1031
1033
  - spec/inputs/multi_value_with_help_input_spec.rb
1032
1034
  - spec/inputs/select_with_help_input_spec.rb
1033
1035
  - spec/inputs/select_with_modal_help_input_spec.rb
1036
+ - spec/javascripts/autocomplete_spec.js.coffee
1034
1037
  - spec/javascripts/helpers/.gitkeep
1035
1038
  - spec/javascripts/helpers/jasmine-jquery.js
1036
1039
  - spec/javascripts/jasmine_spec.rb
@@ -1134,6 +1137,7 @@ files:
1134
1137
  - spec/views/users/_follower_modal.html.erb_spec.rb
1135
1138
  - spec/views/users/_following_modal.html.erb_spec.rb
1136
1139
  - spec/views/users/_notify_number.html.erb_spec.rb
1140
+ - spec/views/users/_user_info.html.erb_spec.rb
1137
1141
  - spec/views/users/_user_util_links.html.erb_spec.rb
1138
1142
  - spec/views/users/edit.html.erb_spec.rb
1139
1143
  - spec/views/users/index.html.erb_spec.rb
@@ -1201,7 +1205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1201
1205
  version: '0'
1202
1206
  requirements: []
1203
1207
  rubyforge_project:
1204
- rubygems_version: 2.4.5
1208
+ rubygems_version: 2.4.6
1205
1209
  signing_key:
1206
1210
  specification_version: 4
1207
1211
  summary: Sufia was extracted from ScholarSphere developed by Penn State University
@@ -1304,6 +1308,7 @@ test_files:
1304
1308
  - spec/inputs/multi_value_with_help_input_spec.rb
1305
1309
  - spec/inputs/select_with_help_input_spec.rb
1306
1310
  - spec/inputs/select_with_modal_help_input_spec.rb
1311
+ - spec/javascripts/autocomplete_spec.js.coffee
1307
1312
  - spec/javascripts/helpers/.gitkeep
1308
1313
  - spec/javascripts/helpers/jasmine-jquery.js
1309
1314
  - spec/javascripts/jasmine_spec.rb
@@ -1407,6 +1412,7 @@ test_files:
1407
1412
  - spec/views/users/_follower_modal.html.erb_spec.rb
1408
1413
  - spec/views/users/_following_modal.html.erb_spec.rb
1409
1414
  - spec/views/users/_notify_number.html.erb_spec.rb
1415
+ - spec/views/users/_user_info.html.erb_spec.rb
1410
1416
  - spec/views/users/_user_util_links.html.erb_spec.rb
1411
1417
  - spec/views/users/edit.html.erb_spec.rb
1412
1418
  - spec/views/users/index.html.erb_spec.rb