decidim-surveys 0.29.1 → 0.30.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/surveys/survey_card_metadata_cell.rb +43 -0
  3. data/app/cells/decidim/surveys/survey_cell.rb +26 -0
  4. data/app/cells/decidim/surveys/survey_l_cell.rb +34 -0
  5. data/app/cells/decidim/surveys/survey_s_cell.rb +21 -0
  6. data/app/commands/decidim/surveys/admin/create_survey.rb +21 -0
  7. data/app/commands/decidim/surveys/admin/publish_survey.rb +58 -0
  8. data/app/commands/decidim/surveys/admin/unpublish_survey.rb +44 -0
  9. data/app/commands/decidim/surveys/admin/update_survey.rb +62 -0
  10. data/app/commands/decidim/surveys/publish_answers.rb +55 -0
  11. data/app/commands/decidim/surveys/unpublish_answers.rb +55 -0
  12. data/app/controllers/concerns/decidim/surveys/admin/filterable.rb +23 -0
  13. data/app/controllers/decidim/surveys/admin/answers_controller.rb +73 -0
  14. data/app/controllers/decidim/surveys/admin/publish_answers_controller.rb +66 -0
  15. data/app/controllers/decidim/surveys/admin/surveys_controller.rb +99 -11
  16. data/app/controllers/decidim/surveys/surveys_controller.rb +50 -5
  17. data/app/forms/decidim/surveys/admin/survey_form.rb +18 -0
  18. data/app/helpers/decidim/surveys/application_helper.rb +34 -0
  19. data/app/helpers/decidim/surveys/publish_answers_helper.rb +104 -0
  20. data/app/helpers/decidim/surveys/survey_helper.rb +4 -0
  21. data/app/models/decidim/surveys/survey.rb +67 -12
  22. data/app/permissions/decidim/surveys/admin/permissions.rb +10 -1
  23. data/app/permissions/decidim/surveys/permissions.rb +0 -2
  24. data/app/presenters/decidim/surveys/admin_log/survey_presenter.rb +34 -0
  25. data/app/queries/decidim/surveys/metrics/answers_metric_manage.rb +3 -3
  26. data/app/queries/decidim/surveys/metrics/survey_participants_metric_measure.rb +2 -2
  27. data/app/views/decidim/surveys/admin/answers/index.html.erb +49 -0
  28. data/app/views/decidim/surveys/admin/answers/show.html.erb +43 -0
  29. data/app/views/decidim/surveys/admin/publish_answers/_toggle_button.html.erb +22 -0
  30. data/app/views/decidim/surveys/admin/publish_answers/index.html.erb +44 -0
  31. data/app/views/decidim/surveys/admin/surveys/_form.html.erb +28 -0
  32. data/app/views/decidim/surveys/admin/surveys/edit.html.erb +4 -21
  33. data/app/views/decidim/surveys/admin/surveys/edit_questions.html.erb +47 -0
  34. data/app/views/decidim/surveys/admin/surveys/index.html.erb +51 -0
  35. data/app/views/decidim/surveys/surveys/_published_questions_answers.html.erb +13 -0
  36. data/app/views/decidim/surveys/surveys/_surveys.html.erb +13 -0
  37. data/app/views/decidim/surveys/surveys/index.html.erb +27 -0
  38. data/app/views/decidim/surveys/surveys/index.js.erb +4 -0
  39. data/app/views/decidim/surveys/surveys/not_allowed.html.erb +22 -0
  40. data/config/locales/ar.yml +4 -3
  41. data/config/locales/bg.yml +0 -14
  42. data/config/locales/bn-BD.yml +1 -0
  43. data/config/locales/bs-BA.yml +1 -0
  44. data/config/locales/ca.yml +83 -14
  45. data/config/locales/cs.yml +87 -14
  46. data/config/locales/de.yml +83 -14
  47. data/config/locales/el.yml +0 -11
  48. data/config/locales/en.yml +83 -14
  49. data/config/locales/es-MX.yml +83 -14
  50. data/config/locales/es-PY.yml +83 -14
  51. data/config/locales/es.yml +83 -14
  52. data/config/locales/eu.yml +85 -16
  53. data/config/locales/fi-plain.yml +83 -14
  54. data/config/locales/fi.yml +83 -14
  55. data/config/locales/fr-CA.yml +74 -14
  56. data/config/locales/fr.yml +74 -14
  57. data/config/locales/ga-IE.yml +0 -4
  58. data/config/locales/gl.yml +0 -10
  59. data/config/locales/hu.yml +0 -3
  60. data/config/locales/id-ID.yml +0 -2
  61. data/config/locales/is-IS.yml +0 -2
  62. data/config/locales/it.yml +3 -10
  63. data/config/locales/ja.yml +80 -13
  64. data/config/locales/lb.yml +0 -10
  65. data/config/locales/lt.yml +0 -11
  66. data/config/locales/lv.yml +0 -3
  67. data/config/locales/nl.yml +0 -10
  68. data/config/locales/no.yml +0 -10
  69. data/config/locales/pl.yml +0 -14
  70. data/config/locales/pt-BR.yml +0 -14
  71. data/config/locales/pt.yml +0 -10
  72. data/config/locales/ro-RO.yml +0 -11
  73. data/config/locales/ru.yml +0 -2
  74. data/config/locales/sk.yml +0 -3
  75. data/config/locales/sv.yml +0 -14
  76. data/config/locales/tr-TR.yml +0 -10
  77. data/config/locales/uk.yml +0 -2
  78. data/config/locales/zh-CN.yml +0 -6
  79. data/config/locales/zh-TW.yml +0 -11
  80. data/db/migrate/20240828103030_add_deleted_at_to_decidim_surveys_surveys.rb +8 -0
  81. data/db/migrate/20240925124312_add_settings_to_decidim_surveys_surveys.rb +42 -0
  82. data/db/migrate/20250115193836_add_allow_survey_editing.rb +7 -0
  83. data/decidim-surveys.gemspec +2 -2
  84. data/lib/decidim/api/survey_type.rb +11 -2
  85. data/lib/decidim/api/surveys_type.rb +5 -8
  86. data/lib/decidim/surveys/admin_engine.rb +15 -5
  87. data/lib/decidim/surveys/component.rb +7 -24
  88. data/lib/decidim/surveys/engine.rb +2 -2
  89. data/lib/decidim/surveys/seeds.rb +115 -10
  90. data/lib/decidim/surveys/test/factories.rb +24 -0
  91. data/lib/decidim/surveys/version.rb +1 -1
  92. metadata +51 -19
  93. data/app/commands/decidim/surveys/create_survey.rb +0 -19
  94. data/app/views/decidim/surveys/admin/component/_actions.html.erb +0 -44
