fe 1.0.0 → 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 (402) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +4 -4
  3. data/app/assets/config/fe/manifest.js +3 -0
  4. data/app/assets/config/manifest.js +3 -0
  5. data/app/assets/javascripts/application.js.erb +1 -1
  6. data/app/assets/javascripts/fe/admin.js +0 -1
  7. data/app/assets/javascripts/fe/fe.admin.js +2 -6
  8. data/app/assets/javascripts/fe/{fe.common.js → fe.common.js.erb} +14 -7
  9. data/app/assets/javascripts/fe/fe.public.js +1 -2
  10. data/app/assets/javascripts/fe/{fe.public.nojquery.js → fe.public.nojquery.js.erb} +152 -76
  11. data/app/assets/javascripts/fe/jquery.html5_upload.js +258 -0
  12. data/app/assets/stylesheets/fe/fe.screen.css.scss.erb +22 -1
  13. data/app/assets/stylesheets/fe/validation.css +5 -1
  14. data/app/controllers/{fe/concerns → concerns/fe}/admin/question_sheets_controller_concern.rb +15 -16
  15. data/app/controllers/concerns/fe/answer_pages_controller_concern.rb +131 -0
  16. data/app/controllers/{fe/concerns → concerns/fe}/answer_sheets_controller_concern.rb +14 -6
  17. data/app/controllers/{fe/concerns → concerns/fe}/application_controller_concern.rb +3 -3
  18. data/app/controllers/fe/admin/elements_controller.rb +46 -24
  19. data/app/controllers/fe/admin/email_templates_controller.rb +5 -5
  20. data/app/controllers/fe/admin/question_pages_controller.rb +8 -8
  21. data/app/controllers/fe/reference_pages_controller.rb +11 -11
  22. data/app/controllers/fe/reference_sheets_controller.rb +4 -4
  23. data/app/controllers/fe/references_controller.rb +19 -19
  24. data/app/controllers/fe/submit_pages_controller.rb +5 -5
  25. data/app/helpers/fe/answer_pages_helper.rb +1 -1
  26. data/app/helpers/fe/application_helper.rb +3 -3
  27. data/app/jobs/fe/update_reference_sheet_visibility_job.rb +11 -0
  28. data/app/mailers/fe/notifier.rb +4 -4
  29. data/app/models/answer_sheet.rb +1 -1
  30. data/app/models/application_record.rb +3 -0
  31. data/app/models/{fe/concerns → concerns/fe}/answer_concern.rb +2 -2
  32. data/app/models/{fe/concerns → concerns/fe}/answer_pages_presenter_concern.rb +6 -5
  33. data/app/models/concerns/fe/answer_sheet_concern.rb +125 -0
  34. data/app/models/{fe/concerns → concerns/fe}/choice_field_concern.rb +41 -23
  35. data/app/models/fe/address.rb +2 -2
  36. data/app/models/fe/answer.rb +1 -1
  37. data/app/models/fe/answer_sheet.rb +1 -1
  38. data/app/models/fe/answer_sheet_question_sheet.rb +2 -2
  39. data/app/models/fe/application.rb +14 -10
  40. data/app/models/fe/condition.rb +4 -4
  41. data/app/models/fe/date_field.rb +1 -1
  42. data/app/models/fe/element.rb +126 -44
  43. data/app/models/fe/email_address.rb +2 -2
  44. data/app/models/fe/email_template.rb +1 -1
  45. data/app/models/fe/page.rb +94 -19
  46. data/app/models/fe/page_element.rb +2 -2
  47. data/app/models/fe/paragraph.rb +1 -1
  48. data/app/models/fe/person.rb +5 -5
  49. data/app/models/fe/phone_number.rb +1 -1
  50. data/app/models/fe/question.rb +62 -38
  51. data/app/models/fe/question_grid.rb +15 -3
  52. data/app/models/fe/question_set.rb +53 -13
  53. data/app/models/fe/question_sheet.rb +49 -16
  54. data/app/models/fe/reference_question.rb +9 -3
  55. data/app/models/fe/reference_sheet.rb +102 -47
  56. data/app/models/fe/state_chooser.rb +2 -2
  57. data/app/models/fe/text_field.rb +2 -2
  58. data/app/models/fe/user.rb +1 -1
  59. data/app/models/staff.rb +6 -6
  60. data/app/views/fe/admin/elements/create.js.erb +3 -3
  61. data/app/views/fe/admin/elements/destroy.js.erb +1 -1
  62. data/app/views/fe/admin/elements/drop.js.erb +1 -1
  63. data/app/views/fe/admin/elements/duplicate.js.erb +1 -1
  64. data/app/views/fe/admin/elements/edit.js.erb +1 -1
  65. data/app/views/fe/admin/elements/error.js.erb +1 -1
  66. data/app/views/fe/admin/elements/new.js.erb +13 -6
  67. data/app/views/fe/admin/elements/update.js.erb +1 -1
  68. data/app/views/fe/admin/email_templates/_form.html.erb +3 -3
  69. data/app/views/fe/admin/email_templates/edit.html.erb +3 -3
  70. data/app/views/fe/admin/email_templates/index.html.erb +3 -3
  71. data/app/views/fe/admin/email_templates/new.html.erb +3 -3
  72. data/app/views/fe/admin/panels/_advanced_options.html.erb +8 -8
  73. data/app/views/fe/admin/panels/_common_boolean_fields.html.erb +1 -0
  74. data/app/views/fe/admin/panels/_common_boolean_fields_default.html.erb +11 -0
  75. data/app/views/fe/admin/panels/_common_fields.html.erb +2 -17
  76. data/app/views/fe/admin/panels/_condition.html.erb +1 -1
  77. data/app/views/fe/admin/panels/_insert.html.erb +25 -25
  78. data/app/views/fe/admin/panels/_nav_controls.html.erb +4 -4
  79. data/app/views/fe/admin/panels/_page.html.erb +1 -1
  80. data/app/views/fe/admin/panels/_pages_list.html.erb +3 -3
  81. data/app/views/fe/admin/panels/_prop_attachment_field.html.erb +2 -2
  82. data/app/views/fe/admin/panels/_prop_choice_field.html.erb +36 -17
  83. data/app/views/fe/admin/panels/_prop_date_field.html.erb +1 -1
  84. data/app/views/fe/admin/panels/_prop_element.html.erb +5 -5
  85. data/app/views/fe/admin/panels/_prop_page.html.erb +3 -3
  86. data/app/views/fe/admin/panels/_prop_paragraph.html.erb +8 -8
  87. data/app/views/fe/admin/panels/_prop_question_grid.html.erb +7 -2
  88. data/app/views/fe/admin/panels/_prop_question_grid_with_total.html.erb +2 -2
  89. data/app/views/fe/admin/panels/_prop_reference_question.html.erb +3 -3
  90. data/app/views/fe/admin/panels/_prop_section.html.erb +1 -1
  91. data/app/views/fe/admin/panels/_prop_sheet.html.erb +3 -3
  92. data/app/views/fe/admin/panels/_prop_text_field.html.erb +12 -12
  93. data/app/views/fe/admin/question_pages/_element.html.erb +7 -7
  94. data/app/views/fe/admin/question_pages/_element_show.html.erb +2 -2
  95. data/app/views/fe/admin/question_pages/_question_page.html.erb +4 -4
  96. data/app/views/fe/admin/question_pages/create.js.erb +3 -3
  97. data/app/views/fe/admin/question_pages/destroy.js.erb +3 -3
  98. data/app/views/fe/admin/question_pages/edit.js.erb +1 -1
  99. data/app/views/fe/admin/question_pages/error.js.erb +1 -1
  100. data/app/views/fe/admin/question_pages/show.js.erb +2 -2
  101. data/app/views/fe/admin/question_pages/show_panel.js.erb +1 -1
  102. data/app/views/fe/admin/question_pages/update.js.erb +1 -1
  103. data/app/views/fe/admin/question_sheets/edit.js.erb +1 -1
  104. data/app/views/fe/admin/question_sheets/error.js.erb +1 -1
  105. data/app/views/fe/admin/question_sheets/index.html.erb +8 -8
  106. data/app/views/fe/admin/question_sheets/new.html.erb +3 -3
  107. data/app/views/fe/admin/question_sheets/show.html.erb +5 -5
  108. data/app/views/fe/admin/question_sheets/update.js.erb +1 -1
  109. data/app/views/fe/answer_pages/_answer_page.html.erb +13 -14
  110. data/app/views/fe/answer_pages/_element.html.erb +22 -2
  111. data/app/views/fe/answer_pages/_page_name.html.erb +1 -1
  112. data/app/views/fe/answer_pages/show.html.erb +39 -0
  113. data/app/views/fe/answer_pages/update.js.erb +10 -2
  114. data/app/views/fe/answer_sheets/_answer_sheet.html.erb +4 -4
  115. data/app/views/fe/answer_sheets/_element.html.erb +9 -7
  116. data/app/views/fe/answer_sheets/_incomplete.html.erb +1 -1
  117. data/app/views/fe/answer_sheets/_page_link.html.erb +9 -7
  118. data/app/views/fe/answer_sheets/_pages_list.html.erb +3 -3
  119. data/app/views/fe/answer_sheets/_submit_to.html.erb +1 -1
  120. data/app/views/fe/answer_sheets/_title.html.erb +1 -1
  121. data/app/views/fe/answer_sheets/edit.html.erb +18 -18
  122. data/app/views/fe/answer_sheets/incomplete.js.erb +7 -4
  123. data/app/views/fe/answer_sheets/index.html.erb +1 -1
  124. data/app/views/fe/answer_sheets/show.html.erb +1 -1
  125. data/app/views/fe/applications/_logout.html.erb +1 -1
  126. data/app/views/fe/questions/fe/_acceptance.html.erb +10 -9
  127. data/app/views/fe/questions/fe/_attachment_field.html.erb +129 -10
  128. data/app/views/fe/questions/fe/_checkbox_field.html.erb +18 -16
  129. data/app/views/fe/questions/fe/_country.html.erb +6 -6
  130. data/app/views/fe/questions/fe/_date_field.html.erb +5 -4
  131. data/app/views/fe/questions/fe/_date_field_mmyy.html.erb +8 -8
  132. data/app/views/fe/questions/fe/_drop_down_field.html.erb +5 -5
  133. data/app/views/fe/questions/fe/_question_grid.html.erb +10 -10
  134. data/app/views/fe/questions/fe/_question_grid_with_total.html.erb +8 -8
  135. data/app/views/fe/questions/fe/_questions.html.erb +11 -5
  136. data/app/views/fe/questions/fe/_radio_button_field.html.erb +35 -19
  137. data/app/views/fe/questions/fe/_rating.html.erb +56 -18
  138. data/app/views/fe/questions/fe/_reference_discipler.html.erb +1 -1
  139. data/app/views/fe/questions/fe/_reference_friend.html.erb +1 -1
  140. data/app/views/fe/questions/fe/_reference_parent.html.erb +1 -1
  141. data/app/views/fe/questions/fe/_reference_peer.html.erb +1 -1
  142. data/app/views/fe/questions/fe/_reference_question.html.erb +40 -24
  143. data/app/views/fe/questions/fe/_reference_roommate.html.erb +1 -1
  144. data/app/views/fe/questions/fe/_reference_spiritual.html.erb +1 -1
  145. data/app/views/fe/questions/fe/_reference_staff.html.erb +1 -1
  146. data/app/views/fe/questions/fe/_state_chooser.html.erb +6 -6
  147. data/app/views/fe/questions/fe/_text_area_field.html.erb +14 -10
  148. data/app/views/fe/questions/fe/_text_field.html.erb +7 -6
  149. data/app/views/fe/questions/fe/_yes_no.html.erb +8 -8
  150. data/app/views/fe/questions/fe/_yes_no_field.erb +11 -8
  151. data/app/views/fe/reference_pages/_reference.html.erb +12 -12
  152. data/app/views/fe/reference_pages/edit.html.erb +4 -4
  153. data/app/views/fe/reference_sheets/done.html.erb +2 -2
  154. data/app/views/fe/reference_sheets/not_found.html.erb +3 -3
  155. data/app/views/fe/references/edit.html.erb +5 -5
  156. data/app/views/fe/references/show.html.erb +3 -3
  157. data/app/views/fe/references/submit.js.erb +3 -3
  158. data/app/views/fe/submit_pages/_thankyou.html.erb +1 -1
  159. data/app/views/fe/submit_pages/edit.html.erb +9 -9
  160. data/app/views/fe/submit_pages/error.js.erb +1 -1
  161. data/app/views/fe/submit_pages/submit.js.erb +2 -2
  162. data/app/views/layouts/fe/_error_messages_for.html.erb +1 -1
  163. data/app/views/layouts/fe/application.html.erb +3 -4
  164. data/app/views/layouts/fe/fe_admin.html.erb +30 -0
  165. data/app/views.current/fe/admin/elements/_errors.html.erb +11 -0
  166. data/app/views.current/fe/admin/elements/create.js.erb +12 -0
  167. data/app/views.current/fe/admin/elements/destroy.js.erb +4 -0
  168. data/app/views.current/fe/admin/elements/drop.js.erb +3 -0
  169. data/app/views.current/fe/admin/elements/duplicate.js.erb +3 -0
  170. data/app/views.current/fe/admin/elements/edit.js.erb +4 -0
  171. data/app/views.current/fe/admin/elements/error.js.erb +4 -0
  172. data/app/views.current/fe/admin/elements/new.js.erb +17 -0
  173. data/app/views.current/fe/admin/elements/update.js.erb +9 -0
  174. data/app/views.current/fe/admin/email_templates/_form.html.erb +8 -0
  175. data/app/views.current/fe/admin/email_templates/edit.html.erb +13 -0
  176. data/app/views.current/fe/admin/email_templates/index.html.erb +20 -0
  177. data/app/views.current/fe/admin/email_templates/new.html.erb +11 -0
  178. data/app/views.current/fe/admin/panels/_advanced_options.html.erb +49 -0
  179. data/app/views.current/fe/admin/panels/_common_boolean_fields.html.erb +1 -0
  180. data/app/views.current/fe/admin/panels/_common_boolean_fields_default.html.erb +11 -0
  181. data/app/views.current/fe/admin/panels/_common_fields.html.erb +23 -0
  182. data/app/views.current/fe/admin/panels/_condition.html.erb +6 -0
  183. data/app/views.current/fe/admin/panels/_insert.html.erb +39 -0
  184. data/app/views.current/fe/admin/panels/_nav_controls.html.erb +6 -0
  185. data/app/views.current/fe/admin/panels/_page.html.erb +3 -0
  186. data/app/views.current/fe/admin/panels/_pages_list.html.erb +16 -0
  187. data/app/views.current/fe/admin/panels/_prop_attachment_field.html.erb +2 -0
  188. data/app/views.current/fe/admin/panels/_prop_choice_field.html.erb +74 -0
  189. data/app/views.current/fe/admin/panels/_prop_date_field.html.erb +7 -0
  190. data/app/views.current/fe/admin/panels/_prop_element.html.erb +23 -0
  191. data/app/views.current/fe/admin/panels/_prop_page.html.erb +26 -0
  192. data/app/views.current/fe/admin/panels/_prop_paragraph.html.erb +46 -0
  193. data/app/views.current/fe/admin/panels/_prop_question_grid.html.erb +28 -0
  194. data/app/views.current/fe/admin/panels/_prop_question_grid_with_total.html.erb +14 -0
  195. data/app/views.current/fe/admin/panels/_prop_reference_question.html.erb +12 -0
  196. data/app/views.current/fe/admin/panels/_prop_section.html.erb +8 -0
  197. data/app/views.current/fe/admin/panels/_prop_sheet.html.erb +20 -0
  198. data/app/views.current/fe/admin/panels/_prop_text_field.html.erb +20 -0
  199. data/app/views.current/fe/admin/question_pages/_element.html.erb +28 -0
  200. data/app/views.current/fe/admin/question_pages/_element_show.html.erb +10 -0
  201. data/app/views.current/fe/admin/question_pages/_errors.html.erb +10 -0
  202. data/app/views.current/fe/admin/question_pages/_question_page.html.erb +13 -0
  203. data/app/views.current/fe/admin/question_pages/create.js.erb +11 -0
  204. data/app/views.current/fe/admin/question_pages/destroy.js.erb +5 -0
  205. data/app/views.current/fe/admin/question_pages/edit.js.erb +3 -0
  206. data/app/views.current/fe/admin/question_pages/error.js.erb +4 -0
  207. data/app/views.current/fe/admin/question_pages/show.js.erb +9 -0
  208. data/app/views.current/fe/admin/question_pages/show_panel.js.erb +3 -0
  209. data/app/views.current/fe/admin/question_pages/update.js.erb +2 -0
  210. data/app/views.current/fe/admin/question_sheets/_errors.html.erb +11 -0
  211. data/app/views.current/fe/admin/question_sheets/edit.js.erb +3 -0
  212. data/app/views.current/fe/admin/question_sheets/error.js.erb +5 -0
  213. data/app/views.current/fe/admin/question_sheets/index.html.erb +41 -0
  214. data/app/views.current/fe/admin/question_sheets/new.html.erb +15 -0
  215. data/app/views.current/fe/admin/question_sheets/show.html.erb +27 -0
  216. data/app/views.current/fe/admin/question_sheets/update.js.erb +2 -0
  217. data/app/views.current/fe/answer_pages/_answer_page.html.erb +53 -0
  218. data/app/views.current/fe/answer_pages/_element.html.erb +32 -0
  219. data/app/views.current/fe/answer_pages/_page_name.html.erb +1 -0
  220. data/app/views.current/fe/answer_pages/show.html.erb +39 -0
  221. data/app/views.current/fe/answer_pages/update.js.erb +13 -0
  222. data/app/views.current/fe/answer_sheets/_answer_sheet.html.erb +26 -0
  223. data/app/views.current/fe/answer_sheets/_element.html.erb +74 -0
  224. data/app/views.current/fe/answer_sheets/_incomplete.html.erb +10 -0
  225. data/app/views.current/fe/answer_sheets/_page_link.html.erb +9 -0
  226. data/app/views.current/fe/answer_sheets/_pages_list.html.erb +11 -0
  227. data/app/views.current/fe/answer_sheets/_submit_to.html.erb +1 -0
  228. data/app/views.current/fe/answer_sheets/_title.html.erb +1 -0
  229. data/app/views.current/fe/answer_sheets/edit.html.erb +66 -0
  230. data/app/views.current/fe/answer_sheets/incomplete.js.erb +11 -0
  231. data/app/views.current/fe/answer_sheets/index.html.erb +18 -0
  232. data/app/views.current/fe/answer_sheets/send_reference_invite.js.erb +8 -0
  233. data/app/views.current/fe/answer_sheets/show.html.erb +13 -0
  234. data/app/views.current/fe/applications/_logout.html.erb +1 -0
  235. data/app/views.current/fe/applications/show.html.erb +1 -0
  236. data/app/views.current/fe/help/builder.html +33 -0
  237. data/app/views.current/fe/help/question_grid.html +18 -0
  238. data/app/views.current/fe/questions/fe/_acceptance.html.erb +14 -0
  239. data/app/views.current/fe/questions/fe/_attachment_field.html.erb +165 -0
  240. data/app/views.current/fe/questions/fe/_checkbox_field.html.erb +53 -0
  241. data/app/views.current/fe/questions/fe/_country.html.erb +7 -0
  242. data/app/views.current/fe/questions/fe/_date_field.html.erb +7 -0
  243. data/app/views.current/fe/questions/fe/_date_field_mmyy.html.erb +9 -0
  244. data/app/views.current/fe/questions/fe/_drop_down_field.html.erb +8 -0
  245. data/app/views.current/fe/questions/fe/_paragraph.html.erb +1 -0
  246. data/app/views.current/fe/questions/fe/_question_grid.html.erb +70 -0
  247. data/app/views.current/fe/questions/fe/_question_grid_with_total.html.erb +64 -0
  248. data/app/views.current/fe/questions/fe/_questions.html.erb +15 -0
  249. data/app/views.current/fe/questions/fe/_radio_button_field.html.erb +60 -0
  250. data/app/views.current/fe/questions/fe/_rating.html.erb +64 -0
  251. data/app/views.current/fe/questions/fe/_reference_discipler.html.erb +1 -0
  252. data/app/views.current/fe/questions/fe/_reference_friend.html.erb +1 -0
  253. data/app/views.current/fe/questions/fe/_reference_parent.html.erb +1 -0
  254. data/app/views.current/fe/questions/fe/_reference_peer.html.erb +1 -0
  255. data/app/views.current/fe/questions/fe/_reference_question.html.erb +61 -0
  256. data/app/views.current/fe/questions/fe/_reference_roommate.html.erb +1 -0
  257. data/app/views.current/fe/questions/fe/_reference_spiritual.html.erb +1 -0
  258. data/app/views.current/fe/questions/fe/_reference_staff.html.erb +1 -0
  259. data/app/views.current/fe/questions/fe/_section.html.erb +1 -0
  260. data/app/views.current/fe/questions/fe/_state_chooser.html.erb +7 -0
  261. data/app/views.current/fe/questions/fe/_text_area_field.html.erb +17 -0
  262. data/app/views.current/fe/questions/fe/_text_field.html.erb +9 -0
  263. data/app/views.current/fe/questions/fe/_yes_no.html.erb +17 -0
  264. data/app/views.current/fe/questions/fe/_yes_no_field.erb +20 -0
  265. data/app/views.current/fe/reference_pages/_reference.html.erb +31 -0
  266. data/app/views.current/fe/reference_pages/edit.html.erb +24 -0
  267. data/app/views.current/fe/reference_sheets/done.html.erb +2 -0
  268. data/app/views.current/fe/reference_sheets/not_found.html.erb +5 -0
  269. data/app/views.current/fe/reference_sheets/submitted.js.erb +1 -0
  270. data/app/views.current/fe/references/edit.html.erb +8 -0
  271. data/app/views.current/fe/references/send_invite.js.erb +7 -0
  272. data/app/views.current/fe/references/show.html.erb +18 -0
  273. data/app/views.current/fe/references/submit.js.erb +3 -0
  274. data/app/views.current/fe/submit_pages/_errors.html.erb +1 -0
  275. data/app/views.current/fe/submit_pages/_thankyou.html.erb +2 -0
  276. data/app/views.current/fe/submit_pages/edit.html.erb +36 -0
  277. data/app/views.current/fe/submit_pages/error.js.erb +1 -0
  278. data/app/views.current/fe/submit_pages/submit.js.erb +3 -0
  279. data/app/views.current/layouts/fe/_error_messages_for.html.erb +7 -0
  280. data/app/views.current/layouts/fe/application.html.erb +47 -0
  281. data/app/{views/layouts/fe/fe.admin.html.erb → views.current/layouts/fe/fe_admin.html.erb} +4 -4
  282. data/config/initializers/paper_trail.rb +3 -0
  283. data/config/routes.rb +3 -1
  284. data/db/migrate/20131003041856_core.rb +23 -23
  285. data/db/migrate/20131003044250_create_reference_sheets.rb +1 -1
  286. data/db/migrate/20131003044436_add_element_and_answer_fields.rb +3 -3
  287. data/db/migrate/20131003044518_create_email_templates.rb +2 -2
  288. data/db/migrate/20131003044621_add_max_lengths.rb +1 -1
  289. data/db/migrate/20131003044714_create_join_table.rb +1 -1
  290. data/db/migrate/20131016162128_remove_question_id_from_element.rb +1 -1
  291. data/db/migrate/20140623153424_create_fe_people.rb +1 -1
  292. data/db/migrate/20140624180246_create_fe_addresses.rb +1 -1
  293. data/db/migrate/20140624182216_create_fe_phone_numbers.rb +1 -1
  294. data/db/migrate/20140625160545_create_fe_users.rb +1 -1
  295. data/db/migrate/20140808202507_add_conditional_type_to_elements.rb +1 -1
  296. data/db/migrate/20140808203609_add_conditional_answer_to_elements.rb +1 -1
  297. data/db/migrate/20141103204704_remove_short_value_column.rb +1 -1
  298. data/db/migrate/20141109154522_move_conditional_ids_used_for_choice_field_to_their_own_column.rb +1 -1
  299. data/db/migrate/20150504221439_add_all_element_ids_to_pages.rb +1 -1
  300. data/db/migrate/20150713022326_add_locale_columns.rb +1 -1
  301. data/db/migrate/20150714220730_add_locale_to_answer_sheet.rb +1 -1
  302. data/db/migrate/20150925181652_add_share_to_elements.rb +5 -0
  303. data/db/migrate/20150928085325_change_pages_all_element_ids_to_text.rb +1 -1
  304. data/db/migrate/20150930191538_add_locale_to_reference_sheets.rb +1 -1
  305. data/db/migrate/20151021181928_switch_conditional_answer_separator_to_semicolon.rb +7 -0
  306. data/db/migrate/20151021184250_add_question_sheet_id_in_refs.rb +12 -0
  307. data/db/migrate/20160201185838_add_visible_and_visibility_cache_key_to_reference_sheets.rb +6 -0
  308. data/db/migrate/20160805221415_add_rating_extra_labels.rb +10 -0
  309. data/db/migrate/20181108201746_create_versions.rb +80 -0
  310. data/db/migrate/20181218201130_increase_slug_length.rb +5 -0
  311. data/lib/fe/engine.rb +10 -10
  312. data/lib/fe/version.rb +1 -1
  313. data/lib/fe.rb +7 -1
  314. data/spec/controllers/fe/admin/elements_controller_spec.rb +30 -20
  315. data/spec/controllers/fe/admin/email_templates_controller_spec.rb +2 -2
  316. data/spec/controllers/fe/admin/question_pages_controller_spec.rb +1 -1
  317. data/spec/controllers/fe/admin/question_sheets_controller_spec.rb +4 -4
  318. data/spec/controllers/fe/answer_pages_controller_spec.rb +86 -30
  319. data/spec/controllers/fe/answer_sheets_controller_spec.rb +65 -9
  320. data/spec/dummy/app/assets/config/manifest.js +0 -0
  321. data/spec/dummy/app/models/user.rb +1 -1
  322. data/spec/dummy/app/views/layouts/application.html.erb +2 -2
  323. data/spec/dummy/config/application.rb +1 -0
  324. data/spec/dummy/config/environments/test.rb +3 -3
  325. data/spec/dummy/config/initializers/assets.rb +5 -2
  326. data/spec/dummy/config/initializers/fast_gettext.rb +1 -1
  327. data/spec/dummy/config/initializers/to_unsafe_h.rb +5 -0
  328. data/spec/dummy/config/initializers/to_unsafe_h.rb.new +5 -0
  329. data/spec/dummy/db/migrate/20141203214017_core.fe_engine.rb +23 -23
  330. data/spec/dummy/db/migrate/20141203214018_create_reference_sheets.fe_engine.rb +1 -1
  331. data/spec/dummy/db/migrate/20141203214019_add_element_and_answer_fields.fe_engine.rb +3 -3
  332. data/spec/dummy/db/migrate/20141203214020_create_email_templates.fe_engine.rb +2 -2
  333. data/spec/dummy/db/migrate/20141203214021_add_max_lengths.fe_engine.rb +1 -1
  334. data/spec/dummy/db/migrate/20141203214022_create_join_table.fe_engine.rb +1 -1
  335. data/spec/dummy/db/migrate/20141203214023_remove_question_id_from_element.fe_engine.rb +1 -1
  336. data/spec/dummy/db/migrate/20141203214024_create_fe_people.fe_engine.rb +1 -1
  337. data/spec/dummy/db/migrate/20141203214025_create_fe_addresses.fe_engine.rb +1 -1
  338. data/spec/dummy/db/migrate/20141203214027_create_fe_users.fe_engine.rb +1 -1
  339. data/spec/dummy/db/migrate/20141203214028_add_conditional_type_to_elements.fe_engine.rb +1 -1
  340. data/spec/dummy/db/migrate/20141203214029_add_conditional_answer_to_elements.fe_engine.rb +1 -1
  341. data/spec/dummy/db/migrate/20141203214030_remove_short_value_column.fe_engine.rb +1 -1
  342. data/spec/dummy/db/migrate/20141203214031_move_conditional_ids_used_for_choice_field_to_their_own_column.fe_engine.rb +1 -1
  343. data/spec/dummy/db/migrate/20150123215803_create_users.rb +1 -1
  344. data/spec/dummy/db/migrate/20150504222619_add_all_element_ids_to_pages.fe_engine.rb +1 -1
  345. data/spec/dummy/db/migrate/20150925192557_add_share_to_elements.fe_engine.rb +6 -0
  346. data/spec/dummy/db/migrate/20150930190001_create_fe_phone_numbers.fe_engine.rb +1 -1
  347. data/spec/dummy/db/migrate/20150930190002_add_locale_columns.fe_engine.rb +1 -1
  348. data/spec/dummy/db/migrate/20150930190003_add_locale_to_answer_sheet.fe_engine.rb +1 -1
  349. data/spec/dummy/db/migrate/20150930190004_change_pages_all_element_ids_to_text.fe_engine.rb +1 -1
  350. data/spec/dummy/db/migrate/20150930191756_add_locale_to_reference_sheets.fe_engine.rb +1 -1
  351. data/spec/dummy/db/migrate/20151021190027_add_question_sheet_id_in_refs.fe_engine.rb +13 -0
  352. data/spec/dummy/db/migrate/20160204164612_switch_conditional_answer_separator_to_semicolon.fe_engine.rb +8 -0
  353. data/spec/dummy/db/migrate/20160204164613_add_visible_and_visibility_cache_key_to_reference_sheets.fe_engine.rb +7 -0
  354. data/spec/dummy/db/migrate/20181108201746_create_versions.rb +80 -0
  355. data/spec/dummy/db/schema.rb +71 -79
  356. data/spec/dummy/log/test.log +101278 -419
  357. data/spec/factories/answer_sheet_question_sheets.rb +1 -1
  358. data/spec/factories/answer_sheets.rb +2 -2
  359. data/spec/factories/answers.rb +1 -1
  360. data/spec/factories/applications.rb +3 -3
  361. data/spec/factories/dummy_applications.rb +3 -3
  362. data/spec/factories/dummy_people.rb +3 -3
  363. data/spec/factories/dummy_users.rb +3 -3
  364. data/spec/factories/elements.rb +21 -21
  365. data/spec/factories/email_templates.rb +3 -3
  366. data/spec/factories/fe_addresses.rb +10 -10
  367. data/spec/factories/fe_email_addresses.rb +3 -3
  368. data/spec/factories/fe_email_templates.rb +4 -4
  369. data/spec/factories/fe_people.rb +5 -5
  370. data/spec/factories/fe_phone_numbers.rb +3 -3
  371. data/spec/factories/fe_user.rb +3 -3
  372. data/spec/factories/page.rb +1 -1
  373. data/spec/factories/page_elements.rb +1 -1
  374. data/spec/factories/paragraphs.rb +1 -1
  375. data/spec/factories/question_sheet.rb +2 -2
  376. data/spec/factories/reference_questions.rb +1 -1
  377. data/spec/factories/reference_sheets.rb +1 -1
  378. data/spec/jobs/fe/update_reference_sheet_visibility_job_spec.rb +40 -0
  379. data/spec/models/fe/answer_sheet_question_sheet_spec.rb +1 -1
  380. data/spec/models/fe/answer_spec.rb +2 -2
  381. data/spec/models/fe/application_spec.rb +94 -1
  382. data/spec/models/fe/choice_field_spec.rb +47 -1
  383. data/spec/models/fe/condition_spec.rb +2 -2
  384. data/spec/models/fe/element_spec.rb +252 -60
  385. data/spec/models/fe/email_template_spec.rb +1 -1
  386. data/spec/models/fe/page_element_spec.rb +1 -1
  387. data/spec/models/fe/page_spec.rb +57 -12
  388. data/spec/models/fe/person_spec.rb +1 -1
  389. data/spec/models/fe/question_set_spec.rb +91 -0
  390. data/spec/models/fe/question_sheet_spec.rb +11 -15
  391. data/spec/models/fe/question_spec.rb +73 -6
  392. data/spec/models/fe/reference_question_spec.rb +20 -0
  393. data/spec/models/fe/reference_sheet_spec.rb +287 -4
  394. data/spec/models/fe/text_field_spec.rb +22 -0
  395. data/spec/rails_helper.rb +79 -76
  396. metadata +195 -57
  397. data/app/assets/javascripts/fe/jquery.scrollTo-min.js +0 -7
  398. data/app/controllers/fe/concerns/answer_pages_controller_concern.rb +0 -84
  399. data/app/models/fe/concerns/answer_sheet_concern.rb +0 -85
  400. data/spec/dummy/db/migrate/20141203214026_create_create_fe_phone_numbers.fe_engine.rb +0 -17
  401. data/spec/dummy/log/development.log +0 -5
  402. /data/app/{assets/stylesheets/360front.css → views.current/fe/admin/elements/reorder.js.erb} +0 -0
