fe 0.0.4 → 2.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 (456) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +4 -4
  3. data/Rakefile +16 -36
  4. data/app/assets/config/fe/manifest.js +3 -0
  5. data/app/assets/config/manifest.js +3 -0
  6. data/app/assets/javascripts/application.js.erb +1 -1
  7. data/app/assets/javascripts/fe/admin.js +0 -2
  8. data/app/assets/javascripts/fe/fe.admin.js +40 -20
  9. data/app/assets/javascripts/fe/fe.common.js.erb +98 -0
  10. data/app/assets/javascripts/fe/fe.public.js +2 -416
  11. data/app/assets/javascripts/fe/fe.public.nojquery.js.erb +526 -0
  12. data/app/assets/javascripts/fe/jquery.html5_upload.js +258 -0
  13. data/app/assets/javascripts/fe/jquery.validate.pack.js +3 -15
  14. data/app/assets/stylesheets/fe/fe.screen.css.scss.erb +90 -10
  15. data/app/assets/stylesheets/fe/validation.css +5 -1
  16. data/app/controllers/concerns/fe/admin/question_sheets_controller_concern.rb +111 -0
  17. data/app/controllers/concerns/fe/answer_pages_controller_concern.rb +131 -0
  18. data/app/controllers/{fe/concerns → concerns/fe}/answer_sheets_controller_concern.rb +15 -7
  19. data/app/controllers/{fe/concerns → concerns/fe}/application_controller_concern.rb +15 -2
  20. data/app/controllers/fe/admin/elements_controller.rb +102 -64
  21. data/app/controllers/fe/admin/email_templates_controller.rb +7 -7
  22. data/app/controllers/fe/admin/question_pages_controller.rb +9 -9
  23. data/app/controllers/fe/admin/question_sheets_controller.rb +2 -103
  24. data/app/controllers/fe/reference_pages_controller.rb +11 -11
  25. data/app/controllers/fe/reference_sheets_controller.rb +6 -4
  26. data/app/controllers/fe/references_controller.rb +20 -19
  27. data/app/controllers/fe/submit_pages_controller.rb +5 -5
  28. data/app/helpers/fe/answer_pages_helper.rb +1 -1
  29. data/app/helpers/fe/application_helper.rb +8 -3
  30. data/app/jobs/fe/update_reference_sheet_visibility_job.rb +11 -0
  31. data/app/mailers/fe/notifier.rb +12 -5
  32. data/app/models/answer_sheet.rb +2 -0
  33. data/app/models/application_record.rb +3 -0
  34. data/app/models/{fe/concerns → concerns/fe}/answer_concern.rb +2 -2
  35. data/app/models/{fe/concerns → concerns/fe}/answer_pages_presenter_concern.rb +15 -5
  36. data/app/models/concerns/fe/answer_sheet_concern.rb +125 -0
  37. data/app/models/{fe/concerns → concerns/fe}/choice_field_concern.rb +56 -31
  38. data/app/models/fe/address.rb +2 -2
  39. data/app/models/fe/answer.rb +1 -1
  40. data/app/models/fe/answer_sheet.rb +1 -1
  41. data/app/models/fe/answer_sheet_question_sheet.rb +2 -2
  42. data/app/models/fe/application.rb +15 -10
  43. data/app/models/fe/condition.rb +4 -4
  44. data/app/models/fe/date_field.rb +2 -2
  45. data/app/models/fe/element.rb +201 -45
  46. data/app/models/fe/email_address.rb +2 -2
  47. data/app/models/fe/email_template.rb +1 -1
  48. data/app/models/fe/page.rb +138 -31
  49. data/app/models/fe/page_element.rb +8 -3
  50. data/app/models/fe/page_link.rb +6 -3
  51. data/app/models/fe/paragraph.rb +1 -1
  52. data/app/models/fe/person.rb +16 -13
  53. data/app/models/fe/phone_number.rb +1 -1
  54. data/app/models/fe/question.rb +64 -44
  55. data/app/models/fe/question_grid.rb +16 -4
  56. data/app/models/fe/question_grid_with_total.rb +15 -0
  57. data/app/models/fe/question_set.rb +54 -14
  58. data/app/models/fe/question_sheet.rb +54 -19
  59. data/app/models/fe/reference_question.rb +9 -13
  60. data/app/models/fe/reference_sheet.rb +113 -54
  61. data/app/models/fe/state_chooser.rb +2 -2
  62. data/app/models/fe/text_field.rb +2 -2
  63. data/app/models/fe/user.rb +1 -1
  64. data/app/models/staff.rb +8 -6
  65. data/app/validators/email_validator.rb +11 -0
  66. data/app/views/fe/admin/elements/create.js.erb +4 -3
  67. data/app/views/fe/admin/elements/destroy.js.erb +1 -1
  68. data/app/views/fe/admin/elements/drop.js.erb +2 -1
  69. data/app/views/fe/admin/elements/duplicate.js.erb +2 -1
  70. data/app/views/fe/admin/elements/edit.js.erb +1 -1
  71. data/app/views/fe/admin/elements/error.js.erb +1 -1
  72. data/app/views/fe/admin/elements/new.js.erb +13 -6
  73. data/app/views/fe/admin/elements/update.js.erb +1 -1
  74. data/app/views/fe/admin/email_templates/_form.html.erb +3 -3
  75. data/app/views/fe/admin/email_templates/edit.html.erb +3 -3
  76. data/app/views/fe/admin/email_templates/index.html.erb +3 -3
  77. data/app/views/fe/admin/email_templates/new.html.erb +3 -3
  78. data/app/views/fe/admin/panels/_advanced_options.html.erb +16 -10
  79. data/app/views/fe/admin/panels/_common_boolean_fields.html.erb +1 -0
  80. data/app/views/fe/admin/panels/_common_boolean_fields_default.html.erb +11 -0
  81. data/app/views/fe/admin/panels/_common_fields.html.erb +18 -19
  82. data/app/views/fe/admin/panels/_condition.html.erb +1 -1
  83. data/app/views/fe/admin/panels/_insert.html.erb +25 -25
  84. data/app/views/fe/admin/panels/_nav_controls.html.erb +4 -4
  85. data/app/views/fe/admin/panels/_page.html.erb +2 -2
  86. data/app/views/fe/admin/panels/_pages_list.html.erb +3 -3
  87. data/app/views/fe/admin/panels/_prop_attachment_field.html.erb +2 -2
  88. data/app/views/fe/admin/panels/_prop_choice_field.html.erb +52 -24
  89. data/app/views/fe/admin/panels/_prop_date_field.html.erb +1 -1
  90. data/app/views/fe/admin/panels/_prop_element.html.erb +7 -14
  91. data/app/views/fe/admin/panels/_prop_page.html.erb +11 -6
  92. data/app/views/fe/admin/panels/_prop_paragraph.html.erb +38 -24
  93. data/app/views/fe/admin/panels/_prop_question_grid.html.erb +7 -2
  94. data/app/views/fe/admin/panels/_prop_question_grid_with_total.html.erb +2 -2
  95. data/app/views/fe/admin/panels/_prop_reference_question.html.erb +3 -3
  96. data/app/views/fe/admin/panels/_prop_section.html.erb +8 -2
  97. data/app/views/fe/admin/panels/_prop_sheet.html.erb +7 -4
  98. data/app/views/fe/admin/panels/_prop_text_field.html.erb +12 -12
  99. data/app/views/fe/admin/question_pages/_element.html.erb +16 -6
  100. data/app/views/fe/admin/question_pages/_element_show.html.erb +2 -2
  101. data/app/views/fe/admin/question_pages/_question_page.html.erb +4 -4
  102. data/app/views/fe/admin/question_pages/create.js.erb +3 -3
  103. data/app/views/fe/admin/question_pages/destroy.js.erb +3 -3
  104. data/app/views/fe/admin/question_pages/edit.js.erb +1 -1
  105. data/app/views/fe/admin/question_pages/error.js.erb +1 -1
  106. data/app/views/fe/admin/question_pages/show.js.erb +2 -2
  107. data/app/views/fe/admin/question_pages/show_panel.js.erb +1 -1
  108. data/app/views/fe/admin/question_pages/update.js.erb +1 -1
  109. data/app/views/fe/admin/question_sheets/edit.js.erb +1 -1
  110. data/app/views/fe/admin/question_sheets/error.js.erb +1 -1
  111. data/app/views/fe/admin/question_sheets/index.html.erb +8 -8
  112. data/app/views/fe/admin/question_sheets/new.html.erb +3 -3
  113. data/app/views/fe/admin/question_sheets/show.html.erb +5 -5
  114. data/app/views/fe/admin/question_sheets/update.js.erb +1 -1
  115. data/app/views/fe/answer_pages/_answer_page.html.erb +14 -14
  116. data/app/views/fe/answer_pages/_element.html.erb +25 -6
  117. data/app/views/fe/answer_pages/_page_name.html.erb +1 -0
  118. data/app/views/fe/answer_pages/show.html.erb +39 -0
  119. data/app/views/fe/answer_pages/update.js.erb +11 -3
  120. data/app/views/fe/answer_sheets/_answer_sheet.html.erb +6 -6
  121. data/app/views/fe/answer_sheets/_element.html.erb +55 -35
  122. data/app/views/fe/answer_sheets/_incomplete.html.erb +1 -1
  123. data/app/views/fe/answer_sheets/_page_link.html.erb +9 -7
  124. data/app/views/fe/answer_sheets/_pages_list.html.erb +4 -4
  125. data/app/views/fe/answer_sheets/_submit_to.html.erb +1 -0
  126. data/app/views/fe/answer_sheets/_title.html.erb +1 -1
  127. data/app/views/fe/answer_sheets/edit.html.erb +24 -24
  128. data/app/views/fe/answer_sheets/incomplete.js.erb +9 -3
  129. data/app/views/fe/answer_sheets/index.html.erb +3 -3
  130. data/app/views/fe/answer_sheets/show.html.erb +1 -1
  131. data/app/views/fe/applications/_logout.html.erb +1 -0
  132. data/app/views/fe/applications/show.html.erb +1 -0
  133. data/app/views/fe/questions/fe/_acceptance.html.erb +11 -10
  134. data/app/views/fe/questions/fe/_attachment_field.html.erb +133 -10
  135. data/app/views/fe/questions/fe/_checkbox_field.html.erb +34 -30
  136. data/app/views/fe/questions/fe/_country.html.erb +6 -6
  137. data/app/views/fe/questions/fe/_date_field.html.erb +5 -5
  138. data/app/views/fe/questions/fe/_date_field_mmyy.html.erb +8 -8
  139. data/app/views/fe/questions/fe/_drop_down_field.html.erb +7 -6
  140. data/app/views/fe/questions/fe/_paragraph.html.erb +1 -1
  141. data/app/views/fe/questions/fe/_question_grid.html.erb +21 -16
  142. data/app/views/fe/questions/fe/_question_grid_with_total.html.erb +25 -18
  143. data/app/views/fe/questions/fe/_questions.html.erb +11 -5
  144. data/app/views/fe/questions/fe/_radio_button_field.html.erb +42 -25
  145. data/app/views/fe/questions/fe/_rating.html.erb +57 -18
  146. data/app/views/fe/questions/fe/_reference_discipler.html.erb +1 -1
  147. data/app/views/fe/questions/fe/_reference_friend.html.erb +1 -1
  148. data/app/views/fe/questions/fe/_reference_parent.html.erb +1 -1
  149. data/app/views/fe/questions/fe/_reference_peer.html.erb +1 -1
  150. data/app/views/fe/questions/fe/_reference_question.html.erb +44 -21
  151. data/app/views/fe/questions/fe/_reference_roommate.html.erb +1 -1
  152. data/app/views/fe/questions/fe/_reference_spiritual.html.erb +1 -1
  153. data/app/views/fe/questions/fe/_reference_staff.html.erb +1 -1
  154. data/app/views/fe/questions/fe/_section.html.erb +1 -1
  155. data/app/views/fe/questions/fe/_state_chooser.html.erb +6 -6
  156. data/app/views/fe/questions/fe/_text_area_field.html.erb +17 -6
  157. data/app/views/fe/questions/fe/_text_field.html.erb +7 -6
  158. data/app/views/fe/questions/fe/_yes_no.html.erb +8 -8
  159. data/app/views/fe/questions/fe/_yes_no_field.erb +12 -9
  160. data/app/views/fe/reference_pages/_reference.html.erb +15 -15
  161. data/app/views/fe/reference_pages/edit.html.erb +9 -9
  162. data/app/views/fe/reference_sheets/done.html.erb +2 -2
  163. data/app/views/fe/reference_sheets/not_found.html.erb +4 -4
  164. data/app/views/fe/references/edit.html.erb +6 -6
  165. data/app/views/fe/references/show.html.erb +8 -8
  166. data/app/views/fe/references/submit.js.erb +3 -3
  167. data/app/views/fe/submit_pages/_thankyou.html.erb +1 -1
  168. data/app/views/fe/submit_pages/edit.html.erb +12 -12
  169. data/app/views/fe/submit_pages/error.js.erb +1 -1
  170. data/app/views/fe/submit_pages/submit.js.erb +2 -2
  171. data/app/views/layouts/fe/_error_messages_for.html.erb +7 -0
  172. data/app/views/layouts/fe/application.html.erb +4 -5
  173. data/app/views/layouts/fe/fe_admin.html.erb +30 -0
  174. data/app/views.current/fe/admin/elements/_errors.html.erb +11 -0
  175. data/app/views.current/fe/admin/elements/create.js.erb +12 -0
  176. data/app/views.current/fe/admin/elements/destroy.js.erb +4 -0
  177. data/app/views.current/fe/admin/elements/drop.js.erb +3 -0
  178. data/app/views.current/fe/admin/elements/duplicate.js.erb +3 -0
  179. data/app/views.current/fe/admin/elements/edit.js.erb +4 -0
  180. data/app/views.current/fe/admin/elements/error.js.erb +4 -0
  181. data/app/views.current/fe/admin/elements/new.js.erb +17 -0
  182. data/app/views.current/fe/admin/elements/reorder.js.erb +0 -0
  183. data/app/views.current/fe/admin/elements/update.js.erb +9 -0
  184. data/app/views.current/fe/admin/email_templates/_form.html.erb +8 -0
  185. data/app/views.current/fe/admin/email_templates/edit.html.erb +13 -0
  186. data/app/views.current/fe/admin/email_templates/index.html.erb +20 -0
  187. data/app/views.current/fe/admin/email_templates/new.html.erb +11 -0
  188. data/app/views.current/fe/admin/panels/_advanced_options.html.erb +49 -0
  189. data/app/views.current/fe/admin/panels/_common_boolean_fields.html.erb +1 -0
  190. data/app/views.current/fe/admin/panels/_common_boolean_fields_default.html.erb +11 -0
  191. data/app/views.current/fe/admin/panels/_common_fields.html.erb +23 -0
  192. data/app/views.current/fe/admin/panels/_condition.html.erb +6 -0
  193. data/app/views.current/fe/admin/panels/_insert.html.erb +39 -0
  194. data/app/views.current/fe/admin/panels/_nav_controls.html.erb +6 -0
  195. data/app/views.current/fe/admin/panels/_page.html.erb +3 -0
  196. data/app/views.current/fe/admin/panels/_pages_list.html.erb +16 -0
  197. data/app/views.current/fe/admin/panels/_prop_attachment_field.html.erb +2 -0
  198. data/app/views.current/fe/admin/panels/_prop_choice_field.html.erb +74 -0
  199. data/app/views.current/fe/admin/panels/_prop_date_field.html.erb +7 -0
  200. data/app/views.current/fe/admin/panels/_prop_element.html.erb +23 -0
  201. data/app/views.current/fe/admin/panels/_prop_page.html.erb +26 -0
  202. data/app/views.current/fe/admin/panels/_prop_paragraph.html.erb +46 -0
  203. data/app/views.current/fe/admin/panels/_prop_question_grid.html.erb +28 -0
  204. data/app/views.current/fe/admin/panels/_prop_question_grid_with_total.html.erb +14 -0
  205. data/app/views.current/fe/admin/panels/_prop_reference_question.html.erb +12 -0
  206. data/app/views.current/fe/admin/panels/_prop_section.html.erb +8 -0
  207. data/app/views.current/fe/admin/panels/_prop_sheet.html.erb +20 -0
  208. data/app/views.current/fe/admin/panels/_prop_text_field.html.erb +20 -0
  209. data/app/views.current/fe/admin/question_pages/_element.html.erb +28 -0
  210. data/app/views.current/fe/admin/question_pages/_element_show.html.erb +10 -0
  211. data/app/views.current/fe/admin/question_pages/_errors.html.erb +10 -0
  212. data/app/views.current/fe/admin/question_pages/_question_page.html.erb +13 -0
  213. data/app/views.current/fe/admin/question_pages/create.js.erb +11 -0
  214. data/app/views.current/fe/admin/question_pages/destroy.js.erb +5 -0
  215. data/app/views.current/fe/admin/question_pages/edit.js.erb +3 -0
  216. data/app/views.current/fe/admin/question_pages/error.js.erb +4 -0
  217. data/app/views.current/fe/admin/question_pages/show.js.erb +9 -0
  218. data/app/views.current/fe/admin/question_pages/show_panel.js.erb +3 -0
  219. data/app/views.current/fe/admin/question_pages/update.js.erb +2 -0
  220. data/app/views.current/fe/admin/question_sheets/_errors.html.erb +11 -0
  221. data/app/views.current/fe/admin/question_sheets/edit.js.erb +3 -0
  222. data/app/views.current/fe/admin/question_sheets/error.js.erb +5 -0
  223. data/app/views.current/fe/admin/question_sheets/index.html.erb +41 -0
  224. data/app/views.current/fe/admin/question_sheets/new.html.erb +15 -0
  225. data/app/views.current/fe/admin/question_sheets/show.html.erb +27 -0
  226. data/app/views.current/fe/admin/question_sheets/update.js.erb +2 -0
  227. data/app/views.current/fe/answer_pages/_answer_page.html.erb +53 -0
  228. data/app/views.current/fe/answer_pages/_element.html.erb +32 -0
  229. data/app/views.current/fe/answer_pages/_page_name.html.erb +1 -0
  230. data/app/views.current/fe/answer_pages/show.html.erb +39 -0
  231. data/app/views.current/fe/answer_pages/update.js.erb +13 -0
  232. data/app/views.current/fe/answer_sheets/_answer_sheet.html.erb +26 -0
  233. data/app/views.current/fe/answer_sheets/_element.html.erb +74 -0
  234. data/app/views.current/fe/answer_sheets/_incomplete.html.erb +10 -0
  235. data/app/views.current/fe/answer_sheets/_page_link.html.erb +9 -0
  236. data/app/views.current/fe/answer_sheets/_pages_list.html.erb +11 -0
  237. data/app/views.current/fe/answer_sheets/_submit_to.html.erb +1 -0
  238. data/app/views.current/fe/answer_sheets/_title.html.erb +1 -0
  239. data/app/views.current/fe/answer_sheets/edit.html.erb +66 -0
  240. data/app/views.current/fe/answer_sheets/incomplete.js.erb +11 -0
  241. data/app/views.current/fe/answer_sheets/index.html.erb +18 -0
  242. data/app/views.current/fe/answer_sheets/send_reference_invite.js.erb +8 -0
  243. data/app/views.current/fe/answer_sheets/show.html.erb +13 -0
  244. data/app/views.current/fe/applications/_logout.html.erb +1 -0
  245. data/app/views.current/fe/applications/show.html.erb +1 -0
  246. data/app/views.current/fe/help/builder.html +33 -0
  247. data/app/views.current/fe/help/question_grid.html +18 -0
  248. data/app/views.current/fe/questions/fe/_acceptance.html.erb +14 -0
  249. data/app/views.current/fe/questions/fe/_attachment_field.html.erb +165 -0
  250. data/app/views.current/fe/questions/fe/_checkbox_field.html.erb +53 -0
  251. data/app/views.current/fe/questions/fe/_country.html.erb +7 -0
  252. data/app/views.current/fe/questions/fe/_date_field.html.erb +7 -0
  253. data/app/views.current/fe/questions/fe/_date_field_mmyy.html.erb +9 -0
  254. data/app/views.current/fe/questions/fe/_drop_down_field.html.erb +8 -0
  255. data/app/views.current/fe/questions/fe/_paragraph.html.erb +1 -0
  256. data/app/views.current/fe/questions/fe/_question_grid.html.erb +70 -0
  257. data/app/views.current/fe/questions/fe/_question_grid_with_total.html.erb +64 -0
  258. data/app/views.current/fe/questions/fe/_questions.html.erb +15 -0
  259. data/app/views.current/fe/questions/fe/_radio_button_field.html.erb +60 -0
  260. data/app/views.current/fe/questions/fe/_rating.html.erb +64 -0
  261. data/app/views.current/fe/questions/fe/_reference_discipler.html.erb +1 -0
  262. data/app/views.current/fe/questions/fe/_reference_friend.html.erb +1 -0
  263. data/app/views.current/fe/questions/fe/_reference_parent.html.erb +1 -0
  264. data/app/views.current/fe/questions/fe/_reference_peer.html.erb +1 -0
  265. data/app/views.current/fe/questions/fe/_reference_question.html.erb +61 -0
  266. data/app/views.current/fe/questions/fe/_reference_roommate.html.erb +1 -0
  267. data/app/views.current/fe/questions/fe/_reference_spiritual.html.erb +1 -0
  268. data/app/views.current/fe/questions/fe/_reference_staff.html.erb +1 -0
  269. data/app/views.current/fe/questions/fe/_section.html.erb +1 -0
  270. data/app/views.current/fe/questions/fe/_state_chooser.html.erb +7 -0
  271. data/app/views.current/fe/questions/fe/_text_area_field.html.erb +17 -0
  272. data/app/views.current/fe/questions/fe/_text_field.html.erb +9 -0
  273. data/app/views.current/fe/questions/fe/_yes_no.html.erb +17 -0
  274. data/app/views.current/fe/questions/fe/_yes_no_field.erb +20 -0
  275. data/app/views.current/fe/reference_pages/_reference.html.erb +31 -0
  276. data/app/views.current/fe/reference_pages/edit.html.erb +24 -0
  277. data/app/views.current/fe/reference_sheets/done.html.erb +2 -0
  278. data/app/views.current/fe/reference_sheets/not_found.html.erb +5 -0
  279. data/app/views.current/fe/reference_sheets/submitted.js.erb +1 -0
  280. data/app/views.current/fe/references/edit.html.erb +8 -0
  281. data/app/views.current/fe/references/send_invite.js.erb +7 -0
  282. data/app/views.current/fe/references/show.html.erb +18 -0
  283. data/app/views.current/fe/references/submit.js.erb +3 -0
  284. data/app/views.current/fe/submit_pages/_errors.html.erb +1 -0
  285. data/app/views.current/fe/submit_pages/_thankyou.html.erb +2 -0
  286. data/app/views.current/fe/submit_pages/edit.html.erb +36 -0
  287. data/app/views.current/fe/submit_pages/error.js.erb +1 -0
  288. data/app/views.current/fe/submit_pages/submit.js.erb +3 -0
  289. data/app/views.current/layouts/fe/_error_messages_for.html.erb +7 -0
  290. data/app/views.current/layouts/fe/application.html.erb +47 -0
  291. data/app/{views/layouts/fe/fe.admin.html.erb → views.current/layouts/fe/fe_admin.html.erb} +4 -4
  292. data/config/initializers/paper_trail.rb +3 -0
  293. data/config/routes.rb +3 -37
  294. data/db/migrate/20131003041856_core.rb +23 -23
  295. data/db/migrate/20131003044250_create_reference_sheets.rb +2 -1
  296. data/db/migrate/20131003044436_add_element_and_answer_fields.rb +3 -3
  297. data/db/migrate/20131003044518_create_email_templates.rb +2 -2
  298. data/db/migrate/20131003044621_add_max_lengths.rb +1 -1
  299. data/db/migrate/20131003044714_create_join_table.rb +1 -1
  300. data/db/migrate/20131016162128_remove_question_id_from_element.rb +1 -1
  301. data/db/migrate/20140623153424_create_fe_people.rb +2 -2
  302. data/db/migrate/20140624180246_create_fe_addresses.rb +2 -2
  303. data/db/migrate/{20140624182216_create_create_fe_phone_numbers.rb → 20140624182216_create_fe_phone_numbers.rb} +2 -2
  304. data/db/migrate/20140625160545_create_fe_users.rb +2 -2
  305. data/db/migrate/20140808202507_add_conditional_type_to_elements.rb +1 -1
  306. data/db/migrate/20140808203609_add_conditional_answer_to_elements.rb +1 -1
  307. data/db/migrate/20141103204704_remove_short_value_column.rb +1 -1
  308. data/db/migrate/20141109154522_move_conditional_ids_used_for_choice_field_to_their_own_column.rb +1 -1
  309. data/db/migrate/20150504221439_add_all_element_ids_to_pages.rb +5 -0
  310. data/db/migrate/20150713022326_add_locale_columns.rb +9 -0
  311. data/db/migrate/20150714220730_add_locale_to_answer_sheet.rb +5 -0
  312. data/db/migrate/20150925181652_add_share_to_elements.rb +5 -0
  313. data/db/migrate/20150928085325_change_pages_all_element_ids_to_text.rb +5 -0
  314. data/db/migrate/20150930191538_add_locale_to_reference_sheets.rb +5 -0
  315. data/db/migrate/20151021181928_switch_conditional_answer_separator_to_semicolon.rb +7 -0
  316. data/db/migrate/20151021184250_add_question_sheet_id_in_refs.rb +12 -0
  317. data/db/migrate/20160201185838_add_visible_and_visibility_cache_key_to_reference_sheets.rb +6 -0
  318. data/db/migrate/20160805221415_add_rating_extra_labels.rb +10 -0
  319. data/db/migrate/20181108201746_create_versions.rb +80 -0
  320. data/db/migrate/20181218201130_increase_slug_length.rb +5 -0
  321. data/lib/access_key_generator.rb +12 -0
  322. data/lib/distinct_distinct_patch.rb +20 -0
  323. data/lib/fe/engine.rb +26 -14
  324. data/lib/fe/version.rb +1 -1
  325. data/lib/fe.rb +11 -1
  326. data/spec/controllers/fe/admin/elements_controller_spec.rb +211 -1
  327. data/spec/controllers/fe/admin/email_templates_controller_spec.rb +26 -1
  328. data/spec/controllers/fe/admin/question_pages_controller_spec.rb +8 -1
  329. data/spec/controllers/fe/admin/question_sheets_controller_spec.rb +48 -1
  330. data/spec/controllers/fe/answer_pages_controller_spec.rb +129 -1
  331. data/spec/controllers/fe/answer_sheets_controller_spec.rb +136 -1
  332. data/spec/controllers/fe/reference_pages_controller.rb +4 -0
  333. data/spec/controllers/fe/references_controller_spec.rb +4 -0
  334. data/spec/controllers/fe/submit_pages_controller_spec.rb +4 -0
  335. data/spec/dummy/app/assets/config/manifest.js +0 -0
  336. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  337. data/spec/dummy/app/helpers/application_helper.rb +9 -0
  338. data/spec/dummy/app/models/application.rb +3 -0
  339. data/spec/dummy/app/models/person.rb +11 -0
  340. data/spec/dummy/app/models/user.rb +3 -0
  341. data/spec/dummy/app/views/layouts/application.html.erb +2 -2
  342. data/spec/dummy/config/application.rb +3 -1
  343. data/spec/dummy/config/database.yml +20 -17
  344. data/spec/dummy/config/environments/production.rb +1 -5
  345. data/spec/dummy/config/environments/test.rb +4 -2
  346. data/spec/dummy/config/initializers/assets.rb +5 -2
  347. data/spec/dummy/config/initializers/fast_gettext.rb +5 -0
  348. data/spec/dummy/config/initializers/to_unsafe_h.rb +5 -0
  349. data/spec/dummy/config/initializers/to_unsafe_h.rb.new +5 -0
  350. data/spec/dummy/config/secrets.yml +2 -2
  351. data/spec/dummy/db/migrate/20141203214017_core.fe_engine.rb +92 -0
  352. data/spec/dummy/db/migrate/20141203214018_create_reference_sheets.fe_engine.rb +25 -0
  353. data/spec/dummy/db/migrate/20141203214019_add_element_and_answer_fields.fe_engine.rb +11 -0
  354. data/spec/dummy/db/migrate/20141203214020_create_email_templates.fe_engine.rb +18 -0
  355. data/spec/dummy/db/migrate/20141203214021_add_max_lengths.fe_engine.rb +9 -0
  356. data/spec/dummy/db/migrate/20141203214022_create_join_table.fe_engine.rb +12 -0
  357. data/spec/dummy/db/migrate/20141203214023_remove_question_id_from_element.fe_engine.rb +10 -0
  358. data/spec/dummy/db/migrate/20141203214024_create_fe_people.fe_engine.rb +13 -0
  359. data/spec/dummy/db/migrate/20141203214025_create_fe_addresses.fe_engine.rb +21 -0
  360. data/spec/dummy/db/migrate/20141203214027_create_fe_users.fe_engine.rb +13 -0
  361. data/spec/dummy/db/migrate/20141203214028_add_conditional_type_to_elements.fe_engine.rb +6 -0
  362. data/spec/dummy/db/migrate/20141203214029_add_conditional_answer_to_elements.fe_engine.rb +6 -0
  363. data/spec/dummy/db/migrate/20141203214030_remove_short_value_column.fe_engine.rb +6 -0
  364. data/spec/dummy/db/migrate/20141203214031_move_conditional_ids_used_for_choice_field_to_their_own_column.fe_engine.rb +8 -0
  365. data/spec/dummy/db/migrate/20150123215803_create_users.rb +9 -0
  366. data/spec/dummy/db/migrate/20150504222619_add_all_element_ids_to_pages.fe_engine.rb +6 -0
  367. data/spec/dummy/db/migrate/20150925192557_add_share_to_elements.fe_engine.rb +6 -0
  368. data/spec/dummy/db/migrate/20150930190001_create_fe_phone_numbers.fe_engine.rb +20 -0
  369. data/spec/dummy/db/migrate/20150930190002_add_locale_columns.fe_engine.rb +10 -0
  370. data/spec/dummy/db/migrate/20150930190003_add_locale_to_answer_sheet.fe_engine.rb +6 -0
  371. data/spec/dummy/db/migrate/20150930190004_change_pages_all_element_ids_to_text.fe_engine.rb +6 -0
  372. data/spec/dummy/db/migrate/20150930191756_add_locale_to_reference_sheets.fe_engine.rb +6 -0
  373. data/spec/dummy/db/migrate/20151021190027_add_question_sheet_id_in_refs.fe_engine.rb +13 -0
  374. data/spec/dummy/db/migrate/20160204164612_switch_conditional_answer_separator_to_semicolon.fe_engine.rb +8 -0
  375. data/spec/dummy/db/migrate/20160204164613_add_visible_and_visibility_cache_key_to_reference_sheets.fe_engine.rb +7 -0
  376. data/spec/dummy/db/migrate/20181108201746_create_versions.rb +80 -0
  377. data/spec/dummy/db/schema.rb +91 -69
  378. data/spec/dummy/log/test.log +101278 -419
  379. data/spec/factories/answer_sheet_question_sheets.rb +1 -1
  380. data/spec/factories/answer_sheets.rb +2 -2
  381. data/spec/factories/answers.rb +1 -1
  382. data/spec/factories/applications.rb +3 -4
  383. data/spec/factories/dummy_applications.rb +6 -0
  384. data/spec/factories/dummy_people.rb +6 -0
  385. data/spec/factories/dummy_users.rb +6 -0
  386. data/spec/factories/elements.rb +35 -10
  387. data/spec/factories/email_templates.rb +5 -0
  388. data/spec/factories/fe_addresses.rb +10 -10
  389. data/spec/factories/fe_email_addresses.rb +3 -3
  390. data/spec/factories/fe_email_templates.rb +9 -0
  391. data/spec/factories/fe_people.rb +5 -7
  392. data/spec/factories/fe_phone_numbers.rb +3 -3
  393. data/spec/factories/fe_user.rb +6 -0
  394. data/spec/factories/page.rb +1 -1
  395. data/spec/factories/page_elements.rb +1 -1
  396. data/spec/factories/paragraphs.rb +1 -1
  397. data/spec/factories/question_sheet.rb +3 -3
  398. data/spec/factories/reference_questions.rb +1 -1
  399. data/spec/factories/reference_sheets.rb +9 -0
  400. data/spec/jobs/fe/update_reference_sheet_visibility_job_spec.rb +40 -0
  401. data/spec/mailers/fe/notifier_spec.rb +39 -0
  402. data/spec/models/fe/answer_sheet_question_sheet_spec.rb +1 -1
  403. data/spec/models/fe/answer_spec.rb +2 -2
  404. data/spec/models/fe/application_spec.rb +94 -1
  405. data/spec/models/fe/choice_field_spec.rb +66 -0
  406. data/spec/models/fe/condition_spec.rb +2 -2
  407. data/spec/models/fe/element_spec.rb +414 -37
  408. data/spec/models/fe/email_template_spec.rb +1 -1
  409. data/spec/models/fe/page_element_spec.rb +1 -1
  410. data/spec/models/fe/page_spec.rb +168 -11
  411. data/spec/models/fe/person_spec.rb +1 -1
  412. data/spec/models/fe/question_set_spec.rb +91 -0
  413. data/spec/models/fe/question_sheet_spec.rb +103 -1
  414. data/spec/models/fe/question_spec.rb +73 -6
  415. data/spec/models/fe/reference_question_spec.rb +20 -0
  416. data/spec/models/fe/reference_sheet_spec.rb +305 -2
  417. data/spec/models/fe/text_field_spec.rb +22 -0
  418. data/spec/rails_helper.rb +85 -54
  419. data/spec/support/choices.xml +6 -0
  420. metadata +310 -84
  421. data/app/assets/javascripts/fe/fe.common.js +0 -57
  422. data/app/assets/javascripts/fe/jquery.scrollTo-min.js +0 -7
  423. data/app/assets/javascripts/fe/rails.extra.js +0 -6
  424. data/app/controllers/fe/applications_controller.rb +0 -183
  425. data/app/controllers/fe/concerns/answer_pages_controller_concern.rb +0 -83
  426. data/app/controllers/fe/payments_controller.rb +0 -184
  427. data/app/models/fe/concerns/answer_sheet_concern.rb +0 -55
  428. data/app/models/fe/payment.rb +0 -77
  429. data/app/models/fe/payment_question.rb +0 -22
  430. data/app/views/fe/admin/panels/_prop_payment_question.html.erb +0 -1
  431. data/app/views/fe/application/_logout.html.erb +0 -1
  432. data/app/views/fe/payment_pages/_credit.html.erb +0 -47
  433. data/app/views/fe/payment_pages/_mail.html.erb +0 -27
  434. data/app/views/fe/payment_pages/_payment.html.erb +0 -6
  435. data/app/views/fe/payment_pages/_staff.html.erb +0 -25
  436. data/app/views/fe/payment_pages/_staff_results.html.erb +0 -17
  437. data/app/views/fe/payment_pages/edit.html.erb +0 -75
  438. data/app/views/fe/payment_pages/staff_search.js.erb +0 -2
  439. data/app/views/fe/payments/_credit.html.erb +0 -47
  440. data/app/views/fe/payments/_errors.html.erb +0 -1
  441. data/app/views/fe/payments/_payment.html.erb +0 -13
  442. data/app/views/fe/payments/_staff.html.erb +0 -21
  443. data/app/views/fe/payments/_staff_results.html.erb +0 -18
  444. data/app/views/fe/payments/approve.js.erb +0 -3
  445. data/app/views/fe/payments/create.js.erb +0 -19
  446. data/app/views/fe/payments/destroy.js.erb +0 -7
  447. data/app/views/fe/payments/edit.html.erb +0 -56
  448. data/app/views/fe/payments/error.js.erb +0 -3
  449. data/app/views/fe/payments/no_access.html.erb +0 -7
  450. data/app/views/fe/payments/staff_search.js.erb +0 -1
  451. data/app/views/fe/payments/update.html.erb +0 -24
  452. data/app/views/fe/questions/fe/_payment_question.html.erb +0 -70
  453. data/db/migrate/20140828045339_create_payments.rb +0 -13
  454. data/spec/dummy/db/test.sqlite3 +0 -0
  455. data/spec/factories/payments.rb +0 -7
  456. data/spec/models/fe/payment_question_spec.rb +0 -65
