curation_concerns 1.3.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -1
  3. data/Gemfile +5 -0
  4. data/app/actors/curation_concerns/actors/actor_stack.rb +20 -4
  5. data/app/actors/curation_concerns/actors/base_actor.rb +1 -1
  6. data/app/assets/javascripts/curation_concerns/boot.es6 +6 -0
  7. data/app/assets/javascripts/curation_concerns/curation_concerns.js +5 -5
  8. data/app/assets/javascripts/curation_concerns/file_manager.es6 +41 -0
  9. data/app/assets/javascripts/curation_concerns/file_manager/member.es6 +2 -8
  10. data/app/assets/javascripts/curation_concerns/file_manager/save_manager.es6 +1 -3
  11. data/app/assets/javascripts/curation_concerns/file_manager/sorting.es6 +69 -75
  12. data/app/controllers/concerns/curation_concerns/collections_controller_behavior.rb +1 -1
  13. data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +3 -3
  14. data/app/controllers/concerns/curation_concerns/file_sets_controller_behavior.rb +5 -7
  15. data/app/controllers/concerns/curation_concerns/single_use_links_controller_behavior.rb +6 -5
  16. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +23 -4
  17. data/app/services/curation_concerns/time_service.rb +2 -1
  18. data/app/views/curation_concerns/file_sets/show.json.jbuilder +1 -1
  19. data/curation_concerns.gemspec +2 -1
  20. data/lib/curation_concerns/engine.rb +1 -0
  21. data/lib/curation_concerns/version.rb +1 -1
  22. data/solr/config/solrconfig.xml +26 -4
  23. data/spec/actors/curation_concerns/apply_order_actor_spec.rb +6 -4
  24. data/spec/actors/curation_concerns/file_set_actor_spec.rb +3 -3
  25. data/spec/actors/curation_concerns/work_actor_spec.rb +8 -7
  26. data/spec/controllers/catalog_controller_spec.rb +1 -1
  27. data/spec/controllers/curation_concerns/collections_controller_spec.rb +1 -1
  28. data/spec/controllers/curation_concerns/file_sets_controller_json_spec.rb +29 -5
  29. data/spec/controllers/curation_concerns/file_sets_controller_spec.rb +20 -4
  30. data/spec/controllers/curation_concerns/generic_works_controller_json_spec.rb +3 -2
  31. data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +6 -1
  32. data/spec/factories/generic_works.rb +2 -2
  33. data/spec/features/create_work_spec.rb +1 -1
  34. data/spec/features/update_file_spec.rb +7 -0
  35. data/spec/features/work_generator_spec.rb +1 -1
  36. data/spec/models/collection_spec.rb +3 -3
  37. data/spec/models/curation_concerns/work_behavior_spec.rb +2 -1
  38. data/spec/models/file_set_spec.rb +2 -1
  39. data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +0 -1
  40. data/spec/services/file_set_audit_service_spec.rb +14 -0
  41. data/spec/services/graph_exporter_spec.rb +1 -1
  42. data/spec/spec_helper.rb +13 -0
  43. data/spec/support/helpers/controller_level_helpers.rb +27 -0
  44. data/spec/support/views/test_view_helpers.rb +10 -0
  45. data/spec/test_app_templates/Gemfile.extra +2 -0
  46. data/spec/views/catalog/index.html.erb_spec.rb +0 -3
  47. data/spec/views/curation_concerns/base/_form_rights_spec.rb +9 -7
  48. data/spec/views/curation_concerns/file_sets/show.json.jbuilder_spec.rb +6 -6
  49. metadata +24 -11
  50. data/app/assets/javascripts/curation_concerns/file_manager/affix.es6 +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41288e2f6cac8f0a3b90f302c1a6cd838397c8ee
4
- data.tar.gz: a599175e07b064de3cf19e081792343b08a21705
3
+ metadata.gz: f7cfdad9a9be43d5356653c2f33b2366241c07b8
4
+ data.tar.gz: fc51ce634c3532c0956d2822f8dcb36f381ab577
5
5
  SHA512:
6
- metadata.gz: 4200cadf0561abed624775a1526e235a093ac006b2dbcc883fb5e80a1d3ed6eb2f33a7c363378529d348525d377d7d462581a15b8c415692f3305fd718f027e3
7
- data.tar.gz: e5567ddae6fb5b4f9bb5949ea45ba8ab7f8e62fdfcd7c17c41275f2080425eb0614449c84ce2b45439d89ffac88095ddb2f5c9e2f6b51ba076ed6dc70eb47980
6
+ metadata.gz: 29f30a7c5a4d29c69b1feb098b918b1a5319025a8f38f811a3699745ace59c3fae94f2341e2950b3b4f134c7552e50ff1a85c02bc28e43b213c6cf5d16e80f93
7
+ data.tar.gz: df6588bfae1ec8231c6d39853f6bf22e9dfff09705e56d7390049631d5fcd969d2787414257ec35f2ef6c18aed154718408403420ae72a637bc79b03eafaad7d
@@ -6,7 +6,9 @@ rvm:
6
6
  env:
7
7
  global:
8
8
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
9
- - RAILS_VERSION=4.2.7
9
+ matrix:
10
+ - RAILS_VERSION=4.2.7
11
+ - RAILS_VERSION=5.0.0
10
12
  notifications:
11
13
  irc:
12
14
  channels:
data/Gemfile CHANGED
@@ -46,3 +46,8 @@ else
46
46
  end
47
47
  # END ENGINE_CART BLOCK
48
48
 
49
+ gem 'rails-controller-testing' if !ENV['RAILS_VERSION'] || ENV['RAILS_VERSION'] =~ /^5\./
50
+
51
+ unless File.exist?(file)
52
+ eval_gemfile File.expand_path('spec/test_app_templates/Gemfile.extra', File.dirname(__FILE__))
53
+ end
@@ -17,12 +17,14 @@ module CurationConcerns
17
17
  first_actor_class.new(curation_concern, user, inner_stack)
18
18
  end
19
19
 
20
- def create(attributes)
21
- actor.create(attributes.with_indifferent_access)
20
+ # @param [ActionController::Parameters,Hash,NilClass] new_attributes
21
+ def create(new_attributes)
22
+ actor.create(cast_to_indifferent_hash(new_attributes))
22
23
  end
23
24
 
24
- def update(attributes)
25
- actor.update(attributes.with_indifferent_access)
25
+ # @param [ActionController::Parameters,Hash,NilClass] new_attributes
26
+ def update(new_attributes)
27
+ actor.update(cast_to_indifferent_hash(new_attributes))
26
28
  end
27
29
 
28
30
  def destroy
@@ -33,6 +35,20 @@ module CurationConcerns
33
35
  end
34
36
  curation_concern.destroy
35
37
  end
38
+
39
+ private
40
+
41
+ # @param [ActionController::Parameters,Hash,NilClass] new_attributes
42
+ def cast_to_indifferent_hash(new_attributes)
43
+ new_attributes ||= {}
44
+ if new_attributes.respond_to?(:to_unsafe_h)
45
+ # This is the typical (not-ActionView::TestCase) code path.
46
+ new_attributes = new_attributes.to_unsafe_h
47
+ end
48
+ # In Rails 5 to_unsafe_h returns a HashWithIndifferentAccess, in Rails 4 it returns Hash
49
+ new_attributes = new_attributes.with_indifferent_access if new_attributes.instance_of? Hash
50
+ new_attributes
51
+ end
36
52
  end
37
53
  end
38
54
  end
@@ -53,7 +53,7 @@ module CurationConcerns
53
53
  def apply_save_data_to_curation_concern(attributes)
54
54
  attributes[:rights] = Array(attributes[:rights]) if attributes.key? :rights
55
55
  remove_blank_attributes!(attributes)
56
- curation_concern.attributes = attributes.symbolize_keys
56
+ curation_concern.attributes = attributes
57
57
  curation_concern.date_modified = CurationConcerns::TimeService.time_in_utc
58
58
  end
59
59
 
@@ -0,0 +1,6 @@
1
+ import FileManager from 'curation_concerns/file_manager'
2
+ export class Initializer {
3
+ constructor() {
4
+ this.file_manager = new FileManager
5
+ }
6
+ }
@@ -1,23 +1,23 @@
1
- //= require hydra-editor/hydra-editor
2
1
  //= require curation_concerns/facet_mine
3
2
  //= require curation_concerns/embargoes
4
3
  //= require curation_concerns/fileupload
5
- //= require curation_concerns/file_manager/affix
4
+ //= require hydra-editor/hydra-editor
6
5
  //= require curation_concerns/file_manager/sorting
7
6
  //= require curation_concerns/file_manager/save_manager
8
7
  //= require curation_concerns/file_manager/member
9
8
  //= require curation_concerns/single_use_links_manager
10
9
  //= require curation_concerns/batch_select
11
10
  //= require curation_concerns/collections
12
-
11
+ //= require curation_concerns/file_manager
12
+ //= require curation_concerns/boot
13
13
 
14
14
  // Initialize plugins and Bootstrap dropdowns on jQuery's ready event as well as
15
15
  // Turbolinks's page change event.
16
16
  Blacklight.onLoad(function() {
17
+ cc = require('curation_concerns/boot')
17
18
  $('abbr').tooltip();
18
19
 
19
20
  $("[data-toggle='dropdown']").dropdown();
20
21
  $('a[data-toggle="popover"]').popover({ html: true })
21
- .click(function() { return false });
22
-
22
+ window.curation_concerns = new cc.Initializer()
23
23
  });
@@ -0,0 +1,41 @@
1
+ import SaveManager from 'curation_concerns/file_manager/save_manager'
2
+ import SortManager from 'curation_concerns/file_manager/sorting'
3
+ import {FileManagerMember} from 'curation_concerns/file_manager/member'
4
+ export default class FileManager {
5
+ constructor() {
6
+ this.save_manager = this.initialize_save_manager()
7
+ this.sorting()
8
+ this.save_affix()
9
+ this.member_tracking()
10
+ }
11
+
12
+ initialize_save_manager() {
13
+ return(new SaveManager)
14
+ }
15
+
16
+ sorting() {
17
+ window.new_sort_manager = new SortManager(this.save_manager)
18
+ }
19
+
20
+ save_affix() {
21
+ let tools = $("#file-manager-tools")
22
+ if(tools.length > 0) {
23
+ tools.affix({
24
+ offset: {
25
+ top: $("#file-manager-tools .actions").offset().top,
26
+ bottom: function() {
27
+ return $("#file-manager-extra-tools").outerHeight(true) + $("footer").outerHeight(true)
28
+ }
29
+ }
30
+ })
31
+ }
32
+ }
33
+
34
+ member_tracking() {
35
+ let sm = this.save_manager
36
+ $("li[data-reorder-id]").each(function(index, element) {
37
+ var manager_member = new FileManagerMember($(element), sm)
38
+ $(element).data("file_manager_member", manager_member)
39
+ })
40
+ }
41
+ }
@@ -1,10 +1,4 @@
1
- Blacklight.onLoad(function() {
2
- $("li[data-reorder-id]").each(function(index, element) {
3
- let manager_member = new FileManagerMember($(element), window.save_manager)
4
- $(element).data("file_manager_member", manager_member)
5
- })
6
- })
7
- class InputTracker {
1
+ export class InputTracker {
8
2
  constructor(element, notifier) {
9
3
  this.element = element
10
4
  this.notifier = notifier
@@ -28,7 +22,7 @@ class InputTracker {
28
22
  }
29
23
  }
30
24
  }
31
- class FileManagerMember {
25
+ export class FileManagerMember {
32
26
  constructor(element, save_manager) {
33
27
  this.element = element
34
28
  this.save_manager = save_manager
@@ -1,4 +1,4 @@
1
- class SaveManager {
1
+ export default class SaveManager {
2
2
  constructor() {
3
3
  this.override_save_button()
4
4
  this.elements = []
@@ -66,5 +66,3 @@ class SaveManager {
66
66
  }
67
67
  }
68
68
  }
69
-
70
- window.save_manager = new SaveManager
@@ -1,91 +1,85 @@
1
- {
2
- Blacklight.onLoad(function() {
3
- window.new_sort_manager = new SortManager
4
- })
1
+ export default class SortManager {
2
+ constructor(save_manager) {
3
+ this.element = $("#sortable")
4
+ this.sorting_info = {}
5
+ this.initialize_sort()
6
+ this.element.data("current-order", this.order)
7
+ this.save_manager = save_manager
8
+ }
5
9
 
6
- class SortManager {
7
- constructor() {
8
- this.element = $("#sortable")
9
- this.sorting_info = {}
10
- this.initialize_sort()
11
- this.element.data("current-order", this.order)
12
- this.save_manager = window.save_manager
13
- }
10
+ initialize_sort() {
11
+ this.element.sortable({handle: ".panel-heading"})
12
+ this.element.on("sortstop", this.stopped_sorting)
13
+ this.element.on("sortstart", this.started_sorting)
14
+ }
14
15
 
15
- initialize_sort() {
16
- this.element.sortable({handle: ".panel-heading"})
17
- this.element.on("sortstop", this.stopped_sorting)
18
- this.element.on("sortstart", this.started_sorting)
16
+ persist() {
17
+ let params = {}
18
+ params[this.singular_class_name] = {
19
+ "ordered_member_ids": this.order
19
20
  }
20
-
21
- persist() {
22
- let params = {}
23
- params[this.singular_class_name] = {
24
- "ordered_member_ids": this.order
25
- }
26
- params["_method"] = "PATCH"
27
- this.element.addClass("pending")
28
- this.element.removeClass("success")
21
+ params["_method"] = "PATCH"
22
+ this.element.addClass("pending")
23
+ this.element.removeClass("success")
24
+ this.element.removeClass("failure")
25
+ let persisting = $.post(
26
+ `/concern/${this.class_name}/${this.id}.json`,
27
+ params
28
+ ).done(() => {
29
+ this.element.data("current-order", this.order)
30
+ this.element.addClass("success")
29
31
  this.element.removeClass("failure")
30
- let persisting = $.post(
31
- `/concern/${this.class_name}/${this.id}`,
32
- params
33
- ).done(() => {
34
- this.element.data("current-order", this.order)
35
- this.element.addClass("success")
36
- this.element.removeClass("failure")
37
- }).fail(() => {
38
- this.element.addClass("failure")
39
- this.element.removeClass("success")
40
- }).always(() => {
41
- this.element.removeClass("pending")
42
- })
43
- return persisting
44
- }
32
+ }).fail(() => {
33
+ this.element.addClass("failure")
34
+ this.element.removeClass("success")
35
+ }).always(() => {
36
+ this.element.removeClass("pending")
37
+ })
38
+ return persisting
39
+ }
45
40
 
46
- get_sort_position(item) {
47
- return this.element.children().index(item)
48
- }
41
+ get_sort_position(item) {
42
+ return this.element.children().index(item)
43
+ }
49
44
 
50
- get stopped_sorting() {
51
- return (event, ui) => {
52
- this.sorting_info.end = this.get_sort_position($(ui.item))
53
- if(this.sorting_info.end == this.sorting_info.start) {
54
- return
55
- }
56
- if(this.order.toString() != this.element.data("current-order").toString()) {
57
- this.save_manager.push_changed(this)
58
- } else {
59
- this.save_manager.mark_unchanged(this)
60
- }
45
+ get stopped_sorting() {
46
+ return (event, ui) => {
47
+ this.sorting_info.end = this.get_sort_position($(ui.item))
48
+ if(this.sorting_info.end == this.sorting_info.start) {
49
+ return
61
50
  }
62
- }
63
-
64
- get started_sorting() {
65
- return (event, ui) => {
66
- this.sorting_element = $(ui.item)
67
- this.sorting_info.start = this.get_sort_position(ui.item)
51
+ if(this.order.toString() != this.element.data("current-order").toString()) {
52
+ this.save_manager.push_changed(this)
53
+ } else {
54
+ this.save_manager.mark_unchanged(this)
68
55
  }
69
56
  }
57
+ }
70
58
 
71
- get id() {
72
- return this.element.data("id")
59
+ get started_sorting() {
60
+ return (event, ui) => {
61
+ this.sorting_element = $(ui.item)
62
+ this.sorting_info.start = this.get_sort_position(ui.item)
73
63
  }
64
+ }
74
65
 
75
- get class_name() {
76
- return this.element.data("class-name")
77
- }
66
+ get id() {
67
+ return this.element.data("id")
68
+ }
78
69
 
79
- get singular_class_name() {
80
- return this.element.data("singular-class-name")
81
- }
70
+ get class_name() {
71
+ return this.element.data("class-name")
72
+ }
82
73
 
83
- get order() {
84
- return $("*[data-reorder-id]").map(
85
- function() {
86
- return $(this).data("reorder-id")
87
- }
88
- ).toArray()
89
- }
74
+ get singular_class_name() {
75
+ return this.element.data("singular-class-name")
76
+ }
77
+
78
+ get order() {
79
+ return $("*[data-reorder-id]").map(
80
+ function() {
81
+ return $(this).data("reorder-id")
82
+ }
83
+ ).toArray()
90
84
  }
91
85
  }
@@ -197,7 +197,7 @@ module CurationConcerns
197
197
  # search_field: 'all_fields'
198
198
  # @return <Hash> the inputs required for the collection member search builder
199
199
  def params_for_members_query
200
- params.symbolize_keys.merge(q: params[:cq])
200
+ params.merge(q: params[:cq])
201
201
  end
202
202
 
203
203
  def collection_member_search_builder
@@ -56,8 +56,6 @@ module CurationConcerns::CurationConcernController
56
56
  wants.html { presenter && parent_presenter }
57
57
  wants.json do
58
58
  # load and authorize @curation_concern manually because it's skipped for html
59
- # This has to use #find instead of #load_instance_from_solr because
60
- # we want to return values like file_set_ids in the json
61
59
  @curation_concern = _curation_concern_type.find(params[:id]) unless curation_concern
62
60
  authorize! :show, @curation_concern
63
61
  render :show, status: :ok
@@ -168,7 +166,9 @@ module CurationConcerns::CurationConcernController
168
166
  end
169
167
 
170
168
  def attributes_for_actor
171
- form_class.model_attributes(params[hash_key_for_curation_concern])
169
+ raw_params = params[hash_key_for_curation_concern]
170
+ return unless raw_params
171
+ form_class.model_attributes(raw_params)
172
172
  end
173
173
 
174
174
  def hash_key_for_curation_concern
@@ -65,12 +65,7 @@ module CurationConcerns
65
65
  def show
66
66
  respond_to do |wants|
67
67
  wants.html { presenter }
68
- wants.json do
69
- # load and authorize @curation_concern manually because it's skipped for html
70
- self.curation_concern ||= curation_concern_type.load_instance_from_solr(params[:id])
71
- authorize! :show, curation_concern
72
- render :show, status: :ok
73
- end
68
+ wants.json { presenter }
74
69
  additional_response_formats(wants)
75
70
  end
76
71
  end
@@ -115,7 +110,10 @@ module CurationConcerns
115
110
  wants.html do
116
111
  redirect_to [main_app, curation_concern], notice: "The file #{view_context.link_to(curation_concern, [main_app, curation_concern])} has been updated."
117
112
  end
118
- wants.json { render :show, status: :ok, location: polymorphic_path([main_app, curation_concern]) }
113
+ wants.json do
114
+ @presenter = show_presenter.new(curation_concern, current_ability)
115
+ render :show, status: :ok, location: polymorphic_path([main_app, curation_concern])
116
+ end
119
117
  end
120
118
  end
121
119
 
@@ -1,6 +1,7 @@
1
1
  module CurationConcerns
2
2
  module SingleUseLinksControllerBehavior
3
3
  extend ActiveSupport::Concern
4
+ include Blacklight::SearchHelper
4
5
  included do
5
6
  class_attribute :show_presenter
6
7
  self.show_presenter = CurationConcerns::SingleUseLinkPresenter
@@ -18,12 +19,12 @@ module CurationConcerns
18
19
  end
19
20
 
20
21
  def create_download
21
- @su = SingleUseLink.create itemId: params[:id], path: main_app.download_path(id: asset)
22
+ @su = SingleUseLink.create itemId: params[:id], path: main_app.download_path(id: params[:id])
22
23
  render text: curation_concerns.download_single_use_link_url(@su.downloadKey)
23
24
  end
24
25
 
25
26
  def create_show
26
- @su = SingleUseLink.create itemId: params[:id], path: polymorphic_path([main_app, asset])
27
+ @su = SingleUseLink.create(itemId: params[:id], path: asset_show_path)
27
28
  render text: curation_concerns.show_single_use_link_url(@su.downloadKey)
28
29
  end
29
30
 
@@ -40,11 +41,11 @@ module CurationConcerns
40
41
  protected
41
42
 
42
43
  def authorize_user!
43
- authorize! :edit, asset
44
+ authorize! :edit, params[:id]
44
45
  end
45
46
 
46
- def asset
47
- @asset ||= ActiveFedora::Base.load_instance_from_solr(params[:id])
47
+ def asset_show_path
48
+ polymorphic_path([main_app, fetch(params[:id]).last])
48
49
  end
49
50
  end
50
51
  end