@@ -15,16 +15,10 @@ zh-CN:
15
15
  surveys:
16
16
  actions:
17
17
  answer: 答案
18
- name: 调查
19
18
  settings:
20
19
  global:
21
20
  announcement: 通 知
22
- clean_after_publish: 在发布调查时删除答案
23
- scope_id: 范围
24
- scopes_enabled: 范围已启用
25
21
  step:
26
- allow_answers: 允许答案
27
- allow_unregistered: 允许未注册用户回答调查
28
22
  announcement: 通 知
29
23
  events:
30
24
  surveys:
@@ -15,21 +15,10 @@ zh-TW:
15
15
  surveys:
16
16
  actions:
17
17
  answer: 回答
18
- name: 調查
19
18
  settings:
20
19
  global:
21
20
  announcement: 公告
22
- clean_after_publish: 當發佈調查問卷時刪除回答
23
- ends_at: 接受回答直到
24
- ends_at_help: 不指定日期則留空
25
- scope_id: 範圍
26
- scopes_enabled: 啟用的範圍
27
- starts_at: 回答接受開始日期
28
- starts_at_help: 不指定日期請留空
29
21
  step:
30
- allow_answers: 允許回答
31
- allow_unregistered: 允許未註冊的使用者回答問卷
32
- allow_unregistered_help: 若啟用此功能,回答問卷時將無需登錄。這可能導致資料品質不佳或不可靠,並增加遭受自動攻擊的風險。請謹慎使用!請注意,參與者可以使用不同的瀏覽器或「私人瀏覽」功能多次回答同一份問卷。
33
22
  announcement: 公告
