decidim-templates 0.32.0 → 0.32.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc2672a2f922b03b4456384eee9192fda1d4ebb1d891a3a2813dd44678777856
4
- data.tar.gz: 93917539f7a03031fcf7c4b06bcf68afde94247373fd9eef6d41890ef1cca3aa
3
+ metadata.gz: 70fb9ae77d3b6f9fd057228c310676cfa83b1386b0fbfa85da112a1f5f8c21ed
4
+ data.tar.gz: 1d72e21fa1533c8d5a0f34bea3e38c344de36639c295a383c3a65619a415ea28
5
5
  SHA512:
6
- metadata.gz: 047a99b14abce3b21734355e4c0f915bb0bf1ef91d053024bb76a44b39795f499d0689f53c32bf8d14f700ecce22fe76bf38e9f29d02bdce966daa8fb30312fc
7
- data.tar.gz: ed577782b4c6bd7216ccc29ecfeef4eb322c87331decf96f75c75897d5e4a60b9b54f4ed6c6bc8dee1975f99c713c8298ed1d53229e7ff28c1589da2254f2a90
6
+ metadata.gz: 7d34370c0ed2b900cd87dab34b852d0f04658359ff1211a8d8e69b729ee0f7aae2ddbad54a8ec648bad66d3b76d65ca206e7882d59714732acb30d504560e915
7
+ data.tar.gz: 2d734eac1d245090e3ecddfc293142dfa5040e1c76c8be8907da899657d40c94dbb5a876fd4a295cec2d6eb602115788d3e0a3a36939c17cf4f26bcdd58fbde6
@@ -7,8 +7,8 @@ module Decidim
7
7
  module QuestionnaireCopier
8
8
  def copy_questionnaire_questions(original_questionnaire, new_questionnaire)
9
9
  # start by copying the questions so that they already exist when cross referencing them in the conditions
10
- original_questionnaire.reload.questions.includes(:response_options, :matrix_rows, :display_conditions)
11
- original_questionnaire.questions.each do |original_question|
10
+ original_questions = original_questionnaire.reload.questions.includes(:response_options, :matrix_rows, display_conditions: [:condition_question, :response_option]).to_a
11
+ original_questions.each do |original_question|
12
12
  new_question = original_question.dup
13
13
  new_question.questionnaire = new_questionnaire
14
14
  new_question.assign_attributes(
@@ -21,9 +21,12 @@ module Decidim
21
21
  copy_questionnaire_response_options(original_question, new_question)
22
22
  copy_questionnaire_matrix_rows(original_question, new_question)
23
23
  end
24
- # once all questions are copied, copy display conditions
25
- original_questionnaire.questions.zip(new_questionnaire.questions.load).each do |original_question, new_question|
26
- copy_question_display_conditions(original_question, new_question)
24
+ # once all questions are copied, copy display conditions. The destination
25
+ # questions are looked up by position (and their response options by body)
26
+ # while cross referencing the conditions, so eager load them to avoid N+1s.
27
+ destination_questions = new_questionnaire.questions.includes(:response_options).to_a
28
+ original_questions.zip(destination_questions).each do |original_question, new_question|
29
+ copy_question_display_conditions(original_question, new_question, destination_questions)
27
30
  end
28
31
  end
29
32
 
@@ -43,12 +46,12 @@ module Decidim
43
46
  end
44
47
  end
45
48
 
46
- def copy_question_display_conditions(original_question, destination_question)
49
+ def copy_question_display_conditions(original_question, destination_question, destination_questions)
47
50
  original_question.display_conditions.each do |original_display_condition|
48
51
  new_display_condition = original_display_condition.dup
49
52
  new_display_condition.question = destination_question
50
53
 
51
- destination_question_to_be_checked = find_question_by_position(destination_question.questionnaire.questions, original_display_condition.condition_question.position)
54
+ destination_question_to_be_checked = find_question_by_position(destination_questions, original_display_condition.condition_question.position)
52
55
  new_display_condition.condition_question = destination_question_to_be_checked
53
56
 
54
57
  if original_display_condition.response_option
@@ -56,7 +59,6 @@ module Decidim
56
59
  original_display_condition.response_option.body)
57
60
  end
58
61
  new_display_condition.save!
59
- destination_question.display_conditions << new_display_condition
60
62
  end
61
63
  end
62
64
 
@@ -17,6 +17,8 @@ module Decidim
17
17
  ::Decidim::Templates::Admin::Permissions,