@@ -1,34 +1,85 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe Fe::Element do
4
- it { expect belong_to :question_grid }
5
- it { expect belong_to :choice_field }
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
+
10
+ describe Fe::Element, type: :model do
11
+ it { expect belong_to :question_grid }
12
+ it { expect belong_to :choice_field }
6
13
  it { expect have_many :page_elements }
7
14
  it { expect have_many :pages }
8
15
  it { expect validate_presence_of :kind }
9
16
  # it { expect validate_presence_of :style } # this isn't working
10
- it { expect ensure_length_of :kind }
11
- it { expect ensure_length_of :style }
17
+ it { expect validate_length_of :kind }
18
+ it { expect validate_length_of :style }
19
+
20
+ it "should not require an element with choice_field set that has a false value" do
21
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
22
+ choice_field = FactoryBot.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 = FactoryBot.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
+ question_sheet.pages[3].elements << element
27
+
28
+ application = FactoryBot.create(:answer_sheet)
29
+ application.question_sheets << question_sheet
30
+
31
+ # make the answer to the conditional question 'no' so that the element is not required
32
+ choice_field.set_response("no", application)
33
+ choice_field.save_response(application)
34
+
35
+ expect(element.required?(application)).to be false
36
+ end
12
37
 
13
38
  it "should update a conditional question if added after that question" do
