formbuilder-rb 0.0.4 → 0.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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +14 -0
  7. data/Gemfile.lock +219 -0
  8. data/Guardfile +17 -0
  9. data/{MIT-LICENSE → LICENSE.md} +1 -1
  10. data/README.md +86 -0
  11. data/app/controllers/formbuilder/concerns/forms_controller.rb +59 -0
  12. data/app/models/formbuilder/entry_attachment.rb +2 -8
  13. data/app/models/formbuilder/form.rb +53 -0
  14. data/app/models/formbuilder/response_field.rb +23 -10
  15. data/app/models/formbuilder/response_field_address.rb +12 -1
  16. data/app/models/formbuilder/response_field_checkboxes.rb +38 -0
  17. data/app/models/formbuilder/response_field_date.rb +7 -1
  18. data/app/models/formbuilder/response_field_dropdown.rb +2 -1
  19. data/app/models/formbuilder/response_field_email.rb +14 -2
  20. data/app/models/formbuilder/response_field_file.rb +75 -20
  21. data/app/models/formbuilder/response_field_number.rb +9 -2
  22. data/app/models/formbuilder/response_field_page_break.rb +13 -0
  23. data/app/models/formbuilder/response_field_paragraph.rb +19 -3
  24. data/app/models/formbuilder/response_field_price.rb +10 -6
  25. data/app/models/formbuilder/response_field_radio.rb +11 -2
  26. data/app/models/formbuilder/response_field_section_break.rb +12 -2
  27. data/app/models/formbuilder/response_field_table.rb +222 -0
  28. data/app/models/formbuilder/response_field_text.rb +9 -2
  29. data/app/models/formbuilder/response_field_time.rb +8 -1
  30. data/app/models/formbuilder/response_field_website.rb +26 -2
  31. data/app/uploaders/formbuilder/entry_attachment_uploader.rb +11 -1
  32. data/bin/rails +8 -0
  33. data/circle.yml +9 -0
  34. data/config/spring.rb +1 -0
  35. data/db/migrate/20130924185815_create_formbuilder_entry_attachments.rb +1 -0
  36. data/formbuilder-rb.gemspec +41 -0
  37. data/formbuilder-rb.sublime-project +20 -0
  38. data/lib/formbuilder.rb +8 -3
  39. data/lib/formbuilder/entry.rb +102 -159
  40. data/lib/formbuilder/entry_validator.rb +13 -6
  41. data/lib/formbuilder/version.rb +1 -1
  42. data/lib/formbuilder/views/entry_dl.rb +56 -0
  43. data/lib/formbuilder/views/form.rb +81 -0
  44. data/lib/formbuilder/views/form_field.rb +45 -0
  45. data/spec/controllers/formbuilder/forms_controller_spec.rb +40 -0
  46. data/spec/dummy/.ruby-gemset +1 -0
  47. data/spec/dummy/.ruby-version +1 -0
  48. data/spec/dummy/README.rdoc +28 -0
  49. data/spec/dummy/Rakefile +6 -0
  50. data/spec/dummy/app/assets/images/.keep +0 -0
  51. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  52. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  53. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  54. data/spec/dummy/app/controllers/forms_controller.rb +3 -0
  55. data/spec/dummy/app/controllers/test_controller.rb +57 -0
  56. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  57. data/spec/dummy/app/mailers/.keep +0 -0
  58. data/spec/dummy/app/models/concerns/.keep +0 -0
  59. data/spec/dummy/app/models/entry.rb +7 -0
  60. data/spec/dummy/app/models/entry_with_alternate_column_name.rb +11 -0
  61. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  62. data/spec/dummy/app/views/test/_form.rb +2 -0
  63. data/spec/dummy/app/views/test/render_entry.html.erb +1 -0
  64. data/spec/dummy/app/views/test/show_form.html.erb +1 -0
  65. data/spec/dummy/bin/bundle +3 -0
  66. data/spec/dummy/bin/rails +4 -0
  67. data/spec/dummy/bin/rake +4 -0
  68. data/spec/dummy/config.ru +4 -0
  69. data/spec/dummy/config/application.rb +25 -0
  70. data/spec/dummy/config/boot.rb +5 -0
  71. data/spec/dummy/config/database.yml.ci +15 -0
  72. data/spec/dummy/config/database.yml.example +15 -0
  73. data/spec/dummy/config/environment.rb +5 -0
  74. data/spec/dummy/config/environments/development.rb +29 -0
  75. data/spec/dummy/config/environments/production.rb +80 -0
  76. data/spec/dummy/config/environments/test.rb +52 -0
  77. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  78. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  79. data/spec/dummy/config/initializers/inflections.rb +16 -0
  80. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  81. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  82. data/spec/dummy/config/initializers/session_store.rb +3 -0
  83. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  84. data/spec/dummy/config/locales/en.yml +23 -0
  85. data/spec/dummy/config/routes.rb +12 -0
  86. data/spec/dummy/db/migrate/20130924182939_create_entries.rb +13 -0
  87. data/spec/dummy/db/migrate/20130924192151_create_formbuilder_forms.formbuilder.rb +11 -0
  88. data/spec/dummy/db/migrate/20130924192152_create_formbuilder_response_fields.formbuilder.rb +17 -0
  89. data/spec/dummy/db/migrate/20130926205845_create_formbuilder_entry_attachments.formbuilder.rb +12 -0
  90. data/spec/dummy/db/migrate/20140128000000_create_entry_with_alternate_column_names.rb +13 -0
  91. data/spec/dummy/db/schema.rb +64 -0
  92. data/spec/dummy/lib/assets/.keep +0 -0
  93. data/spec/dummy/log/.keep +0 -0
  94. data/spec/dummy/public/404.html +58 -0
  95. data/spec/dummy/public/422.html +58 -0
  96. data/spec/dummy/public/500.html +57 -0
  97. data/spec/dummy/public/favicon.ico +0 -0
  98. data/spec/dummy/test/fixtures/entries.yml +9 -0
  99. data/spec/dummy/test/fixtures/response_fields.yml +19 -0
  100. data/spec/dummy/test/models/entry_test.rb +7 -0
  101. data/spec/dummy/test/models/response_field_test.rb +7 -0
  102. data/spec/factories/formbuilder_forms.rb +45 -0
  103. data/spec/features/form_renderer_spec.rb +30 -0
  104. data/spec/features/submitting_an_entry_spec.rb +79 -0
  105. data/spec/fixtures/test_files/text.txt +1 -0
  106. data/spec/fixtures/test_files/text2.txt +1 -0
  107. data/spec/lib/formbuilder/entry_spec.rb +199 -0
  108. data/spec/lib/formbuilder/entry_validator_spec.rb +215 -0
  109. data/spec/lib/formbuilder/entry_with_alternate_column_name_spec.rb +37 -0
  110. data/spec/lib/formbuilder/views/entry_dl_spec.rb +38 -0
  111. data/spec/models/formbuilder/entry_attachment_spec.rb +17 -0
  112. data/spec/models/formbuilder/form_spec.rb +100 -0
  113. data/spec/models/formbuilder/response_field_address_spec.rb +25 -0
  114. data/spec/models/formbuilder/response_field_checkboxes_spec.rb +57 -0
  115. data/spec/models/formbuilder/response_field_file_spec.rb +80 -0
  116. data/spec/models/formbuilder/response_field_paragraph_spec.rb +22 -0
  117. data/spec/models/formbuilder/response_field_radio_spec.rb +30 -0
  118. data/spec/models/formbuilder/response_field_spec.rb +21 -0
  119. data/spec/models/formbuilder/response_field_table_spec.rb +124 -0
  120. data/spec/spec_helper.rb +25 -0
  121. data/spec/support/database_cleaner.rb +21 -0
  122. data/spec/support/submitting_an_entry_spec_helper.rb +151 -0
  123. metadata +286 -44
  124. data/app/controllers/formbuilder/forms_controller.rb +0 -53
  125. data/lib/formbuilder/entry_renderer.rb +0 -47
  126. data/lib/formbuilder/entry_table_renderer.rb +0 -58
  127. data/lib/formbuilder/form_renderer.rb +0 -102