18
18
  ::Decidim::Admin::Permissions)
19
19
 
20
+ protected
21
+
20
22
  def permission_class_chain
21
23
  ::Decidim.permissions_registry.chain_for(::Decidim::Templates::Admin::ApplicationController)
22
24
  end
@@ -13,6 +13,8 @@ module Decidim
13
13
  included do
14
14
  helper_method :templates, :choose_template?
15
15
 
16
+ protected
17
+
16
18
  def templates
17
19
  @templates = current_organization.templates.where(templatable_type:)
18
20
  @templates = @templates.where.not(id: params[:id]) if templates_path?
@@ -29,8 +31,6 @@ module Decidim
29
31
  templates.any? && templatable.pristine?
30
32
  end
31
33
 
32
- protected
33
-
34
34
  def templatable
35
35
  raise NotImplementedError, "Please set the templatable resource in your controller"
36
36
  end
@@ -58,7 +58,7 @@ module Decidim
58
58
  def fetch
59
59
  enforce_permission_to(:read, :template, template:, proposal:)
60
60
 
61
- return render json: { msg: I18n.t("templates.fetch.error", scope: "decidim.admin") }, status: :unprocessable_content if template.blank?
61
+ return render json: { msg: I18n.t("templates.fetch.error", scope: "decidim.admin") }, status: :unprocessable_content if template.blank? || proposal.blank?
62
62
 
63
63
  state = fetch_proposal_state(template)
64
64
 
@@ -136,11 +136,16 @@ module Decidim
136
136
  end
137
137
 
138
138
  def available_states(component_id = nil)
139
- Decidim::Proposals::ProposalState.where(decidim_component_id: component_id)
139
+ Decidim::Proposals::ProposalState.where(decidim_component_id: component_id) # rubocop:disable Decidim/OrganizationScopedFinder -- component_id comes from template.templatable_id, templates are scoped to current_organization
140
140
  end
141
141
 
142
142
  def proposal
143
- @proposal ||= Decidim::Proposals::Proposal.find(params[:proposalId])
143
+ @proposal ||= begin
144
+ component_ids = current_organization.participatory_spaces
145
+ .flat_map { |s| s.components.where(manifest_name: :proposals).pluck(:id) }
146
+ Decidim::Proposals::Proposal.where(decidim_component_id: component_ids) # rubocop:disable Decidim/OrganizationScopedFinder -- scoped via component_ids derived from current_organization.participatory_spaces
147
+ .find_by(id: params[:proposalId].to_i)
148
+ end
144
149
  end
145
150
 
146
151
  def availability_option_as_text(template)
@@ -155,7 +160,7 @@ module Decidim
155
160
 
156
161
  def availability_options
157
162
  @availability_options = []
158
- Decidim::Component.includes(:participatory_space).where(manifest_name: [:proposals])
163
+ Decidim::Component.includes(:participatory_space).where(manifest_name: [:proposals]) # rubocop:disable Decidim/OrganizationScopedFinder -- result is filtered in-memory below by current_organization
159
164
  .select { |a| a.participatory_space.decidim_organization_id == current_organization.id }.each do |component|
160
165
  @availability_options.push [formatted_name(component), component.id]
161
166
  end
@@ -169,7 +174,7 @@ module Decidim
169
174
  end
170
175
 
171
176
  def template
172
- @template ||= Template.find_by(id: params[:id])
177
+ @template ||= current_organization.templates.find_by(id: params[:id])
173
178
  end
174
179
 
175
180
  def collection
@@ -10,6 +10,8 @@ module Decidim
10
10
 
11
11
  helper Decidim::Admin::ExportsHelper
12
12
 
13
+ protected
14
+
13
15
  def questionnaire_for
14
16
  template
15
17
  end
@@ -30,10 +32,22 @@ module Decidim
30
32
  t(:title, scope: "decidim.templates.admin.questionnaire_templates.form", questionnaire_for: translated_attribute(template.name))
31
33
  end
32
34
 
35
+ def response_options_url(params)
36
+ url_for(params.merge(controller: "decidim/templates/admin/questionnaire_templates/questionnaires", action: "response_options", format: :json, template_id: template.id))
37
+ end
38
+
33
39
  private
34
40
 
35
41
  def template