14
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
15
- 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")
39
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
40
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element", conditional_type: "Fe::Element")
16
41
  question_sheet.pages.reload
17
42
  question_sheet.pages[3].elements << conditional_el
18
- 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)
43
+ element = FactoryBot.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)
19
44
  question_sheet.pages[3].elements << element
20
45
  conditional_el.reload
21
46
  expect(conditional_el.conditional).to eq(element)
22
47
  end
23
48
 
49
+ context "in a grid" do
50
+ it "should update a conditional question if added after that question" do
51
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
52
+ question_grid = FactoryBot.create(:question_grid)
53
+ question_sheet.pages.reload
54
+ question_sheet.pages[3].elements << question_grid
55
+
56
+ conditional_el = FactoryBot.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)
57
+ element = FactoryBot.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)
58
+ expect(conditional_el.reload.conditional).to eq(element)
59
+ end
60
+
61
+ it "should update the condition element" do
62
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
63
+ question_grid = FactoryBot.create(:question_grid)
64
+ question_sheet.pages.reload
65
+ question_sheet.pages[3].elements << question_grid
66
+
67
+ conditional_el = FactoryBot.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)
68
+ element = FactoryBot.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)
69
+
70
+ conditional_el.set_conditional_element
71
+ expect(conditional_el.conditional).to eq(element)
72
+ end
73
+ end
74
+
24
75
  it "should update a conditional question if elements are moved around" do
25
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
26
- 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")
76
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
77
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element", conditional_type: "Fe::Element")
27
78
  question_sheet.pages.reload
28
79
  question_sheet.pages[3].elements << conditional_el
29
- element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer that will be moved", conditional_type: nil, conditional_answer: nil)
80
+ element = FactoryBot.create(:text_field_element, label: "This is a test of a short answer that will be moved", conditional_type: nil, conditional_answer: nil)
30
81
  question_sheet.pages[3].elements << element
31
- element2 = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer that will be moved to become hidden", conditional_type: nil, conditional_answer: nil)
82
+ element2 = FactoryBot.create(:text_field_element, label: "This is a test of a short answer that will be moved to become hidden", conditional_type: nil, conditional_answer: nil)
32
83
  question_sheet.pages[3].elements << element2
33
84
 
34
85
  element.reload
@@ -39,17 +90,17 @@ describe Fe::Element do
39
90
  # now swap the last 2 elements
40
91
  old_element_position = element.position(question_sheet.pages[3])
41
92
  old_element2_position = element2.position(question_sheet.pages[3])
42
- element.page_elements.first.update_attributes(position: old_element2_position)
43
- element2.page_elements.first.update_attributes(position: old_element_position)
93
+ element.page_elements.first.update(position: old_element2_position)
94
+ element2.page_elements.first.update(position: old_element_position)
44
95
 
