sufia 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -4
  3. data/Gemfile +0 -3
  4. data/History.md +29 -0
  5. data/README.md +2 -4
  6. data/SUFIA_VERSION +1 -1
  7. data/app/assets/javascripts/sufia/audio.js +28 -0
  8. data/app/assets/javascripts/sufia/single_use_link.js +35 -0
  9. data/app/assets/javascripts/sufia.js +2 -20
  10. data/app/assets/stylesheets/sufia-audio-overrides.css +9 -0
  11. data/app/assets/stylesheets/sufia.css.scss +1 -1
  12. data/app/assets/stylesheets/video-js.css +700 -433
  13. data/app/controllers/concerns/sufia/dashboard_controller_behavior.rb +0 -12
  14. data/app/controllers/concerns/sufia/users_controller_behavior.rb +12 -18
  15. data/app/controllers/dashboard_controller.rb +1 -2
  16. data/app/helpers/sufia_helper.rb +6 -5
  17. data/app/helpers/trophy_helper.rb +1 -1
  18. data/app/views/catalog/_index_partials/_default_group.html.erb +1 -2
  19. data/app/views/catalog/_results_pagination.html.erb +3 -3
  20. data/app/views/catalog/index.html.erb +0 -3
  21. data/app/views/dashboard/_index_partials/_thumbnail_display.html.erb +2 -2
  22. data/app/views/dashboard/_results_pagination.html.erb +5 -21
  23. data/app/views/dashboard/facet.html.erb +1 -1
  24. data/app/views/dashboard/index.html.erb +5 -35
  25. data/app/views/generic_files/_media_display.html.erb +4 -4
  26. data/app/views/layouts/sufia-two-column.html.erb +0 -16
  27. data/app/views/users/_contributions.html.erb +20 -28
  28. data/app/views/users/_profile_actions.html.erb +8 -9
  29. data/app/views/users/edit.html.erb +3 -6
  30. data/config/routes.rb +7 -8
  31. data/lib/sufia/version.rb +1 -1
  32. data/spec/controllers/users_controller_spec.rb +56 -20
  33. data/spec/features/browse_files_spec.rb +14 -12
  34. data/spec/helpers/sufia_helper_spec.rb +21 -0
  35. data/spec/models/generic_file_spec.rb +24 -66
  36. data/spec/models/user_spec.rb +16 -4
  37. data/sufia-models/app/models/checksum_audit_log.rb +0 -1
  38. data/sufia-models/app/models/concerns/sufia/user.rb +11 -21
  39. data/sufia-models/app/models/domain_term.rb +1 -6
  40. data/sufia-models/app/models/local_authority.rb +2 -10
  41. data/sufia-models/app/models/local_authority_entry.rb +0 -1
  42. data/sufia-models/app/models/single_use_link.rb +1 -3
  43. data/sufia-models/app/models/sufia/avatar_uploader.rb +22 -0
  44. data/sufia-models/app/models/sufia/avatar_validator.rb +8 -0
  45. data/sufia-models/app/models/trophy.rb +0 -2
  46. data/sufia-models/app/models/version_committer.rb +0 -1
  47. data/sufia-models/lib/generators/sufia/models/templates/migrations/add_avatars_to_users.rb +8 -2
  48. data/sufia-models/lib/sufia/models/engine.rb +1 -3
  49. data/sufia-models/lib/sufia/models/generic_file.rb +7 -0
  50. data/sufia-models/lib/sufia/models/version.rb +1 -1
  51. data/sufia-models/lib/sufia/models.rb +1 -1
  52. data/sufia-models/sufia-models.gemspec +4 -8
  53. data/sufia.gemspec +1 -1
  54. data/tasks/sufia-dev.rake +0 -1
  55. data/vendor/assets/javascripts/video.js +129 -4569
  56. metadata +24 -23
  57. data/sufia-models/lib/sufia/models/active_record/deprecated_attr_accessible.rb +0 -16
  58. data/sufia-models/lib/sufia/models/active_support/core_ext/marshal.rb +0 -22
  59. data/tasks/sufia.rake +0 -173
@@ -7,8 +7,6 @@ module Sufia
7
7
  include Blacklight::Catalog
8
8
 
9
9
  included do
10
- include Hydra::BatchEditBehavior
11
- include Blacklight::Catalog
12
10
  include Blacklight::Configurable # comply with BL 3.7
13
11
  include ActionView::Helpers::DateHelper
14
12
  # This is needed as of BL 3.7
@@ -30,22 +28,12 @@ module Sufia
30
28
  end
31
29
 
32
30
  def index
