fe 0.0.4 → 1.0.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 (218) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +16 -36
  3. data/app/assets/javascripts/fe/admin.js +0 -1
  4. data/app/assets/javascripts/fe/fe.admin.js +40 -16
  5. data/app/assets/javascripts/fe/fe.common.js +48 -14
  6. data/app/assets/javascripts/fe/fe.public.js +1 -414
  7. data/app/assets/javascripts/fe/fe.public.nojquery.js +450 -0
  8. data/app/assets/javascripts/fe/jquery.validate.pack.js +3 -15
  9. data/app/assets/stylesheets/360front.css +0 -0
  10. data/app/assets/stylesheets/fe/fe.screen.css.scss.erb +69 -10
  11. data/app/controllers/fe/admin/elements_controller.rb +64 -48
  12. data/app/controllers/fe/admin/email_templates_controller.rb +2 -2
  13. data/app/controllers/fe/admin/question_pages_controller.rb +1 -1
  14. data/app/controllers/fe/admin/question_sheets_controller.rb +2 -103
  15. data/app/controllers/fe/concerns/admin/question_sheets_controller_concern.rb +112 -0
  16. data/app/controllers/fe/concerns/answer_pages_controller_concern.rb +2 -1
  17. data/app/controllers/fe/concerns/answer_sheets_controller_concern.rb +1 -1
  18. data/app/controllers/fe/concerns/application_controller_concern.rb +13 -0
  19. data/app/controllers/fe/reference_sheets_controller.rb +2 -0
  20. data/app/controllers/fe/references_controller.rb +1 -0
  21. data/app/helpers/fe/application_helper.rb +5 -0
  22. data/app/mailers/fe/notifier.rb +11 -4
  23. data/app/models/answer_sheet.rb +2 -0
  24. data/app/models/fe/application.rb +2 -1
  25. data/app/models/fe/concerns/answer_pages_presenter_concern.rb +10 -1
  26. data/app/models/fe/concerns/answer_sheet_concern.rb +38 -8
  27. data/app/models/fe/concerns/choice_field_concern.rb +17 -10
  28. data/app/models/fe/date_field.rb +1 -1
  29. data/app/models/fe/element.rb +105 -31
  30. data/app/models/fe/page.rb +52 -20
  31. data/app/models/fe/page_element.rb +6 -1
  32. data/app/models/fe/page_link.rb +6 -3
  33. data/app/models/fe/person.rb +11 -8
  34. data/app/models/fe/question.rb +2 -6
  35. data/app/models/fe/question_grid.rb +1 -1
  36. data/app/models/fe/question_grid_with_total.rb +15 -0
  37. data/app/models/fe/question_set.rb +1 -1
  38. data/app/models/fe/question_sheet.rb +15 -13
  39. data/app/models/fe/reference_question.rb +0 -10
  40. data/app/models/fe/reference_sheet.rb +17 -13
  41. data/app/models/staff.rb +2 -0
  42. data/app/validators/email_validator.rb +11 -0
  43. data/app/views/fe/admin/elements/create.js.erb +1 -0
  44. data/app/views/fe/admin/elements/drop.js.erb +1 -0
  45. data/app/views/fe/admin/elements/duplicate.js.erb +1 -0
  46. data/app/views/fe/admin/panels/_advanced_options.html.erb +9 -3
  47. data/app/views/fe/admin/panels/_common_fields.html.erb +19 -5
  48. data/app/views/fe/admin/panels/_page.html.erb +1 -1
  49. data/app/views/fe/admin/panels/_prop_choice_field.html.erb +20 -11
  50. data/app/views/fe/admin/panels/_prop_element.html.erb +2 -9
  51. data/app/views/fe/admin/panels/_prop_page.html.erb +8 -3
  52. data/app/views/fe/admin/panels/_prop_paragraph.html.erb +38 -24
  53. data/app/views/fe/admin/panels/_prop_section.html.erb +8 -2
  54. data/app/views/fe/admin/panels/_prop_sheet.html.erb +4 -1
  55. data/app/views/fe/admin/question_pages/_element.html.erb +11 -1
  56. data/app/views/fe/answer_pages/_answer_page.html.erb +9 -8
  57. data/app/views/fe/answer_pages/_element.html.erb +6 -7
  58. data/app/views/fe/answer_pages/_page_name.html.erb +1 -0
  59. data/app/views/fe/answer_pages/update.js.erb +3 -3
  60. data/app/views/fe/answer_sheets/_answer_sheet.html.erb +3 -3
  61. data/app/views/fe/answer_sheets/_element.html.erb +52 -34
  62. data/app/views/fe/answer_sheets/_incomplete.html.erb +1 -1
  63. data/app/views/fe/answer_sheets/_page_link.html.erb +2 -2
  64. data/app/views/fe/answer_sheets/_pages_list.html.erb +3 -3
  65. data/app/views/fe/answer_sheets/_submit_to.html.erb +1 -0
  66. data/app/views/fe/answer_sheets/edit.html.erb +14 -14
  67. data/app/views/fe/answer_sheets/incomplete.js.erb +3 -0
  68. data/app/views/fe/answer_sheets/index.html.erb +3 -3
  69. data/app/views/fe/answer_sheets/show.html.erb +1 -1
  70. data/app/views/fe/applications/_logout.html.erb +1 -0
  71. data/app/views/fe/applications/show.html.erb +1 -0
  72. data/app/views/fe/questions/fe/_acceptance.html.erb +3 -3
  73. data/app/views/fe/questions/fe/_attachment_field.html.erb +7 -3
  74. data/app/views/fe/questions/fe/_checkbox_field.html.erb +26 -24
  75. data/app/views/fe/questions/fe/_date_field.html.erb +1 -2
  76. data/app/views/fe/questions/fe/_date_field_mmyy.html.erb +2 -2
  77. data/app/views/fe/questions/fe/_drop_down_field.html.erb +3 -2
  78. data/app/views/fe/questions/fe/_paragraph.html.erb +1 -1
  79. data/app/views/fe/questions/fe/_question_grid.html.erb +14 -9
  80. data/app/views/fe/questions/fe/_question_grid_with_total.html.erb +21 -14
  81. data/app/views/fe/questions/fe/_questions.html.erb +2 -2
  82. data/app/views/fe/questions/fe/_radio_button_field.html.erb +12 -11
  83. data/app/views/fe/questions/fe/_rating.html.erb +9 -8
  84. data/app/views/fe/questions/fe/_reference_discipler.html.erb +1 -1
  85. data/app/views/fe/questions/fe/_reference_friend.html.erb +1 -1
  86. data/app/views/fe/questions/fe/_reference_parent.html.erb +1 -1
  87. data/app/views/fe/questions/fe/_reference_peer.html.erb +1 -1
  88. data/app/views/fe/questions/fe/_reference_question.html.erb +22 -15
  89. data/app/views/fe/questions/fe/_reference_roommate.html.erb +1 -1
  90. data/app/views/fe/questions/fe/_reference_spiritual.html.erb +1 -1
  91. data/app/views/fe/questions/fe/_reference_staff.html.erb +1 -1
  92. data/app/views/fe/questions/fe/_section.html.erb +1 -1
  93. data/app/views/fe/questions/fe/_text_area_field.html.erb +10 -3
  94. data/app/views/fe/questions/fe/_text_field.html.erb +1 -1
  95. data/app/views/fe/questions/fe/_yes_no_field.erb +3 -3
  96. data/app/views/fe/reference_pages/_reference.html.erb +11 -11
  97. data/app/views/fe/reference_pages/edit.html.erb +7 -7
  98. data/app/views/fe/reference_sheets/done.html.erb +2 -2
  99. data/app/views/fe/reference_sheets/not_found.html.erb +4 -4
  100. data/app/views/fe/references/edit.html.erb +6 -6
  101. data/app/views/fe/references/show.html.erb +7 -7
  102. data/app/views/fe/references/submit.js.erb +1 -1
  103. data/app/views/fe/submit_pages/_thankyou.html.erb +1 -1
  104. data/app/views/fe/submit_pages/edit.html.erb +9 -9
  105. data/app/views/layouts/fe/_error_messages_for.html.erb +7 -0
  106. data/app/views/layouts/fe/application.html.erb +1 -1
  107. data/config/routes.rb +0 -36
  108. data/db/migrate/20131003044250_create_reference_sheets.rb +1 -0
  109. data/db/migrate/20140623153424_create_fe_people.rb +1 -1
  110. data/db/migrate/20140624180246_create_fe_addresses.rb +1 -1
  111. data/db/migrate/20140624182216_create_fe_phone_numbers.rb +16 -0
  112. data/db/migrate/20140625160545_create_fe_users.rb +1 -1
  113. data/db/migrate/20150504221439_add_all_element_ids_to_pages.rb +5 -0
  114. data/db/migrate/20150713022326_add_locale_columns.rb +9 -0
  115. data/db/migrate/20150714220730_add_locale_to_answer_sheet.rb +5 -0
  116. data/db/migrate/20150928085325_change_pages_all_element_ids_to_text.rb +5 -0
  117. data/db/migrate/20150930191538_add_locale_to_reference_sheets.rb +5 -0
  118. data/lib/access_key_generator.rb +12 -0
  119. data/lib/distinct_distinct_patch.rb +20 -0
  120. data/lib/fe.rb +4 -0
  121. data/lib/fe/engine.rb +16 -4
  122. data/lib/fe/version.rb +1 -1
  123. data/spec/controllers/fe/admin/elements_controller_spec.rb +201 -1
  124. data/spec/controllers/fe/admin/email_templates_controller_spec.rb +26 -1
  125. data/spec/controllers/fe/admin/question_pages_controller_spec.rb +8 -1
  126. data/spec/controllers/fe/admin/question_sheets_controller_spec.rb +48 -1
  127. data/spec/controllers/fe/answer_pages_controller_spec.rb +73 -1
  128. data/spec/controllers/fe/answer_sheets_controller_spec.rb +80 -1
  129. data/spec/controllers/fe/reference_pages_controller.rb +4 -0
  130. data/spec/controllers/fe/references_controller_spec.rb +4 -0
  131. data/spec/controllers/fe/submit_pages_controller_spec.rb +4 -0
  132. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  133. data/spec/dummy/app/helpers/application_helper.rb +9 -0
  134. data/spec/dummy/app/models/application.rb +3 -0
  135. data/spec/dummy/app/models/person.rb +11 -0
  136. data/spec/dummy/app/models/user.rb +3 -0
  137. data/spec/dummy/config/application.rb +2 -1
  138. data/spec/dummy/config/database.yml +20 -17
  139. data/spec/dummy/config/environments/production.rb +1 -5
  140. data/spec/dummy/config/environments/test.rb +3 -1
  141. data/spec/dummy/config/initializers/fast_gettext.rb +5 -0
  142. data/spec/dummy/config/secrets.yml +2 -2
  143. data/spec/dummy/db/migrate/20141203214017_core.fe_engine.rb +92 -0
  144. data/spec/dummy/db/migrate/20141203214018_create_reference_sheets.fe_engine.rb +25 -0
  145. data/spec/dummy/db/migrate/20141203214019_add_element_and_answer_fields.fe_engine.rb +11 -0
  146. data/spec/dummy/db/migrate/20141203214020_create_email_templates.fe_engine.rb +18 -0
  147. data/spec/dummy/db/migrate/20141203214021_add_max_lengths.fe_engine.rb +9 -0
  148. data/spec/dummy/db/migrate/20141203214022_create_join_table.fe_engine.rb +12 -0
  149. data/spec/dummy/db/migrate/20141203214023_remove_question_id_from_element.fe_engine.rb +10 -0
  150. data/spec/dummy/db/migrate/20141203214024_create_fe_people.fe_engine.rb +13 -0
  151. data/spec/dummy/db/migrate/20141203214025_create_fe_addresses.fe_engine.rb +21 -0
  152. data/{db/migrate/20140624182216_create_create_fe_phone_numbers.rb → spec/dummy/db/migrate/20141203214026_create_create_fe_phone_numbers.fe_engine.rb} +1 -0
  153. data/spec/dummy/db/migrate/20141203214027_create_fe_users.fe_engine.rb +13 -0
  154. data/spec/dummy/db/migrate/20141203214028_add_conditional_type_to_elements.fe_engine.rb +6 -0
  155. data/spec/dummy/db/migrate/20141203214029_add_conditional_answer_to_elements.fe_engine.rb +6 -0
  156. data/spec/dummy/db/migrate/20141203214030_remove_short_value_column.fe_engine.rb +6 -0
  157. data/spec/dummy/db/migrate/20141203214031_move_conditional_ids_used_for_choice_field_to_their_own_column.fe_engine.rb +8 -0
  158. data/spec/dummy/db/migrate/20150123215803_create_users.rb +9 -0
  159. data/spec/dummy/db/migrate/20150504222619_add_all_element_ids_to_pages.fe_engine.rb +6 -0
  160. data/spec/dummy/db/migrate/20150930190001_create_fe_phone_numbers.fe_engine.rb +20 -0
  161. data/spec/dummy/db/migrate/20150930190002_add_locale_columns.fe_engine.rb +10 -0
  162. data/spec/dummy/db/migrate/20150930190003_add_locale_to_answer_sheet.fe_engine.rb +6 -0
  163. data/spec/dummy/db/migrate/20150930190004_change_pages_all_element_ids_to_text.fe_engine.rb +6 -0
  164. data/spec/dummy/db/migrate/20150930191756_add_locale_to_reference_sheets.fe_engine.rb +6 -0
  165. data/spec/dummy/db/schema.rb +50 -20
  166. data/spec/dummy/log/development.log +5 -0
  167. data/spec/factories/applications.rb +0 -1
  168. data/spec/factories/dummy_applications.rb +6 -0
  169. data/spec/factories/dummy_people.rb +6 -0
  170. data/spec/factories/dummy_users.rb +6 -0
  171. data/spec/factories/elements.rb +28 -3
  172. data/spec/factories/email_templates.rb +5 -0
  173. data/spec/factories/fe_email_templates.rb +9 -0
  174. data/spec/factories/fe_people.rb +0 -2
  175. data/spec/factories/fe_user.rb +6 -0
  176. data/spec/factories/question_sheet.rb +1 -1
  177. data/spec/factories/reference_sheets.rb +9 -0
  178. data/spec/mailers/fe/notifier_spec.rb +39 -0
  179. data/spec/models/fe/choice_field_spec.rb +20 -0
  180. data/spec/models/fe/element_spec.rb +185 -0
  181. data/spec/models/fe/page_spec.rb +112 -0
  182. data/spec/models/fe/question_sheet_spec.rb +106 -0
  183. data/spec/models/fe/reference_sheet_spec.rb +20 -0
  184. data/spec/rails_helper.rb +41 -13
  185. data/spec/support/choices.xml +6 -0
  186. metadata +136 -48
  187. data/app/assets/javascripts/fe/rails.extra.js +0 -6
  188. data/app/controllers/fe/applications_controller.rb +0 -183
  189. data/app/controllers/fe/payments_controller.rb +0 -184
  190. data/app/models/fe/payment.rb +0 -77
  191. data/app/models/fe/payment_question.rb +0 -22
  192. data/app/views/fe/admin/panels/_prop_payment_question.html.erb +0 -1
  193. data/app/views/fe/application/_logout.html.erb +0 -1
  194. data/app/views/fe/payment_pages/_credit.html.erb +0 -47
  195. data/app/views/fe/payment_pages/_mail.html.erb +0 -27
  196. data/app/views/fe/payment_pages/_payment.html.erb +0 -6
  197. data/app/views/fe/payment_pages/_staff.html.erb +0 -25
  198. data/app/views/fe/payment_pages/_staff_results.html.erb +0 -17
  199. data/app/views/fe/payment_pages/edit.html.erb +0 -75
  200. data/app/views/fe/payment_pages/staff_search.js.erb +0 -2
  201. data/app/views/fe/payments/_credit.html.erb +0 -47
  202. data/app/views/fe/payments/_errors.html.erb +0 -1
  203. data/app/views/fe/payments/_payment.html.erb +0 -13
  204. data/app/views/fe/payments/_staff.html.erb +0 -21
  205. data/app/views/fe/payments/_staff_results.html.erb +0 -18
  206. data/app/views/fe/payments/approve.js.erb +0 -3
  207. data/app/views/fe/payments/create.js.erb +0 -19
  208. data/app/views/fe/payments/destroy.js.erb +0 -7
  209. data/app/views/fe/payments/edit.html.erb +0 -56
  210. data/app/views/fe/payments/error.js.erb +0 -3
  211. data/app/views/fe/payments/no_access.html.erb +0 -7
  212. data/app/views/fe/payments/staff_search.js.erb +0 -1
  213. data/app/views/fe/payments/update.html.erb +0 -24
  214. data/app/views/fe/questions/fe/_payment_question.html.erb +0 -70
  215. data/db/migrate/20140828045339_create_payments.rb +0 -13
  216. data/spec/dummy/db/test.sqlite3 +0 -0
  217. data/spec/factories/payments.rb +0 -7
  218. data/spec/models/fe/payment_question_spec.rb +0 -65