@@ -7,24 +7,26 @@ Fe::Application.class_eval do
7
7
  belongs_to :applicant, foreign_key: 'applicant_id', class_name: 'Person'
8
8
  end
9
9
 
10
- describe Fe::Element do
11
- it { expect belong_to :question_grid }
12
- it { expect belong_to :choice_field }
10
+ describe Fe::Element, type: :model do
11
+ it { expect belong_to :question_grid }
12
+ it { expect belong_to :choice_field }
13
13
  it { expect have_many :page_elements }
14
14
  it { expect have_many :pages }
15
15
  it { expect validate_presence_of :kind }
16
16
  # it { expect validate_presence_of :style } # this isn't working
17
- it { expect ensure_length_of :kind }
18
- it { expect ensure_length_of :style }
17
+ it { expect validate_length_of :kind }
18
+ it { expect validate_length_of :style }
19
19
 
20
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")
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
23
  question_sheet.pages.reload
24
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)
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
26
27
 
27
- application = FactoryGirl.create(:answer_sheet)
28
+ application = FactoryBot.create(:answer_sheet)
29
+ application.question_sheets << question_sheet
28
30
 
29
31
  # make the answer to the conditional question 'no' so that the element is not required
30
32
  choice_field.set_response("no", application)
@@ -34,11 +36,11 @@ describe Fe::Element do
34
36
  end