33
- if params[:controller] == "dashboard"
34
- extra_head_content << view_context.auto_discovery_link_tag(:rss, sufia.url_for(params.merge(:format => 'rss')), :title => "RSS for results")
35
- extra_head_content << view_context.auto_discovery_link_tag(:atom, sufia.url_for(params.merge(:format => 'atom')), :title => "Atom for results")
36
- else
37
- # This is for controllers that use this behavior that are defined outside Sufia
38
- extra_head_content << view_context.auto_discovery_link_tag(:rss, url_for(params.merge(:format => 'rss')), :title => "RSS for results")
39
- extra_head_content << view_context.auto_discovery_link_tag(:atom, url_for(params.merge(:format => 'atom')), :title => "Atom for results")
40
- end
41
31
  (@response, @document_list) = get_search_results
42
32
  @user = current_user
43
33
  @events = @user.events(100)
44
34
  @last_event_timestamp = @user.events.first[:timestamp].to_i || 0 rescue 0
45
35
  @filters = params[:f] || []
46
36
 
47
- # adding a key to the session so that the history will be saved so that batch_edits select all will work
48
- search_session[:dashboard] = true
49
37
  respond_to do |format|
50
38
  format.html { }
51
39
  format.rss { render :layout => false }
@@ -33,7 +33,7 @@ module Sufia::UsersControllerBehavior
33
33
  else
34
34
  @events = []
35
35
  end
36
- @trophies = @user.trophy_ids
36
+ @trophies = @user.trophy_files
37
37
  @followers = @user.followers
38
38
  @following = @user.all_following
39
39
  end
@@ -41,17 +41,13 @@ module Sufia::UsersControllerBehavior
41
41
  # Display form for users to edit their profile information
42
42
  def edit
43
43
  @user = current_user
44
- @trophies = @user.trophy_ids
44
+ @trophies = @user.trophy_files
45
45
  end
46
46
 
47
47
  # Process changes from profile form
48
48
  def update
49
49
  if params[:user]
50
- if Rails::VERSION::MAJOR == 3
51
- @user.update_attributes(params[:user])
52
- else
53
- @user.update_attributes(params.require(:user).permit(*User.permitted_attributes))
54
- end
50
+ @user.update_attributes(params.require(:user).permit(*User.permitted_attributes))
55
51
  end
56
52
  @user.populate_attributes if params[:update_directory]
57
53
  @user.avatar = nil if params[:delete_avatar]
@@ -59,31 +55,29 @@ module Sufia::UsersControllerBehavior
59
55
  redirect_to sufia.edit_profile_path(URI.escape(@user.to_s,'@.')), alert: @user.errors.full_messages
60
56
  return
61
57
  end
62
- delete_trophy = params.keys.reject{|k,v|k.slice(0,'remove_trophy'.length)!='remove_trophy'}
63
- delete_trophy = delete_trophy.map{|v| v.slice('remove_trophy_'.length..-1)}
64
- delete_trophy.each do | smash_trophy |
65
- Trophy.where(user_id: current_user.id, generic_file_id: smash_trophy).each.map(&:delete)
58
+ params.keys.select {|k, v| k.starts_with? 'remove_trophy_' }.each do |smash_trophy|
59
+ smash_trophy = smash_trophy.sub /^remove_trophy_/, ''
60
+ current_user.trophies.where(generic_file_id: smash_trophy).destroy_all
66
61
  end
67
62
  Sufia.queue.push(UserEditProfileEventJob.new(@user.user_key))
68
63
  redirect_to sufia.profile_path(URI.escape(@user.to_s,'@.')), notice: "Your profile has been updated"
69
64
  end
70
65
 
71
66
  def toggle_trophy
72
- id = params[:file_id]
73
- id = "#{Sufia.config.id_namespace}:#{id}" unless id.include?(":")
67
+ id = Sufia::Noid.namespaceize params[:file_id]
74
68
  unless current_user.can? :edit, id
75
69
  redirect_to root_path, alert: "You do not have permissions to the file"
76
70
  return false
77
71
  end
78
72
  # TODO make sure current user has access to file
79
- t = Trophy.where(:generic_file_id => params[:file_id], :user_id => current_user.id).first
80
- if t.blank?
81
- t = Trophy.create(:generic_file_id => params[:file_id], :user_id => current_user.id)
82
- return false unless t.persisted?
83
- else
73
+ t = current_user.trophies.where(generic_file_id: params[:file_id]).first
74
+ if t
84
75
  t.destroy
85
76
  #TODO do this better says Mike
86
77
  return false if t.persisted?