@@ -0,0 +1,9 @@
1
+ FactoryGirl.define do
2
+ factory :reference_sheet, class: Fe::ReferenceSheet do
3
+ sequence(:email) { |n| "email_#{n}@email.com" }
4
+ sequence(:first_name) { |n| "fn_#{n}" }
5
+ sequence(:last_name) { |n| "ln_#{n}" }
6
+ sequence(:phone) { |n| "phone_#{n}" }
7
+ sequence(:relationship) { |n| "relationship_#{n}" }
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Fe::Notifier do
4
+ describe 'instructions' do
5
+ let(:user) { mock_model User, name: 'Lucas', email: 'lucas@email.com' }
6
+ let(:mail) { Fe::Notifier.notification('recipient@test.com', 'from@test.com', 'Staff Payment Request', {}, {format: 'html'}) }
7
+
8
+ before(:each) do
9
+ create(:fe_email_template, name: 'Staff Payment Request', subject: 'Staff Payment Request Subject', content: "<a href='test'>test</a>")
10
+ end
11
+
12
+ it 'renders the subject' do
13
+ expect(mail.subject).to eql('Staff Payment Request Subject')
14
+ end
15
+
16
+ it 'renders the receiver email' do
17
+ expect(mail.to).to eql(['recipient@test.com'])
18
+ end
19
+
20
+ it 'renders the sender email' do
21
+ expect(mail.from).to eql(['from@test.com'])
22
+ end
23
+
24
+ it 'sets the email to be an html email when format passed in is html' do
25
+ mail = Fe::Notifier.notification('recipient@test.com', 'from@test.com', 'Staff Payment Request', {}, {format: 'html'})
26
+ expect(mail[:content_type].to_s).to match(/text\/html/)
27
+ end
28
+
29
+ it 'sets the email to be a text email when text format is passed in' do
30
+ mail = Fe::Notifier.notification('recipient@test.com', 'from@test.com', 'Staff Payment Request', {}, {format: 'text'})
31
+ expect(mail[:content_type].to_s).to match(/text\/plain/)
32
+ end
33
+
34
+ it 'sets the email to be a text email when no format passed in' do
35
+ mail = Fe::Notifier.notification('recipient@test.com', 'from@test.com', 'Staff Payment Request', {}, {})
36
+ expect(mail[:content_type].to_s).to match(/text\/plain/)
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,5 @@
1
1
  require 'rails_helper'