35
37
 
36
38
  it "should update a conditional question if added after that question" do
37
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
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")
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")
39
41
  question_sheet.pages.reload
40
42
  question_sheet.pages[3].elements << conditional_el
41
- 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)
42
44
  question_sheet.pages[3].elements << element
43
45
  conditional_el.reload
44
46
  expect(conditional_el.conditional).to eq(element)
@@ -46,24 +48,24 @@ describe Fe::Element do
46
48
 
47
49
  context "in a grid" do
48
50
  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 = FactoryBot.create(:question_sheet_with_pages)
52
+ question_grid = FactoryBot.create(:question_grid)
51
53
  question_sheet.pages.reload
52
54
  question_sheet.pages[3].elements << question_grid
53
55
 
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
+ 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)
56
58
  expect(conditional_el.reload.conditional).to eq(element)
57
59
  end
58
60
 
59
61
  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 = FactoryBot.create(:question_sheet_with_pages)
63
+ question_grid = FactoryBot.create(:question_grid)
62
64
  question_sheet.pages.reload
63
65
  question_sheet.pages[3].elements << question_grid
64
66
 
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
+ 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)
67
69
 
68
70
  conditional_el.set_conditional_element
69
71
  expect(conditional_el.conditional).to eq(element)
@@ -71,13 +73,13 @@ describe Fe::Element do
71
73
  end