78
+ else
79
+ t = current_user.trophies.create(generic_file_id: params[:file_id])
80
+ return false unless t.persisted?
87
81
  end
88
82
  render :json => t
89
83
  end
@@ -1,4 +1,3 @@
1
- require 'blacklight/catalog'
2
1
  class DashboardController < ApplicationController
3
- include Sufia::DashboardControllerBehavior
2
+ include Sufia::DashboardControllerBehavior
4
3
  end
@@ -76,13 +76,14 @@ module SufiaHelper
76
76
  end
77
77
 
78
78
  # Create a link back to the index screen, keeping the user's facet, query and paging choices intact by using session.
79
+ # We should be able to do away with this method in Blacklight 5
79
80
  # @example
80
81
  # link_back_to_catalog(:label=>'Back to Search')
81
- def link_back_to_catalog(opts={:label=>t('blacklight.back_to_search')})
82
- query_params = session[:search] ? session[:search].dup : {}
83
- query_params.delete :counter
84
- query_params.delete :total
85
- link_url = sufia.url_for(query_params)
82
+ def link_back_to_catalog(opts={:label=>nil})
83
+ scope = opts.delete(:route_set) || self
84
+ query_params = current_search_session.try(:query_params) || {}
85
+ link_url = scope.url_for(query_params)
86
+ opts[:label] ||= t('blacklight.back_to_search')
86
87
  link_to opts[:label], link_url
87
88
  end
88
89
  end
@@ -7,6 +7,6 @@ module TrophyHelper
7
7
  trophyclass = "trophy-on"
8
8
  end
9
9
 
10
- return link_to raw("<i class='#{trophyclass} icon-trophy'></i> #{trophytitle}"),"", :class=> 'trophy-class', :title => trophytitle, :id => noid, :remote=>true # link to trophy
10
+ link_to raw("<i class='#{trophyclass} icon-trophy'></i> #{trophytitle}"),"", :class=> 'trophy-class', :title => trophytitle, :id => noid, :remote=>true # link to trophy
11
11
  end
12
12
  end
@@ -1,6 +1,5 @@
1
- <% page_info = paginate_params(@response) %>
2
1
  <div id="search-results">
3
- <ol class="catalog" start="<%=1+((page_info.current_page-1)*page_info.limit_value)%>">
2
+ <ol class="catalog" start="<%=1+((@response.current_page-1)*@response.limit_value)%>">
4
3
  <% docs.each_with_index do |document,counter| %>
5
4
  <%= render :partial => 'catalog/_index_partials/list_files', :locals => {:document => document, :counter => counter} %>
6
5
  <% end %>
@@ -1,6 +1,6 @@
1
- <% if paginate_params(@response).num_pages > 1 %>
2
- <div class="pager">
3
- <%= paginate_rsolr_response @response, :outer_window => 2, :theme => 'blacklight', :route_set=> sufia %>
1
+ <% if @response.total_pages > 1 %>
2
+ <div class="pager">
3
+ <%= paginate @response, :outer_window => 2, :theme => 'blacklight', :route_set=> sufia %>
4
4
  <div class="clearfix"></div>
5
5
  </div><!-- /pager -->
6
6
  <% end %>
@@ -14,8 +14,6 @@
14
14
 
15
15
  <% @page_title = application_name + " Search Results" %>
16
16
 
17
- <% extra_head_content << render_opensearch_response_metadata.html_safe %>
18
-
19
17
  <h3>Search Results</h3>
20
18
  <div class="alert alert-info"><i class="icon-search icon-large"></i> You searched for: <strong><%= render_constraints(params) %></strong></div>
21
19
  <%= render :partial => 'did_you_mean' %>
@@ -23,7 +21,6 @@
23
21
  <%# render 'constraints', :localized_params=>params %>
24
22
 
25
23
  <div class="row">
26
- <%= render_pagination_info @response, :entry_name=>'item' %>
27
24
  <%= render 'sort_and_per_page' %>
28
25
  <div class="row offset80">
29
26
  <%= link_to "New Search", catalog_index_path, :id=>"startOverLink", :class=>"btn btn-info btn-medium" %>
@@ -2,8 +2,8 @@
2
2
  <% if document.image? || document.pdf? || document.video? %>
3
3
  <% path = sufia.download_path(document.noid, {datastream_id: 'thumbnail'}) %>
4
4
  <% elsif document.audio? %>
5
- <% path = "/assets/audio.png" %>
5
+ <% path = "audio.png" %>
6
6
  <% else %>
7
- <% path = "/assets/default.png" %>
7
+ <% path = "default.png" %>
8
8
  <% end %>
