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.
- checksums.yaml +4 -4
- data/app/cells/decidim/surveys/survey_card_metadata_cell.rb +43 -0
- data/app/cells/decidim/surveys/survey_cell.rb +26 -0
- data/app/cells/decidim/surveys/survey_l_cell.rb +34 -0
- data/app/cells/decidim/surveys/survey_s_cell.rb +21 -0
- data/app/commands/decidim/surveys/admin/create_survey.rb +21 -0
- data/app/commands/decidim/surveys/admin/publish_survey.rb +58 -0
- data/app/commands/decidim/surveys/admin/unpublish_survey.rb +44 -0
- data/app/commands/decidim/surveys/admin/update_survey.rb +62 -0
- data/app/commands/decidim/surveys/publish_answers.rb +55 -0
- data/app/commands/decidim/surveys/unpublish_answers.rb +55 -0
- data/app/controllers/concerns/decidim/surveys/admin/filterable.rb +23 -0
- data/app/controllers/decidim/surveys/admin/answers_controller.rb +73 -0
- data/app/controllers/decidim/surveys/admin/publish_answers_controller.rb +66 -0
- data/app/controllers/decidim/surveys/admin/surveys_controller.rb +99 -11
- data/app/controllers/decidim/surveys/surveys_controller.rb +50 -5
- data/app/forms/decidim/surveys/admin/survey_form.rb +18 -0
- data/app/helpers/decidim/surveys/application_helper.rb +34 -0
- data/app/helpers/decidim/surveys/publish_answers_helper.rb +104 -0
- data/app/helpers/decidim/surveys/survey_helper.rb +4 -0
- data/app/models/decidim/surveys/survey.rb +67 -12
- data/app/permissions/decidim/surveys/admin/permissions.rb +10 -1
- data/app/permissions/decidim/surveys/permissions.rb +0 -2
- data/app/presenters/decidim/surveys/admin_log/survey_presenter.rb +34 -0
- data/app/queries/decidim/surveys/metrics/answers_metric_manage.rb +3 -3
- data/app/queries/decidim/surveys/metrics/survey_participants_metric_measure.rb +2 -2
- data/app/views/decidim/surveys/admin/answers/index.html.erb +49 -0
- data/app/views/decidim/surveys/admin/answers/show.html.erb +43 -0
- data/app/views/decidim/surveys/admin/publish_answers/_toggle_button.html.erb +22 -0
- data/app/views/decidim/surveys/admin/publish_answers/index.html.erb +44 -0
- data/app/views/decidim/surveys/admin/surveys/_form.html.erb +28 -0
- data/app/views/decidim/surveys/admin/surveys/edit.html.erb +4 -21
- data/app/views/decidim/surveys/admin/surveys/edit_questions.html.erb +47 -0
- data/app/views/decidim/surveys/admin/surveys/index.html.erb +51 -0
- data/app/views/decidim/surveys/surveys/_published_questions_answers.html.erb +13 -0
- data/app/views/decidim/surveys/surveys/_surveys.html.erb +13 -0
- data/app/views/decidim/surveys/surveys/index.html.erb +27 -0
- data/app/views/decidim/surveys/surveys/index.js.erb +4 -0
- data/app/views/decidim/surveys/surveys/not_allowed.html.erb +22 -0
- data/config/locales/ar.yml +4 -3
- data/config/locales/bg.yml +0 -14
- data/config/locales/bn-BD.yml +1 -0
- data/config/locales/bs-BA.yml +1 -0
- data/config/locales/ca.yml +83 -14
- data/config/locales/cs.yml +87 -14
- data/config/locales/de.yml +83 -14
- data/config/locales/el.yml +0 -11
- data/config/locales/en.yml +83 -14
- data/config/locales/es-MX.yml +83 -14
- data/config/locales/es-PY.yml +83 -14
- data/config/locales/es.yml +83 -14
- data/config/locales/eu.yml +85 -16
- data/config/locales/fi-plain.yml +83 -14
- data/config/locales/fi.yml +83 -14
- data/config/locales/fr-CA.yml +74 -14
- data/config/locales/fr.yml +74 -14
- data/config/locales/ga-IE.yml +0 -4
- data/config/locales/gl.yml +0 -10
- data/config/locales/hu.yml +0 -3
- data/config/locales/id-ID.yml +0 -2
- data/config/locales/is-IS.yml +0 -2
- data/config/locales/it.yml +3 -10
- data/config/locales/ja.yml +80 -13
- data/config/locales/lb.yml +0 -10
- data/config/locales/lt.yml +0 -11
- data/config/locales/lv.yml +0 -3
- data/config/locales/nl.yml +0 -10
- data/config/locales/no.yml +0 -10
- data/config/locales/pl.yml +0 -14
- data/config/locales/pt-BR.yml +0 -14
- data/config/locales/pt.yml +0 -10
- data/config/locales/ro-RO.yml +0 -11
- data/config/locales/ru.yml +0 -2
- data/config/locales/sk.yml +0 -3
- data/config/locales/sv.yml +0 -14
- data/config/locales/tr-TR.yml +0 -10
- data/config/locales/uk.yml +0 -2
- data/config/locales/zh-CN.yml +0 -6
- data/config/locales/zh-TW.yml +0 -11
- data/db/migrate/20240828103030_add_deleted_at_to_decidim_surveys_surveys.rb +8 -0
- data/db/migrate/20240925124312_add_settings_to_decidim_surveys_surveys.rb +42 -0
- data/db/migrate/20250115193836_add_allow_survey_editing.rb +7 -0
- data/decidim-surveys.gemspec +2 -2
- data/lib/decidim/api/survey_type.rb +11 -2
- data/lib/decidim/api/surveys_type.rb +5 -8
- data/lib/decidim/surveys/admin_engine.rb +15 -5
- data/lib/decidim/surveys/component.rb +7 -24
- data/lib/decidim/surveys/engine.rb +2 -2
- data/lib/decidim/surveys/seeds.rb +115 -10
- data/lib/decidim/surveys/test/factories.rb +24 -0
- data/lib/decidim/surveys/version.rb +1 -1
- metadata +51 -19
- data/app/commands/decidim/surveys/create_survey.rb +0 -19
- data/app/views/decidim/surveys/admin/component/_actions.html.erb +0 -44
data/config/locales/zh-CN.yml
CHANGED
@@ -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:
|
data/config/locales/zh-TW.yml
CHANGED
@@ -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,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
|
data/decidim-surveys.gemspec
CHANGED
@@ -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.
|
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::
|
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 :
|
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
|
-
|
18
|
-
|
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(
|
45
|
-
surveys = surveys.where(
|
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(
|
53
|
-
answers = answers.where(
|
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#
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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
|
-
|
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:
|
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
|