carrierwave_direct 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+