34
23
  events:
35
24
  surveys:
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddDeletedAtToDecidimSurveysSurveys < ActiveRecord::Migration[7.0]
4
+ def change
5
+ add_column :decidim_surveys_surveys, :deleted_at, :datetime
6
+ add_index :decidim_surveys_surveys, :deleted_at
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddSettingsToDecidimSurveysSurveys < ActiveRecord::Migration[7.0]
4
+ class Survey < ApplicationRecord
5
+ include Decidim::HasComponent
6
+
7
+ self.table_name = :decidim_surveys_surveys
8
+ end
9
+
10
+ def change
11
+ reversible do |dir|
12
+ dir.up do
13
+ add_column :decidim_surveys_surveys, :starts_at, :datetime
14
+ add_column :decidim_surveys_surveys, :ends_at, :datetime
15
+ add_column :decidim_surveys_surveys, :announcement, :jsonb
16
+ add_column :decidim_surveys_surveys, :allow_answers, :boolean
17
+ add_column :decidim_surveys_surveys, :allow_unregistered, :boolean
18
+ add_column :decidim_surveys_surveys, :clean_after_publish, :boolean
19
+ add_column :decidim_surveys_surveys, :published_at, :datetime
20
+ add_index :decidim_surveys_surveys, :published_at
21
+
22
+ Survey.where(published_at: nil).find_each do |survey|
23
+ published_at = survey.component&.published_at
24
+ next if published_at.nil?
25
+
26
+ survey.update(published_at:)
27
+ end
28
+ end
29
+
30
+ dir.down do
31
+ remove_index :decidim_surveys_surveys, :published_at
32
+ remove_column :decidim_surveys_surveys, :starts_at
33
+ remove_column :decidim_surveys_surveys, :ends_at
34
+ remove_column :decidim_surveys_surveys, :announcement
35
+ remove_column :decidim_surveys_surveys, :allow_answers
36
+ remove_column :decidim_surveys_surveys, :allow_unregistered
37
+ remove_column :decidim_surveys_surveys, :clean_after_publish
38
+ remove_column :decidim_surveys_surveys, :published_at
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddAllowSurveyEditing < ActiveRecord::Migration[7.0]
4
+ def up
5
+ add_column :decidim_surveys_surveys, :allow_editing_answers, :boolean
6
+ end
7
+ end
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.version = Decidim::Surveys.version
11
11
  s.authors = ["Josep Jaume Rey Peroy", "Marc Riera Casals", "Oriol Gual Oliva"]
12
12
  s.email = ["josepjaume@gmail.com", "mrc2407@gmail.com", "oriolgual@gmail.com"]
13
- s.license = "AGPL-3.0"
13
+ s.license = "AGPL-3.0-or-later"
14
14
  s.homepage = "https://decidim.org"
15
15
  s.metadata = {
16
16
  "bug_tracker_uri" => "https://github.com/decidim/decidim/issues",
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  "homepage_uri" => "https://decidim.org",
20
20
  "source_code_uri" => "https://github.com/decidim/decidim"
21
21
  }
22
- s.required_ruby_version = "~> 3.2.0"
22
+ s.required_ruby_version = "~> 3.3.0"
23
23
 
24
24
  s.name = "decidim-surveys"
25
25
  s.summary = "Decidim surveys module"
@@ -3,12 +3,21 @@
3
3
  module Decidim
4
4
  module Surveys