72
74
 
73
75
  it "should update a conditional question if elements are moved around" do
74
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
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")
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")
76
78
  question_sheet.pages.reload
77
79
  question_sheet.pages[3].elements << conditional_el
78
- 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)
79
81
  question_sheet.pages[3].elements << element
80
- 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)
81
83
  question_sheet.pages[3].elements << element2
82
84
 
83
85
  element.reload
@@ -88,17 +90,17 @@ describe Fe::Element do
88
90
  # now swap the last 2 elements
89
91
  old_element_position = element.position(question_sheet.pages[3])
90
92
  old_element2_position = element2.position(question_sheet.pages[3])
91
- element.page_elements.first.update_attributes(position: old_element2_position)
92
- 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)
93
95
 
94
96
  conditional_el.reload
95
97
  expect(conditional_el.conditional).to eq(element2)
96
98
  end
97
99
 
98
100
  it "should set the conditional page if a new conditional page element is created" do
99
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
101
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
100
102
  hide_page = question_sheet.pages[4]
101
- 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)
102
104
  question_sheet.pages.reload
103
105
  question_sheet.pages[3].elements << conditional_el
104
106
  conditional_el.reload
@@ -106,20 +108,20 @@ describe Fe::Element do
106
108
  end
107
109
 
108
110
  it "should keep the conditional page if a page is moved" do
