11require 'spec_helper'
22require 'cloudinary'
33
4+ # Add blank? method for testing
5+ class Object
6+ def blank?
7+ respond_to? ( :empty? ) ? !!empty? : !self
8+ end unless method_defined? ( :blank? )
9+ end
10+
11+ class NilClass
12+ def blank?
13+ true
14+ end unless method_defined? ( :blank? )
15+ end
16+
417module CarrierWave
518 module Storage
619 class Abstract
@@ -11,7 +24,81 @@ def initialize(uploader)
1124 attr_accessor :uploader
1225 end
1326 end
14- class SanitizedFile ; end
27+
28+ class SanitizedFile
29+ def self . sanitize_regexp
30+ /[^a-zA-Z0-9\. \- \+ _]/
31+ end
32+ end
33+
34+ module Uploader
35+ class Base
36+ attr_accessor :cache_storage
37+
38+ def self . storage ( storage_class )
39+ @storage_class = storage_class
40+ end
41+
42+ def self . cache_storage
43+ @cache_storage
44+ end
45+
46+ def self . cache_storage = ( storage )
47+ @cache_storage = storage
48+ end
49+
50+ def self . class_attribute ( *attrs , **options )
51+ attrs . each do |attr |
52+ instance_variable_set ( "@#{ attr } " , nil )
53+ define_singleton_method attr do |value = nil |
54+ if value
55+ instance_variable_set ( "@#{ attr } " , value )
56+ else
57+ instance_variable_get ( "@#{ attr } " )
58+ end
59+ end
60+ define_method attr do
61+ self . class . send ( attr )
62+ end
63+ define_method "#{ attr } =" do |value |
64+ self . class . send ( attr , value )
65+ end unless options [ :instance_reader ] == false
66+ end
67+ end
68+
69+ def self . extend ( mod )
70+ super
71+ end
72+
73+ def self . processors
74+ @processors ||= [ ]
75+ end
76+
77+ def self . process ( method_name )
78+ processors << [ method_name . keys . first , method_name . values . first , nil ]
79+ end
80+
81+ def self . version_names
82+ [ ]
83+ end
84+
85+ def initialize
86+ # Mock initialization
87+ end
88+
89+ def version_name
90+ nil
91+ end
92+
93+ def versions
94+ OpenStruct . new ( values : [ ] )
95+ end
96+
97+ def transformation
98+ { }
99+ end
100+ end
101+ end
15102end
16103
17104RSpec . describe Cloudinary ::CarrierWave do
@@ -31,11 +118,112 @@ class SanitizedFile; end
31118 subject
32119 end
33120 end
121+
122+ describe 'upload parameters' do
123+ class TestUploader < CarrierWave ::Uploader ::Base
124+ include Cloudinary ::CarrierWave
125+ attr_accessor :enable_processing
126+
127+ def initialize ( model = nil , mounted_as = nil )
128+ super ( )
129+ @enable_processing = true
130+ end
131+ end
132+
133+ let ( :uploader ) { TestUploader . new }
134+
135+ describe '#upload_params class method' do
136+ before do
137+ # Reset processors between tests
138+ TestUploader . instance_variable_set ( :@processors , [ ] )
139+ end
140+
141+ it 'allows setting upload parameters' do
142+ TestUploader . upload_params ( use_filename : true , overwrite : false )
143+ instance = TestUploader . new
144+ expect ( instance . upload_params ) . to eq ( use_filename : true , overwrite : false )
145+ end
146+
147+ it 'merges multiple upload_params calls' do
148+ TestUploader . upload_params ( use_filename : true )
149+ TestUploader . upload_params ( overwrite : false )
150+ instance = TestUploader . new
151+ expect ( instance . upload_params ) . to eq ( use_filename : true , overwrite : false )
152+ end
153+
154+ it 'supports asset_folder parameter' do
155+ TestUploader . upload_params ( asset_folder : 'my_project_assets' )
156+ instance = TestUploader . new
157+ expect ( instance . upload_params ) . to eq ( asset_folder : 'my_project_assets' )
158+ end
159+
160+ it 'supports display_name parameter' do
161+ TestUploader . upload_params ( display_name : 'Sample Upload Test' )
162+ instance = TestUploader . new
163+ expect ( instance . upload_params ) . to eq ( display_name : 'Sample Upload Test' )
164+ end
165+
166+ it 'combines asset_folder and display_name with other parameters' do
167+ TestUploader . upload_params ( asset_folder : 'ecommerce_project' )
168+ TestUploader . upload_params ( display_name : 'Product Image Upload' )
169+ TestUploader . upload_params ( use_filename : true )
170+ TestUploader . upload_params ( unique_filename : false )
171+ instance = TestUploader . new
172+ expect ( instance . upload_params ) . to eq (
173+ asset_folder : 'ecommerce_project' ,
174+ display_name : 'Product Image Upload' ,
175+ use_filename : true ,
176+ unique_filename : false
177+ )
178+ end
179+
180+ it 'supports complex upload parameters including metadata and context' do
181+ TestUploader . upload_params (
182+ asset_folder : 'demo_project' ,
183+ display_name : 'CarrierWave Upload Test' ,
184+ use_filename : true ,
185+ unique_filename : false ,
186+ overwrite : true ,
187+ context : { category : 'product' , source : 'admin_panel' } ,
188+ metadata : { uploaded_by : 'admin_user' , department : 'marketing' }
189+ )
190+ instance = TestUploader . new
191+ expected_params = {
192+ asset_folder : 'demo_project' ,
193+ display_name : 'CarrierWave Upload Test' ,
194+ use_filename : true ,
195+ unique_filename : false ,
196+ overwrite : true ,
197+ context : { category : 'product' , source : 'admin_panel' } ,
198+ metadata : { uploaded_by : 'admin_user' , department : 'marketing' }
199+ }
200+ expect ( instance . upload_params ) . to eq ( expected_params )
201+ end
202+ end
203+
204+ describe '#upload_params instance method' do
205+ it 'returns empty hash when no upload params are set' do
206+ uploader_class = Class . new ( CarrierWave ::Uploader ::Base ) do
207+ include Cloudinary ::CarrierWave
208+ end
209+ instance = uploader_class . new
210+ expect ( instance . upload_params ) . to eq ( { } )
211+ end
212+
213+ it 'prevents use in versions' do
214+ TestUploader . instance_variable_set ( :@processors , [ ] )
215+ TestUploader . upload_params ( quality : 'auto' )
216+ instance = TestUploader . new
217+ allow ( instance ) . to receive ( :version_name ) . and_return ( 'thumb' )
218+ expect { instance . upload_params } . to raise_error ( CloudinaryException , "upload_params cannot be used in versions." )
219+ end
220+ end
221+ end
34222end
35223
36224RSpec . describe Cloudinary ::PreloadedFile do
37225 let ( :test_api_secret ) { "X7qLTrsES31MzxxkxPPA-pAGGfU" }
38-
226+
39227 before do
40228 Cloudinary . config . update ( :api_secret => test_api_secret )
41229 end
@@ -68,45 +256,45 @@ class SanitizedFile; end
68256 # So if filename is "tests/logo.png", public_id becomes "tests/logo"
69257 filename_with_format = public_id
70258 public_id_without_format = "tests/logo" # public_id without .png extension
71-
259+
72260 # Generate a valid signature using the public_id without extension
73261 # The version parsed from preloaded string will be a string, so we use string here too
74262 version_string = test_version . to_s
75263 expected_signature = Cloudinary ::Utils . api_sign_request (
76- { :public_id => public_id_without_format , :version => version_string } ,
77- test_api_secret ,
78- nil ,
264+ { :public_id => public_id_without_format , :version => version_string } ,
265+ test_api_secret ,
266+ nil ,
79267 1 # verify_api_response_signature uses version 1
80268 )
81-
82- # Create a preloaded file string
269+
270+ # Create a preloaded file string
83271 preloaded_string = "image/upload/v#{ version_string } /#{ filename_with_format } ##{ expected_signature } "
84272 preloaded_file = Cloudinary ::PreloadedFile . new ( preloaded_string )
85-
273+
86274 expect ( preloaded_file ) . to be_valid
87275 end
88276
89277 it "should fail verification with incorrect signature" do
90278 wrong_signature = "wrongsignature"
91279 preloaded_string = "image/upload/v#{ test_version } /#{ public_id } ##{ wrong_signature } "
92280 preloaded_file = Cloudinary ::PreloadedFile . new ( preloaded_string )
93-
281+
94282 expect ( preloaded_file ) . not_to be_valid
95283 end
96284
97285 it "should handle raw resource type correctly" do
98286 raw_filename = "document.pdf"
99287 version_string = test_version . to_s
100288 raw_signature = Cloudinary ::Utils . api_sign_request (
101- { :public_id => raw_filename , :version => version_string } ,
102- test_api_secret ,
103- nil ,
289+ { :public_id => raw_filename , :version => version_string } ,
290+ test_api_secret ,
291+ nil ,
104292 1
105293 )
106-
294+
107295 preloaded_string = "raw/upload/v#{ version_string } /#{ raw_filename } ##{ raw_signature } "
108296 preloaded_file = Cloudinary ::PreloadedFile . new ( preloaded_string )
109-
297+
110298 expect ( preloaded_file ) . to be_valid
111299 expect ( preloaded_file . resource_type ) . to eq ( 'raw' )
112300 end
0 commit comments