36
- @template ||= current_organization.templates.where(templatable_type: "Decidim::Forms::Questionnaire").find(params[:id])
42
+ @template ||= current_organization.templates.where(templatable_type: "Decidim::Forms::Questionnaire").find(template_id)
43
+ end
44
+
45
+ def template_id
46
+ if action_name == "response_options"
47
+ params.expect(:template_id)
48
+ else
49
+ params.expect(:id)
50
+ end
37
51
  end
38
52
  end
39
53
  end
@@ -105,13 +105,19 @@ module Decidim
105
105
  end
106
106
 
107
107
  def apply
108
- questionnaire = Decidim::Forms::Questionnaire.find_by(id: params[:questionnaire_id])
109
- template = Decidim::Templates::Template.find_by(id: params.dig(:questionnaire, :questionnaire_template_id))
108
+ questionnaire = find_questionnaire(params[:questionnaire_id])
109
+ enforce_permission_to :apply, :questionnaire_template, questionnaire:, component: questionnaire_component(questionnaire)
110
+ template = collection.find_by(id: params.dig(:questionnaire, :questionnaire_template_id))
111
+
112
+ if questionnaire.blank?
113
+ flash[:alert] = I18n.t("templates.apply.error", scope: "decidim.admin")
114
+ return redirect_to(internal_redirect_path || { action: :index })
115
+ end
110
116
 
111
117
  ApplyQuestionnaireTemplate.call(questionnaire, template) do
112
118
  on(:ok) do
113
119
  flash[:notice] = I18n.t("templates.apply.success", scope: "decidim.admin")
114
- redirect_to URI.parse(params[:url]).path
120
+ redirect_to(internal_redirect_path || { action: :index })
115
121
  end
116
122
  on(:invalid) do
117
123
  flash[:error] = I18n.t("templates.apply.error", scope: "decidim.admin")
@@ -121,6 +127,7 @@ module Decidim
121
127
  end
122
128
 
123
129
  def preview
130
+ enforce_permission_to :preview, :questionnaire_template
124
131
  respond_to do |format|
125
132
  format.js do
126
133
  @template = template
@@ -131,23 +138,81 @@ module Decidim
131
138
  end
132
139
 
133
140
  def skip
134
- questionnaire = Decidim::Forms::Questionnaire.find_by(id: params[:questionnaire_id])
141
+ questionnaire = find_questionnaire(params[:questionnaire_id])
142
+ enforce_permission_to :skip, :questionnaire_template, questionnaire:, component: questionnaire_component(questionnaire)
143
+
144
+ return redirect_to(internal_redirect_path || { action: :index }) unless questionnaire
145
+
135
146
  # rubocop:disable Rails/SkipsModelValidations
136
147
  questionnaire.touch
137
148
  # rubocop:enable Rails/SkipsModelValidations
138
- redirect_to URI.parse(params[:url]).path
149
+ redirect_to(internal_redirect_path || { action: :index })
139
150
  end
140
151
 
152
+ protected
153
+
141
154
  def edit_questions_template
142
155
  "decidim/templates/admin/questionnaire_templates/edit_questions"
143
156
  end
144
157
 
158
+ def response_options_url(params)
159
+ url_for(params.merge(controller: "decidim/templates/admin/questionnaire_templates/questionnaires", action: "response_options", format: :json, template_id: template.id))
160
+ end
161
+
145
162
  def after_update_url
146
163
  edit_questionnaire_template_path(template)
147
164
  end
148
165
 
149
166
  private
150
167
 
168
+ def find_questionnaire(id)
169
+ questionnaire = Decidim::Forms::Questionnaire.find_by(id:) # rubocop:disable Decidim/OrganizationScopedFinder -- scoping requires polymorphic questionnaire_for chain; org ownership validated via questionnaire_for_in_organization?
170
+ return unless questionnaire
171
+ return unless questionnaire_for_in_organization?(questionnaire)
172
+
173
+ questionnaire
174
+ end
175
+
176
+ def questionnaire_component(questionnaire)
177
+ questionnaire&.questionnaire_for.try(:component)
178
+ end
179
+
180
+ def questionnaire_for_in_organization?(questionnaire)
181
+ questionnaire_for = questionnaire.questionnaire_for
182
+ return false unless questionnaire_for
183
+ return false unless questionnaire_for.respond_to?(:organization)
184
+
185
+ questionnaire_for.organization == current_organization
186
+ end
187
+
188
+ # Returns the path of the `url` param only when it points to the same
189
+ # origin. Absolute same-origin URLs and root-relative paths are
190
+ # accepted; protocol-relative, external and malformed URLs are rejected
191
+ # so they can never be used to redirect the user to another site.
192
+ def internal_redirect_path
193
+ url = params[:url].to_s
194
+ return if url.blank?
195
+
196
+ uri = URI.parse(url)
197
+ return if uri.host.present? && !same_origin?(uri)
198
+
199
+ safe_path(uri.path)
200
+ rescue URI::Error
201
+ nil
202
+ end
203
+
204
+ def same_origin?(uri)
205
+ uri.host == request.host && (uri.scheme.nil? || uri.scheme == request.scheme)
206
+ end
207
+
208
+ def safe_path(path)
209
+ return if path.blank? || !path.start_with?("/")
210
+ return if path.start_with?("//", "/\\") || path.include?("\\")
211
+ return if path.match?(/[\u0000-\u001f\u007f]/)
212
+
213
+ path
214
+ end
215
+
151
216
  def questionnaire