2
+ require 'rexml/document'
2
3
 
3
4
  describe Fe::ChoiceField do
4
5
 
@@ -29,4 +30,23 @@ describe Fe::ChoiceField do
29
30
  end
30
31
  end
31
32
 
33
+ context '#choices' do
34
+ it 'should work for yes-no style' do
35
+ expect(Fe::ChoiceField.new(style: 'yes-no').choices).to eq([["Yes",1],["No",0]])
36
+ end
37
+ it 'should work for acceptance style' do
38
+ expect(Fe::ChoiceField.new(style: 'acceptance').choices).to eq([["Yes",1],["No",0]])
39
+ end
40
+ it 'should work for a local source using libxml' do
41
+ expect(Fe::ChoiceField.new(style: 'drop-down', source: 'spec/support/choices.xml', text_xpath: 'choice', value_xpath: 'value').choices).to eq([["A","1"],["B","0"]])
42
+ end
43
+ if RUBY_VERSION =~ /^2/
44
+ it 'should work for a remote source using rexml' do
45
+ expect(Fe::ChoiceField.new(style: 'drop-down', source: 'https://raw.githubusercontent.com/CruGlobal/qe/fe/spec/support/choices.xml', text_xpath: '*/choice', value_xpath: '*/value').choices).to eq([["A","1"],["B","0"]])
46
+ end
47
+ end
48
+ it 'should work for content set' do
49
+ expect(Fe::ChoiceField.new(style: 'drop-down', content: "1;A\n0;B").choices).to eq([["A","1"],["B","0"]])
50
+ end
51
+ end
32
52
  end