@@ -0,0 +1 @@
1
+ BALEETED
@@ -0,0 +1 @@
1
+ lkasdjlkd
@@ -0,0 +1,199 @@
1
+ require 'spec_helper'
2
+
3
+ def create_entry(value)
4
+ e = Entry.new(form: form, skip_validation: true)
5
+ e.save_response(value, first_field)
6
+ e.save
7
+ e
8
+ end
9
+
10
+ def ensure_sort_order(*args)
11
+ (args.length - 1).times do |i|
12
+ ( (args[i].responses["#{first_field.id}_sortable_value"] || 0) <
13
+ (args[i+1].responses["#{first_field.id}_sortable_value"] || 0) ).should == true
14
+ end
15
+ end
16
+
17
+ def change_field_type(new_field_type, additional_params = {})
18
+ first_field.update_attributes({ type: new_field_type }.merge(additional_params))
19
+ first_field.becomes!(new_field_type.constantize)
20
+ end
21
+
22
+ describe Formbuilder::Entry do
23
+
24
+ let!(:form) { FactoryGirl.create(:form_with_one_field) }
25
+ let!(:entry) { e = Entry.new(form: form, skip_validation: true); e.save; e }
26
+ let(:first_field) { form.response_fields.first }
27
+ let(:file_value) { File.open(File.expand_path('../../fixtures/test_files/text2.txt', File.dirname(__FILE__))) }
28
+
29
+ subject { entry }
30
+
31
+ describe 'callbacks' do
32
+ describe 'normalize responses' do
33
+ it 'gets called before validation' do
34
+ entry.should_receive(:normalize_responses)
35
+ entry.valid?
36
+ end
37
+ end
38
+
39
+ describe 'calculate_responses_text' do
40
+ it 'gets called when responses change and entry is saved' do
41
+ entry.should_receive(:calculate_responses_text).exactly(:once)
42
+ entry.save_responses({ "#{first_field.id}" => 'boo' }, form.response_fields)
43
+ entry.save
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#value_present?' do
49
+ it 'should be true if there is a value' do
50
+ entry.value_present?(first_field).should == false
51
+ entry.responses[first_field.id.to_s] = 'foo'
52
+ entry.value_present?(first_field).should == true
53
+ end
54
+
55
+ context 'Formbuilder::ResponseFieldCheckboxes' do
56
+ let(:first_field_checkboxes) { first_field.becomes!(Formbuilder::ResponseFieldCheckboxes) }
57
+
58
+ it 'should be true when there are no options' do
59
+ entry.value_present?(first_field_checkboxes).should == true
60
+ end
61
+
62
+ context 'when there are options' do
63
+ before { first_field_checkboxes.field_options['options'] = [{ 'label' => 'foo', 'checked' => 'false' }] }
64
+
65
+ it 'should be false' do
66
+ entry.value_present?(first_field_checkboxes).should == false
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'when the field is serialized' do
72
+ let(:first_field_time) { first_field.becomes!(Formbuilder::ResponseFieldTime) }
73
+
74
+ it 'should be true if it has at least one response' do
75
+ entry.value_present?(first_field_time).should == false
76
+ entry.responses[first_field_time.id.to_s] = { 'am_pm' => 'am' }.to_yaml
77
+ entry.value_present?(first_field_time).should == false
78
+ entry.responses[first_field_time.id.to_s] = { 'minutes' => '06' }.to_yaml
79
+ entry.value_present?(first_field_time).should == true
80
+ end
81
+ end
82
+ end
83
+
84
+ describe '#response_value' do
85
+ context 'when value is serialized' do
86
+ let(:first_field_serialized) { first_field.becomes!(Formbuilder::ResponseFieldCheckboxes) }
87
+
88
+ it 'should unserialize a value if necessary' do
89
+ entry.responses[first_field_serialized.id.to_s] = { a: 'b' }.to_yaml
90
+ entry.response_value(first_field_serialized).should == { a: 'b' }
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '#save_responses' do
96
+ # let's not go overboard here. most of this functionality is covered by feature specs.
97
+ it 'should behave properly' do
98
+ entry.save_responses({ "#{first_field.id}" => 'boo' }, form.response_fields)
99
+ entry.response_value(first_field).should == 'boo'
100
+ end
101
+ end
102
+
103
+ describe '#destroy_response' do
104
+ it 'should remove the response and its sortable value' do
105
+ # Setup
106
+ entry.save_responses({ "#{first_field.id}" => 'boo' }, form.response_fields)
107
+ entry.response_value(first_field).should == 'boo'
108
+ entry.responses["#{first_field.id}_sortable_value"].should be_present
109
+
110
+ # Destroy
111
+ entry.destroy_response(first_field)
112
+ entry.response_value(first_field).should be_nil
113
+ entry.responses["#{first_field.id}_sortable_value"].should be_nil
114
+ end
115
+
116
+ context 'Formbuilder::ResponseFieldFile' do
117
+ let(:first_field_file) { first_field.becomes!(Formbuilder::ResponseFieldFile); }
118
+ let(:attachment_id) { entry.response_value(first_field_file) }
119
+
120
+ before do
121
+ first_field.update_attributes(type: 'Formbuilder::ResponseFieldFile')
122
+ entry.save_responses({ "#{first_field_file.id}" => file_value }, form.reload.response_fields)
123
+ end
124
+
125
+ it 'uploads properly' do
126
+ Formbuilder::EntryAttachment.find(attachment_id).should be_present
127
+ end
128
+
129
+ it 'destroys explicitly' do
130
+ entry.destroy_response(first_field_file)
131
+ entry.response_value(first_field_file).should be_nil
132
+ entry.responses["#{first_field_file.id}_sortable_value"].should be_nil
133
+ Formbuilder::EntryAttachment.where(id: attachment_id).first.should_not be_present
134
+ end
135
+
136
+ it 'destroys when changing value' do
137
+ prev_attachment_id = attachment_id
138
+ entry.save_responses({ "#{first_field_file.id}" => file_value }, form.reload.response_fields)
139
+ Formbuilder::EntryAttachment.where(id: prev_attachment_id).first.should_not be_present
140
+ end
141
+
142
+ # Because <input type='file'> can't have an existing file, we preserve the current
143
+ # value if the input is blank.
144
+ it 'preserves when value is blank' do
145
+ prev_attachment_id = attachment_id
146
+ entry.save_responses({ "#{first_field_file.id}" => '' }, form.reload.response_fields)
147
+ Formbuilder::EntryAttachment.where(id: prev_attachment_id).first.should be_present
148
+ end
149
+ end
150
+ end
151
+
152
+ describe '#calculate_responses_text' do
153
+ let(:first_field_number) { first_field.becomes!(Formbuilder::ResponseFieldNumber) }
154
+
155
+ it 'should calculate the text-only values of the responses' do
156
+ entry.save_responses({ "#{first_field_number.id}" => '123' }, form.response_fields)
157
+ entry.responses["#{first_field_number.id}"].should == '123'
158
+ entry.responses["#{first_field_number.id}_sortable_value"].should == '123'
159
+ entry.save
160
+ entry.responses_text.should == '123'
161
+ end
162
+ end
163
+
164
+ describe 'normalize responses' do
165
+ before do
166
+ first_field.update_attributes(type: 'Formbuilder::ResponseFieldWebsite')
167
+ entry.reload
168
+ end
169
+
170
+ it 'functions properly' do
171
+ # does not need normalization
172
+ entry.responses[first_field.id.to_s] = 'http://www.google.com'
173
+ entry.normalize_responses
174
+ entry.responses[first_field.id.to_s].should == 'http://www.google.com'
175
+
176
+ # needs normalization
177
+ entry.responses[first_field.id.to_s] = 'www.google.com'
178
+ entry.normalize_responses
179
+ entry.responses[first_field.id.to_s].should == 'http://www.google.com'
180
+ end
181
+ end
182
+
183
+ describe 'auditing responses' do
184
+ before do
185
+ first_field.update_attributes(type: 'Formbuilder::ResponseFieldAddress')
186
+ entry.reload
187
+ end
188
+
189
+ it 'should run all audits when called explicitly' do
190
+ entry.responses[first_field.id.to_s] = { 'street' => 'hi' }.to_yaml
191
+ entry.skip_validation = true
192
+ entry.save
193
+ entry.responses["#{first_field.id}_x"].should be_nil
194
+ entry.audit_responses
195
+ entry.responses["#{first_field.id}_x"].should == Geocoder::Lookup::Test.read_stub(nil)[0]['latitude']
196
+ end
197
+ end
198
+
199
+ end
@@ -0,0 +1,215 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formbuilder::EntryValidator do
4
+
5
+ let!(:form) { FactoryGirl.create(:form) }
6
+ let!(:entry) { e = Entry.new(form: form); e.save(skip_validation: true); e }
7
+
8
+ describe '#validate' do
9
+ before do
10
+ form.response_fields.create(label: "Text", type: "Formbuilder::ResponseFieldText", sort_order: 0, required: true)
11
+ end
12
+
13
+ it 'should validate properly' do
14
+ entry.should_not be_valid
15
+ end
16
+
17
+ it 'should not validate if there is no form' do
18
+ entry.form = nil
19
+ entry.should be_valid
20
+ end
21
+
22
+ it 'should not validate if the :skip_validation flag is passed' do
23
+ entry.skip_validation = true
24
+ entry.should be_valid
25
+ end
26
+ end
27
+
28
+ describe 'page validation' do
29
+ let!(:rf1) { form.response_fields.create(label: "Text", type: "Formbuilder::ResponseFieldText", sort_order: 0, required: true) }
30
+ let!(:rf2) { form.response_fields.create(label: "pb", type: "Formbuilder::ResponseFieldPageBreak", sort_order: 1) }
31
+ let!(:rf3) { form.response_fields.create(label: "Text2", type: "Formbuilder::ResponseFieldText", sort_order: 2, required: true) }
32
+
33
+ before do
34
+ entry.save_response('Boo', rf1)
35
+ entry.save
36
+ end
37
+
38
+ subject { entry }
39
+
40
+ it 'validates per page' do
41
+ expect(entry.valid_page?(2)).to be_false
42
+ expect(entry.valid_page?(1)).to be_true
43
+ end
44
+
45
+ its(:first_page_with_errors) { should eq 2 }
46
+ its(:pages_with_errors) { should eq [false, true] }
47
+
48
+ describe '#errors_on_page?' do
49
+ before { entry.valid? }
50
+
51
+ it 'calculates properly' do
52
+ expect(entry.errors_on_page?(1)).to be_false
53
+ expect(entry.errors_on_page?(2)).to be_true
54
+ end
55
+ end
56
+ end
57
+
58
+ describe 'ResponseFieldText' do
59
+ let(:field) { form.response_fields.create(label: "Text", type: "Formbuilder::ResponseFieldText", sort_order: 0) }
60
+
61
+ it 'required' do
62
+ field.update_attributes(required: true)
63
+ entry.should_not be_valid
64
+ entry.save_response('Boo', field)
65
+ entry.should be_valid
66
+ end
67
+
68
+ it 'min/max length characters' do
69
+ field.update_attributes(field_options: { 'minlength' => '5', 'maxlength' => '10' })
70
+ entry.should be_valid
71
+ entry.save_response('Boo', field)
72
+ entry.should_not be_valid
73
+ entry.save_response('Boooo', field)
74
+ entry.should be_valid
75
+ entry.save_response('Boooooooooooooooooooo', field)
76
+ entry.should_not be_valid
77
+ entry.save_response('Boooo', field)
78
+ entry.should be_valid
79
+ end
80
+
81
+ it 'min/max length words' do
82
+ field.update_attributes(field_options: { 'minlength' => '2', 'maxlength' => '3', 'min_max_length_units' => 'words' })
83
+ entry.should be_valid
84
+ entry.save_response('Boo', field)
85
+ entry.should_not be_valid
86
+ entry.save_response('Boo hoo', field)
87
+ entry.should be_valid
88
+ entry.save_response('Boo hoo hoo', field)
89
+ entry.should be_valid
90
+ entry.save_response('Booo hoo hoo hooo', field)
91
+ entry.should_not be_valid
92
+ end
93
+ end
94
+
95
+ describe 'ResponseFieldAddress' do
96
+ let(:field) { form.response_fields.create(label: "Address", type: "Formbuilder::ResponseFieldAddress", sort_order: 0) }
97
+
98
+ it 'required' do
99
+ field.update_attributes(required: true)
100
+ entry.should_not be_valid
101
+ entry.save_response({'street' => '123'}, field)
102
+ entry.should be_valid
103
+ end
104
+ end
105
+
106
+ describe 'ResponseFieldDate' do
107
+ let(:field) { form.response_fields.create(label: "Date", type: "Formbuilder::ResponseFieldDate", sort_order: 0) }
108
+
109
+ it 'validates properly' do
110
+ entry.should be_valid
111
+ entry.save_response({'month' => '2'}, field)
112
+ entry.should_not be_valid
113
+ entry.save_response({'month' => '2', 'day' => '3'}, field)
114
+ entry.should_not be_valid
115
+ entry.save_response({'month' => '2', 'day' => '3', 'year' => '2011'}, field)
116
+ entry.should be_valid
117
+
118
+ # @todo automatically add 20** or 19** to dates
119
+ end
120
+ end
121
+
122
+ describe 'ResponseFieldEmail' do
123
+ let(:field) { form.response_fields.create(label: "Email", type: "Formbuilder::ResponseFieldEmail", sort_order: 0) }
124
+
125
+ it 'validates properly' do
126
+ entry.should be_valid
127
+ entry.save_response('a', field)
128
+ entry.should_not be_valid
129
+ entry.save_response('a@a.com', field)
130
+ entry.should be_valid
131
+ end
132
+ end
133
+
134
+ describe 'ResponseFieldNumber' do
135
+ let(:field) { form.response_fields.create(label: "Number", type: "Formbuilder::ResponseFieldNumber", sort_order: 0) }
136
+
137
+ it 'min/max' do
138
+ field.update_attributes(field_options: { 'min' => '5', 'max' => '10' })
139
+ entry.should be_valid
140
+ entry.save_response('1', field)
141
+ entry.should_not be_valid
142
+ entry.save_response('4.99999', field)
143
+ entry.should_not be_valid
144
+ entry.save_response('5.01', field)
145
+ entry.should be_valid
146
+ entry.save_response('10.00', field)
147
+ entry.should be_valid
148
+ entry.save_response('10.9', field)
149
+ entry.should_not be_valid
150
+ end
151
+
152
+ it 'integer only' do
153
+ field.update_attributes(field_options: { 'integer_only' => true })
154
+ entry.should be_valid
155
+ entry.save_response('1.2', field)
156
+ entry.should_not be_valid
157
+ entry.save_response('1.0', field)
158
+ entry.should_not be_valid
159
+ entry.save_response('1', field)
160
+ entry.should be_valid
161
+ end
162
+ end
163
+
164
+ describe 'ResponseFieldPrice' do
165
+ let(:field) { form.response_fields.create(label: "Price", type: "Formbuilder::ResponseFieldPrice", sort_order: 0) }
166
+
167
+ it 'validates properly' do
168
+ entry.should be_valid
169
+ entry.save_response({ 'dollars' => 'a' }, field)
170
+ entry.should_not be_valid
171
+ entry.save_response({ 'dollars' => '0' }, field)
172
+ entry.should be_valid
173
+ entry.save_response({ 'dollars' => '1a' }, field)
174
+ entry.should_not be_valid
175
+ entry.save_response({ 'dollars' => '1' }, field)
176
+ entry.should be_valid
177
+ entry.save_response({ 'cents' => 'a' }, field)
178
+ entry.should_not be_valid
179
+ entry.save_response({ 'cents' => '0' }, field)
180
+ entry.should be_valid
181
+ entry.save_response({ 'cents' => '1a' }, field)
182
+ entry.should_not be_valid
183
+ entry.save_response({ 'cents' => '1' }, field)
184
+ entry.should be_valid
185
+ entry.save_response({ 'dollars' => '3a', 'cents' => '1' }, field)
186
+ entry.should_not be_valid
187
+ entry.save_response({ 'dollars' => '3', 'cents' => '100z' }, field)
188
+ entry.should_not be_valid
189
+ end
190
+ end
191
+
192
+ describe 'ResponseFieldTime' do
193
+ let(:field) { form.response_fields.create(label: "Time", type: "Formbuilder::ResponseFieldTime", sort_order: 0) }
194
+
195
+ it 'validates properly' do
196
+ entry.should be_valid
197
+ entry.save_response({'hours' => '0'}, field)
198
+ entry.should_not be_valid
199
+ entry.save_response({'hours' => '0', 'minutes' => '1'}, field)
200
+ entry.should_not be_valid
201
+ entry.save_response({'hours' => '1', 'minutes' => '3'}, field)
202
+ entry.should be_valid
203
+ end
204
+ end
205
+
206
+ describe 'ResponseFieldWebsite' do
207
+ let(:field) { form.response_fields.create(label: "Website", type: "Formbuilder::ResponseFieldWebsite", sort_order: 0) }
208
+
209
+ it 'validates properly' do
210
+ entry.should be_valid
211
+ # @todo add real validations for website field?
212
+ end
213
+ end
214
+
215
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe EntryWithAlternateColumnName do
4
+
5
+ let!(:form) { FactoryGirl.create(:form_with_one_field) }
6
+ let!(:entry) { e = EntryWithAlternateColumnName.new(form: form, skip_validation: true); e.save; e }
7
+ let(:first_field) { form.response_fields.first }
8
+
9
+ subject { entry }
10
+
11
+ describe '#value_present?' do
12
+ it 'should be true if there is a value' do
13
+ entry.value_present?(first_field).should == false
14
+ entry.responses_alt[first_field.id.to_s] = 'foo'
15
+ entry.value_present?(first_field).should == true
16
+ end
17
+ end
18
+
19
+ describe '#response_value' do
20
+ context 'when value is serialized' do
21
+ let(:first_field_serialized) { first_field.becomes!(Formbuilder::ResponseFieldCheckboxes) }
22
+
23
+ it 'should unserialize a value if necessary' do
24
+ entry.responses_alt[first_field_serialized.id.to_s] = { a: 'b' }.to_yaml
25
+ entry.response_value(first_field_serialized).should == { a: 'b' }
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#save_responses' do
31
+ it 'should behave properly' do
32
+ entry.save_responses({ "#{first_field.id}" => 'boo' }, form.response_fields)
33
+ entry.response_value(first_field).should == 'boo'
34
+ end
35
+ end
36
+
37
+ end