5
5
  class SurveyType < Decidim::Api::Types::BaseObject
6
+ implements Decidim::Core::TimestampsInterface
7
+
6
8
  description "A survey"
7
9
 
8
10
  field :id, GraphQL::Types::ID, "The internal ID for this survey", null: false
9
- field :created_at, Decidim::Core::DateTimeType, "The time this survey was created", null: true
10
- field :updated_at, Decidim::Core::DateTimeType, "The time this survey was updated", null: true
11
11
  field :questionnaire, Decidim::Forms::QuestionnaireType, "The questionnaire for this survey", null: true
12
+
13
+ def self.authorized?(object, context)
14
+ context[:survey] = object
15
+ context[:current_settings] = object.component.current_settings
16
+
17
+ super
18
+ rescue Decidim::PermissionAction::PermissionNotSetError
19
+ false
20
+ end
12
21
  end
13
22
  end
14
23
  end
@@ -2,22 +2,19 @@
2
2
 
3
3
  module Decidim
4
4
  module Surveys
5
- class SurveysType < Decidim::Api::Types::BaseObject
6
- implements Decidim::Core::ComponentInterface
7
-
5
+ class SurveysType < Decidim::Core::ComponentType
8
6
  graphql_name "Surveys"
9
7
  description "A surveys component of a participatory space."
10
8
 
11
- field :surveys, Decidim::Surveys::SurveyType.connection_type, null: true, connection: true
9
+ field :survey, Decidim::Surveys::SurveyType, "A single Survey object", null: true do
10
+ argument :id, GraphQL::Types::ID, "The id of the Survey requested", required: true
11
+ end
12
+ field :surveys, Decidim::Surveys::SurveyType.connection_type, "A collection of Surveys", null: true, connection: true
12
13
 
13
14
  def surveys
14
15
  Survey.where(component: object).includes(:component)
15
16
  end
16
17
 
17
- field :survey, Decidim::Surveys::SurveyType, null: true do
18
- argument :id, GraphQL::Types::ID, required: true
19
- end
20
-
21
18
  def survey(**args)
22
19
  Survey.where(component: object).find_by(id: args[:id])
23
20
  end
@@ -10,12 +10,22 @@ module Decidim
10
10
  paths["lib/tasks"] = nil
11
11
 
12
12
  routes do
13
- get "/answer/:session_token", to: "surveys#show", as: :show_survey
14
- get "/answer/:session_token/export", to: "surveys#export_response", as: :export_response_survey
15
- get "/answers", to: "surveys#index", as: :index_survey
16
13
  get "/answer_options", to: "surveys#answer_options", as: :answer_options_survey
17
- put "/", to: "surveys#update", as: :survey
18
- root to: "surveys#edit"
14
+ resources :surveys, except: [:new] do
15
+ member do
16
+ get :edit_questions
17
+ patch :update_questions
18
+ put :publish
19
+ put :unpublish
20
+ end
21
+ resources :answers, only: [:index, :show] do
22
+ member do
23
+ get :export_response
24
+ end
25
+ end
26
+ resources :publish_answers, only: [:index, :update, :destroy]
27
+ end
28
+ root to: "surveys#index"
19
29
  end
20
30
 
21
31
  initializer "decidim_surveys_admin.notifications.components" do
@@ -12,18 +12,6 @@ Decidim.register_component(:surveys) do |component|
12
12
  component.specific_data_importer_class_name = "Decidim::Surveys::DataImporter"
13
13
  component.query_type = "Decidim::Surveys::SurveysType"
14
14
 
15
- component.on(:copy) do |context|
16
- Decidim::Surveys::CreateSurvey.call(context[:new_component]) do
17
- on(:invalid) { raise "Cannot create survey" }
18
- end
19
- end
20
-
21
- component.on(:create) do |instance|
22
- Decidim::Surveys::CreateSurvey.call(instance) do
23
- on(:invalid) { raise "Cannot create survey" }
24
- end
25
- end
26
-
27
15
  component.data_portable_entities = ["Decidim::Forms::Answer"]