@@ -1,5 +1,12 @@
1
1
  require 'rails_helper'
2
2
 
3
+ # when using a decorator in the enclosing app I get an error, don't have the time to
4
+ # figure it out and since it's low priority since we're just testing, doing it here
5
+ # should be fine
6
+ Fe::Application.class_eval do
7
+ belongs_to :applicant, foreign_key: 'applicant_id', class_name: 'Person'
8
+ end
9
+
3
10
  describe Fe::Element do
4
11
  it { expect belong_to :question_grid }
5
12
  it { expect belong_to :choice_field }
@@ -10,6 +17,22 @@ describe Fe::Element do
10
17
  it { expect ensure_length_of :kind }
11
18
  it { expect ensure_length_of :style }
12
19
 
20
+ it "should not require an element with choice_field set that has a false value" do
21
+ question_sheet = FactoryGirl.create(:question_sheet_with_pages)
22
+ choice_field = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the enclosed element", conditional_type: "Fe::Element")
23
+ question_sheet.pages.reload
24
+ question_sheet.pages[3].elements << choice_field
25
+ element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer that will be hidden by the enclosing element", choice_field_id: choice_field.id, required: true)
26
+
27
+ application = FactoryGirl.create(:answer_sheet)
28
+
29
+ # make the answer to the conditional question 'no' so that the element is not required
30
+ choice_field.set_response("no", application)
31
+ choice_field.save_response(application)
32
+
33
+ expect(element.required?(application)).to be false
34
+ end
35
+
13
36
  it "should update a conditional question if added after that question" do
14
37
  question_sheet = FactoryGirl.create(:question_sheet_with_pages)
15
38
  conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element", conditional_type: "Fe::Element")
@@ -21,6 +44,32 @@ describe Fe::Element do
21
44
  expect(conditional_el.conditional).to eq(element)
22
45
  end
23
46
 
47
+ context "in a grid" do
48
+ it "should update a conditional question if added after that question" do
49
+ question_sheet = FactoryGirl.create(:question_sheet_with_pages)
50
+ question_grid = FactoryGirl.create(:question_grid)
51
+ question_sheet.pages.reload
52
+ question_sheet.pages[3].elements << question_grid
53
+
54
+ conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element", conditional_type: "Fe::Element", question_grid_id: question_grid.id)
55
+ element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer that will be hidden by the previous elemenet", conditional_type: nil, conditional_answer: nil, question_grid_id: question_grid.id)
56
+ expect(conditional_el.reload.conditional).to eq(element)
57
+ end
58
+
59
+ it "should update the condition element" do
60
+ question_sheet = FactoryGirl.create(:question_sheet_with_pages)
61
+ question_grid = FactoryGirl.create(:question_grid)
62
+ question_sheet.pages.reload
63
+ question_sheet.pages[3].elements << question_grid
64
+
65
+ conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element", conditional_type: "Fe::Element", question_grid_id: question_grid.id)
66
+ element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer that will be hidden by the previous elemenet", conditional_type: nil, conditional_answer: nil, question_grid_id: question_grid.id)
67
+
68
+ conditional_el.set_conditional_element
69
+ expect(conditional_el.conditional).to eq(element)
70
+ end
71
+ end
72
+
24
73
  it "should update a conditional question if elements are moved around" do
25
74
  question_sheet = FactoryGirl.create(:question_sheet_with_pages)
26
75
  conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element", conditional_type: "Fe::Element")
@@ -139,4 +188,140 @@ describe Fe::Element do
139
188
  # validate the hidden page, it should be marked complete because of being hidden
140
189
  expect(hide_page.complete?(application)).to eq(true)
141
190
  end
