formbuilder-rb 0.0.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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