152
217
  template.templatable
153
218
  end
@@ -9,11 +9,9 @@ module Decidim
9
9
  return permission_action unless user
10
10
  return permission_action if context[:current_organization] != user.organization
11
11
 
12
- if user_has_a_role? && (permission_action.subject == :template && permission_action.action == :read)
12
+ if read_template_action? || allows_questionnaire_template_action?
13
13
  allow!
14
- else
15
- return permission_action unless user.admin?
16
-
14
+ elsif user.admin?
17
15
  case permission_action.subject
18
16
  when :template
19
17
  allow! if [:read, :create, :update, :destroy, :copy].include? permission_action.action
@@ -21,6 +19,8 @@ module Decidim
21
19
  allow! if permission_action.action == :index
22
20
  when :questionnaire
23
21
  allow!
22
+ when :questionnaire_template
23
+ allow! if [:preview, :apply, :skip].include? permission_action.action
24
24
  end
25
25
  end
26
26
 
@@ -42,6 +42,50 @@ module Decidim
42
42
 
43
43
  user_roles.exists?(user:)
44
44
  end
45
+
46
+ def read_template_action?
47
+ user_has_a_role? && permission_action.subject == :template && permission_action.action == :read
48
+ end
49
+
50
+ # Allows a user who is able to edit the target questionnaire to preview,
51
+ # apply or skip questionnaire templates. Organization admins can always
52
+ # perform these actions. "preview" has no target questionnaire to scope
53
+ # to, so it is allowed to any user holding a role in a participatory
54
+ # space, as it is only reachable from an already authorized form.
55
+ def allows_questionnaire_template_action?
56
+ return false unless permission_action.subject == :questionnaire_template
57
+ return false unless [:preview, :apply, :skip].include?(permission_action.action)
58
+ return true if user.admin?
59
+
60
+ if (component = context[:component]).present?
61
+ return user_can_manage_component?(component)
62
+ end
63
+
64
+ permission_action.action == :preview && user_has_any_role?(user, nil, broad_check: true)
65
+ end
66
+
67
+ # Checks the user can manage the given component by delegating the
68
+ # `:manage, :component` action to the component's own permission chain,
69
+ # so that space admins are authorized while other roles are not.
70
+ def user_can_manage_component?(component)
71
+ [
72
+ component.manifest.permissions_class,
73
+ component.participatory_space.manifest.permissions_class,
74
+ Decidim::Admin::Permissions
75
+ ].inject(permission_action_for_manage_component) do |action, permission_class|
76
+ permission_class.new(
77
+ user,
78
+ action,
79
+ context.merge(component:, current_participatory_space: component.participatory_space)
80
+ ).permissions
81
+ end.allowed?
82
+ rescue Decidim::PermissionAction::PermissionNotSetError
83
+ false
84
+ end
85
+
86
+ def permission_action_for_manage_component
87
+ Decidim::PermissionAction.new(scope: :admin, action: :manage, subject: :component)
88
+ end
45
89
  end
46
90
  end
47
91
  end
@@ -27,7 +27,7 @@ eu:
27
27
  success: Txantiloia zuzen ezabatua.
28
28
  empty: Oraindik ez dago txantiloirik.
29
29
  fetch:
30
- error: Ezin da plantilla hau aurkitu. Kargatu orria, mesedez.
30
+ error: Ezin da txantiloi hau aurkitu. Mesedez kargatu berriro orria.
31
31
  missing_resource: "(baliabide galdua)"
