formeze 3.0.0 → 3.1.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.
@@ -1,8 +0,0 @@
1
- require 'rake/testtask'
2
-
3
- task :default => :spec
4
-
5
- Rake::TestTask.new(:spec) do |t|
6
- t.test_files = FileList['spec/*_spec.rb']
7
- t.warning = true
8
- end
@@ -1,1018 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'formeze'
3
- require 'i18n'
4
- require 'mime-types'
5
-
6
- I18n.available_locales = [:en]
7
-
8
- class FormWithField < Formeze::Form
9
- field :title
10
- end
11
-
12
- describe 'FormWithField' do
13
- before do
14
- @form = FormWithField.new
15
- end
16
-
17
- describe 'title method' do
18
- it 'returns nil' do
19
- @form.title.must_be_nil
20
- end
21
- end
22
-
23
- describe 'title equals method' do
24
- it 'sets the value of the title attribute' do
25
- @form.title = 'Untitled'
26
- @form.title.must_equal('Untitled')
27
- end
28
- end
29
-
30
- describe 'parse method' do
31
- it 'sets the value of the title attribute' do
32
- @form.parse('title=Untitled')
33
- @form.title.must_equal('Untitled')
34
- end
35
-
36
- it 'raises an exception when the key is missing' do
37
- proc { @form.parse('') }.must_raise(Formeze::KeyError)
38
- end
39
-
40
- it 'raises an exception when there are multiple values for the key' do
41
- proc { @form.parse('title=foo&title=bar') }.must_raise(Formeze::ValueError)
42
- end
43
-
44
- it 'raises an exception when the data contains unexpected keys' do
45
- exception = proc { @form.parse('title=Untitled&foo=bar&baz=') }.must_raise(Formeze::KeyError)
46
-
47
- exception.message.must_equal('unexpected form keys: baz, foo')
48
- end
49
-
50
- it 'returns self' do
51
- @form.parse('title=Untitled').must_equal(@form)
52
- end
53
- end
54
-
55
- describe 'fill method' do
56
- it 'sets the value of the title attribute when given a hash with symbol keys' do
57
- @form.fill({:title => 'Untitled'})
58
- @form.title.must_equal('Untitled')
59
- end
60
-
61
- it 'sets the value of the title attribute when given an object with a title attribute' do
62
- object = Object.new
63
-
64
- def object.title; 'Untitled' end
65
-
66
- @form.fill(object)
67
- @form.title.must_equal('Untitled')
68
- end
69
-
70
- it 'returns self' do
71
- @form.fill({:title => 'Untitled'}).must_equal(@form)
72
- end
73
- end
74
- end
75
-
76
- describe 'FormWithField after parsing valid input' do
77
- before do
78
- @form = FormWithField.new
79
- @form.parse('title=Untitled')
80
- end
81
-
82
- describe 'title method' do
83
- it 'returns the value of the field' do
84
- @form.title.must_equal('Untitled')
85
- end
86
- end
87
-
88
- describe 'valid query method' do
89
- it 'returns true' do
90
- @form.valid?.must_equal(true)
91
- end
92
- end
93
-
94
- describe 'errors query method' do
95
- it 'returns false' do
96
- @form.errors?.must_equal(false)
97
- end
98
- end
99
-
100
- describe 'errors method' do
101
- it 'returns an empty array' do
102
- @form.errors.must_equal([])
103
- end
104
- end
105
-
106
- describe 'errors_on query method' do
107
- it 'returns false when given the title field name' do
108
- @form.errors_on?(:title).must_equal(false)
109
- end
110
- end
111
-
112
- describe 'errors_on method' do
113
- it 'returns an empty array when given the title field name' do
114
- @form.errors_on(:title).must_equal([])
115
- end
116
- end
117
-
118
- describe 'to_h method' do
119
- it 'returns a hash containing the field name and its value' do
120
- @form.to_h.must_equal({:title => 'Untitled'})
121
- end
122
- end
123
-
124
- describe 'to_hash method' do
125
- it 'returns a hash containing the field name and its value' do
126
- @form.to_hash.must_equal({:title => 'Untitled'})
127
- end
128
- end
129
- end
130
-
131
- describe 'FormWithField after parsing blank input' do
132
- before do
133
- @form = FormWithField.new
134
- @form.parse('title=')
135
- end
136
-
137
- describe 'valid query method' do
138
- it 'returns false' do
139
- @form.valid?.must_equal(false)
140
- end
141
- end
142
-
143
- describe 'errors query method' do
144
- it 'returns true' do
145
- @form.errors?.must_equal(true)
146
- end
147
- end
148
-
149
- describe 'errors method' do
150
- it 'returns an array containing a single error message' do
151
- @form.errors.must_be_instance_of(Array)
152
- @form.errors.length.must_equal(1)
153
- @form.errors.first.to_s.must_equal('Title is required')
154
- end
155
- end
156
-
157
- describe 'errors_on query method' do
158
- it 'returns true when given the title field name' do
159
- @form.errors_on?(:title).must_equal(true)
160
- end
161
- end
162
-
163
- describe 'errors_on method' do
164
- it 'returns an array containing a single error message when given the title field name' do
165
- errors = @form.errors_on(:title)
166
- errors.must_be_instance_of(Array)
167
- errors.length.must_equal(1)
168
- errors.first.to_s.must_equal('Title is required')
169
- end
170
- end
171
- end
172
-
173
- describe 'FormWithField after parsing input containing newlines' do
174
- before do
175
- @form = FormWithField.new
176
- @form.parse('title=This+is+a+product.%0AIt+is+very+lovely.')
177
- end
178
-
179
- describe 'valid query method' do
180
- it 'returns false' do
181
- @form.valid?.must_equal(false)
182
- end
183
- end
184
- end
185
-
186
- class FormWithOptionalField < Formeze::Form
187
- field :title, :required => false
188
- end
189
-
190
- describe 'FormWithOptionalField after parsing blank input' do
191
- before do
192
- @form = FormWithOptionalField.new
193
- @form.parse('title=')
194
- end
195
-
196
- describe 'valid query method' do
197
- it 'returns true' do
198
- @form.valid?.must_equal(true)
199
- end
200
- end
201
- end
202
-
203
- class FormWithOptionalFieldUsingBlankOption < Formeze::Form
204
- field :title, :required => false, :blank => 42
205
- end
206
-
207
- describe 'FormWithOptionalFieldUsingBlankOption after parsing blank input' do
208
- before do
209
- @form = FormWithOptionalFieldUsingBlankOption.new
210
- @form.parse('title=')
211
- end
212
-
213
- describe 'title method' do
214
- it 'returns the value specified by the blank option' do
215
- @form.title.must_equal(42)
216
- end
217
- end
218
- end
219
-
220
- class FormWithFieldThatCanHaveMultipleLines < Formeze::Form
221
- field :description, :multiline => true
222
- end
223
-
224
- describe 'FormWithFieldThatCanHaveMultipleLines after parsing input containing newlines' do
225
- before do
226
- @form = FormWithFieldThatCanHaveMultipleLines.new
227
- @form.parse('description=This+is+a+product.%0AIt+is+very+lovely.')
228
- end
229
-
230
- describe 'valid query method' do
231
- it 'returns true' do
232
- @form.valid?.must_equal(true)
233
- end
234
- end
235
- end
236
-
237
- class FormWithMaxLengthField < Formeze::Form
238
- field :title, :maxlength => 16
239
- end
240
-
241
- describe 'FormWithMaxLengthField after parsing input with too many characters' do
242
- before do
243
- @form = FormWithMaxLengthField.new
244
- @form.parse('title=This+Title+Will+Be+Too+Long')
245
- end
246
-
247
- describe 'valid query method' do
248
- it 'returns false' do
249
- @form.valid?.must_equal(false)
250
- end
251
- end
252
- end
253
-
254
- class FormWithMinLengthField < Formeze::Form
255
- field :title, :minlength => 8
256
- end
257
-
258
- describe 'FormWithMinLengthField after parsing input with too few characters' do
259
- before do
260
- @form = FormWithMinLengthField.new
261
- @form.parse('title=Hello')
262
- end
263
-
264
- describe 'valid query method' do
265
- it 'returns false' do
266
- @form.valid?.must_equal(false)
267
- end
268
- end
269
- end
270
-
271
- class FormWithFieldThatMustMatchPattern < Formeze::Form
272
- field :number, :pattern => /\A\d+\z/
273
- end
274
-
275
- describe 'FormWithFieldThatMustMatchPattern after parsing input that matches the pattern' do
276
- before do
277
- @form = FormWithFieldThatMustMatchPattern.new
278
- @form.parse('number=12345')
279
- end
280
-
281
- describe 'valid query method' do
282
- it 'returns true' do
283
- @form.valid?.must_equal(true)
284
- end
285
- end
286
- end
287
-
288
- describe 'FormWithFieldThatMustMatchPattern after parsing input that does not match the pattern' do
289
- before do
290
- @form = FormWithFieldThatMustMatchPattern.new
291
- @form.parse('number=notanumber')
292
- end
293
-
294
- describe 'valid query method' do
295
- it 'returns false' do
296
- @form.valid?.must_equal(false)
297
- end
298
- end
299
- end
300
-
301
- class FormWithFieldThatCanHaveMultipleValues < Formeze::Form
302
- field :colour, :multiple => true
303
- end
304
-
305
- describe 'FormWithFieldThatCanHaveMultipleValues' do
306
- before do
307
- @form = FormWithFieldThatCanHaveMultipleValues.new
308
- end
309
-
310
- describe 'colour method' do
311
- it 'returns nil' do
312
- @form.colour.must_be_nil
313
- end
314
- end
315
-
316
- describe 'colour equals method' do
317
- it 'adds the argument to the colour attribute array' do
318
- @form.colour = 'black'
319
- @form.colour.must_include('black')
320
- end
321
- end
322
-
323
- describe 'parse method' do
324
- it 'adds the value to the colour attribute array' do
325
- @form.parse('colour=black')
326
- @form.colour.must_include('black')
327
- end
328
-
329
- it 'does not raise an exception when there are multiple values for the key' do
330
- @form.parse('colour=black&colour=white')
331
- end
332
-
333
- it 'does not raise an exception when the key is missing' do
334
- @form.parse('')
335
- end
336
- end
337
- end
338
-
339
- describe 'FormWithFieldThatCanHaveMultipleValues after parsing input with multiple values' do
340
- before do
341
- @form = FormWithFieldThatCanHaveMultipleValues.new
342
- @form.parse('colour=black&colour=white')
343
- end
344
-
345
- describe 'colour method' do
346
- it 'returns an array containing the values' do
347
- @form.colour.must_equal(['black', 'white'])
348
- end
349
- end
350
-
351
- describe 'valid query method' do
352
- it 'returns true' do
353
- @form.valid?.must_equal(true)
354
- end
355
- end
356
-
357
- describe 'to_hash method' do
358
- it 'returns a hash containing the field name and its array value' do
359
- @form.to_hash.must_equal({:colour => %w(black white)})
360
- end
361
- end
362
- end
363
-
364
- describe 'FormWithFieldThatCanHaveMultipleValues after parsing input with no values' do
365
- before do
366
- @form = FormWithFieldThatCanHaveMultipleValues.new
367
- @form.parse('')
368
- end
369
-
370
- describe 'colour method' do
371
- it 'returns nil' do
372
- @form.colour.must_be_nil
373
- end
374
- end
375
-
376
- describe 'valid query method' do
377
- it 'returns true' do
378
- @form.valid?.must_equal(true)
379
- end
380
- end
381
- end
382
-
383
- class FormWithFieldThatCanOnlyHaveSpecifiedValues < Formeze::Form
384
- field :answer, :values => %w(yes no)
385
- end
386
-
387
- describe 'FormWithFieldThatCanOnlyHaveSpecifiedValues after parsing input with an invalid value' do
388
- before do
389
- @form = FormWithFieldThatCanOnlyHaveSpecifiedValues.new
390
- @form.parse('answer=maybe')
391
- end
392
-
393
- describe 'valid query method' do
394
- it 'returns false' do
395
- @form.valid?.must_equal(false)
396
- end
397
- end
398
- end
399
-
400
- class FormWithGuardCondition < Formeze::Form
401
- field :account_name
402
- field :account_vat_number, :defined_if => proc { @business_account }
403
-
404
- def initialize(business_account)
405
- @business_account = business_account
406
- end
407
- end
408
-
409
- describe 'FormWithGuardCondition with business_account set to false' do
410
- before do
411
- @form = FormWithGuardCondition.new(false)
412
- end
413
-
414
- describe 'parse method' do
415
- it 'raises an exception when the account_vat_number key is present' do
416
- proc { @form.parse('account_name=Something&account_vat_number=123456789') }.must_raise(Formeze::KeyError)
417
- end
418
- end
419
- end
420
-
421
- describe 'FormWithGuardCondition with business_account set to true' do
422
- before do
423
- @form = FormWithGuardCondition.new(true)
424
- end
425
-
426
- describe 'parse method' do
427
- it 'raises an exception when the account_vat_number key is missing' do
428
- proc { @form.parse('account_name=Something') }.must_raise(Formeze::KeyError)
429
- end
430
- end
431
- end
432
-
433
- describe 'FormWithGuardCondition with business_account set to false after parsing valid input' do
434
- before do
435
- @form = FormWithGuardCondition.new(false)
436
- @form.parse('account_name=Something')
437
- end
438
-
439
- describe 'valid query method' do
440
- it 'returns true' do
441
- @form.valid?.must_equal(true)
442
- end
443
- end
444
- end
445
-
446
- class FormWithHaltingCondition < Formeze::Form
447
- field :delivery_address
448
- field :same_address, :values => %w(yes no)
449
- field :billing_address, :defined_unless => :same_address?
450
-
451
- def same_address?
452
- same_address == 'yes'
453
- end
454
- end
455
-
456
- describe 'FormWithHaltingCondition' do
457
- before do
458
- @form = FormWithHaltingCondition.new
459
- end
460
-
461
- describe 'parse method' do
462
- it 'raises an exception when there is an unexpected key' do
463
- proc { @form.parse('delivery_address=123+Main+St&same_address=yes&foo=bar') }.must_raise(Formeze::KeyError)
464
- end
465
- end
466
- end
467
-
468
- describe 'FormWithHaltingCondition after parsing input with same_address set and no billing address' do
469
- before do
470
- @form = FormWithHaltingCondition.new
471
- @form.parse('delivery_address=123+Main+St&same_address=yes')
472
- end
473
-
474
- describe 'valid query method' do
475
- it 'returns true' do
476
- @form.valid?.must_equal(true)
477
- end
478
- end
479
- end
480
-
481
- class FormWithOptionalKey < Formeze::Form
482
- field :accept_terms, :values => %w(true), :key_required => false
483
- end
484
-
485
- describe 'FormWithOptionalKey after parsing input without the key' do
486
- before do
487
- @form = FormWithOptionalKey.new
488
- @form.parse('')
489
- end
490
-
491
- describe 'valid query method' do
492
- it 'returns true' do
493
- @form.valid?.must_equal(true)
494
- end
495
- end
496
- end
497
-
498
- class FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues < Formeze::Form
499
- field :size, :required => false, :values => %w(S M L XL)
500
- end
501
-
502
- describe 'FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues after parsing blank input' do
503
- before do
504
- @form = FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues.new
505
- @form.parse('size=')
506
- end
507
-
508
- describe 'valid query method' do
509
- it 'returns true' do
510
- @form.valid?.must_equal(true)
511
- end
512
- end
513
- end
514
-
515
- module EmailAddress
516
- def self.valid?(address)
517
- address.include?('@')
518
- end
519
- end
520
-
521
- class FormWithCustomEmailValidation < Formeze::Form
522
- field :email
523
-
524
- validates :email, &EmailAddress.method(:valid?)
525
- end
526
-
527
- describe 'FormWithCustomEmailValidation after parsing invalid input' do
528
- before do
529
- @form = FormWithCustomEmailValidation.new
530
- @form.parse('email=alice')
531
- end
532
-
533
- describe 'valid query method' do
534
- it 'returns false' do
535
- @form.valid?.must_equal(false)
536
- end
537
- end
538
-
539
- describe 'errors method' do
540
- it 'includes a generic error message for the named field' do
541
- @form.errors.map(&:to_s).must_include('Email is invalid')
542
- end
543
- end
544
-
545
- describe 'errors_on query method' do
546
- it 'returns true when given the field name' do
547
- @form.errors_on?(:email).must_equal(true)
548
- end
549
- end
550
- end
551
-
552
- describe 'FormWithCustomEmailValidation after parsing blank input' do
553
- before do
554
- @form = FormWithCustomEmailValidation.new
555
- @form.parse('email=')
556
- end
557
-
558
- describe 'errors method' do
559
- it 'will not include the custom validation error message' do
560
- @form.errors.map(&:to_s).wont_include('Email is invalid')
561
- end
562
- end
563
- end
564
-
565
- class FormWithCustomPasswordConfirmationCheck < Formeze::Form
566
- field :password
567
- field :password_confirmation
568
-
569
- validates :password_confirmation, :error => :does_not_match do
570
- password_confirmation == password
571
- end
572
- end
573
-
574
- describe 'FormWithCustomPasswordConfirmationCheck after parsing invalid input' do
575
- before do
576
- @form = FormWithCustomPasswordConfirmationCheck.new
577
- @form.parse('password=foo&password_confirmation=bar')
578
- end
579
-
580
- describe 'valid query method' do
581
- it 'returns false' do
582
- @form.valid?.must_equal(false)
583
- end
584
- end
585
-
586
- describe 'errors method' do
587
- it 'includes a generic error message for the named field' do
588
- @form.errors.map(&:to_s).must_include('Password confirmation is invalid')
589
- end
590
- end
591
-
592
- describe 'errors_on query method' do
593
- it 'returns true when given the field name' do
594
- @form.errors_on?(:password_confirmation).must_equal(true)
595
- end
596
- end
597
- end
598
-
599
- class FormWithCustomMinimumSpendValidation < Formeze::Form
600
- field :minimum_spend
601
-
602
- field :fixed_discount, :required => false, :blank => nil
603
-
604
- validates :minimum_spend, :when => :fixed_discount? do
605
- minimum_spend.to_f > 0
606
- end
607
-
608
- def fixed_discount?
609
- !fixed_discount.nil?
610
- end
611
- end
612
-
613
- describe 'FormWithCustomMinimumSpendValidation after parsing valid input' do
614
- before do
615
- @form = FormWithCustomMinimumSpendValidation.new
616
- @form.parse('minimum_spend=0.00&fixed_discount=')
617
- end
618
-
619
- describe 'valid query method' do
620
- it 'returns true' do
621
- @form.valid?.must_equal(true)
622
- end
623
- end
624
-
625
- describe 'errors method' do
626
- it 'returns an empty array' do
627
- @form.errors.must_be_empty
628
- end
629
- end
630
-
631
- describe 'errors_on query method' do
632
- it 'returns false when given the field name' do
633
- @form.errors_on?(:minimum_spend).must_equal(false)
634
- end
635
- end
636
- end
637
-
638
- describe 'FormWithCustomMinimumSpendValidation after parsing invalid input' do
639
- before do
640
- @form = FormWithCustomMinimumSpendValidation.new
641
- @form.parse('minimum_spend=0.00&fixed_discount=10%')
642
- end
643
-
644
- describe 'valid query method' do
645
- it 'returns false' do
646
- @form.valid?.must_equal(false)
647
- end
648
- end
649
-
650
- describe 'errors method' do
651
- it 'includes a generic error message for the named field' do
652
- @form.errors.map(&:to_s).must_include('Minimum spend is invalid')
653
- end
654
- end
655
-
656
- describe 'errors_on query method' do
657
- it 'returns true when given the field name' do
658
- @form.errors_on?(:minimum_spend).must_equal(true)
659
- end
660
- end
661
- end
662
-
663
- class FormWithOptionalFieldAndCustomValidation < Formeze::Form
664
- field :website, :required => false
665
-
666
- validates :website do
667
- website =~ /\./ && website !~ /\s/
668
- end
669
- end
670
-
671
- describe 'FormWithOptionalFieldAndCustomValidation after parsing blank input' do
672
- before do
673
- @form = FormWithOptionalFieldAndCustomValidation.new
674
- @form.parse('website=')
675
- end
676
-
677
- describe 'valid query method' do
678
- it 'returns true' do
679
- @form.valid?.must_equal(true)
680
- end
681
- end
682
-
683
- describe 'errors method' do
684
- it 'returns an empty array' do
685
- @form.errors.must_be_empty
686
- end
687
- end
688
-
689
- describe 'errors_on query method' do
690
- it 'returns false when given the field name' do
691
- @form.errors_on?(:website).must_equal(false)
692
- end
693
- end
694
- end
695
-
696
- class FormWithFileField < Formeze::Form
697
- field :file, :maxsize => 42, :accept => 'text/plain'
698
- end
699
-
700
- describe 'FormWithFileField after parsing multipart input' do
701
- before do
702
- @form = FormWithFileField.new
703
-
704
- body = <<-EOS.gsub(/\n/, "\r\n")
705
- --AaB03x
706
- Content-Disposition: form-data; name="file"; filename="example.txt"
707
- Content-Type: text/plain
708
-
709
- contents
710
- --AaB03x--
711
- EOS
712
-
713
- request = Struct.new(:body, :env).new(StringIO.new(body), {
714
- 'REQUEST_METHOD' => 'POST',
715
- 'CONTENT_TYPE' => 'multipart/form-data; boundary=AaB03x',
716
- 'CONTENT_LENGTH' => body.bytesize
717
- })
718
-
719
- @form.parse(request)
720
- end
721
-
722
- describe 'file method' do
723
- it 'returns the value of the field' do
724
- @form.file.must_be_instance_of(StringIO)
725
- @form.file.original_filename.must_equal('example.txt')
726
- end
727
- end
728
-
729
- describe 'valid query method' do
730
- it 'returns true' do
731
- @form.valid?.must_equal(true)
732
- end
733
- end
734
-
735
- describe 'errors query method' do
736
- it 'returns false' do
737
- @form.errors?.must_equal(false)
738
- end
739
- end
740
-
741
- describe 'errors method' do
742
- it 'returns an empty array' do
743
- @form.errors.must_equal([])
744
- end
745
- end
746
-
747
- describe 'errors_on query method' do
748
- it 'returns false when given the file field name' do
749
- @form.errors_on?(:file).must_equal(false)
750
- end
751
- end
752
-
753
- describe 'errors_on method' do
754
- it 'returns an empty array when given the file field name' do
755
- @form.errors_on(:file).must_equal([])
756
- end
757
- end
758
- end
759
-
760
- describe 'FormWithFileField after parsing blank multipart input' do
761
- before do
762
- @form = FormWithFileField.new
763
-
764
- body = <<-EOS.gsub(/\n/, "\r\n")
765
- --AaB03x
766
- Content-Disposition: form-data; name="file"; filename=""
767
- Content-Type: application/octet-stream
768
-
769
-
770
- --AaB03x--
771
- EOS
772
-
773
- request = Struct.new(:body, :env).new(StringIO.new(body), {
774
- 'REQUEST_METHOD' => 'POST',
775
- 'CONTENT_TYPE' => 'multipart/form-data; boundary=AaB03x',
776
- 'CONTENT_LENGTH' => body.bytesize
777
- })
778
-
779
- @form.parse(request)
780
- end
781
-
782
- describe 'errors query method' do
783
- it 'returns true' do
784
- @form.errors?.must_equal(true)
785
- end
786
- end
787
-
788
- describe 'errors method' do
789
- it 'returns an array containing a single error message' do
790
- @form.errors.must_be_instance_of(Array)
791
- @form.errors.length.must_equal(1)
792
- @form.errors.first.to_s.must_equal('File is required')
793
- end
794
- end
795
-
796
- describe 'errors_on query method' do
797
- it 'returns true when given the file field name' do
798
- @form.errors_on?(:file).must_equal(true)
799
- end
800
- end
801
-
802
- describe 'errors_on method' do
803
- it 'returns an array containing a single error message when given the file field name' do
804
- errors = @form.errors_on(:file)
805
- errors.must_be_instance_of(Array)
806
- errors.length.must_equal(1)
807
- errors.first.to_s.must_equal('File is required')
808
- end
809
- end
810
- end
811
-
812
- describe 'FormWithFileField after parsing multipart input with too much data' do
813
- before do
814
- @form = FormWithFileField.new
815
-
816
- body = <<-EOS.gsub(/\n/, "\r\n")
817
- --AaB03x
818
- Content-Disposition: form-data; name="file"; filename="example.txt"
819
- Content-Type: text/plain
820
-
821
- The quick brown fox jumps over the lazy dog.
822
- --AaB03x--
823
- EOS
824
-
825
- request = Struct.new(:body, :env).new(StringIO.new(body), {
826
- 'REQUEST_METHOD' => 'POST',
827
- 'CONTENT_TYPE' => 'multipart/form-data; boundary=AaB03x',
828
- 'CONTENT_LENGTH' => body.bytesize
829
- })
830
-
831
- @form.parse(request)
832
- end
833
-
834
- describe 'errors query method' do
835
- it 'returns true' do
836
- @form.errors?.must_equal(true)
837
- end
838
- end
839
-
840
- describe 'errors method' do
841
- it 'returns an array containing a single error message' do
842
- @form.errors.must_be_instance_of(Array)
843
- @form.errors.length.must_equal(1)
844
- @form.errors.first.to_s.must_equal('File is too large')
845
- end
846
- end
847
-
848
- describe 'errors_on query method' do
849
- it 'returns true when given the file field name' do
850
- @form.errors_on?(:file).must_equal(true)
851
- end
852
- end
853
-
854
- describe 'errors_on method' do
855
- it 'returns an array containing a single error message when given the file field name' do
856
- errors = @form.errors_on(:file)
857
- errors.must_be_instance_of(Array)
858
- errors.length.must_equal(1)
859
- errors.first.to_s.must_equal('File is too large')
860
- end
861
- end
862
- end
863
-
864
- describe 'FormWithFileField after parsing multipart input with an unacceptable content type' do
865
- before do
866
- @form = FormWithFileField.new
867
-
868
- body = <<-EOS.gsub(/\n/, "\r\n")
869
- --AaB03x
870
- Content-Disposition: form-data; name="file"; filename="example.html"
871
- Content-Type: text/html
872
-
873
- <!DOCTYPE html>
874
- --AaB03x--
875
- EOS
876
-
877
- request = Struct.new(:body, :env).new(StringIO.new(body), {
878
- 'REQUEST_METHOD' => 'POST',
879
- 'CONTENT_TYPE' => 'multipart/form-data; boundary=AaB03x',
880
- 'CONTENT_LENGTH' => body.bytesize
881
- })
882
-
883
- @form.parse(request)
884
- end
885
-
886
- describe 'errors query method' do
887
- it 'returns true' do
888
- @form.errors?.must_equal(true)
889
- end
890
- end
891
-
892
- describe 'errors method' do
893
- it 'returns an array containing a single error message' do
894
- @form.errors.must_be_instance_of(Array)
895
- @form.errors.length.must_equal(1)
896
- @form.errors.first.to_s.must_equal('File is not an accepted file type')
897
- end
898
- end
899
-
900
- describe 'errors_on query method' do
901
- it 'returns true when given the file field name' do
902
- @form.errors_on?(:file).must_equal(true)
903
- end
904
- end
905
-
906
- describe 'errors_on method' do
907
- it 'returns an array containing a single error message when given the file field name' do
908
- errors = @form.errors_on(:file)
909
- errors.must_be_instance_of(Array)
910
- errors.length.must_equal(1)
911
- errors.first.to_s.must_equal('File is not an accepted file type')
912
- end
913
- end
914
- end
915
-
916
- describe 'FormWithField on Rails' do
917
- before do
918
- @form = FormWithField.new
919
-
920
- Object.const_set(:Rails, Object.new)
921
- end
922
-
923
- after do
924
- Object.send(:remove_const, :Rails)
925
- end
926
-
927
- describe 'parse method' do
928
- it 'silently ignores the utf8 and authenticity_token parameters' do
929
- @form.parse('utf8=%E2%9C%93&authenticity_token=5RMc3sPZdR%2BZz4onNS8NfK&title=Test')
930
- @form.wont_respond_to(:utf8)
931
- @form.wont_respond_to(:authenticity_token)
932
- @form.to_hash.must_equal({:title => 'Test'})
933
- end
934
- end
935
- end
936
-
937
- describe 'I18n integration' do
938
- before do
939
- I18n.backend = I18n::Backend::Simple.new
940
- end
941
-
942
- after do
943
- I18n.backend = I18n::Backend::Simple.new
944
- end
945
-
946
- it 'provides i18n support for overriding the default error messages' do
947
- I18n.backend.store_translations :en, {:formeze => {:errors => {:required => 'cannot be blank'}}}
948
-
949
- form = FormWithField.new
950
- form.parse('title=')
951
- form.errors.first.to_s.must_equal('Title cannot be blank')
952
- end
953
-
954
- it 'provides i18n support for overriding the default custom validation error message' do
955
- I18n.backend.store_translations :en, {:formeze => {:errors => {:invalid => 'is not valid'}}}
956
-
957
- form = FormWithCustomEmailValidation.new
958
- form.parse('email=alice')
959
- form.errors.first.to_s.must_equal('Email is not valid')
960
- end
961
-
962
- it 'provides i18n support for specifying custom validation error messages' do
963
- I18n.backend.store_translations :en, {:formeze => {:errors => {:does_not_match => 'does not match'}}}
964
-
965
- form = FormWithCustomPasswordConfirmationCheck.new
966
- form.parse('password=foo&password_confirmation=bar')
967
- form.errors.first.to_s.must_equal('Password confirmation does not match')
968
- end
969
-
970
- it 'provides i18n support for specifying field labels globally' do
971
- I18n.backend.store_translations :en, {:formeze => {:labels => {:title => 'TITLE'}}}
972
-
973
- form = FormWithField.new
974
- form.parse('title=')
975
- form.errors.first.to_s.must_equal('TITLE is required')
976
- end
977
- end
978
-
979
- class FormWithScrubbedFields < Formeze::Form
980
- field :postcode, :scrub => [:strip, :squeeze, :upcase], :pattern => /\A[A-Z0-9]{2,4} [A-Z0-9]{3}\z/
981
- field :bio, :scrub => [:strip, :squeeze_lines], :multiline => true
982
- end
983
-
984
- describe 'FormWithScrubbedFields' do
985
- describe 'parse method' do
986
- it 'applies the scrub methods to the input before validation' do
987
- form = FormWithScrubbedFields.new
988
- form.parse('postcode=++sw1a+++1aa&bio=My+name+is+Cookie+Monster.%0A%0A%0A%0AI+LOVE+COOKIES!!!!%0A%0A%0A%0A')
989
- form.postcode.must_equal('SW1A 1AA')
990
- form.bio.count("\n").must_equal(2)
991
- form.valid?.must_equal(true)
992
- end
993
- end
994
- end
995
-
996
- describe 'Formeze' do
997
- describe 'scrub module method' do
998
- it 'applies the scrub methods to the given input' do
999
- Formeze.scrub("word\n\n", [:strip, :upcase]).must_equal('WORD')
1000
- end
1001
- end
1002
- end
1003
-
1004
- class FormClassWithExplicitSetupCall
1005
- Formeze.setup(self)
1006
- end
1007
-
1008
- describe 'FormClassWithExplicitSetupCall' do
1009
- before do
1010
- @form_class = FormClassWithExplicitSetupCall
1011
- end
1012
-
1013
- it 'includes the formeze class methods and instance methods' do
1014
- @form_class.singleton_class.must_include(Formeze::ClassMethods)
1015
-
1016
- @form_class.must_include(Formeze::InstanceMethods)
1017
- end
1018
- end