45
96
  conditional_el.reload
46
97
  expect(conditional_el.conditional).to eq(element2)
47
98
  end
48
99
 
49
100
  it "should set the conditional page if a new conditional page element is created" do
50
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
101
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
51
102
  hide_page = question_sheet.pages[4]
52
- conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next pag", conditional_type: "Fe::Page", conditional_id: hide_page.id)
103
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next pag", conditional_type: "Fe::Page", conditional_id: hide_page.id)
53
104
  question_sheet.pages.reload
54
105
  question_sheet.pages[3].elements << conditional_el
55
106
  conditional_el.reload
@@ -57,20 +108,20 @@ describe Fe::Element do
57
108
  end
58
109
 
59
110
  it "should keep the conditional page if a page is moved" do
60
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
111
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
61
112
  hide_page = question_sheet.pages[4]
62
- conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next pag", conditional_type: "Fe::Page", conditional_id: hide_page.id)
113
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next pag", conditional_type: "Fe::Page", conditional_id: hide_page.id)
63
114
  question_sheet.pages.reload
64
115
  question_sheet.pages[3].elements << conditional_el
65
116
  conditional_el.reload
66
117
  expect(conditional_el.conditional).to eq(question_sheet.pages[4])
67
118
 
68
119
  # move some pages around
69
- question_sheet.pages[0].update_attributes number: 1
70
- question_sheet.pages[1].update_attributes number: 2
71
- question_sheet.pages[2].update_attributes number: 3
72
- question_sheet.pages[3].update_attributes number: 0 # the page the conditional element is on
73
- question_sheet.pages[4].update_attributes number: 4
120
+ question_sheet.pages[0].update number: 1
121
+ question_sheet.pages[1].update number: 2
122
+ question_sheet.pages[2].update number: 3
123
+ question_sheet.pages[3].update number: 0 # the page the conditional element is on
124
+ question_sheet.pages[4].update number: 4
74
125
  question_sheet.pages.reload
