curation_concerns 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +20 -9
  3. data/app/actors/curation_concerns/actors/apply_order_actor.rb +1 -1
  4. data/app/assets/javascripts/curation_concerns/application.js +1 -0
  5. data/app/assets/javascripts/curation_concerns/curation_concerns.js +1 -0
  6. data/app/assets/javascripts/curation_concerns/single_use_links_manager.js +53 -0
  7. data/app/controllers/concerns/curation_concerns/single_use_links_controller_behavior.rb +10 -0
  8. data/app/presenters/curation_concerns/file_set_presenter.rb +4 -0
  9. data/app/renderers/curation_concerns/renderers/date_attribute_renderer.rb +11 -0
  10. data/app/renderers/renderers.rb +5 -6
  11. data/app/views/curation_concerns/base/_attributes.html.erb +2 -2
  12. data/app/views/curation_concerns/file_sets/_single_use_link_rows.html.erb +18 -0
  13. data/app/views/curation_concerns/file_sets/_single_use_links.html.erb +20 -0
  14. data/app/views/curation_concerns/file_sets/show.html.erb +1 -0
  15. data/app/views/curation_concerns/single_use_links/index.html.erb +0 -0
  16. data/config/routes.rb +2 -0
  17. data/curation_concerns.gemspec +1 -0
  18. data/lib/curation_concerns/version.rb +1 -1
  19. data/lib/curation_concerns.rb +1 -0
  20. data/spec/controllers/curation_concerns/single_use_links_controller_spec.rb +62 -46
  21. data/spec/controllers/curation_concerns/single_use_links_viewer_controller_spec.rb +6 -6
  22. data/spec/factories/single_use_links.rb +13 -0
  23. data/spec/features/embargo_spec.rb +2 -2
  24. data/spec/features/lease_spec.rb +2 -2
  25. data/spec/javascripts/fixtures/sul_table.html +29 -0
  26. data/spec/javascripts/single_use_links_spec.coffee +51 -0
  27. data/spec/presenters/curation_concerns/file_set_presenter_spec.rb +7 -0
  28. data/spec/renderers/curation_concerns/renderers/date_attribute_renderer_spec.rb +34 -0
  29. data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +33 -0
  30. metadata +29 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 835147e30b02f4bd8176f008f6581a72852a03f0
4
- data.tar.gz: 653102b81aed097f57c153baaea3c1f85f4e3f1f
3
+ metadata.gz: 832c5d5ac39f97b63124797e7ddd1b4f44b50314
4
+ data.tar.gz: dc3f9767e7770d2df1cd944a1b7fa0ae8319c0bb
5
5
  SHA512:
6
- metadata.gz: 7a6827a24f8fc84168c0d53fdfadc4745b08707d29a9ef0b6abaf628ccb8e8ae6177473068e1a723bcfc4b342d49e9323e0e6a354defffe2a7ed14d094581a5a
7
- data.tar.gz: 20707bc6b4305fbc5df1cdf03216f5f8b7634aa442ec141b42b67bacf77e51da16bb58efe3804ae334dba22af31a48be982e5a7e479f53e81bb856df6c1ff106
6
+ metadata.gz: 4d4493a39a865be80e9a9b63b9b6aeea62a4d5080fc989916b798c731b03b2a8e60845f2ab84fdad3adfa12f51838aa3495731da5df8efebd516f331b705f3a1
7
+ data.tar.gz: bc3ae415927e33076d79012f495676f92d08f6b42fa3add0795f7172d91e96cecc7fdd41e29d47c59a149e2618ac77ce27296941cad4a798c74d2390d4e9eec2
data/Gemfile CHANGED
@@ -12,10 +12,10 @@ group :development, :test do
12
12
  end
13
13
 
14
14
  # BEGIN ENGINE_CART BLOCK
15
- # engine_cart: 0.8.0
16
- # engine_cart stanza: 0.8.0
15
+ # engine_cart: 0.10.0
16
+ # engine_cart stanza: 0.10.0
17
17
  # the below comes from engine_cart, a gem used to test this Rails engine gem in the context of a Rails app.
18
- file = File.expand_path("Gemfile", ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path(".internal_test_app", File.dirname(__FILE__)))
18
+ file = File.expand_path('Gemfile', ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path('.internal_test_app', File.dirname(__FILE__)))
19
19
  if File.exist?(file)
20
20
  begin
21
21
  eval_gemfile file
@@ -25,13 +25,24 @@ if File.exist?(file)
25
25
  end
26
26
  else
27
27
  Bundler.ui.warn "[EngineCart] Unable to find test application dependencies in #{file}, using placeholder dependencies"
28
- gem 'rails', ENV['RAILS_VERSION'] if ENV['RAILS_VERSION']
29
28
 
30
- if ENV['RAILS_VERSION'].nil? || ENV['RAILS_VERSION'] =~ /^4.2/
31
- gem 'responders', "~> 2.0"
32
- gem 'sass-rails', ">= 5.0"
33
- else
34
- gem 'sass-rails', "< 5.0"
29
+ if ENV['RAILS_VERSION']
30
+ if ENV['RAILS_VERSION'] == 'edge'
31
+ gem 'rails', github: 'rails/rails'
32
+ ENV['ENGINE_CART_RAILS_OPTIONS'] = '--edge --skip-turbolinks'
33
+ else
34
+ gem 'rails', ENV['RAILS_VERSION']
35
+ end
36
+ end
37
+
38
+ case ENV['RAILS_VERSION']
39
+ when /^4.2/
40
+ gem 'responders', '~> 2.0'
41
+ gem 'sass-rails', '>= 5.0'
42
+ gem 'coffee-rails', '~> 4.1.0'
43
+ when /^4.[01]/
44
+ gem 'sass-rails', '< 5.0'
35
45
  end
36
46
  end
37
47
  # END ENGINE_CART BLOCK
48
+
@@ -11,7 +11,7 @@ module CurationConcerns
11
11
 
12
12
  def sync_members(ordered_member_ids)
13
13
  return true if ordered_member_ids.nil?
14
- existing_members_ids = curation_concern.member_ids
14
+ existing_members_ids = curation_concern.ordered_member_ids
15
15
  (existing_members_ids - ordered_member_ids).each do |old_id|
16
16
  work = ::ActiveFedora::Base.find(old_id)
17
17
  curation_concern.ordered_members.delete(work)
@@ -11,5 +11,6 @@
11
11
  //= require bootstrap/affix
12
12
  //
13
13
  //= require jquery-ui/sortable
14
+ //= require clipboard
14
15
  //
15
16
  //= require curation_concerns/curation_concerns
@@ -6,6 +6,7 @@
6
6
  //= require curation_concerns/file_manager/sorting
7
7
  //= require curation_concerns/file_manager/save_manager
8
8
  //= require curation_concerns/file_manager/member
9
+ //= require curation_concerns/single_use_links_manager
9
10
  //= require curation_concerns/batch_select
10
11
  //= require curation_concerns/collections
11
12
 
@@ -0,0 +1,53 @@
1
+ (function( $ ){
2
+ $.fn.singleUseLinks = function( options ) {
3
+
4
+ var clipboard = new Clipboard('.copy-single-use-link');
5
+
6
+ var manager = {
7
+ reload_table: function() {
8
+ var url = $("table.single-use-links tbody").data('url')
9
+ $.get(url).done(function(data) {
10
+ $('table.single-use-links tbody').html(data);
11
+ });
12
+ },
13
+
14
+ create_link: function(caller) {
15
+ $.post(caller.attr('href')).done(function(data) {
16
+ manager.reload_table()
17
+ })
18
+ },
19
+
20
+ delete_link: function(caller) {
21
+ $.ajax({
22
+ url: caller.attr('href'),
23
+ type: 'DELETE',
24
+ done: caller.parent('td').parent('tr').remove()
25
+ })
26
+ }
27
+ };
28
+
29
+ $('.generate-single-use-link').click(function(event) {
30
+ event.preventDefault()
31
+ manager.create_link($(this))
32
+ return false
33
+ });
34
+
35
+ $("table.single-use-links tbody").on('click', '.delete-single-use-link', function(event) {
36
+ event.preventDefault()
37
+ manager.delete_link($(this))
38
+ return false;
39
+ });
40
+
41
+ clipboard.on('success', function(e) {
42
+ $(e.trigger).tooltip('show');
43
+ e.clearSelection();
44
+ });
45
+
46
+ return manager;
47
+
48
+ };
49
+ })( jQuery );
50
+
51
+ Blacklight.onLoad(function () {
52
+ $('.single-use-links').singleUseLinks();
53
+ });
@@ -25,6 +25,16 @@ module CurationConcerns
25
25
  render text: curation_concerns.show_single_use_link_url(@su.downloadKey)
26
26
  end
27
27
 
28
+ def index
29
+ links = SingleUseLink.where(itemId: params[:id])
30
+ render partial: 'curation_concerns/file_sets/single_use_link_rows', locals: { single_use_links: links }
31
+ end
32
+
33
+ def destroy
34
+ SingleUseLink.find_by_downloadKey(params[:link_id]).destroy
35
+ head :ok
36
+ end
37
+
28
38
  protected
29
39
 
30
40
  def authorize_user!
@@ -33,5 +33,9 @@ module CurationConcerns
33
33
  def link_name
34
34
  current_ability.can?(:read, id) ? label : 'File'
35
35
  end
36
+
37
+ def single_use_links
38
+ @single_use_links ||= SingleUseLink.where(itemId: id)
39
+ end
36
40
  end
37
41
  end
@@ -0,0 +1,11 @@
1
+ module CurationConcerns
2
+ module Renderers
3
+ class DateAttributeRenderer < AttributeRenderer
4
+ private
5
+
6
+ def attribute_value_to_html(value)
7
+ Date.parse(value).to_formatted_s(:standard)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,11 +1,10 @@
1
1
  module CurationConcerns