9
9
  <%= link_to image_tag(path, {width: width}), sufia.generic_file_path(document) %>
@@ -1,22 +1,6 @@
1
- <%#
2
- Copyright © 2012 The Pennsylvania State University
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- %>
16
-
17
- <% if paginate_params(@response).num_pages > 1 %>
18
- <div class="pager">
19
- <%= paginate_rsolr_response @response, :outer_window => 2, :theme => 'blacklight', :route_set=> sufia %>
20
- <div class="clearfix"></div>
21
- </div><!-- /pager -->
1
+ <% if @response.total_pages > 1 %>
2
+ <div class="pager">
3
+ <%= paginate @response, :outer_window => 2, :theme => 'blacklight', :route_set=> sufia %>
4
+ <div class="clearfix"></div>
5
+ </div><!-- /pager -->
22
6
  <% end %>
@@ -2,7 +2,7 @@
2
2
  It implements the facets in the same manner as blacklight does for the main catalog for the individual's dashbord
3
3
  -->
4
4
  <% content_for :sidebar do %>
5
- <p><%= link_back_to_catalog %></p>
5
+ <p><%= link_back_to_catalog (route_set: sufia) %></p>
6
6
  <% end %>
7
7
 
8
8
  <div class="facet_pagination top">
@@ -13,43 +13,15 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  %>
16
+ <% content_for :head do %>
17
+ <%= auto_discovery_link_tag(:rss, sufia.url_for(params.merge(:format => 'rss')), :title => "RSS for results") %>
18
+ <%= auto_discovery_link_tag(:atom, sufia.url_for(params.merge(:format => 'atom')), :title => "Atom for results") %>
19
+ <% end %>
16
20
 
17
21
  <% content_for :local_js do %>
18
22
 
19
23
  initialize_audio();
20
24
 
21
- function getSingleUse(id) {
22
- <% rurl = root_url %>
23
- <% rurl = rurl.slice(0, rurl.length-1) if rurl[rurl.length-1] == "/" %>
24
- var resp = $.ajax({
25
- headers: { Accept: "application/javascript" },
26
- type: 'get',
27
- url: "<%= rurl %>/single_use_link/generate_show/" + id.slice(10),
28
- async: false,
29
- });
30
- return "<%= rurl %>/" + resp.responseText;
31
- }
32
-
33
- // Load clipboard swf
34
- $(document).ready(function() {
35
- ZeroClipboard.setDefaults({ moviePath: "/assets/ZeroClipboard.swf" });
36
- $.each($(".copypaste"), function() {
37
- var clip = new ZeroClipboard();
38
- clip.on("dataRequested", function(client, args) {
39
- clip.setText(getSingleUse(this.id));
40
- })
41
- clip.on("complete", function(client, args) {
42
- alert("A single use link to " + args.text + " was copied to your clipboard.")
43
- })
44
- clip.on("noflash", function(client, args) {
45
- alert("Your single-use link: " + getSingleUse(this.id))
46
- })
47
- clip.on("wrongflash", function(client, args) {
48
- alert("Your single-use link: " + getSingleUse(this.id))
49
- })
50
- clip.glue($("#" + this.id))
51
- })
52
- });
53
25
 
54
26
  // hide or show the batch update buttons on page startup
55
27
  window.batch_part_on_other_page = <%= @batch_part_on_other_page%>;
@@ -73,7 +45,7 @@ limitations under the License.
73
45
  <%= render :partial => 'heading' %>
74
46
  </div>
75
47
 
76
- <% extra_head_content << render_opensearch_response_metadata.html_safe %>
48
+
77
49
  <% if params.has_key?("q") %>
78
50
  <div class="alert alert-info"><i class="icon-search icon-large"></i> You searched for: <strong><%= params[:q] %></strong></div>
79
51
  <% end %>
@@ -82,8 +54,6 @@ limitations under the License.
82
54
  <%= render :partial => 'facet_selected' %>
83
55
 
84
56
  <%= render 'constraints', :localized_params=>params %>
85
-
86
- <% render_pagination_info @response, :entry_name=>'item' %>
87
57
 
88
58
  <%= render 'sort_and_per_page' %>
89
59
 
@@ -1,5 +1,5 @@
1
1
  <% if @generic_file.image? %>
