hydra-core 13.1.0 → 13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39536b09014de9379e5a9edb4a2ee0ca389700c5516e37d1b3e4b92e50a6d060
4
- data.tar.gz: 0a89622ac5a2c47e389aa9d86d2258fda4dae801a859281de3e6b9f1e35c3c01
3
+ metadata.gz: b18b78f7931bd8e03a78a9635ab9f55c9851d6555e56a367ccaec3cff349ca9b
4
+ data.tar.gz: 26b2766d7d8ccaf52d2b127698cb5ec5e49e460b99311ee71c31ee411bd15da7
5
5
  SHA512:
6
- metadata.gz: 5969937147aae853ed04269261f3f9ca18e43da3a3bbaaede49be7abbc27bc3947af653728c8977d57f810b70f8b01eb8a224bf604595402e830f60d2df208d9
7
- data.tar.gz: 0c2ccf95043d278549836083d46a3ffc9245e8dbd36ed575f237d2a8aafeb47b75469a131ee9557dc90d153e17a593bbf827ac64a43a57cda115cc73ec8ae32c
6
+ metadata.gz: 384b95f53a1a1901ac1622fa6afc23e709bc5c8407f630868440b5adbf5438b79e03f6a99787b60b0885daafe25b14e2a5e89ba214206127a5a78958279deb76
7
+ data.tar.gz: 23afe29c5e9fd4c63d99c1d3fe1e377238cabc0081c23f4716dc118b184f637c7a13f0a11c01627222fddb4d1efe74cb4eeb17ad0eb61cf4e1232518a262508b
data/hydra-core.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.required_ruby_version = '>= 3.1'
21
21
 
22
22
  gem.add_dependency 'hydra-access-controls', version
23
- gem.add_dependency "railties", '>= 6.1', '< 8.1'
23
+ gem.add_dependency "railties", '>= 6.1', '< 9'
24
24
 
25
25
  gem.add_development_dependency 'rails-controller-testing'
26
26
  gem.add_development_dependency 'rspec-rails'
@@ -1,3 +1,3 @@
1
1
  module HydraHead
2
- VERSION = "13.1.0"
2
+ VERSION = "13.2.0"
3
3
  end
@@ -39,144 +39,6 @@ describe DownloadsController do
39
39
  Object.send(:remove_const, :ContentHolder)
40
40
  end
41
41
 
42
- context "when not logged in" do
43
-
44
- context "when a specific datastream is requested" do
45
- it "redirects to the root path and display an error" do
46
- get :show, params: { id: obj, file: "descMetadata" }
47
- expect(response).to redirect_to new_user_session_path
48
- expect(flash[:alert]).to eq "You are not authorized to access this page."
49
- end
50
- end
51
- end
52
-
53
- context "when logged in, but without read access" do
54
- let(:user) { User.create(email: 'email2@example.com', password: 'password') }
55
- before do
56
- sign_in user
57
- end
58
- context "when a specific datastream is requested" do
59
- it "redirects to the root path and display an error" do
60
- get :show, params: { id: obj, file: "descMetadata" }
61
- expect(response).to redirect_to root_path
62
- expect(flash[:alert]).to eq "You are not authorized to access this page."
63
- end
64
- end
65
- end
66
-
67
- context "when logged in as reader" do
68
- before do
69
- sign_in @user
70
- allow_any_instance_of(User).to receive(:groups).and_return([])
71
- end
72
-
73
- describe "#show" do
74
- it "defaults to returning default download configured by object" do
75
- allow(ContentHolder).to receive(:default_file_path).and_return('buzz')
76
- get :show, params: { id: obj }
77
- expect(response).to be_successful
78
- expect(response.headers['Content-Type']).to start_with "image/png"
79
- expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"buzz.png\""
80
- expect(response.body).to eq 'fizz'
81
- end
82
-
83
- it "defaults to returning default download configured by controller" do
84
- expect(DownloadsController.default_file_path).to eq "content"
85
- get :show, params: { id: obj }
86
- expect(response).to be_successful
87
- expect(response.headers['Content-Type']).to start_with "image/png"
88
- expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"world.png\""
89
- expect(response.body).to eq 'foobarfoobarfoobar'
90
- end
91
-
92
- context "when a specific datastream is requested" do
93
- context "and it doesn't exist" do
94
- it "returns :not_found when the datastream doesn't exist" do
95
- get :show, params: { id: obj, file: "thumbnail" }
96
- expect(response).to be_not_found
97
- end
98
- end
99
- context "and it exists" do
100
- it "returns it" do
101
- get :show, params: { id: obj, file: "descMetadata" }
102
- expect(response).to be_successful
103
- expect(response.headers['Content-Type']).to start_with "text/plain"
104
- expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"metadata.xml\""
105
- expect(response.body).to eq "It's a stream"
106
- end
107
- end
108
- end
109
-
110
- it "supports setting disposition to inline" do
111
- get :show, params: { id: obj, disposition: "inline" }
112
- expect(response).to be_successful
113
- expect(response.headers['Content-Type']).to start_with "image/png"
114
- expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"world.png\""
115
- expect(response.body).to eq 'foobarfoobarfoobar'
116
- end
117
-
118
- it "allows you to specify filename for download" do
119
- get :show, params: { id: obj, "filename" => "my%20dog.png" }
120
- expect(response).to be_successful
121
- expect(response.headers['Content-Type']).to start_with "image/png"
122
- expect(response.headers["Content-Disposition"]).to start_with "inline; filename="
123
- expect(response.headers["Content-Disposition"]).to include "my%20dog.png"
124
- expect(response.body).to eq 'foobarfoobarfoobar'
125
- end
126
- end
127
- describe "stream" do
128
- let(:parent) { ActiveFedora::Base.new(id: '1234') }
129
-
130
- before do
131
- parent.add_file('one1two2threfour', path: 'webm', mime_type: 'video/webm', original_name: 'MyVideo.webm')
132
- parent.save!
133
- expect(controller).to receive(:authorize!).with(:download, instance_of(ActiveFedora::File)).and_return(true)
134
- end
135
-
136
- it "head request" do
137
- request.env["HTTP_RANGE"] = 'bytes=0-15'
138
- head :show, params: { id: parent, file: 'webm' }
139
- expect(response.headers['Content-Length']).to eq 16
140
- expect(response.headers['Accept-Ranges']).to eq 'bytes'
141
- expect(response.headers['Content-Type']).to start_with 'video/webm'
142
- end
143
-
144
- it "sends the whole thing" do
145
- request.env["HTTP_RANGE"] = 'bytes=0-15'
146
- get :show, params: { id: '1234', file: 'webm' }
147
- expect(response.body).to eq 'one1two2threfour'
148
- expect(response.headers["Content-Range"]).to eq 'bytes 0-15/16'
149
- expect(response.headers["Content-Length"]).to eq '16'
150
- expect(response.headers['Accept-Ranges']).to eq 'bytes'
151
- expect(response.headers['Content-Type']).to start_with "video/webm"
152
- expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"MyVideo.webm\""
153
- expect(response.status).to eq 206
154
- end
155
-
156
- it "sends the whole thing when the range is open ended" do
157
- request.env["HTTP_RANGE"] = 'bytes=0-'
158
- get :show, params: { id: '1234', file: 'webm' }
159
- expect(response.body).to eq 'one1two2threfour'
160
- end
161
-
162
- it "gets a range not starting at the beginning" do
163
- request.env["HTTP_RANGE"] = 'bytes=3-15'
164
- get :show, params: { id: '1234', file: 'webm' }
165
- expect(response.body).to eq '1two2threfour'
166
- expect(response.headers["Content-Range"]).to eq 'bytes 3-15/16'
167
- expect(response.headers["Content-Length"]).to eq '13'
168
- end
169
-
170
- it "gets a range not ending at the end" do
171
- request.env["HTTP_RANGE"] = 'bytes=4-11'
172
- get :show, params: { id: '1234', file: 'webm' }
173
- expect(response.body).to eq 'two2thre'
174
- expect(response.headers["Content-Range"]).to eq 'bytes 4-11/16'
175
- expect(response.headers["Content-Length"]).to eq '8'
176
- end
177
- end
178
- end
179
-
180
42
  describe "overriding the default asset param key" do
181
43
  before do
182
44
  Rails.application.routes.draw do
@@ -0,0 +1,170 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Downloads' do
4
+ before do
5
+ Rails.application.routes.draw do
6
+ resources :downloads
7
+ devise_for :users
8
+ root to: 'catalog#index'
9
+ end
10
+ end
11
+
12
+ describe "with a file" do
13
+ before do
14
+ class ContentHolder < ActiveFedora::Base
15
+ include Hydra::AccessControls::Permissions
16
+ has_subresource 'thumbnail'
17
+ end
18
+ @user = User.new.tap {|u| u.email = 'email@example.com'; u.password = 'password'; u.save}
19
+ end
20
+ let(:obj) do
21
+ ContentHolder.new.tap do |obj|
22
+ obj.add_file('fizz', path: 'buzz', original_name: 'buzz.png', mime_type: 'image/png')
23
+ obj.add_file('foobarfoobarfoobar', path: 'content', original_name: 'world.png', mime_type: 'image/png')
24
+ obj.add_file("It's a stream", path: 'descMetadata', original_name: 'metadata.xml', mime_type: 'text/plain')
25
+ obj.read_users = [@user.user_key]
26
+ obj.save!
27
+ end
28
+ end
29
+
30
+ after do
31
+ obj.destroy
32
+ Object.send(:remove_const, :ContentHolder)
33
+ end
34
+
35
+ context "when not logged in" do
36
+
37
+ context "when a specific datastream is requested" do
38
+ it "redirects to the root path and display an error" do
39
+ get "/downloads/#{obj.id.gsub('/', '%2F')}", params: { file: "descMetadata" }
40
+ expect(response).to redirect_to new_user_session_path
41
+ expect(flash[:alert]).to eq "You are not authorized to access this page."
42
+ end
43
+ end
44
+ end
45
+
46
+ context "when logged in, but without read access" do
47
+ let(:user) { User.create(email: 'email2@example.com', password: 'password') }
48
+ before do
49
+ sign_in user
50
+ end
51
+ context "when a specific datastream is requested" do
52
+ it "redirects to the root path and display an error" do
53
+ get "/downloads/#{obj.id.gsub('/', '%2F')}", params: { file: "descMetadata" }
54
+ expect(response).to redirect_to root_path
55
+ expect(flash[:alert]).to eq "You are not authorized to access this page."
56
+ end
57
+ end
58
+ end
59
+
60
+ context "when logged in as reader" do
61
+ before do
62
+ sign_in @user
63
+ allow_any_instance_of(User).to receive(:groups).and_return([])
64
+ end
65
+
66
+ describe "#show" do
67
+ it "defaults to returning default download configured by object" do
68
+ allow(ContentHolder).to receive(:default_file_path).and_return('buzz')
69
+ get "/downloads/#{obj.id.gsub('/', '%2F')}"
70
+ expect(response).to be_successful
71
+ expect(response.headers['Content-Type']).to start_with "image/png"
72
+ expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"buzz.png\""
73
+ expect(response.body).to eq 'fizz'
74
+ end
75
+
76
+ it "defaults to returning default download configured by controller" do
77
+ expect(DownloadsController.default_file_path).to eq "content"
78
+ get "/downloads/#{obj.id.gsub('/', '%2F')}"
79
+ expect(response).to be_successful
80
+ expect(response.headers['Content-Type']).to start_with "image/png"
81
+ expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"world.png\""
82
+ expect(response.body).to eq 'foobarfoobarfoobar'
83
+ end
84
+
85
+ context "when a specific datastream is requested" do
86
+ context "and it doesn't exist" do
87
+ it "returns :not_found when the datastream doesn't exist" do
88
+ get "/downloads/#{obj.id.gsub('/', '%2F')}", params: { file: "thumbnail" }
89
+ expect(response).to be_not_found
90
+ end
91
+ end
92
+ context "and it exists" do
93
+ it "returns it" do
94
+ get "/downloads/#{obj.id.gsub('/', '%2F')}", params: { file: "descMetadata" }
95
+ expect(response).to be_successful
96
+ expect(response.headers['Content-Type']).to start_with "text/plain"
97
+ expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"metadata.xml\""
98
+ expect(response.body).to eq "It's a stream"
99
+ end
100
+ end
101
+ end
102
+
103
+ it "supports setting disposition to inline" do
104
+ get "/downloads/#{obj.id.gsub('/', '%2F')}", params: { disposition: "inline" }
105
+ expect(response).to be_successful
106
+ expect(response.headers['Content-Type']).to start_with "image/png"
107
+ expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"world.png\""
108
+ expect(response.body).to eq 'foobarfoobarfoobar'
109
+ end
110
+
111
+ it "allows you to specify filename for download" do
112
+ get "/downloads/#{obj.id.gsub('/', '%2F')}", params: { "filename" => "my%20dog.png" }
113
+ expect(response).to be_successful
114
+ expect(response.headers['Content-Type']).to start_with "image/png"
115
+ expect(response.headers["Content-Disposition"]).to start_with "inline; filename="
116
+ expect(response.headers["Content-Disposition"]).to include "my%20dog.png"
117
+ expect(response.body).to eq 'foobarfoobarfoobar'
118
+ end
119
+ end
120
+ describe "stream" do
121
+ let(:parent) { ContentHolder.new(id: '1234') }
122
+
123
+ before do
124
+ parent.add_file('one1two2threfour', path: 'webm', mime_type: 'video/webm', original_name: 'MyVideo.webm')
125
+ parent.read_users = [@user.user_key]
126
+ parent.save!
127
+ sign_in @user
128
+ allow_any_instance_of(User).to receive(:groups).and_return([])
129
+ end
130
+
131
+ it "head request" do
132
+ head "/downloads/1234", params: { file: 'webm' }, headers: { HTTP_RANGE: 'bytes=0-15' }
133
+ expect(response.headers['Content-Length']).to eq 16
134
+ expect(response.headers['Accept-Ranges']).to eq 'bytes'
135
+ expect(response.headers['Content-Type']).to start_with 'video/webm'
136
+ end
137
+
138
+ it "sends the whole thing" do
139
+ get "/downloads/1234", params: { file: 'webm' }, headers: { HTTP_RANGE: 'bytes=0-15' }
140
+ expect(response.body).to eq 'one1two2threfour'
141
+ expect(response.headers["Content-Range"]).to eq 'bytes 0-15/16'
142
+ expect(response.headers["Content-Length"]).to eq '16'
143
+ expect(response.headers['Accept-Ranges']).to eq 'bytes'
144
+ expect(response.headers['Content-Type']).to start_with "video/webm"
145
+ expect(response.headers["Content-Disposition"]).to start_with "inline; filename=\"MyVideo.webm\""
146
+ expect(response.status).to eq 206
147
+ end
148
+
149
+ it "sends the whole thing when the range is open ended" do
150
+ get "/downloads/1234", params: { file: 'webm' }, headers: { HTTP_RANGE: 'bytes=0-' }
151
+ expect(response.body).to eq 'one1two2threfour'
152
+ end
153
+
154
+ it "gets a range not starting at the beginning" do
155
+ get "/downloads/1234", params: { file: 'webm' }, headers: { HTTP_RANGE: 'bytes=3-15' }
156
+ expect(response.body).to eq '1two2threfour'
157
+ expect(response.headers["Content-Range"]).to eq 'bytes 3-15/16'
158
+ expect(response.headers["Content-Length"]).to eq '13'
159
+ end
160
+
161
+ it "gets a range not ending at the end" do
162
+ get "/downloads/1234", params: { file: 'webm' }, headers: { HTTP_RANGE: 'bytes=4-11' }
163
+ expect(response.body).to eq 'two2thre'
164
+ expect(response.headers["Content-Range"]).to eq 'bytes 4-11/16'
165
+ expect(response.headers["Content-Length"]).to eq '8'
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
data/spec/spec_helper.rb CHANGED
@@ -33,6 +33,7 @@ RSpec.configure do |config|
33
33
  config.include ::Rails::Controller::Testing::TemplateAssertions, type: :controller