2
- # Module that will containing Renderers
2
+ # Module that will contain Renderer classes
3
3
  # @since 0.14.0
4
- # Renderers are used to display Ruby objects to users.
5
- # Renderers take the Ruby object supplied by a
6
- # CurationConcerns::Presenter object Renderers are typically # used to respond to read requests from the controller.
7
- # Renderers may apply some level of HTML or may just supply
8
- # human readable values for object attributes.
4
+ # Renderers are used to display Ruby objects to users and take arguments from the CurationConcerns::Presenter
5
+ # supplied by the controller.
6
+ # They are typically used to respond to read requests from the controller, and may apply some level of
7
+ # HTML, or may just display human readable values for object attributes.
9
8
  module Renderers
10
9
  end
11
10
  end
@@ -6,8 +6,8 @@
6
6
  <tbody>
7
7
  <%= render 'attribute_rows', presenter: presenter %>
8
8
  <%= presenter.attribute_to_html(:permission_badge, label: 'Visibility') %>
9
- <%= presenter.attribute_to_html(:embargo_release_date) %>
10
- <%= presenter.attribute_to_html(:lease_expiration_date) %>
9
+ <%= presenter.attribute_to_html(:embargo_release_date, render_as: :date) %>
10
+ <%= presenter.attribute_to_html(:lease_expiration_date, render_as: :date) %>
11
11
  <%= presenter.attribute_to_html(:rights, render_as: :rights) %>
12
12
  </tbody>
13
13
  </table>
@@ -0,0 +1,18 @@
1
+ <% single_use_links.each_with_index do |link, index| %>
2
+ <% type = link.path =~ /downloads/ ? 'Download' : 'Show' %>
3
+ <% url_helper = link.path =~ /downloads/ ? 'download_single_use_link_url' : 'show_single_use_link_url' %>
4
+ <tr>
5
+ <td><%= type %></td>
6
+ <td><%= link.downloadKey %></td>
7
+ <td><%= link.expires %></td>
8
+ <td>
9
+ <button class="btn btn-xs btn-default copy-single-use-link"
10
+ data-clipboard-text="<%= curation_concerns.send(url_helper, link.downloadKey) %>"
11
+ data-toggle="tooltip" data-placement="bottom" title="Copied!">
12
+ Copy to Clipboard
13
+ </button>
14
+ <%= link_to "Delete", curation_concerns.delete_single_use_link_path(params[:id], link),
15
+ class: 'btn btn-xs btn-danger delete-single-use-link' %>
16
+ </td>
17
+ </tr>
18
+ <% end %>
@@ -0,0 +1,20 @@
1
+ <table class="table table-striped <%= dom_class(presenter) %> single-use-links">
2
+ <caption class="table-heading"><h2>Single-Use Links</h2></caption>
3
+ <thead>
4
+ <tr><th>Link</th><th>Key</th><th>Expires</th><th>Actions</th></tr>
5
+ </thead>
6
+ <tbody data-url="<%= curation_concerns.generated_single_use_links_path(presenter) %>">
7
+ <% if presenter.single_use_links.empty? %>
8
+ <tr><td>No links have been generated</td></tr>
9
+ <% else %>
10
+ <%= render 'single_use_link_rows', single_use_links: presenter.single_use_links %>
11
+ <% end %>
12
+ </tbody>
13
+ </table>
14
+
15
+ <div class="form_actions">
16
+ <%= link_to "Generate Download Link", curation_concerns.generate_download_single_use_link_path(presenter),
17
+ class: 'btn btn-default generate-single-use-link' %>
18
+ <%= link_to "Generate Show Link", curation_concerns.generate_show_single_use_link_path(presenter),
19
+ class: 'btn btn-default generate-single-use-link' %>
20
+ </div>
@@ -5,3 +5,4 @@
5
5
  <%= media_display @presenter %>
6
6
  <%= render "attributes", presenter: @presenter %>
7
7
  <%= render "show_actions", presenter: @presenter, parent: parent %>
8
+ <%= render "single_use_links", presenter: @presenter %>
data/config/routes.rb CHANGED
@@ -3,6 +3,8 @@ CurationConcerns::Engine.routes.draw do
3
3
  get 'single_use_link/download/:id' => 'single_use_links_viewer#download', as: :download_single_use_link
4
4
  post 'single_use_link/generate_download/:id' => 'single_use_links#create_download', as: :generate_download_single_use_link
5
5
  post 'single_use_link/generate_show/:id' => 'single_use_links#create_show', as: :generate_show_single_use_link
6
+ get 'single_use_link/generated/:id' => 'single_use_links#index', as: :generated_single_use_links
7
+ delete 'single_use_link/:id/delete/:link_id' => 'single_use_links#destroy', as: :delete_single_use_link
6
8
 
7
9
  # mount BrowseEverything::Engine => '/remote_files/browse'
8
10
  resources :classify_concerns, only: [:new, :create]
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
39
39
  spec.add_dependency 'rdf-vocab', '~> 0'