28
16
 
29
17
  component.newsletter_participant_entities = ["Decidim::Forms::Answer"]
@@ -37,20 +25,22 @@ Decidim.register_component(:surveys) do |component|
37
25
 
38
26
  component.register_resource(:survey) do |resource|
39
27
  resource.model_class_name = "Decidim::Surveys::Survey"
28
+ resource.card = "decidim/surveys/survey"
29
+ resource.actions = %w(answer)
40
30
  end
41
31
 
42
- component.register_stat :surveys_count do |components, start_at, end_at|
32
+ component.register_stat :surveys_count, primary: true, priority: Decidim::StatsRegistry::HIGH_PRIORITY do |components, start_at, end_at|
43
33
  surveys = Decidim::Surveys::Survey.where(component: components)
44
- surveys = surveys.where("created_at >= ?", start_at) if start_at.present?
45
- surveys = surveys.where("created_at <= ?", end_at) if end_at.present?
34
+ surveys = surveys.where(created_at: start_at..) if start_at.present?
35
+ surveys = surveys.where(created_at: ..end_at) if end_at.present?
46
36
  surveys.count
47
37
  end
48
38
 
49
39
  component.register_stat :answers_count, primary: true, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY do |components, start_at, end_at|
50
40
  surveys = Decidim::Surveys::Survey.includes(:questionnaire).where(component: components)
51
41
  answers = Decidim::Forms::Answer.where(questionnaire: surveys.map(&:questionnaire))
52
- answers = answers.where("created_at >= ?", start_at) if start_at.present?
53
- answers = answers.where("created_at <= ?", end_at) if end_at.present?
42
+ answers = answers.where(created_at: start_at..) if start_at.present?
43
+ answers = answers.where(created_at: ..end_at) if end_at.present?
54
44
  answers.group(:session_token).count.size
55
45
  end
56
46
 
@@ -58,17 +48,10 @@ Decidim.register_component(:surveys) do |component|
58
48
  component.actions = %w(answer)
59
49
 
60
50
  component.settings(:global) do |settings|
61
- settings.attribute :scopes_enabled, type: :boolean, default: false
62
- settings.attribute :scope_id, type: :scope
63
- settings.attribute :starts_at, type: :time
64
- settings.attribute :ends_at, type: :time
65
51
  settings.attribute :announcement, type: :text, translated: true, editor: true
66
- settings.attribute :clean_after_publish, type: :boolean, default: true
67
52
  end
68
53
 
69
54
  component.settings(:step) do |settings|
70
- settings.attribute :allow_answers, type: :boolean, default: false
71
- settings.attribute :allow_unregistered, type: :boolean, default: false
72
55
  settings.attribute :announcement, type: :text, translated: true, editor: true
73
56
  end
74
57
 
@@ -9,12 +9,12 @@ module Decidim
9
9
  isolate_namespace Decidim::Surveys
10
10
 
11
11
  routes do
12
- resources :surveys, only: [:show] do
12
+ resources :surveys, only: [:index, :show, :edit] do
13
13
  member do
14
14
  post :answer
15
15
  end
16
16
  end
17
- root to: "surveys#show"
17
+ root to: "surveys#index"
18
18
  end
19
19
 
20
20
  initializer "decidim_surveys.settings_changes" do
@@ -4,7 +4,7 @@ require "decidim/components/namer"
4
4
 
5
5
  module Decidim
6
6
  module Surveys
7
- class Seeds
7
+ class Seeds < Decidim::Seeds
8
8
  attr_reader :participatory_space
9
9
 
10
10
  def initialize(participatory_space:)
@@ -12,11 +12,19 @@ module Decidim
12
12
  end
13
13
 
14
14
  def call