34
34
  config.include ::Rails::Controller::Testing::TestProcess, type: :controller
35
35
  config.include ::Rails::Controller::Testing::Integration, type: :controller
36
+ config.include Devise::Test::IntegrationHelpers, type: :request
36
37
  config.use_transactional_fixtures = true
37
38
  config.infer_spec_type_from_file_location!
38
39
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.1.0
4
+ version: 13.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt, Bess Sadler, Julie Meloni, Naomi Dushay, Jessie Keck, John Scofield,
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-05-23 00:00:00.000000000 Z
12
+ date: 2025-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hydra-access-controls
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 13.1.0
20
+ version: 13.2.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 13.1.0
27
+ version: 13.2.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: railties
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  version: '6.1'
35
35
  - - "<"
36
36
  - !ruby/object:Gem::Version
37
- version: '8.1'
37
+ version: '9'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -44,7 +44,7 @@ dependencies:
44
44
  version: '6.1'
45
45
  - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: '8.1'
47
+ version: '9'
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rails-controller-testing
50
50
  requirement: !ruby/object:Gem::Requirement
@@ -138,6 +138,7 @@ files:
138
138
  - spec/models/solr_document_spec.rb
139
139
  - spec/models/user_spec.rb
140
140
  - spec/rcov.opts
141
+ - spec/requests/downloads_spec.rb
141
142
  - spec/search_builders/search_builder_spec.rb
142
143
  - spec/spec_helper.rb
143
144
  - spec/support/app/models/sample.rb
@@ -181,6 +182,7 @@ test_files:
181
182
  - spec/models/solr_document_spec.rb
182
183
  - spec/models/user_spec.rb
183
184
  - spec/rcov.opts
185
+ - spec/requests/downloads_spec.rb
184
186
  - spec/search_builders/search_builder_spec.rb
185
187
  - spec/spec_helper.rb
186
188
  - spec/support/app/models/sample.rb