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,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