carrierwave_direct 0.0.1

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 (36) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +21 -0
  4. data/README.md +356 -0
  5. data/Rakefile +12 -0
  6. data/carrierwave_direct.gemspec +31 -0
  7. data/lib/carrierwave_direct.rb +44 -0
  8. data/lib/carrierwave_direct/action_view_extensions/form_helper.rb +36 -0
  9. data/lib/carrierwave_direct/form_builder.rb +17 -0
  10. data/lib/carrierwave_direct/locale/en.rb +20 -0
  11. data/lib/carrierwave_direct/locale/en.yml +7 -0
  12. data/lib/carrierwave_direct/mount.rb +38 -0
  13. data/lib/carrierwave_direct/orm/activerecord.rb +55 -0
  14. data/lib/carrierwave_direct/test/capybara_helpers.rb +58 -0
  15. data/lib/carrierwave_direct/test/helpers.rb +32 -0
  16. data/lib/carrierwave_direct/uploader.rb +142 -0
  17. data/lib/carrierwave_direct/uploader/configuration.rb +38 -0
  18. data/lib/carrierwave_direct/validations/active_model.rb +126 -0
  19. data/lib/carrierwave_direct/version.rb +6 -0
  20. data/spec/action_view_extensions/form_helper_spec.rb +28 -0
  21. data/spec/form_builder_spec.rb +59 -0
  22. data/spec/mount_spec.rb +57 -0
  23. data/spec/orm/activerecord_spec.rb +551 -0
  24. data/spec/spec_helper.rb +5 -0
  25. data/spec/support/carrier_wave_config.rb +9 -0
  26. data/spec/support/direct_uploader.rb +4 -0
  27. data/spec/support/form_builder_helpers.rb +36 -0
  28. data/spec/support/global_helpers.rb +6 -0
  29. data/spec/support/model_helpers.rb +80 -0
  30. data/spec/support/mounted_class.rb +6 -0
  31. data/spec/support/uploader_helpers.rb +8 -0
  32. data/spec/support/view_helpers.rb +45 -0
  33. data/spec/test/capybara_helpers_spec.rb +160 -0
  34. data/spec/test/helpers_spec.rb +105 -0
  35. data/spec/uploader_spec.rb +461 -0
  36. metadata +168 -0
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_model/validator'
4
+ require 'active_support/concern'
5
+
6
+ module CarrierWaveDirect
7
+
8
+ module Validations
9
+ module ActiveModel
10
+ extend ActiveSupport::Concern
11
+
12
+ class UniqueFilenameValidator < ::ActiveModel::EachValidator
13
+ def validate_each(record, attribute, value)
14
+ if record.new_record? && record.errors[attribute].empty? && (record.send("has_#{attribute}_upload?") || record.send("has_remote_#{attribute}_net_url?"))
15
+ if record.class.where(attribute => record.send(attribute).filename).exists?
16
+ record.errors.add(attribute, :carrierwave_direct_filename_taken)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ class FilenameFormatValidator < ::ActiveModel::EachValidator
23
+ def validate_each(record, attribute, value)
24
+ if record.new_record? && record.send("has_#{attribute}_upload?") && record.key !~ record.send(attribute).key_regexp
25
+ record.errors.add(
26
+ attribute,
27
+ :carrierwave_direct_filename_invalid,
28
+ :extension_white_list => record.send(attribute).extension_white_list
29
+ )
30
+ end
31
+ end
32
+ end
33
+
34
+ class RemoteNetUrlFormatValidator < ::ActiveModel::EachValidator
35
+ def validate_each(record, attribute, value)
36
+ if record.new_record? && record.send("has_remote_#{attribute}_net_url?")
37
+ remote_net_url = record.send("remote_#{attribute}_net_url")
38
+ uploader = record.send(attribute)
39
+ url_scheme_white_list = uploader.url_scheme_white_list
40
+ if (remote_net_url !~ URI.regexp(url_scheme_white_list) || remote_net_url !~ /#{uploader.extension_regexp}\z/)
41
+ record.errors.add(
42
+ :"remote_#{attribute}_net_url",
43
+ :carrierwave_direct_remote_net_url_invalid,
44
+ :extension_white_list => uploader.extension_white_list,
45
+ :url_scheme_white_list => url_scheme_white_list
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ class IsUploadedValidator < ::ActiveModel::EachValidator
53
+ def validate_each(record, attribute, value)
54
+ if record.new_record?
55
+ unless (record.send("has_#{attribute}_upload?") || record.send("has_remote_#{attribute}_net_url?"))
56
+ record.errors.add(
57
+ attribute,
58
+ :carrierwave_direct_upload_missing
59
+ )
60
+ record.errors.add(
61
+ :"remote_#{attribute}_net_url",
62
+ :blank
63
+ )
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ class IsAttachedValidator < ::ActiveModel::EachValidator
70
+ def validate_each(record, attribute, value)
71
+ if value.blank? && !record.skip_is_attached_validations
72
+ record.errors.add(
73
+ attribute,
74
+ :carrierwave_direct_attachment_missing
75
+ )
76
+ end
77
+ end
78
+ end
79
+
80
+ module HelperMethods
81
+
82
+ ##
83
+ # Makes the record invalid if the filename already exists
84
+ #
85
+ # Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
86
+ #
87
+ # === Note
88
+ #
89
+ # Set this key in your translations file for I18n:
90
+ #
91
+ # carrierwave_direct:
92
+ # errors:
93
+ # filename_taken: 'Here be an error message'
94
+ #
95
+ def validates_filename_uniqueness_of(*attr_names)
96
+ validates_with UniqueFilenameValidator, _merge_attributes(attr_names)
97
+ end
98
+
99
+ def validates_filename_format_of(*attr_names)
100
+ validates_with FilenameFormatValidator, _merge_attributes(attr_names)
101
+ end
102
+
103
+ def validates_remote_net_url_format_of(*attr_names)
104
+ validates_with RemoteNetUrlFormatValidator, _merge_attributes(attr_names)
105
+ end
106
+
107
+ def validates_is_uploaded(*attr_names)
108
+ validates_with IsUploadedValidator, _merge_attributes(attr_names)
109
+ end
110
+
111
+ def validates_is_attached(*attr_names)
112
+ validates_with IsAttachedValidator, _merge_attributes(attr_names)
113
+ end
114
+
115
+ end
116
+
117
+ included do
118
+ extend HelperMethods
119
+ include HelperMethods
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ Dir[File.dirname(__FILE__) << "/../locale/*.*"].each {|file| I18n.load_path << file }
126
+
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierwaveDirect
4
+ VERSION = "0.0.1"
5
+ end
6
+
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CarrierWaveDirect::ActionViewExtensions::FormHelper do
6
+ include FormBuilderHelpers
7
+
8
+ describe "#direct_upload_form_for" do
9
+ it "should yield an instance of CarrierWaveDirect::FormBuilder" do
10
+ direct_upload_form_for(direct_uploader) do |f|
11
+ f.should be_instance_of(CarrierWaveDirect::FormBuilder)
12
+ end
13
+ end
14
+
15
+ context "the form" do
16
+ before do
17
+ direct_uploader.stub(:direct_fog_url).and_return("http://example.com")
18
+ end
19
+
20
+ it "should post to the uploader's #direct_fog_url as a multipart form" do
21
+ form.should submit_to(
22
+ :action => "http://example.com", :method => "post", :enctype => "multipart/form-data"
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CarrierWaveDirect::FormBuilder do
6
+ include FormBuilderHelpers
7
+
8
+ describe "#file_field" do
9
+
10
+ def form_with_file_field
11
+ form {|f| f.file_field :video }
12
+ end
13
+
14
+ hidden_fields = [
15
+ :key,
16
+ {:aws_access_key_id => "AWSAccessKeyId"},
17
+ :acl,
18
+ :success_action_redirect,
19
+ :policy,
20
+ :signature
21
+ ]
22
+
23
+ # http://aws.amazon.com/articles/1434?_encoding=UTF8
24
+ context "form" do
25
+
26
+ hidden_fields.each do |input|
27
+ if input.is_a?(Hash)
28
+ key = input.keys.first
29
+ name = input[key]
30
+ else
31
+ key = name = input
32
+ end
33
+
34
+ it "should have a hidden field for '#{name}'" do
35
+ direct_uploader.stub(key).and_return(key.to_s)
36
+ form_with_file_field.should have_input(
37
+ :direct_uploader,
38
+ key,
39
+ :type => :hidden,
40
+ :name => name,
41
+ :value => key,
42
+ :required => false
43
+ )
44
+ end
45
+ end
46
+
47
+ it "should have an input for a file to upload" do
48
+ form_with_file_field.should have_input(
49
+ :direct_uploader,
50
+ :video,
51
+ :type => :file,
52
+ :name => :file,
53
+ :required => false
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe CarrierWaveDirect::Mount do
4
+ include ModelHelpers
5
+
6
+ class Gathering
7
+ extend CarrierWave::Mount
8
+ extend CarrierWaveDirect::Mount
9
+ mount_uploader :video, DirectUploader
10
+ end
11
+
12
+ context "class Gathering; extend CarrierWave::Mount; extend CarrierWaveDirect::Mount; mount_uploader :video, DirectUploader; end" do
13
+ let(:subject) { Gathering.new }
14
+
15
+ it_should_have_accessor(:remote_video_net_url)
16
+
17
+ describe "#has_video_upload?" do
18
+ context "video does not have a key" do
19
+ before { subject.video.stub(:has_key?).and_return(false) }
20
+
21
+ it "should return false" do
22
+ subject.should_not have_video_upload
23
+ end
24
+ end
25
+
26
+ context "video has a key" do
27
+ before { subject.video.stub(:has_key?).and_return(true) }
28
+
29
+ it "should return true" do
30
+ subject.should have_video_upload
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "#has_remote_video_net_url?" do
36
+ context "remote_video_net_url is nil" do
37
+ before { subject.remote_video_net_url = nil }
38
+
39
+ it "should return false" do
40
+ subject.should_not have_remote_video_net_url
41
+ end
42
+ end
43
+
44
+ context "remote_video_net_url is not nil" do
45
+ before { subject.remote_video_net_url = "something" }
46
+
47
+ it "should return true" do
48
+ subject.should have_remote_video_net_url
49
+ end
50
+ end
51
+ end
52
+
53
+ it_should_delegate(:key, :to => "video#key", :accessible => {"has_video_upload?" => false})
54
+
55
+ end
56
+ end
57
+
@@ -0,0 +1,551 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'carrierwave/orm/activerecord'
5
+ require 'carrierwave_direct/orm/activerecord'
6
+
7
+ describe CarrierWaveDirect::ActiveRecord do
8
+ dbconfig = {
9
+ :adapter => 'sqlite3',
10
+ :database => ':memory:'
11
+ }
12
+
13
+ class TestMigration < ActiveRecord::Migration
14
+ def self.up
15
+ create_table :parties, :force => true do |t|
16
+ t.column :video, :string
17
+ end
18
+ end
19
+
20
+ def self.down
21
+ drop_table :parties
22
+ end
23
+ end
24
+
25
+ class Party < ActiveRecord::Base
26
+ mount_uploader :video, DirectUploader
27
+ end
28
+
29
+ ActiveRecord::Base.establish_connection(dbconfig)
30
+
31
+ # turn off migration output
32
+ ActiveRecord::Migration.verbose = false
33
+
34
+ before(:all) { TestMigration.up }
35
+ after(:all) { TestMigration.down }
36
+ after { Party.delete_all }
37
+
38
+ describe "class Party < ActiveRecord::Base; mount_uploader :video, DirectUploader; end" do
39
+ $arclass = 0
40
+ include UploaderHelpers
41
+ include ModelHelpers
42
+
43
+ let(:party_class) do
44
+ Class.new(Party)
45
+ end
46
+
47
+ let(:subject) do
48
+ party = party_class.new
49
+ end
50
+
51
+ def mount_uploader
52
+ party_class.mount_uploader :video, DirectUploader
53
+ end
54
+
55
+ before do
56
+ # see https://github.com/jnicklas/carrierwave/blob/master/spec/orm/activerecord_spec.rb
57
+ $arclass += 1
58
+ Object.const_set("Party#{$arclass}", party_class)
59
+ party_class.table_name = "parties"
60
+ end
61
+
62
+ shared_examples_for "an invalid filename" do
63
+ it "should not be valid on create" do
64
+ subject.should_not be_valid
65
+ end
66
+
67
+ it "should be valid on update" do
68
+ subject.save(:validate => false)
69
+ subject.should be_valid
70
+ end
71
+
72
+ it "should use i18n for the error messages" do
73
+ subject.valid?
74
+ subject.errors[:video].should == [
75
+ I18n.t("errors.messages.carrierwave_direct_filename_invalid", :extension_white_list => %w{avi mp4})
76
+ ]
77
+ end
78
+ end
79
+
80
+ shared_examples_for "a remote net url i18n error message" do
81
+ it "should use i18n for the error messages" do
82
+ subject.valid?
83
+ subject.errors[:remote_video_net_url].should == [I18n.t("errors.messages.carrierwave_direct_remote_net_url_invalid", i18n_options)]
84
+ end
85
+ end
86
+
87
+ shared_examples_for "without an upload" do
88
+ before do
89
+ subject.remote_video_net_url = remote_video_net_url
90
+ subject.key = upload_path
91
+ end
92
+
93
+ it "should not be valid on create" do
94
+ subject.should_not be_valid
95
+ end
96
+
97
+ it "should use i18n for the file upload error message" do
98
+ subject.valid?
99
+ subject.errors[:video].should == [I18n.t("errors.messages.carrierwave_direct_upload_missing")]
100
+ end
101
+
102
+ it "should use i18n for the remote net url error message" do
103
+ subject.valid?
104
+ subject.errors[:remote_video_net_url].should == [I18n.t("errors.messages.blank")]
105
+ end
106
+
107
+ it "should be valid on update" do
108
+ subject.save(:validate => false)
109
+ subject.should be_valid
110
+ end
111
+ end
112
+
113
+ shared_examples_for "a blank or empty attachment" do
114
+ it "should not be valid" do
115
+ subject.should_not be_valid
116
+ end
117
+
118
+ context "on update" do
119
+ it "should not be valid" do
120
+ subject.save(:validate => false)
121
+ subject.should_not be_valid
122
+ end
123
+ end
124
+
125
+ it "should use i18n for the error messages" do
126
+ subject.valid?
127
+ subject.errors[:video].should == [I18n.t("errors.messages.carrierwave_direct_attachment_missing")]
128
+ end
129
+ end
130
+
131
+ describe ".validates_filename_uniqueness_of" do
132
+ it "should be turned on by default" do
133
+ party_class.should_receive(:validates_filename_uniqueness_of).with(:video)
134
+ mount_uploader
135
+ end
136
+
137
+ context "another Party with a duplicate video filename" do
138
+ before do
139
+ subject.video.key = sample_key
140
+ subject.save
141
+ end
142
+
143
+ let(:another_party) do
144
+ another_party = party_class.new
145
+ another_party.video.key = subject.video.key
146
+ another_party
147
+ end
148
+
149
+ it "should not be valid" do
150
+ another_party.should_not be_valid
151
+ end
152
+
153
+ it "should use I18n for the error messages" do
154
+ another_party.valid?
155
+ another_party.errors[:video].should == [I18n.t("errors.messages.carrierwave_direct_filename_taken")]
156
+ end
157
+ end
158
+
159
+ context "is turned off in the configuration" do
160
+ before do
161
+ DirectUploader.validate_unique_filename = false
162
+ end
163
+
164
+ it "should not validate the filename uniqueness" do
165
+ party_class.should_not_receive(:validates_filename_uniqueness_of)
166
+ mount_uploader
167
+ end
168
+ end
169
+ end
170
+
171
+ describe ".validates_filename_format_of" do
172
+ it "should be turned on by default" do
173
+ party_class.should_receive(:validates_filename_format_of).with(:video)
174
+ mount_uploader
175
+ end
176
+
177
+ context "where the file upload is" do
178
+ context "nil" do
179
+ before do
180
+ subject.key = nil
181
+ end
182
+
183
+ it "should be valid" do
184
+ subject.should be_valid
185
+ end
186
+ end
187
+
188
+ context "blank" do
189
+ before do
190
+ subject.key = ""
191
+ end
192
+
193
+ it "should be valid" do
194
+ subject.should be_valid
195
+ end
196
+ end
197
+ end
198
+
199
+ context "where the uploader has an extension white list" do
200
+ before do
201
+ subject.video.stub(:extension_white_list).and_return(%w{avi mp4})
202
+ end
203
+
204
+ context "and the uploaded file's extension is included in the list" do
205
+ before do
206
+ subject.key = sample_key(:extension => "avi")
207
+ end
208
+
209
+ it "should be valid" do
210
+ subject.should be_valid
211
+ end
212
+ end
213
+
214
+ context "but uploaded file's extension is not included in the list" do
215
+ before do
216
+ subject.key = sample_key(:extension => "mp3")
217
+ end
218
+
219
+ it_should_behave_like "an invalid filename"
220
+
221
+ it "should include the white listed extensions in the error message" do
222
+ subject.valid?
223
+ subject.errors[:video].first.should include("avi and mp4")
224
+ end
225
+ end
226
+
227
+ context "and the video's key does not contain a guid" do
228
+ before do
229
+ subject.video.key = sample_key(:valid => false)
230
+ end
231
+
232
+ it_should_behave_like "an invalid filename"
233
+ end
234
+ end
235
+
236
+ context "is turned off in the configuration" do
237
+ before do
238
+ DirectUploader.validate_filename_format = false
239
+ end
240
+
241
+ it "should not validate the filename format" do
242
+ party_class.should_not_receive(:validates_filename_format_of)
243
+ mount_uploader
244
+ end
245
+ end
246
+ end
247
+
248
+ describe ".validates_remote_net_url_format_of" do
249
+ it "should be turned on by default" do
250
+ party_class.should_receive(:validates_remote_net_url_format_of).with(:video)
251
+ mount_uploader
252
+ end
253
+
254
+ context "with an invalid remote image net url" do
255
+
256
+ context "on create" do
257
+ context "where the uploader has an extension white list" do
258
+ before do
259
+ subject.video.stub(:extension_white_list).and_return(%w{avi mp4})
260
+ end
261
+
262
+ context "and the url's extension is included in the list" do
263
+ before do
264
+ subject.remote_video_net_url = "http://example.com/some_video.mp4"
265
+ end
266
+
267
+ it "should be valid" do
268
+ subject.should be_valid
269
+ end
270
+ end
271
+
272
+ context "but the url's extension is not included in the list" do
273
+ before do
274
+ subject.remote_video_net_url = "http://example.com/some_video.mp3"
275
+ end
276
+
277
+ it "should not be valid" do
278
+ subject.should_not be_valid
279
+ end
280
+
281
+ it_should_behave_like "a remote net url i18n error message" do
282
+ let(:i18n_options) { {:extension_white_list => %w{avi mp4} } }
283
+ end
284
+
285
+ it "should include the white listed extensions in the error message" do
286
+ subject.valid?
287
+ subject.errors[:remote_video_net_url].first.should include("avi and mp4")
288
+ end
289
+ end
290
+ end
291
+
292
+ context "where the url is invalid" do
293
+ before do
294
+ subject.remote_video_net_url = "http$://example.com/some_video.mp4"
295
+ end
296
+
297
+ it "should not be valid" do
298
+ subject.should_not be_valid
299
+ end
300
+
301
+ it_should_behave_like "a remote net url i18n error message" do
302
+ let(:i18n_options) { nil }
303
+ end
304
+ end
305
+
306
+ context "where the url is" do
307
+ context "nil" do
308
+ before do
309
+ subject.remote_video_net_url = nil
310
+ end
311
+
312
+ it "should be valid" do
313
+ subject.should be_valid
314
+ end
315
+ end
316
+
317
+ context "blank" do
318
+ before do
319
+ subject.remote_video_net_url = ""
320
+ end
321
+
322
+ it "should be valid" do
323
+ subject.should be_valid
324
+ end
325
+ end
326
+ end
327
+
328
+ context "where the uploader specifies valid url schemes" do
329
+ before do
330
+ subject.video.stub(:url_scheme_white_list).and_return(%w{http https})
331
+ end
332
+
333
+ context "and the url's scheme is included in the list" do
334
+ before do
335
+ subject.remote_video_net_url = "https://example.com/some_video.mp3"
336
+ end
337
+
338
+ it "should be valid" do
339
+ subject.should be_valid
340
+ end
341
+ end
342
+
343
+ context "but the url's scheme is not included in the list" do
344
+ before do
345
+ subject.remote_video_net_url = "ftp://example.com/some_video.mp3"
346
+ end
347
+
348
+ it "should not be valid" do
349
+ subject.should_not be_valid
350
+ end
351
+
352
+ it_should_behave_like "a remote net url i18n error message" do
353
+ let(:i18n_options) { {:url_scheme_white_list => %w{http https} } }
354
+ end
355
+
356
+ it "should include the white listed url schemes in the error message" do
357
+ subject.valid?
358
+ subject.errors[:remote_video_net_url].first.should include("http and https")
359
+ end
360
+ end
361
+ end
362
+ end
363
+
364
+ context "on update" do
365
+ before do
366
+ subject.remote_video_net_url = "http$://example.com/some_video.mp4"
367
+ end
368
+
369
+ it "should be valid" do
370
+ subject.save(:validate => false)
371
+ subject.should be_valid
372
+ end
373
+ end
374
+ end
375
+
376
+ context "is turned off in the configuration" do
377
+ before do
378
+ DirectUploader.validate_remote_net_url_format = false
379
+ end
380
+
381
+ it "should not validate the format of the remote net url" do
382
+ party_class.should_not_receive(:validates_remote_net_url_format_of)
383
+ mount_uploader
384
+ end
385
+ end
386
+ end
387
+
388
+ describe ".validates_is_uploaded" do
389
+ it "should be turned off by default" do
390
+ party_class.should_not_receive(:validates_is_uploaded)
391
+ mount_uploader
392
+ end
393
+
394
+ context "is turned on in the configuration" do
395
+ before do
396
+ DirectUploader.validate_is_uploaded = true
397
+ end
398
+
399
+ it "should validate that a file has been uploaded" do
400
+ party_class.should_receive(:validates_is_uploaded).with(:video)
401
+ mount_uploader
402
+ end
403
+ end
404
+
405
+ context "is on" do
406
+ before do
407
+ party_class.validates_is_uploaded :video
408
+ end
409
+
410
+ context "where there is no upload" do
411
+ it_should_behave_like "without an upload" do
412
+ let(:remote_video_net_url) { nil }
413
+ let(:upload_path) { nil }
414
+ end
415
+ end
416
+
417
+ context "where the remote net url is blank" do
418
+ it_should_behave_like "without an upload" do
419
+ let(:remote_video_net_url) { "" }
420
+ let(:upload_path) { nil }
421
+ end
422
+ end
423
+
424
+ context "with an upload by remote url" do
425
+ before do
426
+ subject.remote_video_net_url = "http://example.com/some_url.anything"
427
+ end
428
+
429
+ it "should be valid" do
430
+ subject.should be_valid
431
+ end
432
+ end
433
+
434
+ context "with an upload by file" do
435
+ before do
436
+ subject.key = sample_key
437
+ end
438
+
439
+ it "should be valid" do
440
+ subject.should be_valid
441
+ end
442
+ end
443
+ end
444
+ end
445
+
446
+ describe ".validates_is_attached" do
447
+ it "should be turned off by default" do
448
+ party_class.should_not_receive(:validates_is_attached)
449
+ mount_uploader
450
+ end
451
+
452
+ context "is turned on in the configuration" do
453
+ before do
454
+ DirectUploader.validate_is_attached = true
455
+ end
456
+
457
+ it "should validate that a file has been attached" do
458
+ party_class.should_receive(:validates_is_attached).with(:video)
459
+ mount_uploader
460
+ end
461
+ end
462
+
463
+ context "is on" do
464
+ before do
465
+ party_class.validates_is_attached :video
466
+ end
467
+
468
+ context "where the attachment" do
469
+ context "is blank" do
470
+ it_should_behave_like "a blank or empty attachment"
471
+ end
472
+
473
+ context "is nil" do
474
+ before do
475
+ subject.video = nil
476
+ end
477
+
478
+ it_should_behave_like "a blank or empty attachment"
479
+ end
480
+ end
481
+ end
482
+ end
483
+
484
+ it_should_have_accessor(:skip_is_attached_validations)
485
+
486
+ describe "#key" do
487
+ it "should be accessible" do
488
+ party_class.new(:key => "some key").key.should == "some key"
489
+ end
490
+ end
491
+
492
+ describe "#remote_\#\{column\}_net_url" do
493
+ it "should be accessible" do
494
+ party_class.new(:remote_video_net_url => "some url").remote_video_net_url.should == "some url"
495
+ end
496
+ end
497
+
498
+ describe "#filename_valid?" do
499
+ shared_examples_for "having empty errors" do
500
+ before do
501
+ subject.filename_valid?
502
+ end
503
+
504
+ context "where after the call, #errors" do
505
+ it "should be empty" do
506
+ subject.errors.should be_empty
507
+ end
508
+ end
509
+ end
510
+
511
+ context "does not have an upload" do
512
+ it "should be true" do
513
+ subject.filename_valid?.should be_true
514
+ end
515
+
516
+ it_should_behave_like "having empty errors"
517
+ end
518
+
519
+ context "has an upload" do
520
+ context "with a valid filename" do
521
+ before do
522
+ subject.key = sample_key(:model_class => subject.class)
523
+ end
524
+
525
+ it "should be true" do
526
+ subject.filename_valid?.should be_true
527
+ end
528
+
529
+ it_should_behave_like "having empty errors"
530
+ end
531
+
532
+ context "with an invalid filename" do
533
+ before { subject.key = sample_key(:model_class => subject.class, :valid => false) }
534
+
535
+ it "should be false" do
536
+ subject.filename_valid?.should be_false
537
+ end
538
+
539
+ context "after the call, #errors" do
540
+ before { subject.filename_valid? }
541
+
542
+ it "should only contain '\#\{column\}' errors" do
543
+ subject.errors.count.should == subject.errors[:video].count
544
+ end
545
+ end
546
+ end
547
+ end
548
+ end
549
+ end
550
+ end
551
+