decidim 0.2.0 → 0.3.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 (322) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -1
  3. data/.codeclimate.yml +2 -3
  4. data/.rubocop.yml +1 -48
  5. data/.travis.yml +1 -0
  6. data/Dockerfile +1 -0
  7. data/Gemfile +1 -0
  8. data/Gemfile.lock +119 -115
  9. data/README.md +24 -9
  10. data/Rakefile +14 -10
  11. data/decidim-admin/app/assets/javascripts/decidim/admin/application.js.es6 +21 -9
  12. data/decidim-admin/app/assets/javascripts/decidim/admin/sort_list.component.js.es6 +35 -0
  13. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_language-chooser.scss +4 -0
  14. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_sort.scss +12 -0
  15. data/decidim-admin/app/controllers/decidim/admin/application_controller.rb +1 -0
  16. data/decidim-admin/app/controllers/decidim/admin/participatory_process_attachments_controller.rb +4 -0
  17. data/decidim-admin/app/helpers/decidim/admin/menu_helper.rb +0 -1
  18. data/decidim-admin/app/models/decidim/admin/participatory_process_user_role.rb +2 -2
  19. data/decidim-admin/app/views/decidim/admin/categories/index.html.erb +7 -1
  20. data/decidim-admin/app/views/decidim/admin/exports/_dropdown.html.erb +1 -1
  21. data/decidim-admin/app/views/decidim/admin/moderations/index.html.erb +6 -2
  22. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/index.html.erb +1 -0
  23. data/decidim-admin/app/views/layouts/decidim/admin/_title_bar.html.erb +10 -0
  24. data/decidim-admin/bin/rails +3 -3
  25. data/decidim-admin/config/locales/ca.yml +3 -1
  26. data/decidim-admin/config/locales/en.yml +3 -1
  27. data/decidim-admin/config/locales/es.yml +3 -1
  28. data/decidim-admin/config/locales/eu.yml +0 -1
  29. data/decidim-admin/config/locales/fi.yml +0 -1
  30. data/decidim-admin/config/locales/fr.yml +0 -1
  31. data/decidim-admin/config/locales/it.yml +490 -0
  32. data/decidim-admin/db/migrate/20161102144648_add_admin_participatory_process_user_roles.rb +5 -3
  33. data/decidim-admin/db/migrate/20170128112958_change_user_groups_verified_to_timestamp.rb +2 -0
  34. data/decidim-admin/decidim-admin.gemspec +2 -1
  35. data/decidim-admin/lib/decidim/admin/engine.rb +1 -1
  36. data/decidim-admin/lib/decidim/admin/test/manage_attachments_examples.rb +3 -3
  37. data/decidim-admin/spec/commands/reject_user_group_spec.rb +2 -2
  38. data/decidim-admin/spec/features/admin_copy_participatory_process_spec.rb +2 -2
  39. data/decidim-admin/spec/features/admin_invite_spec.rb +1 -1
  40. data/decidim-admin/spec/features/admin_manages_features_spec.rb +2 -2
  41. data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +4 -4
  42. data/decidim-admin/spec/features/admin_manages_organization_spec.rb +6 -6
  43. data/decidim-admin/spec/features/admin_manages_participatory_process_groups_spec.rb +4 -4
  44. data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +4 -4
  45. data/decidim-admin/spec/features/static_pages_spec.rb +4 -4
  46. data/decidim-admin/spec/forms/organization_form_spec.rb +1 -1
  47. data/decidim-admin/spec/shared/manage_process_categories_examples.rb +44 -29
  48. data/decidim-admin/spec/shared/manage_process_steps_examples.rb +3 -3
  49. data/decidim-admin/spec/shared/manage_processes_examples.rb +1 -1
  50. data/decidim-admin/spec/shared/participatory_admin_shared_context.rb +3 -3
  51. data/decidim-admin/spec/spec_helper.rb +3 -2
  52. data/decidim-api/bin/rails +3 -3
  53. data/decidim-api/decidim-api.gemspec +2 -1
  54. data/decidim-api/lib/decidim/api/engine.rb +1 -1
  55. data/decidim-api/spec/spec_helper.rb +3 -2
  56. data/decidim-budgets/app/controllers/decidim/budgets/application_controller.rb +1 -1
  57. data/decidim-budgets/app/models/decidim/budgets/line_item.rb +1 -2
  58. data/decidim-budgets/app/models/decidim/budgets/order.rb +2 -2
  59. data/decidim-budgets/app/views/decidim/budgets/projects/_linked_projects.html.erb +1 -1
  60. data/decidim-budgets/bin/rails +3 -3
  61. data/decidim-budgets/config/locales/it.yml +126 -0
  62. data/decidim-budgets/db/migrate/20170127114122_create_projects.rb +2 -0
  63. data/decidim-budgets/db/migrate/20170130095615_create_orders.rb +2 -0
  64. data/decidim-budgets/db/migrate/20170130101825_create_line_items.rb +2 -0
  65. data/decidim-budgets/db/migrate/20170207101750_remove_short_description_from_decidim_projects.rb +2 -0
  66. data/decidim-budgets/db/migrate/20170215132708_add_reference_to_projects.rb +2 -0
  67. data/decidim-budgets/db/migrate/20170410074214_remove_not_null_reference_budgets.rb +2 -0
  68. data/decidim-budgets/db/migrate/20170612101846_migrate_projects_category.rb +15 -0
  69. data/decidim-budgets/decidim-budgets.gemspec +3 -1
  70. data/decidim-budgets/lib/decidim/budgets/feature.rb +2 -2
  71. data/decidim-budgets/spec/features/admin_manages_project_attachments_spec.rb +5 -3
  72. data/decidim-budgets/spec/features/admin_manages_projects_spec.rb +5 -7
  73. data/decidim-budgets/spec/features/process_admin_manages_project_attachments_spec.rb +4 -4
  74. data/decidim-budgets/spec/features/process_admin_manages_projects_spec.rb +5 -8
  75. data/decidim-budgets/spec/shared/manage_attachments_examples.rb +0 -4
  76. data/decidim-budgets/spec/shared/manage_projects_examples.rb +3 -3
  77. data/decidim-budgets/spec/spec_helper.rb +2 -1
  78. data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
  79. data/decidim-comments/app/commands/decidim/comments/create_comment.rb +2 -2
  80. data/decidim-comments/app/frontend/comments/add_comment_form.component.tsx +1 -0
  81. data/decidim-comments/app/frontend/comments/comment.component.test.tsx +12 -1
  82. data/decidim-comments/app/frontend/comments/comment.component.tsx +42 -4
  83. data/decidim-comments/app/frontend/comments/comment_thread.component.test.tsx +11 -0
  84. data/decidim-comments/app/frontend/comments/comment_thread.component.tsx +5 -1
  85. data/decidim-comments/app/frontend/fragments/comment_data.fragment.graphql +3 -0
  86. data/decidim-comments/app/frontend/support/generate_comments_data.ts +3 -0
  87. data/decidim-comments/app/frontend/support/schema.ts +18 -12
  88. data/decidim-comments/app/mailers/decidim/comments/comment_notification_mailer.rb +6 -4
  89. data/decidim-comments/app/models/decidim/comments/comment.rb +6 -4
  90. data/decidim-comments/app/models/decidim/comments/comment_vote.rb +1 -2
  91. data/decidim-comments/app/models/decidim/comments/seed.rb +5 -2
  92. data/decidim-comments/app/resolvers/decidim/comments/vote_comment_resolver.rb +3 -0
  93. data/decidim-comments/app/types/decidim/comments/commentable_interface.rb +3 -3
  94. data/decidim-comments/app/views/decidim/comments/comment_notification_mailer/comment_created.html.erb +1 -1
  95. data/decidim-comments/app/views/decidim/comments/comment_notification_mailer/reply_created.html.erb +1 -1
  96. data/decidim-comments/bin/rails +3 -3
  97. data/decidim-comments/config/locales/ca.yml +5 -0
  98. data/decidim-comments/config/locales/en.yml +5 -0
  99. data/decidim-comments/config/locales/es.yml +5 -0
  100. data/decidim-comments/config/locales/it.yml +65 -0
  101. data/decidim-comments/db/migrate/20161130143508_create_comments.rb +2 -0
  102. data/decidim-comments/db/migrate/20161214082645_add_depth_to_comments.rb +2 -0
  103. data/decidim-comments/db/migrate/20161216102820_add_alignment_to_comments.rb +2 -0
  104. data/decidim-comments/db/migrate/20161219150806_create_comment_votes.rb +3 -1
  105. data/decidim-comments/db/migrate/20170123102043_add_user_group_id_to_comments.rb +2 -0
  106. data/decidim-comments/db/migrate/20170504085413_add_root_commentable_to_comments.rb +2 -0
  107. data/decidim-comments/db/migrate/20170510091348_update_root_commentable_for_comments.rb +3 -2
  108. data/decidim-comments/db/migrate/20170510091409_set_root_commentable_null_constraints.rb +2 -0
  109. data/decidim-comments/decidim-comments.gemspec +2 -1
  110. data/decidim-comments/lib/decidim/comments/comment_serializer.rb +1 -1
  111. data/decidim-comments/lib/decidim/comments/commentable.rb +4 -4
  112. data/decidim-comments/spec/commands/create_comment_spec.rb +2 -2
  113. data/decidim-comments/spec/features/admin_manages_comments_spec.rb +4 -9
  114. data/decidim-comments/spec/features/process_admin_manages_comments_spec.rb +5 -11
  115. data/decidim-comments/spec/mailers/comment_notification_mailer_spec.rb +12 -7
  116. data/decidim-comments/spec/shared/author_localised_email.rb +26 -0
  117. data/decidim-comments/spec/spec_helper.rb +1 -1
  118. data/decidim-dev/config/locales/it.yml +9 -0
  119. data/decidim-dev/decidim-dev.gemspec +8 -3
  120. data/decidim-dev/lib/decidim/dev.rb +1 -8
  121. data/decidim-dev/lib/decidim/dev/railtie.rb +1 -1
  122. data/decidim-dev/lib/decidim/dev/test/base_spec_helper.rb +6 -4
  123. data/decidim-dev/lib/decidim/dev/test/rspec_support/capybara.rb +2 -2
  124. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +4 -2
  125. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature_context.rb +28 -8
  126. data/decidim-dev/lib/decidim/dev/test/rspec_support/translation_helpers.rb +7 -2
  127. data/decidim-dev/lib/decidim/dev/test/spec_helper.rb +2 -2
  128. data/decidim-dev/lib/generators/decidim/dummy_generator.rb +1 -1
  129. data/decidim-meetings/README.md +1 -1
  130. data/decidim-meetings/app/controllers/decidim/meetings/application_controller.rb +1 -1
  131. data/decidim-meetings/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
  132. data/decidim-meetings/bin/rails +3 -3
  133. data/decidim-meetings/config/locales/it.yml +87 -0
  134. data/decidim-meetings/db/migrate/20161130121354_create_meetings.rb +2 -0
  135. data/decidim-meetings/db/migrate/20170110142105_close_a_meeting.rb +2 -0
  136. data/decidim-meetings/db/migrate/20170123151650_add_latitude_and_longitude_to_meetings.rb +2 -0
  137. data/decidim-meetings/db/migrate/20170129153716_remove_short_description_from_meetings.rb +2 -0
  138. data/decidim-meetings/db/migrate/20170215132546_add_reference_to_meetings.rb +2 -0
  139. data/decidim-meetings/db/migrate/20170410074252_remove_not_null_reference_meetings.rb +2 -0
  140. data/decidim-meetings/db/migrate/20170612101925_migrate_meetings_category.rb +15 -0
  141. data/decidim-meetings/decidim-meetings.gemspec +3 -1
  142. data/decidim-meetings/lib/decidim/meetings/feature.rb +2 -2
  143. data/decidim-meetings/spec/features/admin_manages_meetings_attachments_spec.rb +5 -1
  144. data/decidim-meetings/spec/features/admin_manages_meetings_spec.rb +5 -7
  145. data/decidim-meetings/spec/features/explore_meetings_spec.rb +32 -6
  146. data/decidim-meetings/spec/features/process_admin_manages_meetings_attachments_spec.rb +4 -2
  147. data/decidim-meetings/spec/features/process_admin_manages_meetings_spec.rb +5 -8
  148. data/decidim-meetings/spec/shared/manage_attachments_examples.rb +0 -3
  149. data/decidim-meetings/spec/shared/manage_meetings_examples.rb +11 -11
  150. data/decidim-meetings/spec/spec_helper.rb +2 -1
  151. data/decidim-pages/bin/rails +3 -3
  152. data/decidim-pages/config/locales/it.yml +22 -0
  153. data/decidim-pages/db/migrate/20161116121353_create_decidim_pages.rb +2 -0
  154. data/decidim-pages/db/migrate/20161214150429_add_commentable_to_pages.rb +2 -0
  155. data/decidim-pages/db/migrate/20170110145040_remove_commentable_flag_from_pages.rb +2 -0
  156. data/decidim-pages/db/migrate/20170220091402_remove_page_feature_titles.rb +2 -0
  157. data/decidim-pages/decidim-pages.gemspec +3 -1
  158. data/decidim-pages/spec/features/admin_spec.rb +1 -1
  159. data/decidim-pages/spec/spec_helper.rb +2 -3
  160. data/decidim-proposals/app/commands/decidim/proposals/unvote_proposal.rb +34 -0
  161. data/decidim-proposals/app/commands/decidim/proposals/vote_proposal.rb +39 -0
  162. data/decidim-proposals/app/controllers/concerns/decidim/proposals/orderable.rb +7 -3
  163. data/decidim-proposals/app/controllers/decidim/proposals/proposal_votes_controller.rb +18 -8
  164. data/decidim-proposals/app/models/decidim/proposals/proposal.rb +3 -3
  165. data/decidim-proposals/app/models/decidim/proposals/proposal_vote.rb +0 -1
  166. data/decidim-proposals/app/views/decidim/proposals/proposals/_author.html.erb +23 -0
  167. data/decidim-proposals/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +2 -2
  168. data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -9
  169. data/decidim-proposals/app/views/decidim/proposals/proposals/_vote_button.html.erb +2 -6
  170. data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +1 -1
  171. data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +1 -11
  172. data/decidim-proposals/bin/rails +3 -3
  173. data/decidim-proposals/config/locales/ca.yml +6 -0
  174. data/decidim-proposals/config/locales/en.yml +6 -0
  175. data/decidim-proposals/config/locales/es.yml +6 -0
  176. data/decidim-proposals/config/locales/eu.yml +0 -2
  177. data/decidim-proposals/config/locales/fi.yml +0 -2
  178. data/decidim-proposals/config/locales/fr.yml +0 -2
  179. data/decidim-proposals/config/locales/it.yml +147 -0
  180. data/decidim-proposals/db/migrate/20161212110850_create_decidim_proposals.rb +2 -0
  181. data/decidim-proposals/db/migrate/20170112115253_create_proposal_votes.rb +3 -1
  182. data/decidim-proposals/db/migrate/20170113114245_add_text_search_indexes.rb +2 -0
  183. data/decidim-proposals/db/migrate/20170118120151_add_counter_cache_votes_to_proposals.rb +2 -0
  184. data/decidim-proposals/db/migrate/20170120151202_add_user_group_id_to_proposals.rb +2 -0
  185. data/decidim-proposals/db/migrate/20170131092413_add_answers_to_proposals.rb +2 -0
  186. data/decidim-proposals/db/migrate/20170205082832_add_index_to_decidim_proposals_proposals_proposal_votes_count.rb +2 -0
  187. data/decidim-proposals/db/migrate/20170215113152_create_proposal_reports.rb +2 -0
  188. data/decidim-proposals/db/migrate/20170215131720_add_report_count_to_proposals.rb +2 -0
  189. data/decidim-proposals/db/migrate/20170215132030_add_reference_to_proposals.rb +2 -0
  190. data/decidim-proposals/db/migrate/20170220152416_add_hidden_at_to_proposals.rb +2 -0
  191. data/decidim-proposals/db/migrate/20170228105156_add_geolocalization_fields_to_proposals.rb +2 -0
  192. data/decidim-proposals/db/migrate/20170307085300_migrate_proposal_reports_data_to_reports.rb +8 -10
  193. data/decidim-proposals/db/migrate/20170410073742_remove_not_null_reference_proposals.rb +2 -0
  194. data/decidim-proposals/db/migrate/20170612101809_migrate_proposals_category.rb +15 -0
  195. data/decidim-proposals/decidim-proposals.gemspec +4 -2
  196. data/decidim-proposals/lib/decidim/proposals/feature.rb +5 -1
  197. data/decidim-proposals/lib/decidim/proposals/proposal_serializer.rb +1 -6
  198. data/decidim-proposals/spec/commands/decidim/proposals/unvote_proposal_spec.rb +26 -0
  199. data/decidim-proposals/spec/commands/decidim/proposals/vote_proposal_spec.rb +47 -0
  200. data/decidim-proposals/spec/features/admin_manages_proposals_spec.rb +6 -11
  201. data/decidim-proposals/spec/features/process_admin_manages_proposals_spec.rb +6 -12
  202. data/decidim-proposals/spec/features/proposals_spec.rb +38 -12
  203. data/decidim-proposals/spec/shared/manage_proposals_examples.rb +3 -6
  204. data/decidim-proposals/spec/spec_helper.rb +2 -1
  205. data/decidim-results/app/controllers/decidim/results/application_controller.rb +1 -1
  206. data/decidim-results/app/views/decidim/results/results/_linked_results.html.erb +1 -1
  207. data/decidim-results/bin/rails +3 -3
  208. data/decidim-results/config/locales/it.yml +78 -0
  209. data/decidim-results/db/migrate/20170116104125_create_results.rb +2 -0
  210. data/decidim-results/db/migrate/20170129164553_remove_short_description_from_results.rb +2 -0
  211. data/decidim-results/db/migrate/20170215132624_add_reference_to_results.rb +2 -0
  212. data/decidim-results/db/migrate/20170410074358_remove_not_null_reference_results.rb +2 -0
  213. data/decidim-results/db/migrate/20170612101951_migrate_results_category.rb +15 -0
  214. data/decidim-results/decidim-results.gemspec +3 -1
  215. data/decidim-results/spec/features/admin_manages_results_spec.rb +5 -7
  216. data/decidim-results/spec/features/process_admin_manages_results_spec.rb +5 -8
  217. data/decidim-results/spec/shared/manage_results_examples.rb +3 -3
  218. data/decidim-results/spec/spec_helper.rb +2 -1
  219. data/decidim-surveys/README.md +24 -0
  220. data/decidim-surveys/Rakefile +3 -0
  221. data/decidim-surveys/app/assets/config/admin/decidim_surveys_manifest.js +1 -0
  222. data/decidim-surveys/app/assets/images/decidim/surveys/icon.svg +1 -0
  223. data/decidim-surveys/app/assets/javascripts/decidim/surveys/admin/auto_label_by_position.component.js.es6 +33 -0
  224. data/decidim-surveys/app/assets/javascripts/decidim/surveys/admin/dynamic_fields.component.js.es6 +95 -0
  225. data/decidim-surveys/app/assets/javascripts/decidim/surveys/admin/surveys.js.es6 +85 -0
  226. data/decidim-surveys/app/assets/stylesheets/decidim/surveys/surveys.scss +9 -0
  227. data/decidim-surveys/app/commands/decidim/surveys/admin/update_survey.rb +65 -0
  228. data/decidim-surveys/app/commands/decidim/surveys/answer_survey.rb +43 -0
  229. data/decidim-surveys/app/commands/decidim/surveys/create_survey.rb +19 -0
  230. data/decidim-surveys/app/controllers/decidim/surveys/admin/application_controller.rb +15 -0
  231. data/decidim-surveys/app/controllers/decidim/surveys/admin/surveys_controller.rb +55 -0
  232. data/decidim-surveys/app/controllers/decidim/surveys/application_controller.rb +13 -0
  233. data/decidim-surveys/app/controllers/decidim/surveys/surveys_controller.rb +39 -0
  234. data/decidim-surveys/app/forms/decidim/surveys/admin/survey_form.rb +19 -0
  235. data/decidim-surveys/app/forms/decidim/surveys/admin/survey_question_answer_option_form.rb +15 -0
  236. data/decidim-surveys/app/forms/decidim/surveys/admin/survey_question_form.rb +24 -0
  237. data/decidim-surveys/app/forms/decidim/surveys/survey_answer_form.rb +36 -0
  238. data/decidim-surveys/app/forms/decidim/surveys/survey_form.rb +22 -0
  239. data/decidim-surveys/app/helpers/decidim/surveys/admin/application_helper.rb +39 -0
  240. data/decidim-surveys/app/models/decidim/surveys/abilities/admin_user.rb +34 -0
  241. data/decidim-surveys/app/models/decidim/surveys/abilities/current_user.rb +47 -0
  242. data/decidim-surveys/app/models/decidim/surveys/abilities/process_admin_user.rb +44 -0
  243. data/decidim-surveys/app/models/decidim/surveys/application_record.rb +10 -0
  244. data/decidim-surveys/app/models/decidim/surveys/survey.rb +25 -0
  245. data/decidim-surveys/app/models/decidim/surveys/survey_answer.rb +27 -0
  246. data/decidim-surveys/app/models/decidim/surveys/survey_question.rb +18 -0
  247. data/decidim-surveys/app/queries/decidim/surveys/survey_user_answers.rb +28 -0
  248. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/_answer_option.html.erb +23 -0
  249. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/_form.html.erb +47 -0
  250. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/_question.html.erb +57 -0
  251. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/edit.html.erb +7 -0
  252. data/decidim-surveys/app/views/decidim/surveys/surveys/show.html.erb +102 -0
  253. data/decidim-surveys/bin/rails +15 -0
  254. data/decidim-surveys/config/i18n-tasks.yml +11 -0
  255. data/decidim-surveys/config/locales/ca.yml +69 -0
  256. data/decidim-surveys/config/locales/en.yml +73 -0
  257. data/decidim-surveys/config/locales/es.yml +69 -0
  258. data/decidim-surveys/config/locales/eu.yml +5 -0
  259. data/decidim-surveys/config/locales/fi.yml +5 -0
  260. data/decidim-surveys/config/locales/fr.yml +5 -0
  261. data/decidim-surveys/config/locales/it.yml +5 -0
  262. data/decidim-surveys/config/locales/nl.yml +5 -0
  263. data/decidim-surveys/db/migrate/20170511092231_create_decidim_surveys.rb +15 -0
  264. data/decidim-surveys/db/migrate/20170515090916_create_decidim_survey_questions.rb +12 -0
  265. data/decidim-surveys/db/migrate/20170515144119_create_decidim_survey_answers.rb +14 -0
  266. data/decidim-surveys/db/migrate/20170518085302_add_position_to_surveys_questions.rb +7 -0
  267. data/decidim-surveys/db/migrate/20170522075938_add_mandatory_to_surveys_questions.rb +7 -0
  268. data/decidim-surveys/db/migrate/20170524122229_add_question_type_to_surveys_questions.rb +7 -0
  269. data/decidim-surveys/db/migrate/20170525132233_add_answer_options_to_surveys_questions.rb +7 -0
  270. data/decidim-surveys/decidim-surveys.gemspec +22 -0
  271. data/decidim-surveys/lib/decidim/surveys.rb +14 -0
  272. data/decidim-surveys/lib/decidim/surveys/admin.rb +10 -0
  273. data/decidim-surveys/lib/decidim/surveys/admin_engine.rb +34 -0
  274. data/decidim-surveys/lib/decidim/surveys/engine.rb +25 -0
  275. data/decidim-surveys/lib/decidim/surveys/feature.rb +85 -0
  276. data/decidim-surveys/lib/decidim/surveys/survey_user_answers_serializer.rb +23 -0
  277. data/decidim-surveys/lib/decidim/surveys/test/factories.rb +39 -0
  278. data/decidim-surveys/spec/commands/decidim/surveys/admin/update_survey_spec.rb +147 -0
  279. data/decidim-surveys/spec/commands/decidim/surveys/answer_survey_spec.rb +71 -0
  280. data/decidim-surveys/spec/commands/decidim/surveys/create_survey_spec.rb +44 -0
  281. data/decidim-surveys/spec/factories.rb +3 -0
  282. data/decidim-surveys/spec/features/admin_manages_surveys_spec.rb +13 -0
  283. data/decidim-surveys/spec/features/process_admin_manages_surveys_spec.rb +13 -0
  284. data/decidim-surveys/spec/features/survey_spec.rb +235 -0
  285. data/decidim-surveys/spec/forms/decidim/surveys/admin/survey_form_spec.rb +64 -0
  286. data/decidim-surveys/spec/forms/decidim/surveys/admin/survey_question_form_spec.rb +36 -0
  287. data/decidim-surveys/spec/forms/decidim/surveys/survey_answer_form_spec.rb +36 -0
  288. data/decidim-surveys/spec/forms/decidim/surveys/survey_form_spec.rb +32 -0
  289. data/decidim-surveys/spec/models/decidim/surveys/abilities/admin_user_spec.rb +22 -0
  290. data/decidim-surveys/spec/models/decidim/surveys/abilities/current_user_spec.rb +19 -0
  291. data/decidim-surveys/spec/models/decidim/surveys/abilities/process_admin_user_spec.rb +23 -0
  292. data/decidim-surveys/spec/models/decidim/surveys/survey_answer_spec.rb +55 -0
  293. data/decidim-surveys/spec/models/decidim/surveys/survey_question_spec.rb +19 -0
  294. data/decidim-surveys/spec/models/decidim/surveys/survey_spec.rb +65 -0
  295. data/decidim-surveys/spec/queries/decidim/surveys/survey_user_answers_spec.rb +21 -0
  296. data/decidim-surveys/spec/services/decidim/surveys/surveys/survey_user_answer_serializer_spec.rb +34 -0
  297. data/decidim-surveys/spec/shared/edit_survey_examples.rb +213 -0
  298. data/decidim-surveys/spec/shared/export_survey_user_answers_examples.rb +47 -0
  299. data/decidim-surveys/spec/spec_helper.rb +4 -0
  300. data/decidim-system/app/controllers/decidim/system/devise/passwords_controller.rb +2 -0
  301. data/decidim-system/app/helpers/decidim/system/menu_helper.rb +0 -1
  302. data/decidim-system/bin/rails +3 -3
  303. data/decidim-system/config/locales/it.yml +66 -0
  304. data/decidim-system/db/migrate/20160919105637_devise_create_decidim_admins.rb +2 -0
  305. data/decidim-system/decidim-system.gemspec +2 -1
  306. data/decidim-system/spec/spec_helper.rb +3 -2
  307. data/decidim.gemspec +5 -4
  308. data/docs/geocoding.md +2 -2
  309. data/docs/how_to_create_a_plugin.md +11 -11
  310. data/lib/decidim.rb +1 -0
  311. data/lib/generators/decidim/app_generator.rb +3 -2
  312. data/lib/generators/decidim/demo_generator.rb +1 -1
  313. data/lib/generators/decidim/docker_generator.rb +2 -2
  314. data/lib/generators/decidim/install_generator.rb +3 -6
  315. data/lib/generators/decidim/templates/initializer.rb +2 -2
  316. metadata +130 -47
  317. data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +0 -30
  318. data/decidim-budgets/spec/shared/admin_shared_context.rb +0 -13
  319. data/decidim-comments/spec/shared/admin_shared_context.rb +0 -13
  320. data/decidim-meetings/spec/shared/admin_shared_context.rb +0 -13
  321. data/decidim-proposals/spec/shared/admin_shared_context.rb +0 -13
  322. data/decidim-results/spec/shared/admin_shared_context.rb +0 -13
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ module Surveys
7
+ module Admin
8
+ describe UpdateSurvey, :db do
9
+ let(:current_organization) { create(:organization) }
10
+ let(:participatory_process) { create(:participatory_process, organization: current_organization) }
11
+ let(:feature) { create(:feature, manifest_name: "surveys", participatory_process: participatory_process) }
12
+ let(:survey) { create(:survey, feature: feature) }
13
+ let(:published_at) { nil }
14
+ let(:form_params) do
15
+ {
16
+ "description" => {
17
+ "en" => "<p>Content</p>",
18
+ "ca" => "<p>Contingut</p>",
19
+ "es" => "<p>Contenido</p>"
20
+ },
21
+ "questions" => [
22
+ {
23
+ "body" => {
24
+ "en" => "First question",
25
+ "ca" => "Primera pregunta",
26
+ "es" => "Primera pregunta"
27
+ },
28
+ "position" => "0",
29
+ "question_type" => "short_answer",
30
+ "answer_options" => []
31
+ },
32
+ {
33
+ "body" => {
34
+ "en" => "Second question",
35
+ "ca" => "Segona pregunta",
36
+ "es" => "Segunda pregunta"
37
+ },
38
+ "position" => "1",
39
+ "mandatory" => "1",
40
+ "question_type" => "long_answer",
41
+ "answer_options" => []
42
+ },
43
+ {
44
+ "body" => {
45
+ "en" => "Third question",
46
+ "ca" => "Tercera pregunta",
47
+ "es" => "Tercera pregunta"
48
+ },
49
+ "position" => "2",
50
+ "question_type" => "single_option",
51
+ "answer_options" => [
52
+ {
53
+ "body" => {
54
+ "en" => "First answer",
55
+ "ca" => "Primera resposta",
56
+ "es" => "Primera respuesta"
57
+ }
58
+ },
59
+ {
60
+ "body" => {
61
+ "en" => "Second answer",
62
+ "ca" => "Segona resposta",
63
+ "es" => "Segunda respuesta"
64
+ }
65
+ }
66
+ ]
67
+ }
68
+ ],
69
+ "published_at" => published_at
70
+ }
71
+ end
72
+ let(:form) do
73
+ SurveyForm.from_params(
74
+ form_params
75
+ ).with_context(
76
+ current_organization: current_organization
77
+ )
78
+ end
79
+ let(:command) { described_class.new(form, survey) }
80
+
81
+ describe "when the form is invalid" do
82
+ before do
83
+ expect(form).to receive(:invalid?).and_return(true)
84
+ end
85
+
86
+ it "broadcasts invalid" do
87
+ expect { command.call }.to broadcast(:invalid)
88
+ end
89
+
90
+ it "doesn't update the survey" do
91
+ expect(survey).not_to receive(:update_attributes!)
92
+ command.call
93
+ end
94
+ end
95
+
96
+ describe "when the form is valid" do
97
+ it "broadcasts ok" do
98
+ expect { command.call }.to broadcast(:ok)
99
+ end
100
+
101
+ it "updates the survey" do
102
+ command.call
103
+ survey.reload
104
+
105
+ expect(survey.description["en"]).to eq("<p>Content</p>")
106
+ expect(survey.questions.length).to eq(3)
107
+
108
+ survey.questions.each_with_index do |question, idx|
109
+ expect(question.body["en"]).to eq(form_params["questions"][idx]["body"]["en"])
110
+ end
111
+
112
+ expect(survey.questions[1]).to be_mandatory
113
+ expect(survey.questions[1].question_type).to eq("long_answer")
114
+ expect(survey.questions[2].answer_options[1]["body"]["en"]).to eq(form_params["questions"][2]["answer_options"][1]["body"]["en"])
115
+ end
116
+ end
117
+
118
+ describe "when the survey has an existing question" do
119
+ let!(:survey_question) { create(:survey_question, survey: survey) }
120
+
121
+ context "and the question should be removed" do
122
+ let(:form_params) do
123
+ {
124
+ "questions" => [
125
+ {
126
+ "id" => survey_question.id,
127
+ "body" => survey_question.body,
128
+ "position" => 0,
129
+ "question_type" => "short_answer",
130
+ "deleted" => "true"
131
+ }
132
+ ]
133
+ }
134
+ end
135
+
136
+ it "deletes the survey question" do
137
+ command.call
138
+ survey.reload
139
+
140
+ expect(survey.questions.length).to eq(0)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ module Surveys
7
+ describe AnswerSurvey, :db do
8
+ let(:current_organization) { create(:organization) }
9
+ let(:current_user) { create(:user, organization: current_organization) }
10
+ let(:participatory_process) { create(:participatory_process, organization: current_organization) }
11
+ let(:feature) { create(:feature, manifest_name: "surveys", participatory_process: participatory_process) }
12
+ let(:survey) { create(:survey, feature: feature) }
13
+ let(:survey_question_1) { create(:survey_question, survey: survey) }
14
+ let(:survey_question_2) { create(:survey_question, survey: survey) }
15
+ let(:form_params) do
16
+ {
17
+ "answers" => [
18
+ {
19
+ "body" => "This is my first answer",
20
+ "question_id" => survey_question_1.id
21
+ },
22
+ {
23
+ "body" => "This is my first answer",
24
+ "question_id" => survey_question_2.id
25
+ }
26
+ ],
27
+ "tos_agreement" => "1"
28
+ }
29
+ end
30
+ let(:form) do
31
+ SurveyForm.from_params(
32
+ form_params
33
+ ).with_context(
34
+ current_organization: current_organization,
35
+ current_feature: feature
36
+ )
37
+ end
38
+ let(:command) { described_class.new(form, current_user, survey) }
39
+
40
+ describe "when the form is invalid" do
41
+ before do
42
+ expect(form).to receive(:invalid?).and_return(true)
43
+ end
44
+
45
+ it "broadcasts invalid" do
46
+ expect { command.call }.to broadcast(:invalid)
47
+ end
48
+
49
+ it "doesn't create survey answers" do
50
+ expect do
51
+ command.call
52
+ end.not_to change { SurveyAnswer.count }
53
+ end
54
+ end
55
+
56
+ describe "when the form is valid" do
57
+ it "broadcasts ok" do
58
+ expect { command.call }.to broadcast(:ok)
59
+ end
60
+
61
+ it "creates a survey answer for each question answered" do
62
+ expect do
63
+ command.call
64
+ end.to change { SurveyAnswer.count }.by(2)
65
+ last_answer = SurveyAnswer.last
66
+ expect(last_answer.survey).to eq(survey)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Decidim
6
+ module Surveys
7
+ describe CreateSurvey, :db do
8
+ describe "call" do
9
+ let(:feature) { create(:feature, manifest_name: "surveys") }
10
+ let(:command) { described_class.new(feature) }
11
+
12
+ describe "when the survey is not saved" do
13
+ before do
14
+ expect_any_instance_of(Survey).to receive(:save).and_return(false)
15
+ end
16
+
17
+ it "broadcasts invalid" do
18
+ expect { command.call }.to broadcast(:invalid)
19
+ end
20
+
21
+ it "doesn't create a survey" do
22
+ expect do
23
+ command.call
24
+ end.not_to change { Survey.count }
25
+ end
26
+ end
27
+
28
+ describe "when the survey is saved" do
29
+ it "broadcasts ok" do
30
+ expect { command.call }.to broadcast(:ok)
31
+ end
32
+
33
+ it "creates a new survey with the same name as the feature" do
34
+ expect(Survey).to receive(:new).with(feature: feature).and_call_original
35
+
36
+ expect do
37
+ command.call
38
+ end.to change { Survey.count }.by(1)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/surveys/test/factories"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Admin manages surveys", type: :feature do
6
+ let(:manifest_name) { "surveys" }
7
+ let!(:survey) { create :survey, feature: feature }
8
+
9
+ include_context "feature admin"
10
+
11
+ it_behaves_like "edit surveys"
12
+ it_behaves_like "export survey user answers"
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Process admin manages surveys", type: :feature do
6
+ let(:manifest_name) { "surveys" }
7
+ let!(:survey) { create :survey, feature: feature }
8
+
9
+ include_context "feature process admin"
10
+
11
+ it_behaves_like "edit surveys"
12
+ it_behaves_like "export survey user answers"
13
+ end
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Answer a survey", type: :feature do
6
+ let(:manifest_name) { "surveys" }
7
+
8
+ let(:title) do
9
+ {
10
+ "en" => "Survey's title",
11
+ "ca" => "Títol de l'enquesta'",
12
+ "es" => "Título de la encuesta"
13
+ }
14
+ end
15
+ let(:description) do
16
+ {
17
+ "en" => "<p>Survey's content</p>",
18
+ "ca" => "<p>Contingut de l'enquesta</p>",
19
+ "es" => "<p>Contenido de la encuesta</p>"
20
+ }
21
+ end
22
+ let(:user) { create(:user, :confirmed, organization: feature.organization) }
23
+ let!(:survey) { create(:survey, feature: feature, title: title, description: description) }
24
+ let!(:survey_question_1) { create(:survey_question, survey: survey, position: 1) }
25
+ let!(:survey_question_2) { create(:survey_question, survey: survey, position: 0) }
26
+
27
+ include_context "feature"
28
+
29
+ context "when the survey doesn't allow answers" do
30
+ it "the survey cannot be answered" do
31
+ visit_feature
32
+
33
+ expect(page).to have_i18n_content(survey.title, upcase: true)
34
+ expect(page).to have_i18n_content(survey.description)
35
+
36
+ expect(page).not_to have_i18n_content(survey_question_1.body)
37
+ expect(page).not_to have_i18n_content(survey_question_2.body)
38
+
39
+ expect(page).to have_content("The survey is closed and cannot be answered.")
40
+ end
41
+ end
42
+
43
+ context "when the survey allow answers" do
44
+ before do
45
+ feature.update_attributes(
46
+ step_settings: {
47
+ feature.participatory_process.active_step.id => {
48
+ allow_answers: true
49
+ }
50
+ }
51
+ )
52
+ end
53
+
54
+ context "when the user is not logged in" do
55
+ it "the survey cannot be answered" do
56
+ visit_feature
57
+
58
+ expect(page).to have_i18n_content(survey.title, upcase: true)
59
+ expect(page).to have_i18n_content(survey.description)
60
+
61
+ expect(page).not_to have_i18n_content(survey_question_1.body)
62
+ expect(page).not_to have_i18n_content(survey_question_2.body)
63
+
64
+ expect(page).to have_content("Sign in with your account or sign up to answer the survey.")
65
+ end
66
+ end
67
+
68
+ context "when the user is logged in" do
69
+ before do
70
+ login_as user, scope: :user
71
+ end
72
+
73
+ it "the survey can be answered" do
74
+ visit_feature
75
+
76
+ expect(page).to have_i18n_content(survey.title, upcase: true)
77
+ expect(page).to have_i18n_content(survey.description)
78
+
79
+ fill_in "survey_#{survey.id}_question_#{survey_question_1.id}_answer_body", with: "My first answer"
80
+ fill_in "survey_#{survey.id}_question_#{survey_question_2.id}_answer_body", with: "My second answer"
81
+
82
+ check "survey_tos_agreement"
83
+
84
+ click_button "Submit"
85
+
86
+ within ".success.flash" do
87
+ expect(page).to have_content("successfully")
88
+ end
89
+
90
+ expect(page).to have_content("You have already answered this survey.")
91
+ expect(page).not_to have_i18n_content(survey_question_1.body)
92
+ expect(page).not_to have_i18n_content(survey_question_2.body)
93
+ end
94
+
95
+ it "the questions are ordered by position" do
96
+ visit_feature
97
+
98
+ form_fields = all(".answer-survey .row")
99
+
100
+ expect(form_fields[0]).to have_i18n_content(survey_question_2.body)
101
+ expect(form_fields[1]).to have_i18n_content(survey_question_1.body)
102
+ end
103
+
104
+ context "when a question is mandatory" do
105
+ let!(:survey_question_2) { create(:survey_question, survey: survey, position: 0, mandatory: true) }
106
+
107
+ it "users cannot leave that question blank" do
108
+ visit_feature
109
+
110
+ check "survey_tos_agreement"
111
+
112
+ click_button "Submit"
113
+
114
+ within ".alert.flash" do
115
+ expect(page).to have_content("error")
116
+ end
117
+ expect(page).to have_content("can't be blank")
118
+ end
119
+ end
120
+
121
+ context "when question type is long answer" do
122
+ let!(:survey_question_1) { create(:survey_question, survey: survey, question_type: "long_answer") }
123
+ let!(:survey_question_2) { create(:survey_question, survey: survey, question_type: "long_answer") }
124
+
125
+ it "the question answer is rendered as a textarea" do
126
+ visit_feature
127
+
128
+ expect(page).to have_selector("textarea#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body")
129
+ expect(page).to have_selector("textarea#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body")
130
+ end
131
+ end
132
+
133
+ context "when question type is single option" do
134
+ let(:answer_options) { Array.new(4) { { "body" => Decidim::Faker::Localized.sentence } } }
135
+ let!(:survey_question_1) { create(:survey_question, survey: survey, question_type: "single_option", answer_options: [answer_options[0], answer_options[1]]) }
136
+ let!(:survey_question_2) { create(:survey_question, survey: survey, question_type: "single_option", answer_options: [answer_options[2], answer_options[3]]) }
137
+
138
+ it "the question answers are rendered as a collection of radio buttons" do
139
+ visit_feature
140
+
141
+ expect(page).to have_selector("#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body_answer_options input[type='radio']", count: 2)
142
+ expect(page).to have_selector("#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body_answer_options input[type='radio']", count: 2)
143
+
144
+ within "#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body_answer_options" do
145
+ choose answer_options[1]["body"][:en]
146
+ end
147
+
148
+ within "#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body_answer_options" do
149
+ choose answer_options[2]["body"][:en]
150
+ end
151
+
152
+ check "survey_tos_agreement"
153
+
154
+ click_button "Submit"
155
+
156
+ within ".success.flash" do
157
+ expect(page).to have_content("successfully")
158
+ end
159
+
160
+ expect(page).to have_content("You have already answered this survey.")
161
+ expect(page).not_to have_i18n_content(survey_question_1.body)
162
+ expect(page).not_to have_i18n_content(survey_question_2.body)
163
+ end
164
+ end
165
+
166
+ context "when question type is multiple option" do
167
+ let(:answer_options) { Array.new(4) { { "body" => Decidim::Faker::Localized.sentence } } }
168
+ let!(:survey_question_1) { create(:survey_question, survey: survey, question_type: "multiple_option", answer_options: [answer_options[0], answer_options[1]]) }
169
+ let!(:survey_question_2) { create(:survey_question, survey: survey, question_type: "multiple_option", answer_options: [answer_options[2], answer_options[3]]) }
170
+
171
+ it "the question answers are rendered as a collection of radio buttons" do
172
+ visit_feature
173
+
174
+ expect(page).to have_selector("#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body_answer_options input[type='checkbox']", count: 2)
175
+ expect(page).to have_selector("#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body_answer_options input[type='checkbox']", count: 2)
176
+
177
+ within "#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body_answer_options" do
178
+ check answer_options[0]["body"][:en]
179
+ check answer_options[1]["body"][:en]
180
+ end
181
+
182
+ within "#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body_answer_options" do
183
+ check answer_options[2]["body"][:en]
184
+ end
185
+
186
+ check "survey_tos_agreement"
187
+
188
+ click_button "Submit"
189
+
190
+ within ".success.flash" do
191
+ expect(page).to have_content("successfully")
192
+ end
193
+
194
+ expect(page).to have_content("You have already answered this survey.")
195
+ expect(page).not_to have_i18n_content(survey_question_1.body)
196
+ expect(page).not_to have_i18n_content(survey_question_2.body)
197
+ end
198
+ end
199
+
200
+ context "when question type is multiple option" do
201
+ let(:answer_options) { Array.new(4) { { "body" => Decidim::Faker::Localized.sentence } } }
202
+ let!(:survey_question_1) { create(:survey_question, survey: survey, question_type: "multiple_option", answer_options: [answer_options[0], answer_options[1]]) }
203
+ let!(:survey_question_2) { create(:survey_question, survey: survey, question_type: "multiple_option", answer_options: [answer_options[2], answer_options[3]]) }
204
+
205
+ it "the question answers are rendered as a collection of radio buttons" do
206
+ visit_feature
207
+
208
+ expect(page).to have_selector("#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body_answer_options input[type='checkbox']", count: 2)
209
+ expect(page).to have_selector("#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body_answer_options input[type='checkbox']", count: 2)
210
+
211
+ within "#survey_#{survey.id}_question_#{survey_question_1.id}_answer_body_answer_options" do
212
+ check answer_options[0]["body"][:en]
213
+ check answer_options[1]["body"][:en]
214
+ end
215
+
216
+ within "#survey_#{survey.id}_question_#{survey_question_2.id}_answer_body_answer_options" do
217
+ check answer_options[2]["body"][:en]
218
+ end
219
+
220
+ check "survey_tos_agreement"
221
+
222
+ click_button "Submit"
223
+
224
+ within ".success.flash" do
225
+ expect(page).to have_content("successfully")
226
+ end
227
+
228
+ expect(page).to have_content("You have already answered this survey.")
229
+ expect(page).not_to have_i18n_content(survey_question_1.body)
230
+ expect(page).not_to have_i18n_content(survey_question_2.body)
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end