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,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::Views::EntryDl do
|
|
4
|
+
|
|
5
|
+
TEXT_FIELD_PARAMS = { label: "Text", type: "Formbuilder::ResponseFieldText", sort_order: 0 }
|
|
6
|
+
|
|
7
|
+
let(:form) { FactoryGirl.create(:form) }
|
|
8
|
+
let(:entry) { e = Entry.new(form: form); e.save(validate: false); e }
|
|
9
|
+
|
|
10
|
+
it 'should display a label for blind fields' do
|
|
11
|
+
form.response_fields.create TEXT_FIELD_PARAMS.merge(blind: true)
|
|
12
|
+
Formbuilder::Views::EntryDl.new(entry: entry, form: form, show_blind: true).to_html.should match('Blind')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should only display blind fields when instructed to' do
|
|
16
|
+
form.response_fields.create TEXT_FIELD_PARAMS.merge(blind: true)
|
|
17
|
+
Formbuilder::Views::EntryDl.new(entry: entry, form: form).to_html.should_not match('Blind')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should optionally display a label for admin only fields' do
|
|
21
|
+
form.response_fields.create TEXT_FIELD_PARAMS.merge(admin_only: true)
|
|
22
|
+
Formbuilder::Views::EntryDl.new(entry: entry, form: form).to_html.should_not match('Admin only')
|
|
23
|
+
Formbuilder::Views::EntryDl.new(entry: entry, form: form, show_admin_only: true).to_html.should match('Admin only')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should display placeholder text if there is no response' do
|
|
27
|
+
form.response_fields.create TEXT_FIELD_PARAMS
|
|
28
|
+
Formbuilder::Views::EntryDl.new(entry: entry, form: form).to_html.should match('No response')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'should display the response' do
|
|
32
|
+
rf = form.response_fields.create TEXT_FIELD_PARAMS
|
|
33
|
+
entry.save_response('buzz', rf)
|
|
34
|
+
entry.save(validate: false)
|
|
35
|
+
Formbuilder::Views::EntryDl.new(entry: entry, form: form).to_html.should match('buzz')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::EntryAttachment do
|
|
4
|
+
|
|
5
|
+
let!(:model) { Formbuilder::EntryAttachment.new }
|
|
6
|
+
|
|
7
|
+
it 'saves the content type and file size' do
|
|
8
|
+
model.upload = File.open(File.join(Formbuilder.root, 'spec/fixtures/test_files/text.txt'))
|
|
9
|
+
model.save
|
|
10
|
+
model.upload.should be_present
|
|
11
|
+
model.file_size.should == 8
|
|
12
|
+
model.content_type.should == 'text/plain'
|
|
13
|
+
model.update_attributes(remove_upload: true)
|
|
14
|
+
model.upload.should_not be_present
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::Form do
|
|
4
|
+
|
|
5
|
+
let(:form) { Formbuilder::Form.new }
|
|
6
|
+
subject { form }
|
|
7
|
+
|
|
8
|
+
it { should be_valid }
|
|
9
|
+
it { should respond_to(:formable) }
|
|
10
|
+
it { should respond_to(:response_fields) }
|
|
11
|
+
|
|
12
|
+
describe '#copy_response_fields!' do
|
|
13
|
+
let!(:other_form) do
|
|
14
|
+
f = Formbuilder::Form.create
|
|
15
|
+
f.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo')
|
|
16
|
+
f
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'copies properly' do
|
|
20
|
+
form.save
|
|
21
|
+
form.response_fields.count.should == 0
|
|
22
|
+
form.copy_response_fields!(other_form)
|
|
23
|
+
form.response_fields.count.should == 1
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#num_pages' do
|
|
28
|
+
before { form.save }
|
|
29
|
+
|
|
30
|
+
context 'no response fields' do
|
|
31
|
+
its(:num_pages) { should eq 1 }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'multiple response fields' do
|
|
35
|
+
before do
|
|
36
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo')
|
|
37
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldParagraph', label: 'foo2')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
its(:num_pages) { should eq 1 }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context '2 pages' do
|
|
44
|
+
before do
|
|
45
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo')
|
|
46
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldPageBreak')
|
|
47
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldParagraph', label: 'foo2')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
its(:num_pages) { should eq 2 }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'with 3 pages' do
|
|
54
|
+
before do
|
|
55
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo')
|
|
56
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldPageBreak')
|
|
57
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldParagraph', label: 'foo2')
|
|
58
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldPageBreak')
|
|
59
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo3')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
its(:num_pages) { should eq 3 }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'with admin only fields' do
|
|
66
|
+
before do
|
|
67
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo')
|
|
68
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldPageBreak')
|
|
69
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldParagraph', label: 'foo2', admin_only: true)
|
|
70
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldPageBreak')
|
|
71
|
+
form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo3')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'showing admin only' do
|
|
75
|
+
before { form.show_admin_only = true }
|
|
76
|
+
its(:num_pages) { should eq 3 }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context 'not showing admin only' do
|
|
80
|
+
its(:num_pages) { should eq 2 }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe '#response_fields_for_page' do
|
|
86
|
+
before { form.save }
|
|
87
|
+
|
|
88
|
+
context 'with 2 pages' do
|
|
89
|
+
let!(:rf1) { form.response_fields.create(type: 'Formbuilder::ResponseFieldText', label: 'foo') }
|
|
90
|
+
let!(:rf2) { form.response_fields.create(type: 'Formbuilder::ResponseFieldPageBreak') }
|
|
91
|
+
let!(:rf3) { form.response_fields.create(type: 'Formbuilder::ResponseFieldParagraph', label: 'foo2') }
|
|
92
|
+
|
|
93
|
+
it 'calculates properly' do
|
|
94
|
+
expect(form.response_fields_for_page(1)).to eq [rf1]
|
|
95
|
+
expect(form.response_fields_for_page(2)).to eq [rf3]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseFieldAddress do
|
|
4
|
+
|
|
5
|
+
let(:response_field) { Formbuilder::ResponseFieldAddress.new }
|
|
6
|
+
subject { response_field }
|
|
7
|
+
subject(:rf) { response_field }
|
|
8
|
+
|
|
9
|
+
describe '#audit_response' do
|
|
10
|
+
it 'geocodes properly' do
|
|
11
|
+
Geocoder.should_receive(:coordinates).and_return([1, 1])
|
|
12
|
+
all_responses = {}
|
|
13
|
+
response_field.audit_response({ 'street' => 'New York, NY, US' }, all_responses)
|
|
14
|
+
expect(all_responses["#{response_field.id}_x"]).to eq 1
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#sortable_value' do
|
|
19
|
+
it 'functions properly' do
|
|
20
|
+
expect(rf.sortable_value({'city' => 'zzzz', 'street' => 'adams town'})).to be < rf.sortable_value({'street' => 'cffff'})
|
|
21
|
+
expect(rf.sortable_value({'city' => 'aaaa', 'street' => 'zzzz'})).to be > rf.sortable_value({'street' => 'cffff'})
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseFieldCheckboxes do
|
|
4
|
+
|
|
5
|
+
let(:response_field) do
|
|
6
|
+
Formbuilder::ResponseFieldCheckboxes.new(
|
|
7
|
+
field_options: { 'options' => [{'label' => 'foo', 'checked' => false}]}
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
subject { response_field }
|
|
11
|
+
subject(:rf) { response_field }
|
|
12
|
+
|
|
13
|
+
describe '#normalize_response' do
|
|
14
|
+
it 'calculates the individual sortable values' do
|
|
15
|
+
all_responses = {}
|
|
16
|
+
rf.normalize_response({'foo' => true}, all_responses)
|
|
17
|
+
all_responses["#{rf.id}_sortable_values_foo"].should eq true
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#transform_raw_value' do
|
|
22
|
+
let(:entry) { Entry.new }
|
|
23
|
+
|
|
24
|
+
it 'transforms the options properly' do
|
|
25
|
+
transformed = rf.transform_raw_value({ '0' => 'on' }, entry)
|
|
26
|
+
transformed['foo'].should == true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'transforms the other option' do
|
|
30
|
+
transformed = rf.transform_raw_value({ 'other_checkbox' => 'on', 'other' => 'bar' }, entry)
|
|
31
|
+
transformed['Other'].should == 'bar'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'does not save the other option unless the checkbox is checked' do
|
|
35
|
+
transformed = rf.transform_raw_value({ 'other_checkbox' => nil, 'other' => 'bar' }, entry)
|
|
36
|
+
transformed['Other'].should == nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'sets the _present attribute' do
|
|
40
|
+
rf.transform_raw_value({ '0' => 'on' }, entry)
|
|
41
|
+
entry.responses["#{rf.id}_present"].should == true
|
|
42
|
+
rf.transform_raw_value({ '0' => nil }, entry)
|
|
43
|
+
entry.responses["#{rf.id}_present"].should == nil
|
|
44
|
+
rf.transform_raw_value({ 'other_checkbox' => 'on', 'other' => 'z' }, entry)
|
|
45
|
+
entry.responses["#{rf.id}_present"].should == true
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe '#render_entry_text' do
|
|
50
|
+
it 'functions properly' do
|
|
51
|
+
expect(rf.render_entry_text({'foo' => true})).to eq 'foo: y'
|
|
52
|
+
expect(rf.render_entry_text({'foo' => true, 'bar' => false})).to eq "foo: y\nbar: n"
|
|
53
|
+
expect(rf.render_entry_text({'foo' => true, 'Other' => 'yee'})).to eq "foo: y\nOther: yee"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseFieldFile do
|
|
4
|
+
|
|
5
|
+
let!(:form) { Formbuilder::Form.create }
|
|
6
|
+
let!(:response_field) { Formbuilder::ResponseFieldFile.create(form: form) }
|
|
7
|
+
let!(:entry) { Entry.create(form: form) }
|
|
8
|
+
|
|
9
|
+
let(:file_value) { File.open(File.expand_path('../../fixtures/test_files/text2.txt', File.dirname(__FILE__))) }
|
|
10
|
+
|
|
11
|
+
subject { response_field }
|
|
12
|
+
subject(:rf) { response_field }
|
|
13
|
+
|
|
14
|
+
describe '#audit_response' do
|
|
15
|
+
it 'adds the filename param' do
|
|
16
|
+
entry.save_response([file_value], rf)
|
|
17
|
+
entry.audit_responses
|
|
18
|
+
entry.responses["#{rf.id}_filename"].should == 'text2.txt'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#sortable_value' do
|
|
23
|
+
it 'calculates properly' do
|
|
24
|
+
entry.save_response([file_value], rf)
|
|
25
|
+
entry.responses["#{rf.id}_sortable_value"].should == 1
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#transform_raw_value' do
|
|
30
|
+
it 'preserves old upload' do
|
|
31
|
+
entry.save_response([file_value], rf)
|
|
32
|
+
initial_attachment = rf.get_attachments(entry.responses[rf.id.to_s]).first
|
|
33
|
+
entry.save_response([], rf)
|
|
34
|
+
initial_attachment.reload.should be_present
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'removes old upload when setting a new one' do
|
|
38
|
+
entry.save_response([file_value], rf)
|
|
39
|
+
initial_attachment = rf.get_attachments(entry.responses[rf.id.to_s]).first
|
|
40
|
+
entry.save_response([file_value], rf)
|
|
41
|
+
expect { initial_attachment.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'uploads multiple files' do
|
|
45
|
+
expect {
|
|
46
|
+
entry.save_response([file_value, file_value], rf)
|
|
47
|
+
}.to change { Formbuilder::EntryAttachment.count }.by(2)
|
|
48
|
+
|
|
49
|
+
rf.get_attachments(entry.responses[rf.id.to_s]).length.should == 2
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'does not choke on nil values' do
|
|
53
|
+
expect {
|
|
54
|
+
entry.save_response([nil], rf)
|
|
55
|
+
}.to_not change { Formbuilder::EntryAttachment.count }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#render_entry' do
|
|
60
|
+
before do
|
|
61
|
+
entry.save_response([file_value], rf)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'renders properly' do
|
|
65
|
+
rf.render_entry(entry.responses[rf.id.to_s]).should match 'text2.txt'
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe '#render_entry_text' do
|
|
70
|
+
before do
|
|
71
|
+
entry.save_response([file_value], rf)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'renders properly' do
|
|
75
|
+
rf.render_entry_text(entry.responses[rf.id.to_s]).should match 'text2.txt'
|
|
76
|
+
rf.render_entry_text(entry.responses[rf.id.to_s]).should_not match '<'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseFieldParagraph do
|
|
4
|
+
|
|
5
|
+
let(:response_field) { Formbuilder::ResponseFieldParagraph.new }
|
|
6
|
+
subject { response_field }
|
|
7
|
+
|
|
8
|
+
describe '#render_entry' do
|
|
9
|
+
INPUT = "blah blah\n\nhttp://www.google.com asldfkj"
|
|
10
|
+
EXPECTED_OUTPUT = %Q{<p>blah blah</p>\n\n<p><a href="http://www.google.com">http://www.google.com</a> asldfkj</p>}
|
|
11
|
+
|
|
12
|
+
it 'autolinks properly' do
|
|
13
|
+
expect(response_field.render_entry(INPUT)).to eq EXPECTED_OUTPUT
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'doesnt choke on nil value' do
|
|
17
|
+
expect(response_field.render_entry(nil)).to eq ''
|
|
18
|
+
expect(response_field.render_entry('')).to eq ''
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseFieldRadio do
|
|
4
|
+
|
|
5
|
+
let(:response_field) do
|
|
6
|
+
Formbuilder::ResponseFieldRadio.new(
|
|
7
|
+
field_options: { 'options' => [{'label' => 'foo', 'checked' => false}]}
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
subject { response_field }
|
|
11
|
+
subject(:rf) { response_field }
|
|
12
|
+
|
|
13
|
+
describe '#transform_raw_value' do
|
|
14
|
+
before { rf.save }
|
|
15
|
+
let(:entry) { Entry.new }
|
|
16
|
+
|
|
17
|
+
it 'does not set the other option if raw_value is not other' do
|
|
18
|
+
transformed = rf.transform_raw_value('Goats', entry, { response_field_params: { "#{rf.id}_other" => 'foo' } })
|
|
19
|
+
transformed.should == 'Goats'
|
|
20
|
+
entry.responses["#{rf.id}_other"].should == nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'sets the other option on the entry if raw_value is other' do
|
|
24
|
+
transformed = rf.transform_raw_value('Other', entry, { response_field_params: { "#{rf.id}_other" => 'foo' } })
|
|
25
|
+
transformed.should == 'Other'
|
|
26
|
+
entry.responses["#{rf.id}_other"].should == 'foo'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseField do
|
|
4
|
+
|
|
5
|
+
let(:response_field) { Formbuilder::ResponseFieldText.new }
|
|
6
|
+
subject { response_field }
|
|
7
|
+
|
|
8
|
+
it { should be_valid }
|
|
9
|
+
|
|
10
|
+
describe '#options_array' do
|
|
11
|
+
its(:options_array) { should be_empty }
|
|
12
|
+
|
|
13
|
+
context 'with options' do
|
|
14
|
+
before { response_field.field_options['options'] = [{'checked' => 'false', 'label' => 'Choice #1'},
|
|
15
|
+
{'checked' => 'false', 'label' => 'Choice #2'}] }
|
|
16
|
+
|
|
17
|
+
its(:options_array) { should == ['Choice #1', 'Choice #2'] }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formbuilder::ResponseFieldTable do
|
|
4
|
+
|
|
5
|
+
let(:response_field) do
|
|
6
|
+
Formbuilder::ResponseFieldTable.new(
|
|
7
|
+
field_options: { 'columns' => [{'label' => 'column one'}],
|
|
8
|
+
'column_totals' => true }
|
|
9
|
+
)
|
|
10
|
+
end
|
|
11
|
+
subject { response_field }
|
|
12
|
+
subject(:rf) { response_field }
|
|
13
|
+
|
|
14
|
+
describe '#normalize_response' do
|
|
15
|
+
it 'calculates the individual sortable values' do
|
|
16
|
+
all_responses = {}
|
|
17
|
+
rf.normalize_response({'column one' => ['1', '2', '3.5', 'asdf']}, all_responses)
|
|
18
|
+
all_responses["#{rf.id}_sum_column one"].should eq 6.5
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'calculates the sums' do
|
|
22
|
+
all_responses = {}
|
|
23
|
+
rf.normalize_response({'column one' => ['asdfasdf', 'fasdf']}, all_responses)
|
|
24
|
+
all_responses["#{rf.id}_sum_column one"].should eq 0
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#transform_raw_value' do
|
|
29
|
+
let(:entry) { Entry.new }
|
|
30
|
+
|
|
31
|
+
before do
|
|
32
|
+
response_field.update_attributes(
|
|
33
|
+
field_options: { 'columns' => [{'label' => 'column one'},
|
|
34
|
+
{'label' => 'column two'}] }
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'transforms the options properly' do
|
|
39
|
+
transformed = rf.transform_raw_value({ '0' => ['foo', 'bar'] }, entry)
|
|
40
|
+
transformed['column one'].should == ['foo', 'bar']
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'preserves rows with one input' do
|
|
44
|
+
transformed = rf.transform_raw_value({ '0' => ['', 'bar'], '1' => ['baz', ''] }, entry)
|
|
45
|
+
transformed['column one'].should == ['', 'bar']
|
|
46
|
+
transformed['column two'].should == ['baz', '']
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'removes blank rows' do
|
|
51
|
+
transformed = rf.transform_raw_value({ '0' => ['', 'bar'], '1' => ['', 'baz'] }, entry)
|
|
52
|
+
transformed['column one'].should == ['bar']
|
|
53
|
+
transformed['column two'].should == ['baz']
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'doesnt choke on nils' do
|
|
57
|
+
transformed = rf.transform_raw_value({ }, entry)
|
|
58
|
+
transformed['column one'].should == nil
|
|
59
|
+
transformed['column two'].should == nil
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe '#render_entry_text' do
|
|
64
|
+
it 'functions properly' do
|
|
65
|
+
expect(rf.render_entry_text({'column one' => ['bar', 'baz']})).to eq 'column one: bar, baz'
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe '#render_entry' do
|
|
70
|
+
it 'does not trip on blanks' do
|
|
71
|
+
rendered = rf.render_entry(
|
|
72
|
+
{'column one' => ['bar', 'baz']},
|
|
73
|
+
entry: OpenStruct.new(get_responses: {})
|
|
74
|
+
)
|
|
75
|
+
expect(rendered).to match 'bar'
|
|
76
|
+
expect(rendered).to match 'baz'
|
|
77
|
+
expect(rendered).to_not match '0'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'does not render zeroes' do
|
|
81
|
+
rendered = rf.render_entry(
|
|
82
|
+
{'column one' => ['bar', 'baz']},
|
|
83
|
+
entry: OpenStruct.new(get_responses: {"#{rf.id}_sum_column one" => '0.0'})
|
|
84
|
+
)
|
|
85
|
+
expect(rendered).to match 'bar'
|
|
86
|
+
expect(rendered).to match 'baz'
|
|
87
|
+
expect(rendered).to_not match '0'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'renders sums greater than zero' do
|
|
91
|
+
rendered = rf.render_entry(
|
|
92
|
+
{'column one' => ['bar', '1', '1.5']},
|
|
93
|
+
entry: OpenStruct.new(get_responses: {"#{rf.id}_sum_column one" => '2.5'})
|
|
94
|
+
)
|
|
95
|
+
expect(rendered).to match 'bar'
|
|
96
|
+
expect(rendered).to match '1'
|
|
97
|
+
expect(rendered).to match '1.5'
|
|
98
|
+
expect(rendered).to match '2.5'
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe '#render_input' do
|
|
103
|
+
it 'renders properly' do
|
|
104
|
+
rendered = rf.render_input({})
|
|
105
|
+
expect(rendered).to match("<textarea")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'with default row values' do
|
|
109
|
+
before do
|
|
110
|
+
rf.field_options['preset_values'] = {'column one' => ['p1', 'p2']}
|
|
111
|
+
rf.field_options['minrows'] = 2
|
|
112
|
+
rf.save
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'renders properly' do
|
|
116
|
+
rendered = rf.render_input({})
|
|
117
|
+
expect(rendered).to match(">p1<")
|
|
118
|
+
expect(rendered).to match(">p2<")
|
|
119
|
+
expect(rendered).to match("readonly")
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|