75
126
 
76
127
  # the page after the conditional page should still be set to the same page
@@ -79,51 +130,97 @@ describe Fe::Element do
79
130
  end
80
131
 
81
132
  it "should not let a hidden page make the questionnaire incomplete" do
82
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
133
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
83
134
  hide_page = question_sheet.pages[4]
84
- conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next page", conditional_type: "Fe::Page", conditional_id: hide_page.id, conditional_answer: "yes")
135
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the page", conditional_type: "Fe::Page", conditional_id: hide_page.id, conditional_answer: "yes")
85
136
  question_sheet.pages.reload
86
137
  question_sheet.pages[3].elements << conditional_el
87
138
  conditional_el.reload
88
139
  expect(conditional_el.conditional).to eq(question_sheet.pages[4])
89
140
 
90
141
  # add required element on hidden page
91
- element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer on a hidden page")
142
+ element = FactoryBot.create(:text_field_element, label: "This is a test of a short answer on a hidden page")
92
143
  hide_page.elements << element
93
144
 
94
145
  # set up an answer sheet
95
- application = FactoryGirl.create(:answer_sheet)
96
- application.answer_sheet_question_sheet = FactoryGirl.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
97
- application.answer_sheet_question_sheets.first.update_attributes(question_sheet_id: question_sheet.id)
146
+ application = FactoryBot.create(:answer_sheet)
147
+ application.answer_sheet_question_sheet = FactoryBot.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
148
+ application.answer_sheet_question_sheets.first.update(question_sheet_id: question_sheet.id)
149
+ application.reload
98
150
 
99
151
  # validate the hidden page, it should be marked complete
100
152
  expect(hide_page.complete?(application)).to eq(true)
101
153
 
102
- # make the answer to the conditional question 'yes' so that the element shows up and is thus required
154
+ # make the answer to the conditional question 'yes' so that the page is now visible
103
155
  conditional_el.set_response("yes", application)
104
156
  conditional_el.save_response(application)
105
157
 
106
- # validate the now-visible page, it should be marked not complete
158
+ # validate the now-visible page, it should be marked not complete
159
+ hide_page.clear_hidden_cache
107
160
  expect(hide_page.complete?(application)).to eq(false)
108
161
  end
109
162
 
163
+ it "should not require a nested element in nested hidden page" do
164
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
165
+ conditional_el1 = FactoryBot.create(:choice_field_element, label: 'LVL1')
166
+ question_sheet.pages.reload
167
+ question_sheet.pages[0].elements << conditional_el1
168
+
169
+ conditional_el2 = FactoryBot.create(:choice_field_element, label: 'LVL2', choice_field_id: conditional_el1.id)
170
+ conditional_el2.reload
171
+
172
+ group = FactoryBot.create(:question_grid, choice_field_id: conditional_el2.id, label: 'LVL3 (GRID)')
173
+
174
+ conditional_el3 = FactoryBot.create(:choice_field_element, label: 'LVL4', question_grid_id: group.id)
175
+ conditional_el3.reload
176
+
177
+ # add required element on hidden group
178
+ element = FactoryBot.create(:text_field_element, label: "EL (LVL5)", choice_field_id: conditional_el3.id)
179
+
180
+ # set up an answer sheet
181
+ application = FactoryBot.create(:answer_sheet)
182
+ application.answer_sheet_question_sheet = FactoryBot.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
183
+ application.answer_sheet_question_sheets.first.update(question_sheet_id: question_sheet.id)
184
+ application.reload
185
+
186
+ # start with all the conditional element values yes so that the element will show
187
+ conditional_el1.set_response("yes", application)
188
+ conditional_el1.save_response(application)
189
+ conditional_el2.set_response("yes", application)
190
+ conditional_el2.save_response(application)
191
+ conditional_el3.set_response("yes", application)
192
+ conditional_el3.save_response(application)
193
+
194
+ # the element should be visible at this point
195
+ expect(element.visible?(application)).to be(true)
196
+
197
+ # hide the second conditional element, that should hide the group and the element with it
198
+ conditional_el2.set_response("no", application)
199
+ conditional_el2.save_response(application)
200
+
201
+ # the element should be hidden now
202
+ element = Fe::Element.find(element.id)
203
+ expect(element.visible?(application)).to be(false)
204
+ end
205
+
110
206
  it "should not require questions in a hidden page" do
111
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
207
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
112
208
  hide_page = question_sheet.pages[4]
