hydra-file-access 5.0.0.pre1

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 (169) hide show
  1. data/.gitignore +2 -0
  2. data/Rakefile +5 -0
  3. data/app/assets/images/hydra/powered_by_hydra.png +0 -0
  4. data/app/assets/images/hydra/search-button.png +0 -0
  5. data/app/assets/javascripts/date-picker/booking/index.html +368 -0
  6. data/app/assets/javascripts/date-picker/calendarHTML.txt +84 -0
  7. data/app/assets/javascripts/date-picker/css/datepicker.css +511 -0
  8. data/app/assets/javascripts/date-picker/css/demo.css +229 -0
  9. data/app/assets/javascripts/date-picker/index.html +798 -0
  10. data/app/assets/javascripts/date-picker/js/datepicker.js +2898 -0
  11. data/app/assets/javascripts/date-picker/js/datepicker.packed.js +1 -0
  12. data/app/assets/javascripts/date-picker/js/lang/ar.js +9 -0
  13. data/app/assets/javascripts/date-picker/js/lang/cs.js +9 -0
  14. data/app/assets/javascripts/date-picker/js/lang/da.js +10 -0
  15. data/app/assets/javascripts/date-picker/js/lang/de.js +10 -0
  16. data/app/assets/javascripts/date-picker/js/lang/en.js +9 -0
  17. data/app/assets/javascripts/date-picker/js/lang/eo.js +13 -0
  18. data/app/assets/javascripts/date-picker/js/lang/es.js +9 -0
  19. data/app/assets/javascripts/date-picker/js/lang/et.js +23 -0
  20. data/app/assets/javascripts/date-picker/js/lang/fi.js +7 -0
  21. data/app/assets/javascripts/date-picker/js/lang/fr.js +69 -0
  22. data/app/assets/javascripts/date-picker/js/lang/he.js +9 -0
  23. data/app/assets/javascripts/date-picker/js/lang/hu.js +9 -0
  24. data/app/assets/javascripts/date-picker/js/lang/id.js +9 -0
  25. data/app/assets/javascripts/date-picker/js/lang/it.js +11 -0
  26. data/app/assets/javascripts/date-picker/js/lang/kr.js +9 -0
  27. data/app/assets/javascripts/date-picker/js/lang/lt.js +8 -0
  28. data/app/assets/javascripts/date-picker/js/lang/lv.js +9 -0
  29. data/app/assets/javascripts/date-picker/js/lang/nl.js +9 -0
  30. data/app/assets/javascripts/date-picker/js/lang/no.js +9 -0
  31. data/app/assets/javascripts/date-picker/js/lang/pl.js +10 -0
  32. data/app/assets/javascripts/date-picker/js/lang/pt-br.js +11 -0
  33. data/app/assets/javascripts/date-picker/js/lang/pt.js +9 -0
  34. data/app/assets/javascripts/date-picker/js/lang/ru.js +11 -0
  35. data/app/assets/javascripts/date-picker/js/lang/se.js +9 -0
  36. data/app/assets/javascripts/date-picker/js/lang/si.js +9 -0
  37. data/app/assets/javascripts/date-picker/js/lang/tr.js +9 -0
  38. data/app/assets/javascripts/date-picker/language/index.html +240 -0
  39. data/app/assets/javascripts/date-picker/media/Thumbs.db +0 -0
  40. data/app/assets/javascripts/date-picker/media/backstripes.gif +0 -0
  41. data/app/assets/javascripts/date-picker/media/bg_header.jpg +0 -0
  42. data/app/assets/javascripts/date-picker/media/bullet1.gif +0 -0
  43. data/app/assets/javascripts/date-picker/media/bullet2.gif +0 -0
  44. data/app/assets/javascripts/date-picker/media/cal-grey.gif +0 -0
  45. data/app/assets/javascripts/date-picker/media/cal.gif +0 -0
  46. data/app/assets/javascripts/date-picker/media/gradient-e5e5e5-ffffff.gif +0 -0
  47. data/app/assets/javascripts/hydra/hydra-head.js +195 -0
  48. data/app/assets/javascripts/hydra/mediashelf.datepicker.js +39 -0
  49. data/app/assets/javascripts/hydra/mediashelf.placeholder.js +67 -0
  50. data/app/assets/javascripts/jquery.form.js +1076 -0
  51. data/app/assets/javascripts/jquery.ui.datepicker.js +1793 -0
  52. data/app/assets/javascripts/spin.min.js +2 -0
  53. data/app/assets/stylesheets/hydra/html_refactor.css +79 -0
  54. data/app/assets/stylesheets/hydra/hydrangea-split-button.css +18 -0
  55. data/app/assets/stylesheets/hydra/hydrangea.css +288 -0
  56. data/app/assets/stylesheets/hydra/ie-styles.css +149 -0
  57. data/app/assets/stylesheets/hydra/styles.css +946 -0
  58. data/app/assets/stylesheets/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  59. data/app/assets/stylesheets/redmond/images/ui-bg_flat_55_fbec88_40x100.png +0 -0
  60. data/app/assets/stylesheets/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  61. data/app/assets/stylesheets/redmond/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
  62. data/app/assets/stylesheets/redmond/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  63. data/app/assets/stylesheets/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  64. data/app/assets/stylesheets/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
  65. data/app/assets/stylesheets/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  66. data/app/assets/stylesheets/redmond/images/ui-icons_217bc0_256x240.png +0 -0
  67. data/app/assets/stylesheets/redmond/images/ui-icons_2e83ff_256x240.png +0 -0
  68. data/app/assets/stylesheets/redmond/images/ui-icons_469bdd_256x240.png +0 -0
  69. data/app/assets/stylesheets/redmond/images/ui-icons_6da8d5_256x240.png +0 -0
  70. data/app/assets/stylesheets/redmond/images/ui-icons_cd0a0a_256x240.png +0 -0
  71. data/app/assets/stylesheets/redmond/images/ui-icons_d8e7f3_256x240.png +0 -0
  72. data/app/assets/stylesheets/redmond/images/ui-icons_f9bd01_256x240.png +0 -0
  73. data/app/assets/stylesheets/redmond/jquery-ui-1.8.5.custom.css +572 -0
  74. data/app/controllers/hydra/application_controller.rb +5 -0
  75. data/app/controllers/hydra/file_assets_controller.rb +3 -0
  76. data/app/helpers/application_helper.rb +3 -0
  77. data/app/helpers/hydra/application_helper_behavior.rb +8 -0
  78. data/app/helpers/hydra/hydra_helper_behavior.rb +70 -0
  79. data/app/helpers/hydra_helper.rb +4 -0
  80. data/app/models/file_asset.rb +5 -0
  81. data/app/models/uses_default_partials.rb +23 -0
  82. data/app/views/_add_assets_links.html.erb +14 -0
  83. data/app/views/_user_util_links.html.erb +24 -0
  84. data/app/views/generic_content_objects/_contributor_form.html.erb +11 -0
  85. data/app/views/generic_content_objects/_description_form.html.erb +7 -0
  86. data/app/views/generic_content_objects/_edit_description.html.erb +23 -0
  87. data/app/views/generic_content_objects/_new.html.erb +0 -0
  88. data/app/views/generic_content_objects/_show_description.html.erb +41 -0
  89. data/app/views/generic_contents/_edit.html.erb +10 -0
  90. data/app/views/generic_contents/_index.html.erb +21 -0
  91. data/app/views/generic_contents/_show.html.erb +6 -0
  92. data/app/views/generic_contents/_show_content.html.erb +7 -0
  93. data/app/views/generic_images/_edit.html.erb +36 -0
  94. data/app/views/generic_images/_index.html.erb +24 -0
  95. data/app/views/generic_images/_show.html.erb +13 -0
  96. data/app/views/generic_images/_show_all.html.erb +14 -0
  97. data/app/views/generic_images/_show_content.html.erb +7 -0
  98. data/app/views/hydra/file_assets/_asset_saved_flash.html.erb +2 -0
  99. data/app/views/hydra/file_assets/_deletable_result.html.erb +5 -0
  100. data/app/views/hydra/file_assets/_file_assets_form.html.erb +11 -0
  101. data/app/views/hydra/file_assets/_index.html.erb +29 -0
  102. data/app/views/hydra/file_assets/_new.html.erb +6 -0
  103. data/app/views/hydra/file_assets/_result.html.erb +11 -0
  104. data/app/views/hydra/file_assets/index.html.erb +5 -0
  105. data/app/views/hydra/permissions/_edit_person_permissions.html.erb +30 -0
  106. data/app/views/hydra/permissions/_index.html.erb +46 -0
  107. data/app/views/hydra/permissions/_new.html.erb +14 -0
  108. data/app/views/hydra/permissions/_permissions_form.html.erb +23 -0
  109. data/app/views/hydra/permissions/index.html.erb +1 -0
  110. data/app/views/hydra/permissions/new.html.erb +1 -0
  111. data/app/views/mods_assets/_additional_info_form.html.erb +44 -0
  112. data/app/views/mods_assets/_contributor_form.html.erb +14 -0
  113. data/app/views/mods_assets/_edit.html.erb +10 -0
  114. data/app/views/mods_assets/_edit_description.html.erb +73 -0
  115. data/app/views/mods_assets/_edit_journal.html.erb +57 -0
  116. data/app/views/mods_assets/_index.html.erb +1 -0
  117. data/app/views/mods_assets/_index_list.html.erb +37 -0
  118. data/app/views/mods_assets/_index_table.html.erb +7 -0
  119. data/app/views/mods_assets/_progress_box.html.erb +82 -0
  120. data/app/views/mods_assets/_publication_form.html.erb +13 -0
  121. data/app/views/mods_assets/_show.html.erb +39 -0
  122. data/app/views/mods_assets/_show_additional_info.html.erb +17 -0
  123. data/app/views/mods_assets/_show_contributors.html.erb +7 -0
  124. data/app/views/mods_assets/_show_description.html.erb +35 -0
  125. data/app/views/mods_assets/_show_file_assets.html.erb +22 -0
  126. data/app/views/mods_assets/_show_journal.html.erb +42 -0
  127. data/app/views/mods_assets/_show_permissions.html.erb +15 -0
  128. data/app/views/mods_assets/_show_publication.html.erb +8 -0
  129. data/app/views/shared/_delete_asset_confirmation.html.erb +17 -0
  130. data/config/jetty.yml +7 -0
  131. data/hydra-file-access.gemspec +39 -0
  132. data/lib/hydra-file-access.rb +15 -0
  133. data/lib/hydra/assets.rb +5 -0
  134. data/lib/hydra/assets_controller_helper.rb +122 -0
  135. data/lib/hydra/controller/assets_controller_behavior.rb +153 -0
  136. data/lib/hydra/controller/file_assets_behavior.rb +140 -0
  137. data/lib/hydra/file_access/engine.rb +12 -0
  138. data/lib/hydra/file_assets.rb +11 -0
  139. data/lib/hydra/submission_workflow.rb +139 -0
  140. data/lib/hydra/ui.rb +6 -0
  141. data/spec/.gitignore +1 -0
  142. data/spec/controllers/file_assets_controller_spec.rb +180 -0
  143. data/spec/fixtures/small_file.txt +1 -0
  144. data/spec/helpers/access_controls_evaluation_spec.rb +19 -0
  145. data/spec/helpers/assets_controller_helper_spec.rb +63 -0
  146. data/spec/helpers/file_assets_helper_spec.rb +116 -0
  147. data/spec/helpers/hydra_helper_spec.rb +21 -0
  148. data/spec/helpers/hydra_model_methods_spec.rb +88 -0
  149. data/spec/integration/file_asset_spec.rb +68 -0
  150. data/spec/lib/hydra_submission_workflow_spec.rb +141 -0
  151. data/spec/models/file_asset_spec.rb +25 -0
  152. data/spec/spec_helper.rb +27 -0
  153. data/spec/support/Gemfile +12 -0
  154. data/spec/support/app/models/generic_content.rb +26 -0
  155. data/spec/support/app/models/sample.rb +33 -0
  156. data/spec/support/app/models/solr_document.rb +5 -0
  157. data/spec/support/db/migrate/20111101221803_create_searches.rb +16 -0
  158. data/spec/support/lib/generators/test_app_generator.rb +39 -0
  159. data/spec/support/matchers/helper_matcher.rb +14 -0
  160. data/spec/support/matchers/solr_matchers.rb +60 -0
  161. data/spec/support/spec/factories/users.rb +11 -0
  162. data/spec/support/spec/fixtures/hydra_test_generic_content.foxml.xml +138 -0
  163. data/spec/support/spec/fixtures/hydrangea_fixture_file_asset1.foxml.xml +4946 -0
  164. data/spec/support/spec/fixtures/hydrangea_fixture_mods_article1.foxml.xml +234 -0
  165. data/spec/support/spec/fixtures/hydrangea_fixture_mods_article2.foxml.xml +177 -0
  166. data/spec/support/spec/fixtures/hydrangea_fixture_mods_article3.foxml.xml +170 -0
  167. data/spec/support/spec/fixtures/hydrangea_fixture_uploaded_svg1.foxml.xml +676 -0
  168. data/tasks/rspec.rake +55 -0
  169. metadata +516 -0
@@ -0,0 +1,140 @@
1
+ # will move to lib/hydra/controller / file_assets_controller_behavior.rb in release 5.x
2
+ module Hydra::Controller::FileAssetsBehavior
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Hydra::AccessControlsEnforcement
7
+ include Hydra::AssetsControllerHelper
8
+ include Hydra::Controller::UploadBehavior
9
+ include Hydra::Controller::RepositoryControllerBehavior
10
+ include Blacklight::SolrHelper
11
+ include Hydra::SubmissionWorkflow
12
+ include Blacklight::Configurable
13
+ copy_blacklight_config_from(CatalogController)
14
+ prepend_before_filter :sanitize_update_params
15
+ end
16
+
17
+ def index
18
+ if params[:layout] == "false"
19
+ layout = false
20
+ end
21
+
22
+ if params[:asset_id].nil?
23
+ @solr_result = FileAsset.find_with_conditions({})
24
+ else
25
+ container_uri = "info:fedora/#{params[:asset_id]}"
26
+ escaped_uri = container_uri.gsub(/(:)/, '\\:')
27
+ extra_controller_params = {:q=>"is_part_of_s:#{escaped_uri}", :qt=>'standard'}
28
+ @response, @document_list = get_search_results( extra_controller_params )
29
+
30
+ # Including this line so permissions tests can be run against the container
31
+ @container_response, @document = get_solr_response_for_doc_id(params[:asset_id])
32
+
33
+ # Including these lines for backwards compatibility (until we can use Rails3 callbacks)
34
+ @container = ActiveFedora::Base.find(params[:asset_id], :cast=>true)
35
+ @solr_result = @container.parts(:response_format=>:solr)
36
+ end
37
+
38
+ # Load permissions_solr_doc based on params[:asset_id]
39
+ load_permissions_from_solr(params[:asset_id])
40
+
41
+ render :action=>params[:action], :layout=>layout
42
+ end
43
+
44
+ def new
45
+ render :partial=>"new", :layout=>false
46
+ end
47
+
48
+ # Creates and Saves a File Asset to contain the the Uploaded file
49
+ # If container_id is provided:
50
+ # * the File Asset will use RELS-EXT to assert that it's a part of the specified container
51
+ # * the method will redirect to the container object's edit view after saving
52
+ def create
53
+ if params.has_key?(:number_of_files) and params[:number_of_files] != "0"
54
+ return redirect_to edit_catalog_path(params[:id], :wf_step => :files, :number_of_files => params[:number_of_files])
55
+ elsif params.has_key?(:number_of_files) and params[:number_of_files] == "0"
56
+ return redirect_to next_step(params[:id])
57
+ end
58
+
59
+ if params.has_key?(:Filedata)
60
+ notice = process_files
61
+ flash[:notice] = notice.join("<br/>".html_safe) unless notice.blank?
62
+ else
63
+ flash[:notice] = "You must specify a file to upload."
64
+ end
65
+
66
+ if params[:container_id]
67
+ redirect_to next_step(params[:container_id])
68
+ else
69
+ redirect_to catalog_index_path
70
+ end
71
+
72
+ end
73
+
74
+ def process_files
75
+ @file_assets = create_and_save_file_assets_from_params
76
+ notice = []
77
+ @file_assets.each do |file_asset|
78
+ apply_depositor_metadata(file_asset)
79
+
80
+ notice << render_to_string(:partial=>'hydra/file_assets/asset_saved_flash', :locals => { :file_asset => file_asset })
81
+
82
+ if !params[:container_id].nil?
83
+ associate_file_asset_with_container(file_asset,'info:fedora/' + params[:container_id])
84
+ end
85
+
86
+ ## Apply any posted file metadata
87
+ unless params[:asset].nil?
88
+ logger.debug("applying submitted file metadata: #{@sanitized_params.inspect}")
89
+ apply_file_metadata
90
+ end
91
+ # If redirect_params has not been set, use {:action=>:index}
92
+ logger.debug "Created #{file_asset.pid}."
93
+ end
94
+ notice
95
+ end
96
+
97
+ # Common destroy method for all AssetsControllers
98
+ def destroy
99
+ ActiveFedora::Base.find(params[:id], :cast=>true).delete
100
+
101
+ flash[:notice] = "Deleted #{params[:id]} from #{params[:container_id]}."
102
+
103
+ if !params[:container_id].nil?
104
+ redirect_params = edit_catalog_path(params[:container_id], :anchor => "file_assets")
105
+ end
106
+ redirect_params ||= {:action => 'index', :q => nil , :f => nil}
107
+
108
+ redirect_to redirect_params
109
+
110
+ end
111
+
112
+
113
+ def show
114
+ begin
115
+ @file_asset = FileAsset.find(params[:id])
116
+ rescue ActiveFedora::ObjectNotFoundError
117
+ logger.warn("No such file asset: " + params[:id])
118
+ flash[:notice]= "No such file asset."
119
+ redirect_to(:action => 'index', :q => nil , :f => nil)
120
+ return
121
+ end
122
+ # get containing object for this FileAsset
123
+ pid = @file_asset.container_id
124
+ parent = ActiveFedora::Base.find(pid, :cast=>true)
125
+ @downloadable = false
126
+ # A FileAsset is downloadable iff the user has read or higher access to a parent
127
+
128
+ if can? :read, parent
129
+ # First try to use datastream_id value (set in FileAssetsHelper)
130
+ if @file_asset.datastreams.include?(datastream_id)
131
+ send_datastream @file_asset.datastreams[datastream_id]
132
+ elsif @file_asset.datastreams.include?("DS1")
133
+ send_datastream @file_asset.datastreams["DS1"]
134
+ end
135
+ else
136
+ raise Hydra::AccessDenied.new("You do not have sufficient access privileges to download this file.")
137
+ end
138
+ end
139
+ end
140
+
@@ -0,0 +1,12 @@
1
+ module Hydra
2
+ module FileAccess
3
+ class Engine < Rails::Engine
4
+ # Load rake tasks
5
+ rake_tasks do
6
+ # Dir.glob(File.join(File.expand_path('../', File.dirname(__FILE__)),'railties', '*.rake')).each do |railtie|
7
+ # load railtie
8
+ # end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # will move to lib/hydra/controller / file_assets_controller_behavior.rb in release 5.x
2
+ require 'deprecation'
3
+ module Hydra::FileAssets
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ Deprecation.warn Hydra::FileAssets, "Hydra::FileAssets was moved to Hydra::Controller::FileAssetsBehavior"
8
+ include Hydra::Controller::FileAssetsBehavior
9
+ end
10
+ end
11
+
@@ -0,0 +1,139 @@
1
+ require "hydra"
2
+ class Hydra::WorkflowError < StandardError; end;
3
+
4
+ # will move to lib/hydra/workflow/submission_workflow in release 5.x
5
+ module Hydra::SubmissionWorkflow
6
+
7
+ # When in this module is incuded in a controller (e.g. responds to :before_filter) add the validate_worflow_step method to the before filter chain.
8
+ def self.included(base)
9
+ base.before_filter :validate_workflow_step if base.respond_to?(:before_filter)
10
+ end
11
+
12
+ # To be used in a before_filter. This will call a method with the #{af_model}_#{action_param}_validation. If that method returns false then we will redirect back. The controller method doing the validation should set an appropriate flash message.
13
+ def validate_workflow_step
14
+ unless model_config.nil?
15
+ # we may want to use the workflow name instead of or in addition to the action in the validation naming convention.
16
+ validation_method = "#{get_af_model_from_params}_#{params[:action]}_validation".to_sym
17
+ if self.respond_to?(validation_method) and self.send(validation_method) === false
18
+ redirect_to :back
19
+ end
20
+ end
21
+ end
22
+
23
+ # Returns the name field for the next step in the configuration for the current model given the current step.
24
+ def next_step_in_workflow(current_step)
25
+ unless model_config.nil?
26
+ if current_step.blank?
27
+ # The first edit step won't have a wf_step param so we will need to pass it off to the 2nd step.
28
+ return next_step_in_workflow(first_step_in_workflow)
29
+ else
30
+ model_config.each_with_index do |step,i|
31
+ return model_config[i+1][:name] if step[:name] == current_step.to_s and step != model_config.last
32
+ end
33
+ end
34
+ end
35
+ nil
36
+ end
37
+
38
+ # Convenience method to return the first step of a models workflow.
39
+ def first_step_in_workflow
40
+ model_config.first[:name] unless model_config.nil?
41
+ end
42
+
43
+ # Convenience method to return the last step of a models workflow.
44
+ def last_step_in_workflow
45
+ model_config.last[:name] unless model_config.nil?
46
+ end
47
+
48
+ def next_step(id)
49
+ return_params = {:wf_step=>next_step_in_workflow(params[:wf_step])}
50
+ if params[:new_asset]
51
+ return_params[:new_asset] = true
52
+ end
53
+ if params[:wf_step] == last_step_in_workflow or params.has_key?(:finish)
54
+ return_params[:viewing_context] = "browse"
55
+ return_params[:action] = "show"
56
+ return_params.delete(:wf_step)
57
+ return catalog_path(id, return_params)
58
+ end
59
+ return edit_catalog_path(id,return_params)
60
+ end
61
+
62
+ # Convenience method to return the partial for any given step by name.
63
+ def workflow_partial_for_step(step)
64
+ find_workflow_step_by_name(step)[:edit_partial]
65
+ end
66
+
67
+ # Convenience method to return an entire workflow step by name.
68
+ def find_workflow_step_by_name(name)
69
+ model_config.find{|config| config[:name] == name.to_s} unless model_config.nil?
70
+ end
71
+
72
+ # Returns an array of display partials for steps previous to the given step.
73
+ def previous_show_partials(current_step)
74
+ previous_partials = []
75
+ # if there is no step then we are on the first step of the workflow and don't need to display anything.
76
+ return previous_partials if current_step.blank?
77
+ unless model_config.nil?
78
+ model_config.each do |config|
79
+ break if config[:name] == current_step.to_s
80
+ previous_partials << config[:show_partial]
81
+ end
82
+ end
83
+ previous_partials
84
+ end
85
+
86
+ # Returns an array of all edit partials for the current content type.
87
+ def all_edit_partials
88
+ edit_partials = []
89
+ unless model_config.nil?
90
+ model_config.each do |config|
91
+ edit_partials << config[:edit_partial]
92
+ end
93
+ end
94
+ edit_partials
95
+ end
96
+
97
+ # Will return the entire workflow configuration for the current model.
98
+ # We determing model first by seeing the @document object is a SolrDocument. If it is we will determing from the has_model_s field.
99
+ # Otherwise we will attempt to determine by the parameters (content_type directly passed or the id of an object).
100
+ def model_config
101
+ # If we can get it directly from solr get it there.
102
+ if !@document.nil? and @document.is_a?(SolrDocument)
103
+ _model = get_af_model_from_solr
104
+ return workflow_config[_model] if !_model.nil? and workflow_config.has_key?(_model)
105
+
106
+ # If we can get the model from the params get it there.
107
+ elsif params.has_key?(:content_type) or params.has_key?(:id)
108
+ _model = get_af_model_from_params
109
+ return workflow_config[_model] if workflow_config.has_key?(_model) and _model
110
+ else
111
+ nil #raise Hydra::WorkflowError
112
+ end
113
+ end
114
+
115
+ # Reutrns a symbolized model name determined by parameters.
116
+ def get_af_model_from_params
117
+ if params.has_key?(:content_type)
118
+ return params[:content_type].pluralize.to_sym
119
+ elsif params[:id]
120
+ begin
121
+ af = ActiveFedora::Base.load_instance_from_solr(params[:id])
122
+ return "#{ActiveFedora::ContentModel.known_models_for( af ).first}".underscore.pluralize.to_sym
123
+ rescue ActiveFedora::ObjectNotFoundError => e
124
+ nil
125
+ end
126
+ end
127
+ end
128
+
129
+ # Convenience method to return the model from the @document objects has_model_s field.
130
+ def get_af_model_from_solr
131
+ @document[:has_model_s].first.gsub("info:fedora/afmodel:","").underscore.pluralize.to_sym
132
+ end
133
+
134
+ # The configuration hash. This should probably live somewhere else and get read in so it can be properly configured at the application level. But for now it's here.
135
+ def workflow_config
136
+ Hydra.config[:submission_workflow]
137
+ end
138
+
139
+ end
data/lib/hydra/ui.rb ADDED
@@ -0,0 +1,6 @@
1
+ # Modules, etc. to support Hydra default UI.
2
+ module Hydra::UI
3
+ extend ActiveSupport::Autoload
4
+ autoload :Controller
5
+ end
6
+
data/spec/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /internal
@@ -0,0 +1,180 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::FileAssetsController do
4
+ include Devise::TestHelpers
5
+ before do
6
+ session[:user]='bob'
7
+ end
8
+
9
+ it "should be restful" do
10
+ { :get => "/hydra/file_assets" }.should route_to(:controller=>'hydra/file_assets', :action=>'index')
11
+ { :get => "/hydra/file_assets/3" }.should route_to(:controller=>'hydra/file_assets', :action=>'show', :id=>"3")
12
+ { :delete=> "/hydra/file_assets/3" }.should route_to(:controller=>'hydra/file_assets', :action=>'destroy', :id=>"3")
13
+ { :put=>"/hydra/file_assets/3" }.should route_to(:controller=>'hydra/file_assets', :action=>'update', :id=>"3")
14
+ { :get => "/hydra/file_assets/3/edit" }.should route_to(:controller=>'hydra/file_assets', :action=>'edit', :id=>"3")
15
+ { :get =>"/hydra/file_assets/new" }.should route_to(:controller=>'hydra/file_assets', :action=>'new')
16
+ { :post => "/hydra/file_assets" }.should route_to(:controller=>'hydra/file_assets', :action=>'create')
17
+
18
+ end
19
+
20
+ describe "index" do
21
+
22
+ it "should find all file assets in the repo if no container_id is provided" do
23
+ ActiveFedora::SolrService.should_receive(:query).with("has_model_s:info\\:fedora/afmodel\\:FileAsset", {:sort=>["system_create_dt asc"]}).and_return("solr result")
24
+ controller.stub(:load_permissions_from_solr)
25
+ ActiveFedora::Base.should_receive(:new).never
26
+ xhr :get, :index
27
+ assigns[:solr_result].should == "solr result"
28
+ end
29
+ it "should find all file assets belonging to a given container object if asset_id is provided" do
30
+ pid = 'hydrangea:fixture_mods_article3'
31
+ xhr :get, :index, :asset_id=>pid
32
+ assigns[:response][:response][:docs].first["id"].should == "hydrangea:fixture_file_asset1"
33
+ assigns[:document_list].first.id.should == "hydrangea:fixture_file_asset1"
34
+
35
+ assigns[:container_response][:response][:docs].first["id"].should == "hydrangea:fixture_mods_article3"
36
+ assigns[:document].id.should == "hydrangea:fixture_mods_article3"
37
+ assigns[:solr_result].first["id"].should == "hydrangea:fixture_file_asset1"
38
+ assigns[:container].should == ModsAsset.find('hydrangea:fixture_mods_article3')
39
+ end
40
+
41
+ end
42
+
43
+ describe "new" do
44
+ it "should set :container_id to value of :container_id if available" do
45
+ xhr :get, :new, :asset_id=>"_PID_"
46
+ @controller.params[:asset_id].should == "_PID_"
47
+ end
48
+ end
49
+
50
+ describe "show" do
51
+ it "should redirect back if current_user does not have read or edit permissions" do
52
+ mock_user = double("User")
53
+ mock_user.stub(:email).and_return("fake_user@example.com")
54
+ mock_user.stub(:is_being_superuser?).and_return(false)
55
+ mock_user.stub(:persisted?).and_return(true)
56
+ mock_user.stub(:new_record?).and_return(false)
57
+ controller.stub(:current_user).and_return(mock_user)
58
+ request.env["HTTP_REFERER"] = "http://example.com/?q=search"
59
+ get(:show, :id=>"hydrangea:fixture_file_asset1")
60
+ response.should redirect_to(root_url)
61
+ end
62
+ it "should redirect to the login page if the user is not logged in" do
63
+ mock_user = double("User")
64
+ mock_user.stub(:email).and_return("fake_user@example.com")
65
+ mock_user.stub(:is_being_superuser?).and_return(false)
66
+ mock_user.stub(:persisted?).and_return(false)
67
+ mock_user.stub(:new_record?).and_return(true)
68
+ controller.stub(:current_user).and_return(mock_user)
69
+ request.env["HTTP_REFERER"] = "http://example.com/?q=search"
70
+ get(:show, :id=>"hydrangea:fixture_file_asset1")
71
+ response.should redirect_to("http://test.host/users/sign_in")
72
+ session['user_return_to'].should =~ /fixture_file_asset1/
73
+ end
74
+ it "should redirect to index view if the file does not exist" do
75
+ get(:show, :id=>"example:invalid_object")
76
+ response.should redirect_to(:action => 'index')
77
+ end
78
+ end
79
+
80
+ describe "create" do
81
+ it "should create and save a file asset from the given params" do
82
+ mock_fa = double("FileAsset")
83
+ mock_file = double("File")
84
+ mock_fa.stub(:pid).and_return("foo:pid")
85
+ controller.should_receive(:create_and_save_file_assets_from_params).and_return([mock_fa])
86
+ xhr :post, :create, :Filedata=>[mock_file], :Filename=>"Foo File"
87
+ end
88
+ it "if container_id is provided, should associate the created file asset wtih the container" do
89
+ stub_fa = double("FileAsset")
90
+ stub_fa.stub(:pid).and_return("foo:pid")
91
+ stub_fa.stub(:label).and_return("Foo File")
92
+ mock_file = double("File")
93
+ controller.should_receive(:create_and_save_file_assets_from_params).and_return([stub_fa])
94
+ controller.should_receive(:associate_file_asset_with_container)
95
+ xhr :post, :create, :Filedata=>[mock_file], :Filename=>"Foo File", :container_id=>"_PID_"
96
+ end
97
+ it "should redirect back to edit view if no Filedata is provided but container_id is provided" do
98
+ controller.should_receive(:model_config).at_least(:once).and_return(controller.workflow_config[:mods_assets])
99
+ xhr :post, :create, :container_id=>"_PID_", :wf_step=>"files"
100
+ response.should redirect_to edit_catalog_path("_PID_", :wf_step=>"permissions")
101
+ request.flash[:notice].should == "You must specify a file to upload."
102
+ end
103
+ it "should display a message that you need to select a file to upload if no Filedata is provided" do
104
+ xhr :post, :create
105
+ request.flash[:notice].include?("You must specify a file to upload.").should be_true
106
+ end
107
+
108
+ end
109
+
110
+ describe "destroy" do
111
+ it "should delete the asset identified by pid" do
112
+ mock_obj = double("asset")
113
+ mock_obj.should_receive(:delete)
114
+ ActiveFedora::Base.should_receive(:find).with("__PID__", :cast=>true).and_return(mock_obj)
115
+ delete(:destroy, :id => "__PID__")
116
+ end
117
+ it "should remove container relationship and perform proper garbage collection" do
118
+ pending "relies on ActiveFedora implementing Base.file_objects_remove"
119
+ mock_container = mock("asset")
120
+ mock_container.should_receive(:file_objects_remove).with("_file_asset_pid_")
121
+ FileAsset.should_receive(:garbage_collect).with("_file_asset_pid_")
122
+ ActiveFedora::Base.should_receive(:find).with("_container_pid_", :cast=>true).and_return(mock_container)
123
+ delete(:destroy, :id => "_file_asset_pid_", :asset_id=>"_container_pid_")
124
+ end
125
+ end
126
+
127
+ describe "integration tests - " do
128
+ before(:all) do
129
+ class TestObj < ActiveFedora::Base
130
+ include ActiveFedora::FileManagement
131
+ end
132
+
133
+ ActiveFedora::SolrService.register(ActiveFedora.solr_config[:url])
134
+ @test_container = TestObj.new
135
+ @test_container.add_relationship(:is_member_of, "info:fedora/foo:1")
136
+ @test_container.add_relationship(:has_collection_member, "info:fedora/foo:2")
137
+ @test_container.save
138
+
139
+ @test_fa = FileAsset.new
140
+ @test_fa.add_relationship(:is_part_of, @test_container)
141
+ @test_fa.save
142
+ end
143
+
144
+ after(:all) do
145
+ @test_container.delete
146
+ @test_fa.delete
147
+ Object.send(:remove_const, :TestObj)
148
+ end
149
+
150
+ describe "index" do
151
+ it "should retrieve the container object and its file assets" do
152
+ #xhr :get, :index, :container_id=>@test_container.pid
153
+ get :index, {:asset_id=>@test_container.pid}
154
+ @controller.params[:asset_id].should_not be_nil
155
+ assigns(:solr_result).should_not be_nil
156
+ #puts assigns(:solr_result).inspect
157
+ assigns(:container).file_objects(:response_format=>:id_array).should include(@test_fa.pid)
158
+ assigns(:container).file_objects(:response_format=>:id_array).should include("foo:2")
159
+ end
160
+ end
161
+
162
+ describe "create" do
163
+ before :each do
164
+ mock_user = double("User")
165
+ mock_user.stub(:user_key).and_return('user@example.com')
166
+ mock_warden = double("Warden")
167
+ mock_warden.stub(:authenticate).and_return(mock_user)
168
+ request.env['warden'] = mock_warden
169
+ end
170
+
171
+ it "should set is_part_of relationship on the new File Asset pointing back at the container" do
172
+ test_file = fixture_file_upload('spec/fixtures/small_file.txt', 'text/plain')
173
+ filename = "My File Name"
174
+ post :create, {:Filedata=>[test_file], :Filename=>filename, :container_id=>@test_container.pid}
175
+ assigns(:file_asset).ids_for_outbound(:is_part_of).should == [@test_container.pid]
176
+ retrieved_fa = FileAsset.find(@test_fa.pid).ids_for_outbound(:is_part_of).should == [@test_container.pid]
177
+ end
178
+ end
179
+ end
180
+ end