2
- <a href="<%= sufia.download_path(@generic_file) %>" target="_new" title="Download the full-sized image"><img src="<%= sufia.download_path(@generic_file, {:datastream_id => 'thumbnail'}) %>" width="338" alt="Download the full-sized image of <%= @generic_file.title.first %>"/>Download the full-sized image</a>
2
+ <%= link_to image_tag(sufia.download_path(@generic_file, datastream_id: 'thumbnail'),{width:"338", alt:"Download the full-sized image of #{@generic_file.title.first}"})+"Download the full-sized image", sufia.download_path(@generic_file), { target:"_new", title:"Download the full-sized image"}%>
3
3
  <% elsif @generic_file.video? %>
4
4
  <video controls="controls" class="video-js vjs-default-skin" data-setup="{}" preload="auto">
5
5
  <source src="<%= sufia.download_path(@generic_file, datastream_id: 'webm') %>" type="video/webm" />
@@ -7,13 +7,13 @@
7
7
  Your browser does not support the video tag.
8
8
  </video>
9
9
  <% elsif @generic_file.audio? %>
10
- <audio controls="controls" class="video-js vjs-default-skin" data-setup="{}" preload="auto">
10
+ <audio controls="controls" class="audiojs" preload="auto">
11
11
  <source src="<%= sufia.download_path(@generic_file, datastream_id: 'ogg') %>" type="audio/ogg" />
12
12
  <source src="<%= sufia.download_path(@generic_file, datastream_id: 'mp3') %>" type="audio/mpeg" />
13
13
  Your browser does not support the audio tag.
14
14
  </audio>
15
15
  <% elsif @generic_file.pdf?%>
16
- <a href="<%= sufia.download_path(@generic_file) %>" target="_new" title="Download the full-sized PDF"><img src="<%= sufia.download_path(@generic_file, datastream_id: 'thumbnail') %>" width="338" alt="Download the full-sized PDF of <%= @generic_file.title.first %>"/>Download the full-sized PDF</a>
16
+ <%= link_to image_tag(sufia.download_path(@generic_file, datastream_id: 'thumbnail'),{width:"338", alt:"Download the full-sized PDF of #{@generic_file.title.first}"})+"Download the full-sized PDF", sufia.download_path(@generic_file), { target:"_new", title:"Download the full-sized PDF"}%>
17
17
  <% else %>
18
- <a href="<%= sufia.download_path(@generic_file) %>" target="_new"><img src="/assets/default.png" alt="No preview available" width="338" height="493" /></a>
18
+ <%= link_to image_tag("default.png", {alt:"No preview available", width:"338", height:"493"}), sufia.download_path(@generic_file), { target:"_new", title:"Download the document"} %>
19
19
  <% end %>
@@ -1,19 +1,3 @@
1
- <%#
2
- Copyright © 2012 The Pennsylvania State University
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- %>
16
-
17
1
  <!DOCTYPE html>
18
2
  <html>
19
3
  <head>
@@ -1,29 +1,21 @@
1
- <div class="tab-pane active" id="contributions">
2
- <i class="icon-trophy trophy-on" ></i> <strong>Highlighted Files</strong>
3
- <% if @trophies.count > 0 %>
4
- <table>
5
- <% @trophies.each do |t| %>
6
- <tr id="trophyrow_<%= Sufia::Noid.noidify(t.pid) %>">
7
- <% if t.image? || t.pdf? %>
8
- <% temp_thumbnail_path = sufia.download_path(t) + "?datastream_id=thumbnail" %>
9
- <% temp_href = "<a href=\"" + sufia.download_path(t) + "\"> <img src=\"" + temp_thumbnail_path + "\" width=\"90\" alt=\"Download the full-sized image\"/></a>" %>
10
- <% else %>
11
- <% temp_href = "<a href=\"" + sufia.download_path(t) + "\"> <img src=\"/assets/default.png\" width=\"90\" alt=\"Download file\"/></a>" %>
12
- <% end %>
13
- <td>
14
- <%= temp_href.html_safe() %>
15
- </td>
16
- <td>
17
- <%= link_to display_title(t), sufia.generic_file_path(t) %>
18
- <% if current_user == @user %>
19
- <%= link_to raw("<i class='trophy-on icon-remove'></i>"),"", class: 'trophy-on trophy-class', title: "Click to remove from Highlighted files.", id: Sufia::Noid.noidify(t.pid), remote: true, data: {removerow: "true" } %>
20
- <% end %>
21
- </td>
22
- </tr>
23
- <% end %>
24
- </table>
25
- <% else %>
26
- <%= @user.name %> has no highlighted files.
27
- <% end %>
28
- </div>
1
+ <div class="tab-pane active" id="contributions">
2
+ <i class="icon-trophy trophy-on"></i> <strong>Highlighted Files</strong>
3
+ <% if @trophies.count > 0 %>
4
+ <table>
5
+ <% @trophies.each do |t| %>
6
+ <tr id="trophyrow_<%= Sufia::Noid.noidify(t.pid) %>">
7
+ <td>
8
+ <%= render partial: "dashboard/_index_partials/thumbnail_display", locals: {document: t, width: 90} %>
9
+ </td>
10
+ <td>
11
+ <%= link_to display_title(t), sufia.generic_file_path(t) %>
12
+ <%= link_to raw("<i class='trophy-on icon-remove'></i>"), "", class: 'trophy-on trophy-class', title: "Click to remove from Highlighted files.", id: Sufia::Noid.noidify(t.pid), remote: true, data: {removerow: "true"} if current_user == @user%>
13
+ </td>
14
+ </tr>
15
+ <% end %>
16
+ </table>
17
+ <% else %>
18
+ <%= @user.name %> has no highlighted files.
19
+ <% end %>
20
+ </div>
29
21
 