113
- conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next page", conditional_type: "Fe::Page", conditional_id: hide_page.id, conditional_answer: "yes")
209
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next page", conditional_type: "Fe::Page", conditional_id: hide_page.id, conditional_answer: "yes")
114
210
  question_sheet.pages.reload
115
211
  question_sheet.pages[3].elements << conditional_el
116
212
  conditional_el.reload
117
213
  expect(conditional_el.conditional).to eq(question_sheet.pages[4])
118
214
 
119
215
  # add required element on hidden page
120
- element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer on a hidden page")
216
+ element = FactoryBot.create(:text_field_element, label: "This is a test of a short answer on a hidden page")
121
217
  hide_page.elements << element
122
218
 
123
219
  # set up an answer sheet
124
- application = FactoryGirl.create(:answer_sheet)
125
- application.answer_sheet_question_sheet = FactoryGirl.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
126
- application.answer_sheet_question_sheets.first.update_attributes(question_sheet_id: question_sheet.id)
220
+ application = FactoryBot.create(:answer_sheet)
221
+ application.answer_sheet_question_sheet = FactoryBot.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
222
+ application.answer_sheet_question_sheets.first.update(question_sheet_id: question_sheet.id)
223
+ application.reload
127
224
 
128
225
  # make the answer to the conditional question 'yes' (match) so that the element is visible (and thus required)
129
226
  conditional_el.set_response("yes", application)
@@ -137,6 +234,286 @@ describe Fe::Element do
137
234
  conditional_el.save_response(application)
138
235
 
139
236
  # validate the hidden page, it should be marked complete because of being hidden
237
+ hide_page.clear_hidden_cache
140
238
  expect(hide_page.complete?(application)).to eq(true)
141
239
  end