32
32
  update:
33
33
  error: Arazo bat egon da eztabaida hau eguneratzean.
@@ -43,7 +43,7 @@ eu:
43
43
  title: Galdeketaren Izenburua
44
44
  template:
45
45
  fields:
46
- created_at: Noiz sortua
46
+ created_at: Sortze-data
47
47
  name: Txantiloia
48
48
  templates:
49
49
  admin:
@@ -61,24 +61,24 @@ eu:
61
61
  select_template: Hautatu txantiloi-fitxategi bat
62
62
  proposal_answer_templates:
63
63
  edit:
64
- title: Editatu proposamenaren erantzun-txantilioia
64
+ title: Editatu proposamenaren erantzun-txantiloia
65
65
  form:
66
66
  component_constraint_help: Kontuan izan soilik zerrendatuko direla "proposamenak" motako osagaiak dituzten parte hartzeko espazioak.
67
67
  hint1_html: "\n<strong>%{organization}</strong> erakundearen izenak ordezkatuko du."
68
- hint2_html: "<strong>%{name}</strong> egilearen izenak ordezkatuko du."
69
- hint3_html: "<strong>%{admin}</strong> administratzailearen izenak ordezkatuko du (proposamenari erantzuten diona)."
68
+ hint2_html: "<strong>%{name}</strong> egilearen izenak ordezkatuko du"
69
+ hint3_html: "<strong>%{admin}</strong> administratzailearen izenak ordezkatuko du (proposamenari erantzuten diona)"
70
70
  hint_html: "<strong>Iradokizuna</strong> Aldagarri hauek erantzunaren txantiloiaren edozein lekutan erabil ditzakezu, txantiloia erabiltzean ordezkatuko baitira"
71
71
  save: Gorde
72
72
  index:
73
- component_constraint: Gehitu hertsapena.
73
+ component_constraint: Gehitu hertsapena
74
74
  confirm_delete: Ziur zaude txantiloi hau ezabatu nahi duzula?
75
75
  missing_state: Egoera desagertua
76
76
  proposal_state_id: Barne egoera
77
77
  title: Proposamenen erantzunak
78
78
  new:
79
- title: Proposamenaren erantzun-txantilioi berria
79
+ title: Proposamenaren erantzun-txantiloi berria
80
80
  template_chooser:
81
- select_template: Aukeratu erantzun-txantiloi bat.
81
+ select_template: Aukeratu erantzun-txantiloi bat
82
82
  questionnaire_templates:
83
83
  choose:
84
84
  continue: Jarraitu
@@ -107,7 +107,7 @@ eu:
107
107
  title: Beste galdetegi-txantiloi bat
108
108
  preview:
109
109
  current_step: '%{step} urratsa'
110
- of_total_steps: '%{total_steps} etik'
110
+ of_total_steps: guztira %{total_steps}
111
111
  tos_agreement: Parte hartzean erabilera-irizpideak eta baldintzak onartzen dituzu
112
112
  admin_log:
113
113
  template:
@@ -12,13 +12,26 @@ gl:
12
12
  menu:
13
13
  templates: Padróns
14
14
  templates:
15
+ actions:
16
+ new_template: Novo modelo
15
17
  apply:
16
18
  error: Produciuse un problema ao aplicar o padrón.
19
+ success: O modelo aplicouse correctamente.
17
20
  copy:
18
21
  error: Produciuse un problema ao copiar o padrón.
22
+ success: O modelo copiouse correctamente.
19
23
  create:
20
24
  error: Produciuse un problema ao crear o padrón.
25
+ success: O modelo creouse correctamente.
26
+ destroy:
27
+ success: O modelo eliminouse correctamente.
21
28
  empty: Aínda non hai padróns.
29
+ fetch:
30
+ error: Non se puido atopar este modelo. Volve cargar a páxina.
31
+ missing_resource: "(falta o recurso)"
32
+ update:
33
+ error: Produciuse un problema ao actualizar este modelo.
34
+ success: O modelo actualizouse correctamente.
22
35
  titles:
23
36
  template_types:
24
37
  questionnaires: Padrón para cuestionarios
@@ -35,26 +48,74 @@ gl:
35
48
  templates:
36
49
  admin:
37
50
  block_user_templates:
51
+ edit:
52
+ title: Editar o modelo de mensaxe de bloqueo de participante
38
53
  form:
39
54
  save: Gardar