109
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
111
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
110
112
  hide_page = question_sheet.pages[4]
111
- 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)
112
114
  question_sheet.pages.reload
113
115
  question_sheet.pages[3].elements << conditional_el
114
116
  conditional_el.reload
115
117
  expect(conditional_el.conditional).to eq(question_sheet.pages[4])
116
118
 
117
119
  # move some pages around
118
- question_sheet.pages[0].update_attributes number: 1
119
- question_sheet.pages[1].update_attributes number: 2
120
- question_sheet.pages[2].update_attributes number: 3
121
- question_sheet.pages[3].update_attributes number: 0 # the page the conditional element is on
122
- 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
123
125
  question_sheet.pages.reload
124
126
 
125
127
  # the page after the conditional page should still be set to the same page
@@ -128,51 +130,97 @@ describe Fe::Element do
128
130
  end
129
131
 
130
132
  it "should not let a hidden page make the questionnaire incomplete" do
131
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
133
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
132
134
  hide_page = question_sheet.pages[4]
133
- 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")
134
136
  question_sheet.pages.reload
135
137
  question_sheet.pages[3].elements << conditional_el
136
138
  conditional_el.reload
137
139
  expect(conditional_el.conditional).to eq(question_sheet.pages[4])
138
140
 
139
141
  # add required element on hidden page