191
+
192
+ it "should return false for has_response?" do
193
+ element = Fe::Element.new
194
+ expect(element.has_response?).to be false
195
+ end
196
+
197
+ context '#limit' do
198
+ it "should return a value for a legitimate object_name and attribute_name" do
199
+ application = FactoryGirl.create(:application)
200
+ application.applicant_id = create(:fe_person).id
201
+ element = Fe::Element.new object_name: 'applicant', attribute_name: 'first_name'
202
+ expect(element.limit(application)).to_not be_nil
203
+ end
204
+ it "should return nil instead of crashing if there's an exception thrown" do
205
+ application = FactoryGirl.create(:application)
206
+ application.applicant_id = create(:fe_person).id
207
+ element = Fe::Element.new object_name: 'applicant', attribute_name: 'asdf'
208
+ expect(element.limit(application)).to be_nil
209
+ end
210
+ end
211
+
212
+ context '#previous_element' do
213
+ it "should work" do
214
+ application = FactoryGirl.create(:application)
215
+ application.applicant_id = create(:fe_person).id
216
+ element1 = create(:text_field_element)
217
+ element2 = create(:text_field_element)
218
+ element3 = create(:text_field_element)
219
+ page = create(:page)
220
+ create(:page_element, page_id: page.id, element_id: element1.id)
221
+ create(:page_element, page_id: page.id, element_id: element2.id)
222
+ create(:page_element, page_id: page.id, element_id: element3.id)
223
+ expect(element2.previous_element(page.question_sheet)).to eq(element1)
224
+ end
225
+ end
226
+
227
+ context '#required' do
228
+ it "should work when the required flag is set" do
229
+ # TODO
230
+ end
231
+ it "should not require a conditional element when its prev element isn't matching the answer text" do
232
+ application = FactoryGirl.create(:application)
233
+ application.applicant_id = create(:fe_person).id
234
+ element1 = create(:text_field_element)
235
+ element2 = create(:text_field_element, conditional_answer: 'test')
236
+ element3 = create(:text_field_element, required: true)
237
+ # set conditional element to element3 (note that an element's conditional ref will always either be a page or the *next* element, never any other element than the next one)
238
+ element2.conditional = element3
239
+ element2.save!
240
+
241
+ page = create(:page)
242
+ question_sheet = page.question_sheet
243
+ create(:page_element, page_id: page.id, element_id: element1.id)
244
+ create(:page_element, page_id: page.id, element_id: element2.id)
245
+ create(:page_element, page_id: page.id, element_id: element3.id)
246
+
247
+ # set up an answer sheet
248
+ application = FactoryGirl.create(:answer_sheet)
249
+ application.answer_sheet_question_sheet = FactoryGirl.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
250
+ application.answer_sheet_question_sheets.first.update_attributes(question_sheet_id: question_sheet.id)
251
+
252
+ # make the answer to the conditional question 'yes' so that the element shows up and is thus required
253
+ element2.set_response('nomatch', application)
254
+ element2.save_response(application)
255
+
256
+ expect(element3.required?(application)).to be false
257
+ end
258
+ end
259
+ context '#clone' do
260
+ it 'should duplicate question grid elements' do
261
+ element1 = create(:question_grid)
262
+ element2 = create(:text_field_element, question_grid_id: element1.id, position: 0) # added to grid
263
+ element3 = create(:text_field_element, question_grid_id: element1.id, position: 1) # added to grid
264
+ page = create(:page)
265
+ create(:page_element, page_id: page.id, element_id: element1.id)
266
+ expect {
267
+ element3.duplicate(page, element1)
268
+ }.to change{element1.reload.elements.count}.by(1) # added to grid
269
+ expect(element1.elements.last.position).to eq(2) # added to end of grid
270
+ expect(element1.elements.last.question_grid).to eq(element1) # added to the right grid
271
+ expect(element1.elements.last.pages).to eq([]) # not added to any pages
272
+ end
273
+ it 'should duplicate question' do
274
+ element1 = create(:question_grid)
275
+ element2 = create(:text_field_element)
276
+ element3 = create(:text_field_element)
277
+ page = create(:page)
278
+ create(:page_element, page_id: page.id, element_id: element1.id)
279
+ create(:page_element, page_id: page.id, element_id: element2.id)
280
+ create(:page_element, page_id: page.id, element_id: element3.id)
281
+ expect {
282
+ element3.duplicate(page)
283
+ }.to change{page.reload.elements.count}.by(1)
284
+ expect(page.page_elements.last.position).to eq(4)
285
+ expect(page.elements.last.question_grid).to be_nil
286
+ expect(page.elements.last.pages).to eq([page])
287
+ end
288
+ end
289
+
290
+ context '#update_page_all_element_ids' do
291
+ it 'should rebuild all_element_ids in all pages' do
292
+ element1 = create(:text_field_element)
293
+ page1 = create(:page)
294
+ page2 = create(:page)
295
+ create(:page_element, page_id: page1.id, element_id: element1.id)
296
+ create(:page_element, page_id: page2.id, element_id: element1.id)
297
+ page1.update_column(:all_element_ids, nil)
298
+ page2.update_column(:all_element_ids, nil)
299
+ element1.pages.reload
300
+ element1.update_page_all_element_ids
301
+ expect(page1.reload.all_element_ids).to eq("#{element1.id}")
302
+ expect(page2.reload.all_element_ids).to eq("#{element1.id}")
303
+ end
304
+ it 'should rebuild all_element_ids when adding a question grid' do
305
+ page = create(:page)
306
+ grid = create(:question_grid)
307
+ create(:page_element, page_id: page.id, element_id: grid.id)
308
+ grid.pages.reload
309
+ textfield = create(:text_field_element, question_grid: grid)
310
+
311
+ page.update_column(:all_element_ids, nil)
312
+ textfield.update_page_all_element_ids
313
+ expect(page.reload.all_element_ids).to eq("#{grid.id},#{textfield.id}")
314
+ end
315
+ it 'should rebuild all_element_ids when adding a question grid with total' do
316
+ page = create(:page)
317
+ grid = create(:question_grid)
318
+ create(:page_element, page_id: page.id, element_id: grid.id)
319
+ grid.pages.reload
320
+ textfield = create(:text_field_element, question_grid: grid)
321
+
322
+ page.update_column(:all_element_ids, nil)
323
+ textfield.update_page_all_element_ids
324
+ expect(page.reload.all_element_ids).to eq("#{grid.id},#{textfield.id}")
325
+ end
326
+ end
142
327
  end