240
+
241
+ it "should return false for has_response?" do
242
+ element = Fe::Element.new
243
+ expect(element.has_response?).to be false
244
+ end
245
+
246
+ context '#limit' do
247
+ it "should return a value for a legitimate object_name and attribute_name" do
248
+ application = FactoryBot.create(:application)
249
+ application.applicant_id = create(:fe_person).id
250
+ element = Fe::Element.new object_name: 'applicant', attribute_name: 'first_name'
251
+ expect(element.limit(application)).to_not be_nil
252
+ end
253
+ it "should return nil instead of crashing if there's an exception thrown" do
254
+ application = FactoryBot.create(:application)
255
+ application.applicant_id = create(:fe_person).id
256
+ element = Fe::Element.new object_name: 'applicant', attribute_name: 'asdf'
257
+ expect(element.limit(application)).to be_nil
258
+ end
259
+ end
260
+
261
+ context '#previous_element' do
262
+ it "should work" do
263
+ application = FactoryBot.create(:application)
264
+ application.applicant_id = create(:fe_person).id
265
+ element1 = create(:text_field_element)
266
+ element2 = create(:text_field_element)
267
+ element3 = create(:text_field_element)
268
+ page = create(:page)
269
+ create(:page_element, page_id: page.id, element_id: element1.id)
270
+ create(:page_element, page_id: page.id, element_id: element2.id)
271
+ create(:page_element, page_id: page.id, element_id: element3.id)
272
+ expect(element2.previous_element(page.question_sheet)).to eq(element1)
273
+ end
274
+ end
275
+
276
+ context '#required' do
277
+ it "should not require a conditional element when its prev element isn't matching the answer text" do
278
+ application = FactoryBot.create(:application)
279
+ application.applicant_id = create(:fe_person).id
280
+ element1 = create(:text_field_element)
281
+ element2 = create(:text_field_element, conditional_answer: 'test')
282
+ element3 = create(:text_field_element, required: true)
283
+ # 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)
284
+ element2.conditional = element3
285
+ element2.save!
286
+
287
+ page = create(:page)
288
+ question_sheet = page.question_sheet
289
+ create(:page_element, page_id: page.id, element_id: element1.id)
290
+ create(:page_element, page_id: page.id, element_id: element2.id)
291
+ create(:page_element, page_id: page.id, element_id: element3.id)
292
+
293
+ # set up an answer sheet
294
+ application = FactoryBot.create(:answer_sheet)
295
+ application.answer_sheet_question_sheet = FactoryBot.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
296
+ application.answer_sheet_question_sheets.first.update(question_sheet_id: question_sheet.id)
297
+
298
+ # make the answer to the conditional question 'yes' so that the element shows up and is thus required
299
+ element2.set_response('nomatch', application)
300
+ element2.save_response(application)
301
+
302
+ expect(element3.required?(application)).to be false
303
+ end
304
+ end
305
+ context '#clone' do
306
+ it 'should duplicate question grid elements' do
307
+ element1 = create(:question_grid)
308
+ element2 = create(:text_field_element, question_grid_id: element1.id, position: 0) # added to grid
309
+ element3 = create(:text_field_element, question_grid_id: element1.id, position: 1) # added to grid
310
+ page = create(:page)
311
+ create(:page_element, page_id: page.id, element_id: element1.id)
312
+ expect {
313
+ element3.duplicate(page, element1)
314
+ }.to change{element1.reload.elements.count}.by(1) # added to grid
315
+ expect(element1.elements.last.position).to eq(2) # added to end of grid
316
+ expect(element1.elements.last.question_grid).to eq(element1) # added to the right grid
317
+ expect(element1.elements.last.pages).to eq([]) # not added to any pages
318
+ end
319
+ it 'should duplicate question' do
320
+ element1 = create(:question_grid)
321
+ element2 = create(:text_field_element)
322
+ element3 = create(:text_field_element)
323
+ page = create(:page)
324
+ create(:page_element, page_id: page.id, element_id: element1.id)
325
+ create(:page_element, page_id: page.id, element_id: element2.id)
326
+ create(:page_element, page_id: page.id, element_id: element3.id)
327
+ expect {
328
+ element3.duplicate(page)
329
+ }.to change{page.reload.elements.count}.by(1)
330
+ expect(page.page_elements.last.position).to eq(4)
331
+ expect(page.elements.last.question_grid).to be_nil
332
+ expect(page.elements.last.pages).to eq([page])
333
+ end
334
+ end
335
+
336
+ context '#update_page_all_element_ids' do
337
+ it 'should rebuild all_element_ids in all pages' do
338
+ element1 = create(:text_field_element)
339
+ page1 = create(:page)
340
+ page2 = create(:page)
341
+ create(:page_element, page_id: page1.id, element_id: element1.id)
342
+ create(:page_element, page_id: page2.id, element_id: element1.id)
343
+ page1.update_column(:all_element_ids, nil)
344
+ page2.update_column(:all_element_ids, nil)
345
+ element1.pages.reload
346
+ element1.update_page_all_element_ids
347
+ expect(page1.reload.all_element_ids).to eq("#{element1.id}")
348
+ expect(page2.reload.all_element_ids).to eq("#{element1.id}")
349
+ end
350
+ it 'should rebuild all_element_ids when adding a question grid' do
351
+ page = create(:page)
352
+ grid = create(:question_grid)
353
+ create(:page_element, page_id: page.id, element_id: grid.id)
354
+ grid.pages.reload
355
+ textfield = create(:text_field_element, question_grid: grid)
356
+
357
+ page.update_column(:all_element_ids, nil)
358
+ textfield.update_page_all_element_ids
359
+ expect(page.reload.all_element_ids).to eq("#{grid.id},#{textfield.id}")
360
+ end
361
+ it 'should rebuild all_element_ids when adding a question grid with total' do
362
+ page = create(:page)
363
+ grid = create(:question_grid)
364
+ create(:page_element, page_id: page.id, element_id: grid.id)
365
+ grid.pages.reload
366
+ textfield = create(:text_field_element, question_grid: grid)
367
+
368
+ page.update_column(:all_element_ids, nil)
369
+ textfield.update_page_all_element_ids
370
+ expect(page.reload.all_element_ids).to eq("#{grid.id},#{textfield.id}")
371
+ end
372
+ end
373
+
374
+ context 'translations' do
375
+ it 'uses the translation' do
376
+ e = create(:text_field_element, label_translations: { 'fr' => 'fr label' }, tip_translations: { 'fr' => 'fr tip' },
377
+ content_translations: { 'fr' => 'fr content' })
378
+ expect(e.label('fr')).to eq('fr label')
379
+ expect(e.content('fr')).to eq('fr content')
380
+ expect(e.tooltip('fr')).to eq('fr tip')
381
+ end
382
+ it 'shows english if the translation is an empty string' do
383
+ e = create(:text_field_element, label_translations: { 'fr' => '' }, tip_translations: { 'fr' => '' },
384
+ content_translations: { 'fr' => '' })
385
+ expect(e.label('fr')).to eq(e[:label])
386
+ expect(e.content('fr')).to eq(e[:content])
387
+ expect(e.tooltip('fr')).to eq(e[:tooltip])
388
+ end
389
+ it 'uses english choices if the translation is an empty string' do
390
+ e = create(:choice_field_element, style: 'drop-down', content: "1\r\n2", content_translations: { 'fr' => '' })
391
+ expect(e.choices('fr')).to eq([['1', '1'], ['2', '2']])
392
+ end
393
+ end
394
+
395
+ context '#css_classes' do
396
+ it 'splits the css classes into an array' do
397
+ e = create(:text_field_element, css_class: 'a 1 2')
398
+ expect(e.css_classes).to eq(%w(a 1 2))
399
+ end
400
+ it 'handles nil' do
401
+ e = create(:text_field_element, css_class: nil)
402
+ expect(e.css_classes).to eq([])
403
+ end
404
+ end
405
+
406
+ context '#matches_filter' do
407
+ let(:e) { create(:text_field_element, is_confidential: true, share: true, hide_label: false) }
408
+
409
+ it 'matches when all filter methods match' do
410
+ expect(e.matches_filter([:is_confidential, :share])).to be true
411
+ end
412
+ it "doesn't matches when any methods is false" do
413
+ expect(e.matches_filter([:is_confidential, :hide_label])).to be false
414
+ end
415
+ it "doesn't matches when all methods are false" do
416
+ expect(e.matches_filter([:hide_label])).to be false
417
+ end
418
+ end
419
+
420
+ context '#hidden?' do
421
+ let(:e) { create(:text_field_element, is_confidential: true, share: true, hide_label: false) }
422
+ let(:application) { FactoryBot.create(:answer_sheet) }
423
+
424
+ it "returns true if the page is nil and the element isn't on any pages" do
425
+ expect(e.hidden?(application, nil)).to be true
426
+ end
427
+ end
428
+
429
+ context 'multiple question sheets' do
430
+ let(:e2) { create(:text_field_element, is_confidential: true, share: true, hide_label: false) }
431
+ let(:e) { create(:text_field_element, is_confidential: true, share: true, hide_label: false,
432
+ conditional_type: 'Fe::Element', conditional_id: e2, conditional_answer: 'match') }
433
+ let(:application) { FactoryBot.create(:answer_sheet) }
434
+ let(:qs) { create(:question_sheet_with_pages) }
435
+ let(:qs2) { create(:question_sheet_with_pages) }
436
+ let(:p2) { qs2.pages.first }
437
+
438
+ before do
439
+ e.set_response('nomatch', application) # no match so the next element is hidden
440
+ e.save_response(application)
441
+ application.question_sheets << qs << qs2
442
+ p2.elements << e << e2
443
+ end
444
+
445
+ context '#hidden?' do
446
+ it "returns true for a page that's not on the application" do
447
+ qs2 = create(:question_sheet_with_pages)
448
+ expect(e2.hidden?(application, p2)).to be(true)
449
+ end
450
+ it "returns false for a conditionally visible element on a question sheet that isn't the first one" do
451
+ e.set_response('match', application) # match so the next element is visible
452
+ e.save_response(application)
453
+ expect(e2.hidden?(application, p2)).to be(false)
454
+ end
455
+ it "returns true for a hidden element on a question sheet that isn't the first one" do
456
+ expect(e2.hidden?(application, p2)).to be(true)
457
+ end
458
+ end
459
+ context '#hidden_by_conditional?' do
460
+ it "returns false for a page passed in that's not on the application" do
461
+ expect(e.hidden_by_conditional?(application, create(:page))).to be(false)
462
+ end
463
+ end
464
+ end
465
+
466
+ context '#visibility_affecting_element_ids' do
467
+ let(:grid_el) { create(:question_grid) }
468
+ let(:grid_cond) { create(:choice_field_element, label: "Is the grid visible?", conditional_type: "Fe::Element", conditional_id: grid_el.id, conditional_answer: "yes") }
469
+ let(:ref_el) { create(:reference_element, question_grid_id: grid_el.id) }
470
+ let(:choice) { create(:choice_field_element, label: "is the ref element inside this element visible?") }
471
+ let(:ref_el2) { create(:reference_element, choice_field_id: choice.id) }
472
+ let(:choice_cond) { create(:choice_field_element, label: "Is the next choice element visible?", conditional_type: "Fe::Element", conditional_id: choice.id, conditional_answer: "yes") }
473
+ let(:ref_el3_cond) { create(:choice_field_element, label: "Is the next ref element visible?", conditional_type: "Fe::Element", conditional_id: ref_el3.id, conditional_answer: "yes") }
474
+ let(:ref_el3) { create(:reference_element) }
475
+
476
+ before do
477
+ # make sure all the elements are created
478
+ grid_el
479
+ grid_cond
480
+ ref_el
481
+ choice
482
+ ref_el2
483
+ choice_cond
484
+ ref_el3_cond
485
+ ref_el3
486
+ end
487
+
488
+ it 'recomputes the visibility affecting element ids after a new element is added' do
489
+ expect(ref_el.visibility_affecting_element_ids).to eq([grid_el.id, grid_cond.id])
490
+ # add a new visibility affecting element and it should pick it up
491
+ # need to instantiate the ref_el again though to clear out the in-memory
492
+ # instance variable cache
493
+ ref_el1 = Fe::Element.find(ref_el.id)
494
+ grid_cond_cond = create(:choice_field_element, label: "Is the grid conditional visible?", conditional_type: "Fe::Element", conditional_id: grid_cond.id, conditional_answer: "yes")
495
+ expect(ref_el1.visibility_affecting_element_ids).to eq([grid_el.id, grid_cond.id, grid_cond_cond.id])
496
+ end
497
+ it 'includes affecting element ids of an element in a grid' do
498
+ expect(ref_el.visibility_affecting_element_ids).to eq([grid_el.id, grid_cond.id])
499
+ end
500
+ it 'includes affecting element ids of an element in a choice field' do
501
+ expect(ref_el2.visibility_affecting_element_ids).to eq([choice.id, choice_cond.id])
502
+ end
503
+ it 'includes directly affecting element ids' do
504
+ expect(ref_el3.visibility_affecting_element_ids).to eq([ref_el3_cond.id])
505
+ end
506
+ end
507
+
508
+ context '#visibility_affecting_questions' do
509
+ let!(:ref_el) { create(:reference_element) }
510
+ let!(:text_el) { create(:text_field_element) }
511
+ let!(:grid_el) { create(:question_grid) }
512
+
513
+ it 'returns all questions with id in visibility_affecting_element_ids' do
514
+ element_ids = [ text_el.id, grid_el.id ]
515
+ expect(ref_el).to receive(:visibility_affecting_element_ids).and_return(element_ids)
516
+ expect(ref_el.visibility_affecting_questions).to eq([text_el])
517
+ end
518
+ end
142
519
  end
@@ -1,5 +1,5 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe Fe::EmailTemplate do
3
+ describe Fe::EmailTemplate, type: :model do
4
4
  it { expect validate_presence_of :name }
5
5
  end
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe Fe::PageElement do
3
+ describe Fe::PageElement, type: :model do
4
4
  it { expect belong_to :page }
5
5
  it { expect belong_to :element }
6
6
  end