140
- 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")
141
143
  hide_page.elements << element
142
144
 
143
145
  # set up an answer sheet
144
- application = FactoryGirl.create(:answer_sheet)
145
- application.answer_sheet_question_sheet = FactoryGirl.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
146
- 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
147
150
 
148
151
  # validate the hidden page, it should be marked complete
149
152
  expect(hide_page.complete?(application)).to eq(true)
150
153
 
151
- # 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
152
155
  conditional_el.set_response("yes", application)
153
156
  conditional_el.save_response(application)
154
157
 
155
- # 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
156
160
  expect(hide_page.complete?(application)).to eq(false)
157
161
  end
158
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
+
159
206
  it "should not require questions in a hidden page" do
160
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
207
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
161
208
  hide_page = question_sheet.pages[4]
162
- 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")
163
210
  question_sheet.pages.reload
164
211
  question_sheet.pages[3].elements << conditional_el
165
212
  conditional_el.reload
166
213
  expect(conditional_el.conditional).to eq(question_sheet.pages[4])
167
214
 
168
215
  # add required element on hidden page
169
- 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")
170
217
  hide_page.elements << element
171
218
 
172
219
  # set up an answer sheet
173
- application = FactoryGirl.create(:answer_sheet)
174
- application.answer_sheet_question_sheet = FactoryGirl.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
175
- 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
176
224
 