@@ -33,6 +33,8 @@ describe Fe::Page do
33
33
 
34
34
  # validate the page -- the next element after the conditional should not be required
35
35
  page = question_sheet.pages[3]
36
+ question_sheet.pages.reload
37
+ page.reload
36
38
  expect(page.complete?(application)).to eq(true)
37
39
 
38
40
  # make the answer to the conditional question 'yes' so that the next element shows up and is thus required
@@ -43,4 +45,114 @@ describe Fe::Page do
43
45
  page = question_sheet.pages[3]
44
46
  expect(page.complete?(application)).to eq(false)
45
47
  end
48
+
49
+ context '#all_elements' do
50
+ it 'should return elements in the same order the ids were given' do
51
+ p = create(:page, all_element_ids: '2,1')
52
+ e1 = create(:text_field_element)
53
+ e2 = create(:text_field_element)
54
+ expect(p.all_elements).to eq([e2,e1])
55
+ end
56
+ it 'should include elements in a grid' do
57
+ p = create(:page)
58
+ e = create(:question_grid)
59
+ create(:page_element, page: p, element: e)
60
+ tf1 = create(:text_field_element, question_grid: e)
61
+
62
+ # add text field directly to page
63
+ tf2 = create(:text_field_element)
64
+ create(:page_element, page: p, element: tf2)
65
+
66
+ # add section to grid
67
+ section = create(:section, question_grid: e)
68
+
69
+ p.reload # get the updated all_element_ids column
70
+ expect(p.all_elements).to eq([e, tf1, section, tf2])
71
+ end
72
+ it 'should return an empty active record result set when no elements are added' do
73
+ p = create(:page)
74
+ expect(p.all_elements).to eq([])
75
+ end
76
+ it 'should rebuild_all_element_ids first when not set' do
77
+ p = create(:page)
78
+ p.all_elements
79
+ p.reload
80
+ expect(p.all_element_ids).to eq('')
81
+ end
82
+ end
83
+ context '#has_questions?' do
84
+ it 'should return true when there is a question directly on the page' do
85
+ p = create(:page)
86
+ e = create(:text_field_element)
87
+ create(:page_element, page: p, element: e)
88
+ expect(p.has_questions?).to be true
89
+ end
90
+ it 'should not count a non-question directly on the page' do
91
+ p = create(:page)
92
+ e = create(:section)
93
+ create(:page_element, page: p, element: e)
94
+ expect(p.has_questions?).to be false
95
+ end
96
+ it 'should return true when the only question is in a grid' do
97
+ p = create(:page)
98
+ e = create(:question_grid)
99
+ create(:page_element, page: p, element: e)
100
+ tf1 = create(:text_field_element, question_grid: e)
101
+ section = create(:section, question_grid: e)
102
+ p.reload # get the updated all_element_ids column
103
+ expect(p.has_questions?).to be true
104
+ end
105
+ it 'should not count a non-question inside a grid as a question' do
106
+ p = create(:page)
107
+ e = create(:question_grid)
108
+ create(:page_element, page: p, element: e)
109
+ section = create(:section, question_grid: e)
110
+ p.reload # get the updated all_element_ids column
111
+ expect(p.has_questions?).to be false
112
+ end
113
+ end
114
+ context '#all_questions' do
115
+ it 'should include elements in a grid with total' do
116
+ p = create(:page)
117
+ grid = create(:question_grid_with_total) # shouldn't be included in all_questions because it's a not a question
118
+ create(:page_element, page: p, element: grid, position: 1)
119
+ tf1 = create(:text_field_element, question_grid: grid)
120
+ tf2 = create(:text_field_element) # add directly to page
121
+ create(:page_element, page: p, element: tf2, position: 2)
122
+ section = create(:section, question_grid: grid) # shouldn't be included in all_questions because it's not a question
123
+ p.reload # get the updated all_element_ids column
124
+ expect(p.all_questions).to eq([tf1, tf2])
125
+ end
126
+ end
127
+ context '#rebuild_all_element_ids' do
128
+ it 'should include elements in a grid' do
129
+ p = create(:page)
130
+ e = create(:question_grid)
131
+ create(:page_element, page: p, element: e)
132
+ tf1 = create(:text_field_element, question_grid: e)
133
+ tf2 = create(:text_field_element) # add directly to page
134
+ create(:page_element, page: p, element: tf2)
135
+ section = create(:section, question_grid: e)
136
+ p.update_column :all_element_ids, nil
137
+ p.rebuild_all_element_ids
138
+ expect(p.all_element_ids).to eq("#{e.id},#{tf1.id},#{section.id},#{tf2.id}")
139
+ end
140
+ end
141
+ context '#all_element_ids' do
142
+ it 'should rebuild_all_element_ids first when not set' do
143
+ p = create(:page)
144
+ p.all_element_ids
145
+ p.reload
146
+ expect(p.all_element_ids).to eq('')
147
+ end
148
+ it 'should rebuild_all_element_ids when an element is removed from a page' do
149
+ p = create(:page)
150
+ e = create(:text_field_element, question_grid: e)
151
+ pe = create(:page_element, page: p, element: e)
152
+ expect(p.all_element_ids).to eq(e.id.to_s)
153
+ pe.destroy
154
+ p.reload
155
+ expect(p.all_element_ids).to eq('')
156
+ end
157
+ end
46
158
  end