15
- admin_user = Decidim::User.find_by(
16
- organization: participatory_space.organization,
17
- email: "admin@example.org"
18
- )
15
+ component = create_component!
16
+
17
+ 3.times do
18
+ questionnaire = create_questionnaire!(component:)
19
+ create_questions!(questionnaire:)
20
+
21
+ next if questionnaire.questionnaire_for.allow_answers
19
22
 
23
+ rand(200).times { create_answers!(questionnaire:) }
24
+ end
25
+ end
26
+
27
+ def create_component!
20
28
  params = {
21
29
  name: Decidim::Components::Namer.new(participatory_space.organization.available_locales, :surveys).i18n_name,
22
30
  manifest_name: :surveys,
@@ -24,7 +32,7 @@ module Decidim
24
32
  participatory_space:
25
33
  }
26
34
 
27
- component = Decidim.traceability.perform_action!(
35
+ Decidim.traceability.perform_action!(
28
36
  "publish",
29
37
  Decidim::Component,
30
38
  admin_user,
@@ -32,7 +40,9 @@ module Decidim
32
40
  ) do
33
41
  Decidim::Component.create!(params)
34
42
  end
43
+ end
35
44
 
45
+ def create_questionnaire!(component:)
36
46
  questionnaire = Decidim::Forms::Questionnaire.new(
37
47
  title: Decidim::Faker::Localized.paragraph,
38
48
  description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
@@ -45,7 +55,9 @@ module Decidim
45
55
 
46
56
  params = {
47
57
  component:,
48
- questionnaire:
58
+ questionnaire:,
59
+ allow_answers: [true, false].sample,
60
+ published_at: Time.current
49
61
  }
50
62
 
51
63
  Decidim.traceability.create!(
@@ -55,16 +67,22 @@ module Decidim
55
67
  visibility: "all"
56
68
  )
57
69
 
58
- %w(short_answer long_answer).each_with_index do |text_question_type, index|
70
+ questionnaire
71
+ end
72
+
73
+ def create_questions!(questionnaire:)
74
+ %w(short_answer long_answer files).each_with_index do |text_question_type, index|
59
75
  Decidim::Forms::Question.create!(
76
+ mandatory: text_question_type == "short_answer",
60
77
  questionnaire:,
61
78
  body: Decidim::Faker::Localized.paragraph,
62
79
  question_type: text_question_type,
63
80
  position: index
64
81
  )
82
+ next if text_question_type == "files"
65
83
  end
66
84
 
67
- %w(single_option multiple_option).each_with_index do |multiple_choice_question_type, index|
85
+ %w(single_option multiple_option sorting).each_with_index do |multiple_choice_question_type, index|
68
86
  question = Decidim::Forms::Question.create!(
69
87
  questionnaire:,
70
88
  body: Decidim::Faker::Localized.paragraph,
@@ -76,8 +94,12 @@ module Decidim
76
94
  question.answer_options.create!(body: Decidim::Faker::Localized.sentence)
77
95
  end
78
96
 
97
+ # Files type questions do not support being conditionals for another questions
98
+ files_question = questionnaire.questions.where(question_type: "files")
99
+ possible_condition_questions = questionnaire.questions.excluding(files_question)
100
+
79
101
  question.display_conditions.create!(
80
- condition_question: questionnaire.questions.find_by(position: question.position - 2),
102
+ condition_question: possible_condition_questions.sample,
81
103
  question:,
82
104
  condition_type: :answered,
83
105
  mandatory: true
@@ -97,6 +119,89 @@ module Decidim
97
119
  question.matrix_rows.create!(body: Decidim::Faker::Localized.sentence, position:)
98
120
  end
99
121
  end
122
+
123
+ Decidim::Forms::Question.create!(
124
+ questionnaire:,
125
+ body: nil,
126
+ question_type: "separator",
127
+ position: 3
128
+ )
129
+ end
130
+
131
+ def create_answers!(questionnaire:, user: nil)
132
+ user = find_or_initialize_user_by(email: "survey-#{questionnaire.id}-#{rand(1_000_000)}@example.org") if user.nil?
133
+
134
+ answer_options = {
135
+ user:,
136
+ questionnaire:,
137
+ session_token: Digest::MD5.hexdigest("#{user.id}-#{Rails.application.secret_key_base}"),
138
+ ip_hash: Faker::Internet.device_token.slice(0, 24)
139
+ }
140
+
141
+ questionnaire.questions.each do |question|
142
+ case question.question_type
143
+ when "short_answer", "long_answer"
144
+ create_answer_for_text_question_type!(answer_options.merge({ question: }))
145
+ when "single_option", "multiple_option"
146
+ create_answer_for_multiple_choice_question_type(answer_options.merge({ question: }))
147
+ when "sorting"
148
+ create_answer_for_sorting_question_type(answer_options.merge({ question: }))
149
+ when "matrix_single", "matrix_multiple"
150
+ create_answer_for_matrix_question_type(answer_options.merge({ question: }))
151
+ end
152
+ end
153
+ rescue ActiveRecord::RecordInvalid
154
+ # Silently ignore the error as we do not care if the user already exists
155
+ end
156
+
157
+ def create_answer_for_text_question_type!(options)
158
+ Decidim::Forms::Answer.create!(
159
+ **options, body: ::Faker::Lorem.paragraph(sentence_count: 1)
160
+ )
161
+ end
162
+
163
+ def create_answer_for_sorting_question_type(options)
164
+ answer = Decidim::Forms::Answer.create!(**options)
165
+ answer_options = options[:question].answer_options
166
+ available_positions = (0..(answer_options.size - 1)).to_a
167
+
168
+ answer_options.each do |answer_option|
169
+ position = available_positions.sample
170
+ body = answer_option[I18n.locale]
171
+
172
+ Decidim::Forms::AnswerChoice.create!(
173
+ answer:,
174
+ answer_option:,
175
+ body:,
176
+ position:
177
+ )
178
+ end
179
+ end
180
+
181
+ def create_answer_for_multiple_choice_question_type(options)
182
+ answer = Decidim::Forms::Answer.create!(**options)
183
+ answer_option = options[:question].answer_options.sample
184
+ body = answer_option[I18n.locale]
185
+
186
+ Decidim::Forms::AnswerChoice.create!(
187
+ answer:,
188
+ answer_option:,
189
+ body:
190
+ )
191
+ end
192
+
193
+ def create_answer_for_matrix_question_type(options)
194
+ answer = Decidim::Forms::Answer.create!(**options)
195
+ answer_option = options[:question].answer_options.sample
196
+ matrix_row = options[:question].matrix_rows.sample
197
+ body = answer_option[I18n.locale]
198
+
199
+ Decidim::Forms::AnswerChoice.create!(
200
+ answer:,
201
+ answer_option:,
202
+ matrix_row:,
203
+ body:
204
+ )
100
205
  end
101
206
  end
102
207
  end
@@ -21,5 +21,29 @@ FactoryBot.define do
21
21
  end
22
22
  questionnaire { build(:questionnaire, :with_questions, skip_injection:) }
23
23
  component { build(:surveys_component, skip_injection:) }
24
+
25
+ trait :published do
26
+ published_at { Time.current }
27
+ end
28
+
29
+ trait :allow_edit do
30
+ allow_editing_answers { true }
31
+ end
32
+
33
+ trait :allow_answers do
34
+ allow_answers { true }
35
+ end
36
+
37
+ trait :allow_unregistered do
38
+ allow_unregistered { true }
39
+ end
40
+
41
+ trait :clean_after_publish do
42
+ clean_after_publish { true }
43
+ end
44
+
45
+ trait :announcement do
46
+ announcement { "This is a custom announcement." }
47
+ end
24
48
  end
25
49
  end
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-surveys version.
5
5
  module Surveys
6
6
  def self.version
7
- "0.29.1"
7
+ "0.30.0.rc1"
8
8
  end
9
9
  end
10
10
  end