40
40
  spec.add_dependency 'awesome_nested_set', '~> 3.0'
41
41
  spec.add_dependency 'browse-everything', '~> 0.10'
42
+ spec.add_dependency 'clipboard-rails', '~> 1.5'
42
43
 
43
44
  spec.add_development_dependency 'solr_wrapper', '~> 0.13', '>= 0.13.1'
44
45
  spec.add_development_dependency 'fcrepo_wrapper', '~> 0.1'
@@ -1,3 +1,3 @@
1
1
  module CurationConcerns
2
- VERSION = "1.1.2".freeze
2
+ VERSION = "1.2.0".freeze
3
3
  end
@@ -4,6 +4,7 @@ require 'curation_concerns/configuration'
4
4
  require 'curation_concerns/collections'
5
5
  require 'blacklight_advanced_search'
6
6
  require 'kaminari_route_prefix'
7
+ require 'clipboard/rails'
7
8
 
8
9
  module CurationConcerns
9
10
  end
@@ -2,78 +2,94 @@ require 'spec_helper'
2
2
 
3
3
  describe CurationConcerns::SingleUseLinksController, type: :controller do
4
4
  routes { CurationConcerns::Engine.routes }
5
- let(:user) { create(:user) }
6
5
 
7
- let(:file) do
8
- FileSet.create do |file|
9
- file.apply_depositor_metadata(user)
10
- end
11
- end
6
+ let(:user) { create(:user) }
7
+ let(:file) { create(:file_set, user: user) }
12
8
 
13
9
  describe "logged in user with edit permission" do
14
10
  let(:hash) { "some-dummy-sha2-hash" }
15
11
 
16
- before do
17
- sign_in user
18
- allow(DateTime).to receive(:now).and_return(DateTime.now)
19
- expect(Digest::SHA2).to receive(:new).and_return(hash)
12
+ before { sign_in user }
13
+
14
+ context "POST create" do
15
+ before do
16
+ allow(DateTime).to receive(:now).and_return(DateTime.now)
17
+ expect(Digest::SHA2).to receive(:new).and_return(hash)
18
+ end
19
+
20
+ describe "creating a single-use download link" do
21
+ it "returns a link for downloading" do
22
+ post 'create_download', id: file
23
+ expect(response).to be_success
24
+ expect(response.body).to eq download_single_use_link_url(hash)
25
+ end
26
+ end
27
+
28
+ describe "creating a single-use show link" do
29
+ it "returns a link for showing" do
30
+ post 'create_show', id: file
31
+ expect(response).to be_success
32
+ expect(response.body).to eq show_single_use_link_url(hash)
33
+ end
34
+ end
20
35
  end
21
36
 
22
- describe "GET 'download'" do
23
- it "and_return http success" do
24
- post 'create_download', id: file
25
- expect(response).to be_success
26
- expect(response.body).to eq download_single_use_link_url(hash)
37
+ context "GET index" do
38
+ describe "viewing existing links" do
39
+ before { get :index, id: file }
40
+ subject { response }
41
+ it { is_expected.to be_success }
27
42
  end
28
43
  end
29
44
 
30
- describe "GET 'show'" do
31
- it "and_return http success" do
32
- post 'create_show', id: file
45
+ context "DELETE destroy" do
46
+ let!(:link) { create(:download_link) }
47
+ it "deletes the link" do
48
+ expect { delete :destroy, id: file, link_id: link }.to change { SingleUseLink.count }.by(-1)
33
49
  expect(response).to be_success
34
- expect(response.body).to eq show_single_use_link_url(hash)
35
50
  end
36
51
  end
37
52
  end
38
53
 
39
54
  describe "logged in user without edit permission" do
40
- before do
41
- @other_user = create(:user)
42
- file.read_users << @other_user
43
- file.save!
44
- sign_in @other_user
45
- file.read_users << @other_user
46
- file.save!
55
+ let(:other_user) { create(:user) }
56
+ let(:file) { create(:file_set, user: user, read_users: [other_user]) }
57
+
58
+ before { sign_in other_user }
59
+ subject { response }
60
+
61
+ describe "creating a single-use download link" do
62
+ before { post 'create_download', id: file }
63
+ it { is_expected.not_to be_success }
47
64
  end
48
65
 
49
- describe "GET 'download'" do
50
- it "and_return http success" do
51
- post 'create_download', id: file
52
- expect(response).not_to be_success
53
- end
66
+ describe "creating a single-use show link" do
67
+ before { post 'create_show', id: file }
68
+ it { is_expected.not_to be_success }
54
69
  end
55
70
 
56
- describe "GET 'show'" do
57
- it "and_return http success" do
58
- post 'create_show', id: file
59
- expect(response).not_to be_success
60
- end
71
+ describe "viewing existing links" do
72
+ before { get :index, id: file }
73
+ it { is_expected.not_to be_success }
61
74
  end
62
75
  end
63
76
 
64
77
  describe "unknown user" do
65
- describe "GET 'download'" do
66
- it "and_return http failure" do
67
- post 'create_download', id: file
68
- expect(response).not_to be_success
69
- end
78
+ subject { response }
79
+
80
+ describe "creating a single-use download link" do
81
+ before { post 'create_download', id: file }
82
+ it { is_expected.not_to be_success }
70
83
  end
71
84
 
72
- describe "GET 'show'" do
73
- it "and_return http failure" do
74
- post 'create_show', id: file
75
- expect(response).not_to be_success
76
- end
85
+ describe "creating a single-use show link" do
86
+ before { post 'create_show', id: file }
87
+ it { is_expected.not_to be_success }
88
+ end
89
+
90
+ describe "viewing existing links" do
91
+ before { get :index, id: file }
92
+ it { is_expected.not_to be_success }
77
93
  end
78
94
  end
79
95
  end
@@ -31,7 +31,7 @@ describe CurationConcerns::SingleUseLinksViewerController do
31
31
  describe "GET 'download'" do
32
32
  let(:expected_content) { ActiveFedora::Base.find(file.id).original_file.content }
33
33
 
34
- it "and_return http success" do
34
+ it "downloads the file and deletes the link from the database" do
35
35
  expect(controller).to receive(:send_file_headers!).with(filename: 'world.png', disposition: 'attachment', type: 'image/png')
36
36
  get :download, id: download_link_hash
37
37
  expect(response.body).to eq expected_content
@@ -39,10 +39,10 @@ describe CurationConcerns::SingleUseLinksViewerController do
39
39
  expect { SingleUseLink.find_by_downloadKey!(download_link_hash) }.to raise_error ActiveRecord::RecordNotFound
40
40
  end
41
41
 
42
- context "and the key is not found" do
42
+ context "when the key is not found" do
43
43
  before { SingleUseLink.find_by_downloadKey!(download_link_hash).destroy }
44
44
 
45
- it "returns 404 if the key is not present" do
45
+ it "returns 404" do
46
46
  get :download, id: download_link_hash
47
47
  expect(response).to render_template("curation_concerns/single_use_links_viewer/single_use_error", "layouts/error")
48
48
  end
@@ -50,16 +50,16 @@ describe CurationConcerns::SingleUseLinksViewerController do
50
50
  end
51
51
 
52
52
  describe "GET 'show'" do
53
- it "and_return http success" do
53
+ it "renders the file set's show page and deletes the link from the database" do
54
54
  get 'show', id: show_link_hash
55
55
  expect(response).to be_success
56
56
  expect(assigns[:presenter].id).to eq file.id
57
57
  expect { SingleUseLink.find_by_downloadKey!(show_link_hash) }.to raise_error ActiveRecord::RecordNotFound
58
58
  end
59
59
 
60
- context "and the key is not found" do
60
+ context "when the key is not found" do
61
61
  before { SingleUseLink.find_by_downloadKey!(show_link_hash).destroy }
62
- it "returns 404 if the key is not present" do
62
+ it "returns 404" do
63
63
  get :show, id: show_link_hash
64
64
  expect(response).to render_template("curation_concerns/single_use_links_viewer/single_use_error", "layouts/error")
65
65
  end
@@ -0,0 +1,13 @@
1
+ FactoryGirl.define do
2
+ factory :single_use_link do
3
+ factory :show_link do
4
+ itemId 'fs-id'
5
+ path '/concerns/generic_work/1234'
6
+ end
7
+
8
+ factory :download_link do
9
+ itemId 'fs-id'
10
+ path '/downloads/1234'
11
+ end
12
+ end
13
+ end
@@ -23,7 +23,7 @@ feature 'embargo' do
23
23
  click_button 'Create Generic work'
24
24
 
25
25
  # chosen embargo date is on the show page
26
- expect(page).to have_content(future_date.to_datetime.iso8601.sub(/\+00:00/, 'Z'))
26
+ expect(page).to have_content(future_date.to_date.to_formatted_s(:standard))
27
27
 
28
28
  click_link 'Edit This Generic Work'
29
29
  click_link 'Embargo Management Page'
@@ -34,7 +34,7 @@ feature 'embargo' do
34
34
  fill_in 'until', with: later_future_date.to_s
35
35
 
36
36
  click_button 'Update Embargo'
37
- expect(page).to have_content(later_future_date.iso8601)
37
+ expect(page).to have_content(later_future_date.to_date.to_formatted_s(:standard))
38
38
  end
39
39
  end
40
40
 
@@ -20,7 +20,7 @@ feature 'leases' do
20
20
  click_button 'Create Generic work'
21
21
 
22
22
  # chosen lease date is on the show page
23
- expect(page).to have_content(future_date.to_datetime.iso8601.sub(/\+00:00/, 'Z'))
23
+ expect(page).to have_content(future_date.to_date.to_formatted_s(:standard))
24
24
 
25
25
  click_link 'Edit This Generic Work'
26
26
  click_link 'Lease Management Page'
@@ -31,7 +31,7 @@ feature 'leases' do
31
31
  fill_in 'until', with: later_future_date.to_s
32
32
 
33
33
  click_button 'Update Lease'
34
- expect(page).to have_content(later_future_date.iso8601) # new lease date is displayed in message
34
+ expect(page).to have_content(later_future_date.to_date.to_formatted_s(:standard)) # new lease date is displayed in message
35
35
  end
36
36
  end
37
37
 
@@ -0,0 +1,29 @@
1
+ <table class="table table-striped file_set single-use-links">
2
+ <caption class="table-heading"><h2>Single-Use Links</h2></caption>
3
+ <thead>
4
+ <tr><th>Link</th><th>Key</th><th>Expires</th><th>Actions</th></tr>
5
+ </thead>
6
+ <tbody data-url="/single_use_link/generated/fs-id">
7
+ <tr>
8
+ <td>Download</td>
9
+ <td>key</td>
10
+ <td>timestamp</td>
11
+ <td>
12
+ <button class="btn btn-xs btn-default copy-single-use-link"
13
+ data-clipboard-text="download-link" data-toggle="tooltip"
14
+ data-placement="bottom" title="Copied!">
15
+ Copy to Clipboard
16
+ </button>
17
+ <a class="btn btn-xs btn-danger delete-single-use-link" href="/single_use_link/fs-id/delete/key">
18
+ Delete
19
+ </a>
20
+ </td>
21
+ </tr>
22
+ </tbody>
23
+ </table>
24
+
25
+ <div class="form_actions">
26
+ <a class="btn btn-default generate-single-use-link" href="/single_use_link/generate/fs-id">
27
+ Generate A Link
28
+ </a>
29
+ </div>
@@ -0,0 +1,51 @@
1
+ describe "Single Use Links manager", ->
2
+ sul_manager = null
3
+ beforeEach () ->
4
+ loadFixtures('sul_table.html')
5
+ sul_manager = $.fn.singleUseLinks()
6
+ jasmine.Ajax.install()
7
+ afterEach () ->
8
+ jasmine.Ajax.uninstall()
9
+
10
+ describe "#reload_table", ->
11
+ request = null
12
+
13
+ it "replaces the table's content with html data", ->
14
+ jasmine.Ajax.stubRequest('/single_use_link/generated/fs-id').andReturn({
15
+ "status": 200,
16
+ "contentType": 'text/plain',
17
+ "responseText": 'updated table contents'
18
+ });
19
+
20
+ sul_manager.reload_table()
21
+ request = jasmine.Ajax.requests.mostRecent()
22
+ expect(request.responseText).toEqual("updated table contents")
23
+
24
+ describe "#create_link", ->
25
+ request = null
26
+
27
+ it "requests a new link", ->
28
+ jasmine.Ajax.stubRequest('/single_use_link/generate/fs-id').andReturn({
29
+ "status": 200,
30
+ "contentType": 'text/plain',
31
+ "responseText": 'created a link'
32
+ });
33
+
34
+ sul_manager.create_link($('.generate-single-use-link'))
35
+ request = jasmine.Ajax.requests.mostRecent()
36
+ expect(request.responseText).toEqual("created a link")
37
+
38
+ describe "#delete_link", ->
39
+ request = null
40
+
41
+ it "removes the link from the table", ->
42
+ jasmine.Ajax.stubRequest('/single_use_link/fs-id/delete/key').andReturn({
43
+ "status": 200,
44
+ "contentType": 'text/plain',
45
+ "responseText": 'deleted a link'
46
+ });
47
+
48
+ sul_manager.delete_link($('.delete-single-use-link'))
49
+ request = jasmine.Ajax.requests.mostRecent()
50
+ expect(request.responseText).toEqual("deleted a link")
51
+ expect($("table.single-use-links tbody").html).not.toContain("<tr>")
@@ -77,4 +77,11 @@ describe CurationConcerns::FileSetPresenter do
77
77
  it { is_expected.to eq 'File' }
78
78
  end
79
79
  end
80
+
81
+ describe "single_use_links" do
82
+ it "returns ActiveRecord::Relation of all single use links for the file set" do
83
+ expect(SingleUseLink).to receive(:where).with(itemId: presenter.id)
84
+ presenter.single_use_links
85
+ end
86
+ end
80
87
  end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe CurationConcerns::Renderers::DateAttributeRenderer do
