curation_concerns 1.1.2 → 1.2.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 (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