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.
- checksums.yaml +4 -4
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +219 -0
- data/Guardfile +17 -0
- data/{MIT-LICENSE → LICENSE.md} +1 -1
- data/README.md +86 -0
- data/app/controllers/formbuilder/concerns/forms_controller.rb +59 -0
- data/app/models/formbuilder/entry_attachment.rb +2 -8
- data/app/models/formbuilder/form.rb +53 -0
- data/app/models/formbuilder/response_field.rb +23 -10
- data/app/models/formbuilder/response_field_address.rb +12 -1
- data/app/models/formbuilder/response_field_checkboxes.rb +38 -0
- data/app/models/formbuilder/response_field_date.rb +7 -1
- data/app/models/formbuilder/response_field_dropdown.rb +2 -1
- data/app/models/formbuilder/response_field_email.rb +14 -2
- data/app/models/formbuilder/response_field_file.rb +75 -20
- data/app/models/formbuilder/response_field_number.rb +9 -2
- data/app/models/formbuilder/response_field_page_break.rb +13 -0
- data/app/models/formbuilder/response_field_paragraph.rb +19 -3
- data/app/models/formbuilder/response_field_price.rb +10 -6
- data/app/models/formbuilder/response_field_radio.rb +11 -2
- data/app/models/formbuilder/response_field_section_break.rb +12 -2
- data/app/models/formbuilder/response_field_table.rb +222 -0
- data/app/models/formbuilder/response_field_text.rb +9 -2
- data/app/models/formbuilder/response_field_time.rb +8 -1
- data/app/models/formbuilder/response_field_website.rb +26 -2
- data/app/uploaders/formbuilder/entry_attachment_uploader.rb +11 -1
- data/bin/rails +8 -0
- data/circle.yml +9 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20130924185815_create_formbuilder_entry_attachments.rb +1 -0
- data/formbuilder-rb.gemspec +41 -0
- data/formbuilder-rb.sublime-project +20 -0
- data/lib/formbuilder.rb +8 -3
- data/lib/formbuilder/entry.rb +102 -159
- data/lib/formbuilder/entry_validator.rb +13 -6
- data/lib/formbuilder/version.rb +1 -1
- data/lib/formbuilder/views/entry_dl.rb +56 -0
- data/lib/formbuilder/views/form.rb +81 -0
- data/lib/formbuilder/views/form_field.rb +45 -0
- data/spec/controllers/formbuilder/forms_controller_spec.rb +40 -0
- data/spec/dummy/.ruby-gemset +1 -0
- data/spec/dummy/.ruby-version +1 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/forms_controller.rb +3 -0
- data/spec/dummy/app/controllers/test_controller.rb +57 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/entry.rb +7 -0
- data/spec/dummy/app/models/entry_with_alternate_column_name.rb +11 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/test/_form.rb +2 -0
- data/spec/dummy/app/views/test/render_entry.html.erb +1 -0
- data/spec/dummy/app/views/test/show_form.html.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +25 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml.ci +15 -0
- data/spec/dummy/config/database.yml.example +15 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +52 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +12 -0
- data/spec/dummy/db/migrate/20130924182939_create_entries.rb +13 -0
- data/spec/dummy/db/migrate/20130924192151_create_formbuilder_forms.formbuilder.rb +11 -0
- data/spec/dummy/db/migrate/20130924192152_create_formbuilder_response_fields.formbuilder.rb +17 -0
- data/spec/dummy/db/migrate/20130926205845_create_formbuilder_entry_attachments.formbuilder.rb +12 -0
- data/spec/dummy/db/migrate/20140128000000_create_entry_with_alternate_column_names.rb +13 -0
- data/spec/dummy/db/schema.rb +64 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/test/fixtures/entries.yml +9 -0
- data/spec/dummy/test/fixtures/response_fields.yml +19 -0
- data/spec/dummy/test/models/entry_test.rb +7 -0
- data/spec/dummy/test/models/response_field_test.rb +7 -0
- data/spec/factories/formbuilder_forms.rb +45 -0
- data/spec/features/form_renderer_spec.rb +30 -0
- data/spec/features/submitting_an_entry_spec.rb +79 -0
- data/spec/fixtures/test_files/text.txt +1 -0
- data/spec/fixtures/test_files/text2.txt +1 -0
- data/spec/lib/formbuilder/entry_spec.rb +199 -0
- data/spec/lib/formbuilder/entry_validator_spec.rb +215 -0
- data/spec/lib/formbuilder/entry_with_alternate_column_name_spec.rb +37 -0
- data/spec/lib/formbuilder/views/entry_dl_spec.rb +38 -0
- data/spec/models/formbuilder/entry_attachment_spec.rb +17 -0
- data/spec/models/formbuilder/form_spec.rb +100 -0
- data/spec/models/formbuilder/response_field_address_spec.rb +25 -0
- data/spec/models/formbuilder/response_field_checkboxes_spec.rb +57 -0
- data/spec/models/formbuilder/response_field_file_spec.rb +80 -0
- data/spec/models/formbuilder/response_field_paragraph_spec.rb +22 -0
- data/spec/models/formbuilder/response_field_radio_spec.rb +30 -0
- data/spec/models/formbuilder/response_field_spec.rb +21 -0
- data/spec/models/formbuilder/response_field_table_spec.rb +124 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/database_cleaner.rb +21 -0
- data/spec/support/submitting_an_entry_spec_helper.rb +151 -0
- metadata +286 -44
- data/app/controllers/formbuilder/forms_controller.rb +0 -53
- data/lib/formbuilder/entry_renderer.rb +0 -47
- data/lib/formbuilder/entry_table_renderer.rb +0 -58
- 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
|