177
225
  # make the answer to the conditional question 'yes' (match) so that the element is visible (and thus required)
178
226
  conditional_el.set_response("yes", application)
@@ -186,6 +234,7 @@ describe Fe::Element do
186
234
  conditional_el.save_response(application)
187
235
 
188
236
  # validate the hidden page, it should be marked complete because of being hidden
237
+ hide_page.clear_hidden_cache
189
238
  expect(hide_page.complete?(application)).to eq(true)
190
239
  end
191
240
 
@@ -196,13 +245,13 @@ describe Fe::Element do
196
245
 
197
246
  context '#limit' do
198
247
  it "should return a value for a legitimate object_name and attribute_name" do
199
- application = FactoryGirl.create(:application)
248
+ application = FactoryBot.create(:application)
200
249
  application.applicant_id = create(:fe_person).id
201
250
  element = Fe::Element.new object_name: 'applicant', attribute_name: 'first_name'
202
251
  expect(element.limit(application)).to_not be_nil
203
252
  end
204
253
  it "should return nil instead of crashing if there's an exception thrown" do
205
- application = FactoryGirl.create(:application)
254
+ application = FactoryBot.create(:application)
206
255
  application.applicant_id = create(:fe_person).id
207
256
  element = Fe::Element.new object_name: 'applicant', attribute_name: 'asdf'
208
257
  expect(element.limit(application)).to be_nil
@@ -211,7 +260,7 @@ describe Fe::Element do
211
260
 
212
261
  context '#previous_element' do
213
262
  it "should work" do
214
- application = FactoryGirl.create(:application)
263
+ application = FactoryBot.create(:application)
215
264
  application.applicant_id = create(:fe_person).id
216
265
  element1 = create(:text_field_element)
217
266
  element2 = create(:text_field_element)
@@ -225,11 +274,8 @@ describe Fe::Element do
225
274
  end
226
275
 
227
276
  context '#required' do
228
- it "should work when the required flag is set" do
229
- # TODO
230
- end
231
277
  it "should not require a conditional element when its prev element isn't matching the answer text" do
232
- application = FactoryGirl.create(:application)
278
+ application = FactoryBot.create(:application)
233
279
  application.applicant_id = create(:fe_person).id
234
280
  element1 = create(:text_field_element)
235
281
  element2 = create(:text_field_element, conditional_answer: 'test')
@@ -245,9 +291,9 @@ describe Fe::Element do
245
291
  create(:page_element, page_id: page.id, element_id: element3.id)
246
292
 
247
293
  # 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)
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)
251
297
 
252
298
  # make the answer to the conditional question 'yes' so that the element shows up and is thus required
253
299
  element2.set_response('nomatch', application)