4
+ subject { Nokogiri::HTML(renderer.render) }
5
+ let(:expected) { Nokogiri::HTML(tr_content) }
6
+
7
+ describe "#attribute_to_html" do
8
+ context 'with embargo release date' do
9
+ let(:field) { :embargo_release_date }
10
+ let(:renderer) { described_class.new(field, ['2013-03-14T00:00:00Z']) }
11
+ let(:tr_content) {%(
12
+ <tr><th>Embargo release date</th>
13
+ <td><ul class="tabular">
14
+ <li class="attribute embargo_release_date">03/14/2013</li>
15
+ </ul></td></tr>
16
+ )}
17
+ it { expect(renderer).not_to be_microdata(field) }
18
+ it { expect(subject).to be_equivalent_to(expected) }
19
+ end
20
+
21
+ context 'with lease expiration date' do
22
+ let(:field) { :lease_expiration_date }
23
+ let(:renderer) { described_class.new(field, ['2013-03-14T00:00:00Z']) }
24
+ let(:tr_content) {%(
25
+ <tr><th>Lease expiration date</th>
26
+ <td><ul class="tabular">
27
+ <li class="attribute lease_expiration_date">03/14/2013</li>
28
+ </ul></td></tr>
29
+ )}
30
+ it { expect(renderer).not_to be_microdata(field) }
31
+ it { expect(subject).to be_equivalent_to(expected) }
32
+ end
33
+ end
34
+ end
@@ -130,4 +130,37 @@ describe 'curation_concerns/file_sets/show.html.erb', type: :view do
130
130
  expect(rendered).to have_selector '.attribute.description', text: 'Lorem ipsum'
131
131
  end
132
132
  end
133
+
134
+ describe 'single use links' do
135
+ before do
136
+ allow(presenter).to receive(:single_use_links).and_return(links)
137
+ controller.params = { id: presenter.id }
138
+ render
139
+ end
140
+
141
+ context "when links are present" do
142
+ let(:show_link) { create(:show_link) }
143
+ let(:download_link) { create(:download_link) }
144
+ let(:links) { [show_link, download_link] }
145
+
146
+ it "renders single use links for the file set" do
147
+ expect(rendered).to have_selector('td', text: 'Show')
148
+ expect(rendered).to have_selector('td', text: 'Download')
149
+ expect(rendered).to have_selector('td', text: show_link.downloadKey)
150
+ expect(rendered).to have_selector('td', text: show_link.expires)
151
+ expect(rendered).to have_link("Generate Download Link")
152
+ expect(rendered).to have_link("Generate Show Link")
153
+ end
154
+ end
155
+
156
+ context "when no links are present" do
157
+ let(:links) { [] }
158
+
159
+ it "renders a table without links" do
160
+ expect(rendered).to have_selector('td', text: 'No links have been generated')
161
+ expect(rendered).to have_link("Generate Download Link")
162
+ expect(rendered).to have_link("Generate Show Link")
163
+ end
164
+ end
165
+ end
133
166
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curation_concerns
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-07-12 00:00:00.000000000 Z
13
+ date: 2016-07-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hydra-head
@@ -318,6 +318,20 @@ dependencies:
318
318
  - - "~>"
319
319
  - !ruby/object:Gem::Version
320
320
  version: '0.10'
321
+ - !ruby/object:Gem::Dependency
322
+ name: clipboard-rails
323
+ requirement: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - "~>"
326
+ - !ruby/object:Gem::Version
327
+ version: '1.5'
328
+ type: :runtime
329
+ prerelease: false
330
+ version_requirements: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - "~>"
333
+ - !ruby/object:Gem::Version
334
+ version: '1.5'
321
335
  - !ruby/object:Gem::Dependency
322
336
  name: solr_wrapper
323
337
  requirement: !ruby/object:Gem::Requirement
@@ -659,6 +673,7 @@ files:
659
673
  - app/assets/javascripts/curation_concerns/file_manager/save_manager.es6
660
674
  - app/assets/javascripts/curation_concerns/file_manager/sorting.es6
661
675
  - app/assets/javascripts/curation_concerns/fileupload.js
676
+ - app/assets/javascripts/curation_concerns/single_use_links_manager.js
662
677
  - app/assets/javascripts/curation_concerns/uploader.js
663
678
  - app/assets/javascripts/modernizr.js
664
679
  - app/assets/stylesheets/curation_concerns.scss
@@ -787,6 +802,7 @@ files:
787
802
  - app/presenters/curation_concerns/work_show_presenter.rb
788
803
  - app/renderers/curation_concerns/renderers/attribute_renderer.rb
789
804
  - app/renderers/curation_concerns/renderers/configured_microdata.rb
805
+ - app/renderers/curation_concerns/renderers/date_attribute_renderer.rb
790
806
  - app/renderers/curation_concerns/renderers/faceted_attribute_renderer.rb
791
807
  - app/renderers/curation_concerns/renderers/linked_attribute_renderer.rb
792
808
  - app/renderers/curation_concerns/renderers/rights_attribute_renderer.rb
@@ -932,6 +948,8 @@ files:
932
948
  - app/views/curation_concerns/file_sets/_form.html.erb
933
949
  - app/views/curation_concerns/file_sets/_rights_modal.html.erb
934
950
  - app/views/curation_concerns/file_sets/_show_actions.html.erb
951
+ - app/views/curation_concerns/file_sets/_single_use_link_rows.html.erb
952
+ - app/views/curation_concerns/file_sets/_single_use_links.html.erb
935
953
  - app/views/curation_concerns/file_sets/edit.html.erb
936
954
  - app/views/curation_concerns/file_sets/jq_upload.json.jbuilder
937
955
  - app/views/curation_concerns/file_sets/media_display/_audio.html.erb
@@ -949,6 +967,7 @@ files:
949
967
  - app/views/curation_concerns/operations/index.html.erb
950
968
  - app/views/curation_concerns/operations/show.html.erb
951
969
  - app/views/curation_concerns/permissions/confirm.html.erb
970
+ - app/views/curation_concerns/single_use_links/index.html.erb
952
971
  - app/views/curation_concerns/single_use_links_viewer/show.html.erb
953
972
  - app/views/curation_concerns/single_use_links_viewer/single_use_error.html.erb
954
973
  - app/views/embargoes/_embargo_history.html.erb
@@ -1090,6 +1109,7 @@ files:
1090
1109
  - spec/factories/file_sets.rb
1091
1110
  - spec/factories/generic_works.rb
1092
1111
  - spec/factories/operations.rb
1112
+ - spec/factories/single_use_links.rb
1093
1113
  - spec/factories/users.rb
1094
1114
  - spec/features/add_file_spec.rb
1095
1115
  - spec/features/catalog_search_spec.rb
@@ -1120,11 +1140,13 @@ files:
1120
1140
  - spec/javascripts/fixtures/.gitkeep
1121
1141
  - spec/javascripts/fixtures/file_manager_member.html
1122
1142
  - spec/javascripts/fixtures/save_button.html
1143
+ - spec/javascripts/fixtures/sul_table.html
1123
1144
  - spec/javascripts/helpers/jasmine-jquery.js
1124
1145
  - spec/javascripts/helpers/mock-ajax.js
1125
1146
  - spec/javascripts/helpers/test_responses.js
1126
1147
  - spec/javascripts/jasmine_spec.rb
1127
1148
  - spec/javascripts/save_manager_spec.coffee
1149
+ - spec/javascripts/single_use_links_spec.coffee
1128
1150
  - spec/javascripts/support/jasmine.yml
1129
1151
  - spec/javascripts/support/jasmine_helper.rb
1130
1152
  - spec/jobs/audit_job_spec.rb
@@ -1167,6 +1189,7 @@ files:
1167
1189
  - spec/presenters/embargo_presenter_spec.rb
1168
1190
  - spec/presenters/lease_presenter_spec.rb
1169
1191
  - spec/renderers/curation_concerns/renderers/attribute_renderer_spec.rb
1192
+ - spec/renderers/curation_concerns/renderers/date_attribute_renderer_spec.rb
1170
1193
  - spec/renderers/curation_concerns/renderers/faceted_attribute_renderer_spec.rb
1171
1194
  - spec/renderers/curation_concerns/renderers/linked_attribute_renderer_spec.rb
1172
1195
  - spec/renderers/curation_concerns/renderers/rights_attribute_renderer_spec.rb
@@ -1295,6 +1318,7 @@ test_files:
1295
1318
  - spec/factories/file_sets.rb
1296
1319
  - spec/factories/generic_works.rb
1297
1320
  - spec/factories/operations.rb
1321
+ - spec/factories/single_use_links.rb
1298
1322
  - spec/factories/users.rb
1299
1323
  - spec/features/add_file_spec.rb
1300
1324
  - spec/features/catalog_search_spec.rb
@@ -1325,11 +1349,13 @@ test_files:
1325
1349
  - spec/javascripts/fixtures/.gitkeep
1326
1350
  - spec/javascripts/fixtures/file_manager_member.html
1327
1351
  - spec/javascripts/fixtures/save_button.html
1352
+ - spec/javascripts/fixtures/sul_table.html
1328
1353
  - spec/javascripts/helpers/jasmine-jquery.js
1329
1354
  - spec/javascripts/helpers/mock-ajax.js
1330
1355
  - spec/javascripts/helpers/test_responses.js
1331
1356
  - spec/javascripts/jasmine_spec.rb
1332
1357
  - spec/javascripts/save_manager_spec.coffee
1358
+ - spec/javascripts/single_use_links_spec.coffee
1333
1359
  - spec/javascripts/support/jasmine.yml
1334
1360
  - spec/javascripts/support/jasmine_helper.rb
1335
1361
  - spec/jobs/audit_job_spec.rb
@@ -1372,6 +1398,7 @@ test_files:
1372
1398
  - spec/presenters/embargo_presenter_spec.rb
1373
1399
  - spec/presenters/lease_presenter_spec.rb
1374
1400
  - spec/renderers/curation_concerns/renderers/attribute_renderer_spec.rb
1401
+ - spec/renderers/curation_concerns/renderers/date_attribute_renderer_spec.rb
1375
1402
  - spec/renderers/curation_concerns/renderers/faceted_attribute_renderer_spec.rb
1376
1403
  - spec/renderers/curation_concerns/renderers/linked_attribute_renderer_spec.rb
1377
1404
  - spec/renderers/curation_concerns/renderers/rights_attribute_renderer_spec.rb