@@ -5,4 +5,110 @@ describe Fe::QuestionSheet do
5
5
  it { expect have_many :answer_sheets }
6
6
  it { expect validate_presence_of :label }
7
7
  it { expect validate_uniqueness_of :label }
8
+
9
+ context '#questions_count' do
10
+ it 'should count elements in a grid' do
11
+ s = create(:question_sheet)
12
+ p = create(:page, question_sheet: s)
13
+ e = create(:question_grid)
14
+ create(:page_element, page: p, element: e)
15
+ create(:text_field_element, question_grid: e)
16
+ create(:section, question_grid: e) # this shouldn't get counted
17
+ p.reload # get the updated all_element_ids column
18
+ expect(s.questions_count).to eq(1)
19
+ end
20
+ end
21
+
22
+ context '#all_elements' do
23
+ it 'should return elements in the same order as the ids' do
24
+ s = create(:question_sheet)
25
+
26
+ # P1
27
+ p1 = create(:page, question_sheet: s)
28
+ tf1 = create(:text_field_element)
29
+ create(:page_element, page: p1, element: tf1)
30
+ tf2 = create(:text_field_element)
31
+ create(:page_element, page: p1, element: tf2)
32
+ p1.update_column(:all_element_ids, "#{tf2.id},#{tf1.id}")
33
+
34
+ # P2
35
+ p2 = create(:page, question_sheet: s)
36
+ tf3 = create(:text_field_element)
37
+ create(:page_element, page: p2, element: tf3)
38
+ tf4 = create(:text_field_element)
39
+ create(:page_element, page: p2, element: tf4)
40
+ p2.update_column(:all_element_ids, "#{tf4.id},#{tf3.id}")
41
+
42
+ p1.reload # get the updated all_element_ids column
43
+ p2.reload # get the updated all_element_ids column
44
+ expect(s.all_elements).to eq([tf2, tf1, tf4, tf3])
45
+ end
46
+
47
+ it 'should include elements in a grid' do
48
+ s = create(:question_sheet)
49
+ p = create(:page, question_sheet: s)
50
+ e = create(:question_grid)
51
+ create(:page_element, page: p, element: e)
52
+ tf1 = create(:text_field_element, question_grid: e)
53
+ tf2 = create(:text_field_element) # add directly to page
54
+ create(:page_element, page: p, element: tf2)
55
+ section = create(:section, question_grid: e)
56
+ p.reload # get the updated all_element_ids column
57
+ expect(s.all_elements).to eq([e, tf1, section, tf2])
58
+ end
59
+ it 'should include elements across multiple pages' do
60
+ s = create(:question_sheet)
61
+
62
+ # P1
63
+ p1 = create(:page, question_sheet: s)
64
+
65
+ # grid pg1
66
+ g1 = create(:question_grid)
67
+ create(:page_element, page: p1, element: g1)
68
+ tf1 = create(:text_field_element, question_grid: g1)
69
+ s1 = create(:section, question_grid: g1)
70
+
71
+ # tf added directly to pg1
72
+ tf2 = create(:text_field_element)
73
+ create(:page_element, page: p1, element: tf2)
74
+
75
+ # P2
76
+ p2 = create(:page, question_sheet: s)
77
+
78
+ # grid pg2
79
+ g2 = create(:question_grid)
80
+ create(:page_element, page: p2, element: g2)
81
+ tf3 = create(:text_field_element, question_grid: g2)
82
+ s2 = create(:section, question_grid: g2)
83
+
84
+ # tf added directly to pg2
85
+ tf4 = create(:text_field_element)
86
+ create(:page_element, page: p2, element: tf4)
87
+
88
+ p1.reload # get the updated all_element_ids column
89
+ p2.reload # get the updated all_element_ids column
90
+ expect(s.all_elements).to eq([g1, tf1, s1, tf2, g2, tf3, s2, tf4])
91
+ end
92
+ it 'should handle pages with no elements' do
93
+ qs = create(:question_sheet)
94
+ p = create(:page)
95
+ qs.pages.reload
96
+ expect(qs.all_elements).to eq([])
97
+ end
98
+ end
99
+
100
+ context '#elements' do
101
+ it 'should not include elements in a grid' do
102
+ s = create(:question_sheet)
103
+ p = create(:page, question_sheet: s)
104
+ e = create(:question_grid)
105
+ create(:page_element, page: p, element: e)
106
+ tf1 = create(:text_field_element, question_grid: e) # shouldn't be included because it's in grid
107
+ tf2 = create(:text_field_element)
108
+ create(:page_element, page: p, element: tf2)
109
+ create(:section, question_grid: e) # shouldn't be included because it's in grid
110
+ p.reload # get the updated all_element_ids column
111
+ expect(s.elements).to eq([e, tf2])
112
+ end
113
+ end
8
114
  end