@@ -1,11 +1,10 @@
1
1
  <!-- profile and view buttons -->
2
- <% if not signed_in? %>
3
- <!-- sign in to access social functions -->
4
- <% elsif current_user == @user %>
5
- <a class="btn" href="<%= sufia.edit_profile_path(@user) %>"><i class="icon-edit"></i> Edit Your Profile </a>
6
- <% elsif current_user.following?(@user) %>
7
- <a class="btn btn-primary" href="<%= sufia.unfollow_user_path(@user) %>"><i class="icon-eye-close"></i> Unfollow </a>
8
- <% else %>
9
- <a class="btn btn-primary" href="<%= sufia.follow_user_path(@user) %>"><i class="icon-eye-open"></i> Follow</a>
2
+ <% if signed_in? %>
3
+ <% if current_user == @user %>
4
+ <%= link_to raw('<i class="icon-edit"></i> Edit Your Profile'), sufia.edit_profile_path(@user), class: "btn" %>
5
+ <% elsif current_user.following?(@user) %>
6
+ <%= link_to raw('<i class="icon-eye-close"></i> Unfollow'), sufia.unfollow_profile_path(@user), method: :post, class: "btn btn-primary" %>
7
+ <% else %>
8
+ <%= link_to raw('<i class="icon-eye-open"></i> Follow'), sufia.follow_profile_path(@user), method: :post, class: "btn btn-primary" %>
9
+ <% end %>
10
10
  <% end %>
11
-
@@ -9,10 +9,9 @@ $("a[rel=popover]").popover({ html: true });
9
9
  <div class="control-group">
10
10
  <%= f.label :avatar, '<i class="icon-camera-retro"></i> Change picture'.html_safe, :class => "control-label" %>
11
11
  <div class="controls">
12
- <% if @user.avatar? %>
13
- <%= image_tag @user.avatar.url(:thumb) %>
14
- <% end %>
12
+ <%= image_tag @user.avatar.url(:thumb) if @user.avatar? %>
15
13
  <%= f.file_field :avatar %>
14
+ <%= f.hidden_field :avatar_cache %>
16
15
  <span class="label label-important">JPG, GIF, or PNG (less than 2MB)</span>
17
16
  </div>
18
17
  </div>
@@ -21,7 +20,7 @@ $("a[rel=popover]").popover({ html: true });
21
20
  <%= f.label :delete_avatar, '<i class="icon-remove"></i> Delete picture'.html_safe, :class => 'control-label' %>
22
21
  <div class="controls">
23
22
  <label class="checkbox">
24
- <%= check_box_tag 'delete_avatar' %> Yes
23
+ <%= f.check_box :remove_avatar %> Yes
25
24
  <a href="#" id="delete_picture_help" rel="popover" data-content="If you would like to remove your picture entirely, check the box and save your profile." data-original-title="Delete Picture"><i class="icon-question-sign icon-large"></i></a>
26
25
  </label>
27
26
  </div>
@@ -60,7 +59,6 @@ $("a[rel=popover]").popover({ html: true });
60
59
 
61
60
  <%= render :partial => 'trophy_edit', :locals => {:trophies => @trophies} %>
62
61
 
63
-
64
62
  <div class="form-actions">
65
63
  <%= f.button '<i class="icon-save"></i> Save Profile'.html_safe, :type => 'submit', :class => "btn-primary btn-large" %>
66
64
  </div>
@@ -78,4 +76,3 @@ $("a[rel=popover]").popover({ html: true });
78
76
  <i class="icon-caret-right"></i> <%= g %><br />
79
77
  <% end %>
80
78
  </div>