55
+ index:
56
+ confirm_delete: Seguro que queres eliminar este modelo?
57
+ title: Mensaxes de bloqueo de participantes
58
+ new:
59
+ title: Novo modelo de mensaxe de bloqueo de participante
60
+ template_chooser:
61
+ select_template: Seleccionar unha resposta modelo
40
62
  proposal_answer_templates:
63
+ edit:
64
+ title: Editar o modelo de resposta a propostas
41
65
  form:
66
+ component_constraint_help: Ten en conta que só se mostrarán os espazos participativos que teñan compoñentes do tipo «propostas».
67
+ hint1_html: "<strong>%{organization}</strong> substituirase polo nome da organización"
68
+ hint2_html: "<strong>%{name}</strong> substituirase polo nome da persoa autora"
69
+ hint3_html: "<strong>%{admin}</strong> substituirase polo nome da persoa administradora (a que responde á proposta)"
70
+ hint_html: "<strong>Consello:</strong> podes usar estas variables en calquera lugar do modelo de resposta; substituiranse ao usar o modelo"
42
71
  save: Gardar
72
+ index:
73
+ component_constraint: Engadir restrición
74
+ confirm_delete: Seguro que queres eliminar este modelo?
75
+ missing_state: Falta o estado
76
+ proposal_state_id: Estado interno
77
+ title: Respostas a propostas
78
+ new:
79
+ title: Novo modelo de resposta a propostas
80
+ template_chooser:
81
+ select_template: Seleccionar unha resposta modelo
43
82
  questionnaire_templates:
44
83
  choose:
84
+ continue: Continuar
85
+ description: Podes crear un novo cuestionario ou escoller un modelo predefinido e modificalo máis adiante. Selecciona unha opción.
45
86
  label: Escoller padrón
87
+ options:
88
+ create_new_form: Crear un novo formulario
89
+ select_template: Seleccionar modelo
46
90
  placeholder: Escoller padrón
47
91
  edit:
48
92
  edit: Editar
93
+ empty: Aínda non hai preguntas.
94
+ manage_questions: Preguntas
49
95
  questionnaire: Cuestionario
96
+ title: Editar o modelo de cuestionario
97
+ edit_questions:
98
+ add_question: Engadir pregunta
99
+ add_separator: Engadir separador
100
+ add_title_and_description: Engadir título e descrición
50
101
  form:
51
102
  title: Padrón de cuestionario %{questionnaire_for}
52
103
  index:
53
104
  confirm_delete: Tes a certeza de querer eliminar este padrón?
54
105
  title: Padróns de cuestionario
106
+ new:
107
+ title: Novo modelo de cuestionario
55
108
  preview:
56
109
  current_step: Paso %{step}
57
110
  of_total_steps: de %{total_steps}
58
111
  tos_agreement: Ao participar, aceptas os termos do servizo
112
+ admin_log:
113
+ template:
114
+ create: "%{user_name} creou o modelo de cuestionario %{resource_name}"
115
+ delete: "%{user_name} eliminou o modelo de cuestionario %{resource_name}"
116
+ duplicate: "%{user_name} duplicou o modelo de cuestionario %{resource_name}"
117
+ update: "%{user_name} actualizou o modelo de cuestionario %{resource_name}"
59
118
  template_types:
119
+ block_user: Mensaxes de bloqueo de participantes
120
+ proposal_answer_templates: Respostas a propostas
60
121
  questionnaires: Cuestionarios