@@ -286,7 +332,7 @@ describe Fe::Element do
286
332
  expect(page.elements.last.pages).to eq([page])
287
333
  end
288
334
  end
289
-
335
+
290
336
  context '#update_page_all_element_ids' do
291
337
  it 'should rebuild all_element_ids in all pages' do
292
338
  element1 = create(:text_field_element)
@@ -324,4 +370,150 @@ describe Fe::Element do
324
370
  expect(page.reload.all_element_ids).to eq("#{grid.id},#{textfield.id}")
325
371
  end
326
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
327
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
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe Fe::Page do
3
+ describe Fe::Page, type: :model do
4
4
  it { expect belong_to :question_sheet }
5
5
  it { expect have_many :page_elements }
6
6
  it { expect have_many :elements }
@@ -9,39 +9,40 @@ describe Fe::Page do
9
9
  it { expect have_many :question_grid_with_totals }
10
10
  # it { expect validate_presence_of :label } # this isn't working
11
11
  # it { expect validate_presence_of :number } # this isn't working
12
- it { expect ensure_length_of :label }
12
+ it { expect validate_length_of :label }
13
13
  # it { expect validate_numericality_of :number }
14
14
 
15
15
  it "should not require a hidden element" do
16
- question_sheet = FactoryGirl.create(:question_sheet_with_pages)
17
- conditional_el = FactoryGirl.create(:choice_field_element, label: "This is a test for a yes/no question that will hide the next element if the answer is yes", conditional_type: "Fe::Element", conditional_answer: "yes")
16
+ question_sheet = FactoryBot.create(:question_sheet_with_pages)
17
+ conditional_el = FactoryBot.create(:choice_field_element, label: "This is a test for a yes/no question that will show the next element if the answer is yes", conditional_type: "Fe::Element", conditional_answer: "yes")
18
18
  question_sheet.pages.reload
19
19
  question_sheet.pages[3].elements << conditional_el
20
- element = FactoryGirl.create(:text_field_element, label: "This is a test of a short answer that is made visible by the previous elemenet")
20
+ element = FactoryBot.create(:text_field_element, label: "This is a test of a short answer that is made visible by the previous element")
21
21
  question_sheet.pages[3].elements << element
22
22
  conditional_el.reload
23
23
  expect(conditional_el.conditional).to eq(element)
24
24
 
25
25
  # set up an answer sheet
26
- application = FactoryGirl.create(:answer_sheet)
27
- application.answer_sheet_question_sheet = FactoryGirl.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
28
- application.answer_sheet_question_sheets.first.update_attributes(question_sheet_id: question_sheet.id)
26
+ application = FactoryBot.create(:answer_sheet)
27
+ application.answer_sheet_question_sheet = FactoryBot.create(:answer_sheet_question_sheet, answer_sheet: application, question_sheet: question_sheet)
28
+ application.answer_sheet_question_sheets.first.update(question_sheet_id: question_sheet.id)
29
+ application.reload
29
30
 
30
- # make the answer to the conditional question 'yes' so that the next element shows up and is thus required
31
+ # make the answer to the conditional question 'no' so that the next element does not show up and is not required
31
32
  conditional_el.set_response("no", application)
32
33
  conditional_el.save_response(application)
33
34
 
34
- # validate the page -- the next element after the conditional should not be required
35
+ # validate the page -- the next element after the conditional should not be required (because it's hidden)
35
36
  page = question_sheet.pages[3]
36
37
  question_sheet.pages.reload
37
- page.reload
38
38
  expect(page.complete?(application)).to eq(true)
39
39
 
40
40
  # make the answer to the conditional question 'yes' so that the next element shows up and is thus required
41
41
  conditional_el.set_response("yes", application)
42
42
  conditional_el.save_response(application)
43
+ conditional_el.display_response(application)
43
44
 
44
- # validate the page -- the next element after the conditional should not be required
45
+ # validate the page -- the next element after the conditional be required now, making the page incomplete
45
46
  page = question_sheet.pages[3]
46
47
  expect(page.complete?(application)).to eq(false)
47
48
  end
@@ -155,4 +156,48 @@ describe Fe::Page do
155
156
  expect(p.all_element_ids).to eq('')
156
157
  end
157
158
  end
159
+ context '#copy_to' do
160
+ it 'should return the new page' do
161
+ q = create(:question_sheet)
162
+ p = create(:page)
163
+ r = p.copy_to(q)
164
+ expect(r.class).to be(Fe::Page)
165
+ end
166
+ end
167
+ context '#complete' do
168
+ it "is complete when there's a required element inside a hidden group" do
169
+ q = create(:question_sheet)
170
+ p = create(:page, question_sheet: q)
171
+ g1 = create(:question_grid)
172
+ c = create(:text_field_element, conditional_answer: 'asdf', conditional: g1)
173
+ create(:page_element, page: p, element: c)
174
+ create(:page_element, page: p, element: g1)
175
+ g2 = create(:question_grid_with_total, question_grid: g1)
176
+ e = create(:text_field_element, question_grid: g2)
177
+
178
+ application = create(:answer_sheet)
179
+ application.question_sheets << q
180
+
181
+ c.set_response('asdf', application)
182
+ c.save_response(application)
183
+ expect(e.hidden?(application)).to be(false)
184
+ expect(p.complete?(application)).to be(false)
185
+
186
+ # change the answer to make sure it changes to not required
187
+ c.set_response('something else', application)
188
+ c.save_response(application)
189
+ expect(c.display_response(application)).to eq('something else')
190
+
191
+ expect(e.hidden?(application)).to be(true)
192
+ p.clear_all_hidden_elements
193
+ expect(p.complete?(application)).to be(true)
194
+ end
195
+ end
196
+ context '#hidden' do
197
+ it 'checks the hidden column' do
198
+ q = create(:question_sheet)
199
+ p = create(:page, question_sheet: q, hidden: true)
200
+ expect(p.hidden).to be true
201
+ end
202
+ end
158
203
  end
@@ -1,4 +1,4 @@
1
1
  require 'rails_helper'
2
2
 
3
- RSpec.describe Fe::Person, :type => :model do
3
+ RSpec.describe Fe::Person, type: :model do
4
4
  end