81
-
data/config/routes.rb CHANGED
@@ -34,14 +34,13 @@ Sufia::Engine.routes.draw do
34
34
  end
35
35
 
36
36
  # User profile & follows
37
- resources :users, only: [:index, :show, :edit, :update], as: :profiles
38
- # get 'users' => 'users#index', :as => :profiles
39
- # get 'users/:uid' => 'users#show', :as => :profile
40
- # get 'users/:uid/edit' => 'users#edit', :as => :edit_profile
41
- # put 'users/:uid/update' => 'users#update', :as => :update_profile
42
- post "users/:id/trophy" => "users#toggle_trophy", :as => :update_trophy_user
43
- match 'users/:id/follow' => 'users#follow', :as => :follow_user, via: [:get, :post]
44
- match 'users/:id/unfollow' => 'users#unfollow', :as => :unfollow_user, via: [:get, :post]
37
+ resources :users, only: [:index, :show, :edit, :update], as: :profiles do
38
+ member do
39
+ post 'trophy' => 'users#toggle_trophy' #used by trophy.js
40
+ post 'follow' => 'users#follow'
41
+ post 'unfollow' => 'users#unfollow'
42
+ end
43
+ end
45
44
 
46
45
  # Dashboard routes (based partly on catalog routes)
47
46
  resources 'dashboard', :only=>:index do
data/lib/sufia/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sufia
2
- VERSION = "3.6.0"
2
+ VERSION = "3.7.0"
3
3
  end
@@ -26,6 +26,23 @@ describe UsersController do
26
26
  response.should redirect_to(root_path)
27
27
  flash[:alert].should include ("User 'johndoe666' does not exist")
28
28
  end
29
+
30
+ describe "when the user has trophies" do
31
+ let(:user) { @user }
32
+ let(:file1) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
33
+ let(:file2) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
34
+ let(:file3) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
35
+ let!(:trophy1) { user.trophies.create!(generic_file_id: file1.noid) }
36
+ let!(:trophy2) { user.trophies.create!(generic_file_id: file2.noid) }
37
+ let!(:trophy3) { user.trophies.create!(generic_file_id: file3.noid) }
38
+
39
+ it "show the user profile if user exists" do
40
+ get :show, id: user.user_key
41
+ response.should be_success
42
+ assigns[:trophies].should match_array([file1, file2, file3])
43
+ end
44
+
45
+ end
29
46
  end
30
47
  describe "#index" do
31
48
  before do
@@ -61,6 +78,22 @@ describe UsersController do
61
78
  response.should redirect_to(@routes.url_helpers.profile_path(URI.escape(@another_user.user_key,'@.')))
62
79
  flash[:alert].should include("Permission denied: cannot access this page.")
63
80
  end
81
+ describe "when the user has trophies" do
82
+ let(:user) { @user }
83
+ let(:file1) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
84
+ let(:file2) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
85
+ let(:file3) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
86
+ let!(:trophy1) { user.trophies.create!(generic_file_id: file1.noid) }
87
+ let!(:trophy2) { user.trophies.create!(generic_file_id: file2.noid) }
88
+ let!(:trophy3) { user.trophies.create!(generic_file_id: file3.noid) }
89
+
90
+ it "show the user profile if user exists" do
91
+ get :edit, id: @user.user_key
92
+ response.should be_success
93
+ assigns[:trophies].should match_array([file1, file2, file3])
94
+ end
95
+
96
+ end
64
97
  end
65
98
  describe "#update" do
66
99
  it "should not allow other users to update" do
@@ -69,7 +102,7 @@ describe UsersController do
69
102
  flash[:alert].should include("Permission denied: cannot access this page.")
70
103
  end
71
104
  it "should set an avatar and redirect to profile" do
72
- @user.avatar.file?.should be_false
105
+ @user.avatar?.should be_false
73
106
  s1 = double('one')
74
107
  UserEditProfileEventJob.should_receive(:new).with(@user.user_key).and_return(s1)
75
108
  Sufia.queue.should_receive(:push).with(s1).once
@@ -77,23 +110,21 @@ describe UsersController do
77
110
  post :update, id: @user.user_key, user: { avatar: f }
78
111
  response.should redirect_to(@routes.url_helpers.profile_path(URI.escape(@user.user_key,'@.')))
79
112
  flash[:notice].should include("Your profile has been updated")
80
- User.find_by_user_key(@user.user_key).avatar.file?.should be_true
113
+ User.find_by_user_key(@user.user_key).avatar?.should be_true
81
114
  end
82
115
  it "should validate the content type of an avatar" do
83
- #Resque.should_receive(:enqueue).with(UserEditProfileEventJob, @user.user_key).never
84
116
  Sufia.queue.should_receive(:push).never
85
117
  f = fixture_file_upload('/image.jp2', 'image/jp2')
86
118
  post :update, id: @user.user_key, user: { avatar: f }
87
119
  response.should redirect_to(@routes.url_helpers.edit_profile_path(URI.escape(@user.user_key,'@.')))
88
- flash[:alert].should include("Avatar content type is invalid")
120
+ flash[:alert].should include("Avatar You are not allowed to upload \"jp2\" files, allowed types: jpg, jpeg, png, gif, bmp, tif, tiff")
89
121
  end
90
122
  it "should validate the size of an avatar" do
91
123
  f = fixture_file_upload('/4-20.png', 'image/png')
92
- #Resque.should_receive(:enqueue).with(UserEditProfileEventJob, @user.user_key).never
93
124
  Sufia.queue.should_receive(:push).never
94
125
  post :update, id: @user.user_key, user: { avatar: f }
95
126
  response.should redirect_to(@routes.url_helpers.edit_profile_path(URI.escape(@user.user_key,'@.')))
96
- flash[:alert].should include("Avatar file size must be less than 2097152 Bytes")
127
+ flash[:alert].should include("Avatar file size must be less than 2MB")
97
128
  end
98
129
  it "should delete an avatar" do
99
130
  s1 = double('one')
@@ -102,7 +133,7 @@ describe UsersController do
102
133
  post :update, id: @user.user_key, delete_avatar: true
103
134
  response.should redirect_to(@routes.url_helpers.profile_path(URI.escape(@user.user_key,'@.')))
104
135
  flash[:notice].should include("Your profile has been updated")
105
- @user.avatar.file?.should be_false
136
+ @user.avatar?.should be_false
106
137
  end
107
138
  it "should refresh directory attributes" do
108
139
  s1 = double('one')
@@ -117,28 +148,33 @@ describe UsersController do
117
148
  @user.twitter_handle.blank?.should be_true
118
149
  @user.facebook_handle.blank?.should be_true
119
150
  @user.googleplus_handle.blank?.should be_true
120
- post :update, id: @user.user_key, user: { twitter_handle: 'twit', facebook_handle: 'face', googleplus_handle: 'goo' }
151
+ @user.linkedin_handle.blank?.should be_true
152
+ post :update, id: @user.user_key, user: { twitter_handle: 'twit', facebook_handle: 'face', googleplus_handle: 'goo', linkedin_handle:"link" }
121
153
  response.should redirect_to(@routes.url_helpers.profile_path(URI.escape(@user.user_key,'@.')))
122
154
  flash[:notice].should include("Your profile has been updated")
123
155
  u = User.find_by_user_key(@user.user_key)
124
156
  u.twitter_handle.should == 'twit'
125
157
  u.facebook_handle.should == 'face'
126
158
  u.googleplus_handle.should == 'goo'
159
+ u.linkedin_handle.should == 'link'
127
160
  end
128
- it "should remove a trophy" do
129
- f = GenericFile.create(title:"myFile")
130
- f.apply_depositor_metadata(@user)
131
- f.save
132
- file_id = f.pid.split(":").last
133
- Trophy.create(:generic_file_id => file_id, :user_id => @user.id)
134
- @user.trophy_ids.length.should == 1
135
- post :update, id: @user.user_key, 'remove_trophy_'+file_id=> 'yes'
136
- response.should redirect_to(@routes.url_helpers.profile_path(URI.escape(@user.user_key,'@.')))
137
- flash[:notice].should include("Your profile has been updated")
138
- @user.trophy_ids.length.should == 0
139
- f.destroy
161
+
162
+ context "when removing a trophy" do
163
+ let(:user) { @user }
164
+ let(:file) { GenericFile.new.tap { |f| f.apply_depositor_metadata(user); f.save! } }
165
+ before do
166
+ user.trophies.create!(generic_file_id: file.noid)
167
+ end
168
+ it "should remove a trophy" do
169
+ expect {
170
+ post :update, id: user.user_key, 'remove_trophy_'+file.noid => 'yes'
171
+ }.to change { user.trophies.count }.by(-1)
172
+ response.should redirect_to(@routes.url_helpers.profile_path(URI.escape(user.user_key,'@.')))
173
+ flash[:notice].should include("Your profile has been updated")
174
+ end
140
175
  end
141
176
  end
177
+
142
178
  describe "#follow" do
143
179
  after(:all) do
144
180
  @user.unfollow(@another_user) rescue nil