@@ -3,7 +3,7 @@
3
3
  $LOAD_PATH.push File.expand_path("lib", __dir__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
- version = "0.32.0"
6
+ version = "0.32.2"
7
7
  s.version = version
8
8
  s.authors = ["Vera Rojman"]
9
9
  s.email = ["vrojman@protonmail.com"]
@@ -2,13 +2,11 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- # rubocop:disable Rails/SkipsModelValidations
6
-
7
5
  shared_examples_for "uses questionnaire templates" do |_questionnaire_for|
8
6
  describe "choose a template" do
9
7
  context "when there are no templates" do
10
8
  before do
11
- questionnaire.update_columns(
9
+ questionnaire.update!(
12
10
  created_at: 1.day.ago,
13
11
  updated_at: Time.zone.now
14
12
  )
@@ -26,7 +24,7 @@ shared_examples_for "uses questionnaire templates" do |_questionnaire_for|
26
24
 
27
25
  context "when it is an existing questionnaire" do
28
26
  before do
29
- questionnaire.update_columns(
27
+ questionnaire.update!(
30
28
  created_at: 1.day.ago,
31
29
  updated_at: Time.zone.now
32
30
  )
@@ -39,9 +37,10 @@ shared_examples_for "uses questionnaire templates" do |_questionnaire_for|
39
37
 
40
38
  context "when it is a newly created questionnaire" do
41
39
  before do
42
- questionnaire.update_columns(
43
- created_at: Time.zone.now,
44
- updated_at: Time.zone.now,
40
+ time = Time.zone.now
41
+ questionnaire.update!(
42
+ created_at: time,
43
+ updated_at: time,
45
44
  title: {},
46
45
  description: {},
47
46
  tos: {}
@@ -82,9 +81,10 @@ shared_examples_for "uses questionnaire templates" do |_questionnaire_for|
82
81
  let(:questionnaire_question) { questionnaire.questions.first }
83
82
 
84
83
  before do
85
- questionnaire.update_columns(
86
- created_at: Time.zone.now,
87
- updated_at: Time.zone.now,
84
+ time = Time.zone.now
85
+ questionnaire.update!(
86
+ created_at: time,
87
+ updated_at: time,
88
88
  title: {},
89
89
  description: {},
90
90
  tos: {}
@@ -106,6 +106,30 @@ shared_examples_for "uses questionnaire templates" do |_questionnaire_for|
106
106
  expect(page.find("#questions_questions_#{questionnaire_question.id}_body_en").value).to eq(question.body["en"])
107
107
  end
108
108
  end
109
- end
110
109
 
111
- # rubocop:enable Rails/SkipsModelValidations
110
+ describe "skip the template" do
111
+ let!(:templates) { create_list(:questionnaire_template, 6, :with_questions, skip_injection: true, organization: questionnaire.questionnaire_for.organization) }
112
+
113
+ before do
114
+ questionnaire.update!(
115
+ created_at: 1.hour.ago,
116
+ updated_at: 1.hour.ago,
117
+ title: {},
118
+ description: {},
119
+ tos: {}
120
+ )
121
+ visit current_path
122
+ end
123
+
124
+ it "continues to the questionnaire without applying any template" do
125
+ choose("Create new form")
126
+
127
+ expect(page).to have_css("a[data-create-new-form-button]")
128
+ click_on "Continue"
129
+
130
+ expect(page).to have_text("Add question")
131
+ expect(page).to have_no_text("Select template")
132
+ expect(questionnaire.reload.updated_at).not_to eq(questionnaire.created_at)
133
+ end
134
+ end
135
+ end
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-templates version.
5
5
  module Templates
6
6
  def self.version
7
- "0.32.0"
7
+ "0.32.2"
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 0.32.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vera Rojman
@@ -15,98 +15,98 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.32.0
18
+ version: 0.32.2
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.32.0
25
+ version: 0.32.2
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: decidim-forms
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.32.0
32
+ version: 0.32.2
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.32.0
39
+ version: 0.32.2
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: decidim-admin
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - '='
45
45
  - !ruby/object:Gem::Version
46
- version: 0.32.0
46
+ version: 0.32.2
47
47
  type: :development
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: 0.32.0
53
+ version: 0.32.2
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: decidim-dev
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - '='
59
59
  - !ruby/object:Gem::Version
60
- version: 0.32.0
60
+ version: 0.32.2
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - '='
66
66
  - !ruby/object:Gem::Version
67
- version: 0.32.0
67
+ version: 0.32.2
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: decidim-participatory_processes
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - '='
73
73
  - !ruby/object:Gem::Version
74
- version: 0.32.0
74
+ version: 0.32.2
75
75
  type: :development
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - '='
80
80
  - !ruby/object:Gem::Version
81
- version: 0.32.0
81
+ version: 0.32.2
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: decidim-proposals
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - '='
87
87
  - !ruby/object:Gem::Version
88
- version: 0.32.0
88
+ version: 0.32.2
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
- version: 0.32.0
95
+ version: 0.32.2
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: decidim-surveys
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - '='
101
101
  - !ruby/object:Gem::Version
102
- version: 0.32.0
102
+ version: 0.32.2
103
103
  type: :development
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 0.32.0
109
+ version: 0.32.2
110
110
  description: This module provides a solution to create templates for different Decidim
111
111
  models, such as Proposals and Questionnaires..
112
112
  email: