decidim-elections 0.31.0 → 0.31.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/commands/decidim/elections/admin/update_election.rb +3 -3
  3. data/app/controllers/concerns/decidim/elections/uses_votes_booth.rb +8 -2
  4. data/app/controllers/decidim/elections/per_question_votes_controller.rb +28 -1
  5. data/app/forms/decidim/elections/admin/election_form.rb +10 -0
  6. data/app/forms/decidim/elections/censuses/internal_users_form.rb +7 -13
  7. data/app/models/decidim/elections/election.rb +4 -8
  8. data/app/packs/entrypoints/decidim_elections.js +1 -0
  9. data/app/packs/src/decidim/elections/live_results_update.js +22 -0
  10. data/app/packs/src/decidim/elections/question_status_checker.js +42 -0
  11. data/app/permissions/decidim/elections/admin/permissions.rb +3 -5
  12. data/app/presenters/decidim/elections/election_presenter.rb +8 -3
  13. data/app/views/decidim/elections/admin/dashboard/_questions_with_results.html.erb +5 -0
  14. data/app/views/decidim/elections/admin/elections/_election-tr.html.erb +1 -1
  15. data/app/views/decidim/elections/admin/elections/_form.html.erb +1 -1
  16. data/app/views/decidim/elections/admin/questions/_form.html.erb +1 -30
  17. data/app/views/decidim/elections/censuses/_internal_users_form.html.erb +15 -0
  18. data/app/views/decidim/elections/elections/_election_aside.html.erb +2 -1
  19. data/app/views/decidim/elections/elections/_vote_results_question.html.erb +4 -0
  20. data/app/views/decidim/elections/per_question_votes/show.html.erb +2 -0
  21. data/app/views/decidim/elections/votes/receipt.html.erb +18 -1
  22. data/config/locales/ca-IT.yml +7 -3
  23. data/config/locales/ca.yml +7 -3
  24. data/config/locales/cs.yml +6 -1
  25. data/config/locales/de.yml +4 -0
  26. data/config/locales/en.yml +8 -4
  27. data/config/locales/es-MX.yml +7 -3
  28. data/config/locales/es-PY.yml +7 -3
  29. data/config/locales/es.yml +7 -3
  30. data/config/locales/eu.yml +8 -4
  31. data/config/locales/fi-plain.yml +7 -3
  32. data/config/locales/fi.yml +7 -3
  33. data/config/locales/fr-CA.yml +8 -4
  34. data/config/locales/fr.yml +8 -4
  35. data/config/locales/ja.yml +6 -3
  36. data/config/locales/pt-BR.yml +194 -0
  37. data/config/locales/sv.yml +10 -3
  38. data/lib/decidim/elections/admin_engine.rb +4 -4
  39. data/lib/decidim/elections/test/per_question_vote_examples.rb +105 -3
  40. data/lib/decidim/elections/test/vote_examples.rb +5 -3
  41. data/lib/decidim/elections/version.rb +1 -1
  42. metadata +15 -14
@@ -1,11 +1,21 @@
1
1
  ---
2
2
  pt-BR:
3
+ activemodel:
4
+ attributes:
5
+ token_csv:
6
+ file: Arquivo
7
+ remove_all: Remover todos os dados do censo atual
3
8
  decidim:
4
9
  admin:
5
10
  menu:
6
11
  elections_menu:
12
+ basic_elections: Principal
7
13
  election_census: Censo
14
+ election_dashboard: Painel de Controle
8
15
  election_questions: Questões
16
+ tooltips:
17
+ deleted_elections_info: Não é possível excluir esta eleição
18
+ edit_elections_info: Não é possível editar esta eleição
9
19
  components:
10
20
  elections:
11
21
  actions:
@@ -20,86 +30,270 @@ pt-BR:
20
30
  announcement: Anúncio
21
31
  elections:
22
32
  actions:
33
+ confirm_delete_election: Você tem certeza que deseja excluir esta eleição?
34
+ confirm_unpublish_election: Você tem certeza que deseja cancelar a publicação desta eleição?
35
+ deleted_election_info: Eleições excluídas não são exibidas na lista. Você pode visualizá-las clicando no botão abaixo.
36
+ edit: Editar eleição
37
+ new: Nova eleição
23
38
  preview: Pré-visualização
24
39
  title: Ações
40
+ view: Ver eleição
41
+ view_deleted_elections: Ver eleições excluídas
25
42
  admin:
26
43
  census:
27
44
  edit:
45
+ choose_census: Escolha o tipo de censo que deseja usar para esta eleição
28
46
  created_at: Criado em
47
+ identifier: Identificador de usuário
48
+ preview:
49
+ title:
50
+ one: A lista de pré-visualização é limitada ao registro %{count}.
51
+ other: A lista de pré-visualização é limitada aos %{count} registros.
52
+ update:
53
+ error: Ocorreu um erro ao gerar ou salvar o censo.
54
+ success: Censo atualizados com sucesso.
29
55
  dashboard:
56
+ calendar:
57
+ end_at: 'Hora de término:'
58
+ end_election: Final da eleição
59
+ manual_start: Manualmente
60
+ published_results_at: Resultados publicados em
61
+ start_at: 'Horário de início:'
62
+ start_election: Começar a eleição
63
+ title: Calendário
30
64
  census:
31
65
  title: Censo
32
66
  main:
33
67
  labels:
68
+ calendar: Calendário
34
69
  description: Descrição
70
+ image: Galeria de imagens
71
+ results: Disponibilidade de resultados
72
+ title: Título
73
+ title: Principal
74
+ publish_confirm: Você tem certeza que deseja publicar esta eleição?
35
75
  questions:
36
76
  labels:
37
77
  answers: Respostas
78
+ limit_info: Esta eleição tem mais perguntas. A previsão é limitada a três perguntas.
38
79
  title: Questões
39
80
  questions_table:
40
81
  answer: Respostas
82
+ percentage: Porcentagem
83
+ total: Total
41
84
  votes: Votos
85
+ votes_count:
86
+ one: 1 voto
87
+ other: "%{count} votos"
42
88
  results:
89
+ not_started: A eleição ainda não começou.
90
+ per_question_waiting: Votação ainda não está habilitada para nenhuma pergunta. Os participantes verão uma mensagem "Aguardando pela próxima pergunta" até que você ative pelo menos uma.
43
91
  publish_button: Publicar resultados
92
+ results_availability:
93
+ after_end: Você pode publicar todos os resultados após o término da eleição. Os resultados permanecerão ocultos até que você os publique manualmente.
94
+ per_question: Você precisa habilitar a votação e publicar manualmente os resultados para cada pergunta individualmente.
95
+ real_time: Os resultados são exibidos automaticamente durante a eleição.
96
+ start_question_button: Habilitar votação
44
97
  title: Resultados
45
98
  status:
99
+ census: 'Censo:'
100
+ results_availability:
101
+ after_end: Resultados disponíveis após o término da eleição
102
+ per_question: Resultados disponíveis por pergunta
103
+ real_time: Resultados disponíveis em tempo real
46
104
  title: Status da eleição
47
105
  elections:
106
+ create:
107
+ invalid: Houve um problema ao criar a eleição.
108
+ success: Eleição criada com sucesso.
109
+ dashboard:
110
+ subtitle: 'Etapa final: Revise seus detalhes. Edições ainda podem ser feitas antes de publicar. Uma vez publicado, você ainda poderá atualizar a descrição das eleições.'
111
+ title: Painel de controle
48
112
  edit:
49
113
  title: Editar eleição
50
114
  form:
51
115
  add_images: Adicionar imagens
116
+ attachment_legend: Adicionar uma galeria de imagens (opcional)
117
+ basic_title: Informação básica
118
+ calendar: Calendário
119
+ calendar_description: Verifique se o fuso horário da organização está correto nas configurações da organização. A configuração atual é %{timezone}.
120
+ edit_attachments: Editar anexos
121
+ end_at: Hora de término
122
+ manual_start: Início manual
52
123
  publish: Publicar
124
+ results_availability:
125
+ after_end: Após o fim das eleições
126
+ after_end_help: publicar resultados quando a eleição for concluída
127
+ per_question: Pergunta por pergunta
128
+ per_question_help: manipular manualmente a votação e publicar os resultados para cada questão
129
+ real_time: Tempo real
130
+ real_time_help: publicar automaticamente os resultados durante a votação
131
+ title: Disponibilidade de resultados
132
+ save: Salvar e continuar
133
+ start_at: Horário de início
53
134
  index:
54
135
  title: Eleições
136
+ manage_trash:
137
+ title: Eleições apagadas
55
138
  new:
56
139
  title: Nova eleição
140
+ publish:
141
+ invalid: Ocorreu um erro ao publicar a eleição.
142
+ success: Eleição publicada com sucesso.
143
+ unpublish:
144
+ invalid: Ocorreu um erro ao cancelar a publicação da eleição.
145
+ success: Eleição não publicada com sucesso.
146
+ update:
147
+ invalid: Ocorreu um erro ao atualizar a eleição.
148
+ success: Eleição atualizada com sucesso.
57
149
  questions:
58
150
  edit_questions:
59
151
  new_question: Nova questão
152
+ remove_question_confirm: Tem certeza de que deseja excluir esta questão?
60
153
  title: Questões
154
+ form:
155
+ errors:
156
+ at_least_one_question: Pelo menos uma pergunta é necessária.
157
+ form_description: A pergunta deve ter pelo menos duas respostas para dar o passo seguinte.
158
+ update:
159
+ invalid: Ocorreu um erro ao atualizar as perguntas.
160
+ success: Perguntas atualizadas com sucesso.
61
161
  statuses:
162
+ enable_voting:
163
+ invalid: Houve um problema ao permitir a votação.
164
+ success: Votação habilitada com sucesso.
165
+ end:
166
+ invalid: Houve um problema ao terminar a eleição.
167
+ success: A eleição terminou com sucesso.
62
168
  publish_results:
63
169
  invalid: Ocorreu um erro ao publicar os resultados.
170
+ success: Resultados publicados com sucesso.
171
+ start:
172
+ invalid: Houve um problema ao iniciar a eleição.
173
+ success: Eleição iniciada com sucesso.
174
+ unknown: Status desconhecido
64
175
  censuses:
176
+ census_ready_html: Os dados do censo são enviados e preparados para seu uso na eleição <b>%{election_title}</b>.
177
+ census_size_html:
178
+ one: Atualmente há uma pessoa <strong>1</strong> elegível para votar nesta eleição (isso pode mudar em um censo dinâmico).
179
+ other: Existem atualmente <strong>%{count}</strong> pessoas elegíveis para votar nesta eleição (isso pode mudar em um censo dinâmico).
180
+ internal_users:
181
+ already_have_an_account?: Já possui uma conta?
182
+ are_you_new?: Novo participante?
183
+ info_html: |
184
+ Você pode restringir a participação nas eleições para participantes que tenham uma autorização.<br>
185
+ Note que os participantes precisam cumprir as autorizações selecionadas para poder votar. Deixar todas as caixas de seleção vazias permitirá votar qualquer pessoa registrada.
186
+ internal_type_title: Autorização adicional necessária para votar (opcional)
187
+ label: Participantes registrados (dinâmico)
188
+ sign_in_description: Faça login para votar nesta eleição
189
+ sign_up_description: Criar uma conta para votar nesta eleição
190
+ internal_users_form:
191
+ authorization_options_invalid: Infelizmente, embora tenha todas as autorizações necessárias, algumas delas não são válidas para esta eleição.
192
+ exit_button: Sair da cabine de votação
193
+ invalid: Você não está autorizado a votar nesta eleição.
194
+ resume_with_method: Retomar verificação com %{name}
195
+ verify_with_method: Verificar com %{name}
196
+ token_csv:
197
+ example: |
198
+ email;token
199
+ user@example.org;123456
200
+ user2@example.org;ABCXYZ
201
+ info_html: |
202
+ Deve ser um arquivo em formato CSV com duas colunas, uma com o endereço de e-mail e outra com o valor de um token que o usuário deverá inserir para votar.
203
+ Deve ser separado por um ponto e vírgula (;)
204
+ label: Usuários não registrados com tokens (corrigidos)
205
+ remove_before_upload: Se você deseja carregar um novo censo, primeiro você deve remover o já existente.
206
+ upload_file: Enviar um arquivo
207
+ upload_new_census: Carregar arquivo CSV
65
208
  token_csv_form:
66
209
  email: E-mail
210
+ email_placeholder: Insira o endereço de email do eleitor
211
+ invalid: O email ou token não é válido. Por favor, verifique os detalhes e tente novamente.
212
+ token: Token
213
+ token_placeholder: Insira o token do eleitor
67
214
  elections:
68
215
  count:
69
216
  elections_count:
70
217
  one: "%{count} eleição"
71
218
  other: "%{count} eleições"
219
+ elections:
220
+ empty: Não há eleições disponíveis.
221
+ empty_filters: Não há eleições que correspondam aos seus filtros.
72
222
  filters:
73
223
  all: Todos
74
224
  state: Status
75
225
  state_values:
76
226
  finished: Finalizado
77
227
  ongoing: Em andamento
228
+ scheduled: Agendado
78
229
  orders:
230
+ end_at: Data de término
231
+ label: Ordenar por
79
232
  recent: Recente
233
+ start_at: Data de início
80
234
  questions:
235
+ subtitle: 'Estas são as questões que determinam este processo de votação:'
81
236
  title: Perguntas eleitorais
82
237
  show:
238
+ active_voting_until: 'Ativar votação até: %{end_date}'
239
+ edit_vote_button: Editar voto
83
240
  vote_button: Voto
241
+ voted: Você já votou. Você pode votar novamente, apenas o seu último voto será contado.
242
+ votes_count:
243
+ one: 1 voto
244
+ other: "%{count} votos"
245
+ voting_began: 'Votação iniciada em: %{start_date}'
84
246
  vote_results:
247
+ subtitle:
248
+ after_end: A eleição terminou. Agora você pode ver os resultados.
249
+ per_question: Os resultados estão disponíveis por pergunta. Você pode ver os resultados para cada questão após a votação ser habilitada e os resultados são publicados.
250
+ real_time: Os resultados estão disponíveis em tempo real. Você pode ver os resultados enquanto a votação estiver em andamento.
85
251
  title: Resultados
252
+ total: 'TOTAL:'
253
+ total_votes:
254
+ one: 1 voto
255
+ other: "%{count} votos"
86
256
  models:
87
257
  election:
88
258
  fields:
89
259
  census: Censo
260
+ end_at: Hora de término
261
+ start_at: Horário de início
90
262
  status: Status
91
263
  title: Título
264
+ per_question_votes:
265
+ waiting:
266
+ description: Você pode esperar aqui até que a próxima pergunta esteja disponível. Você será automaticamente redirecionado para a próxima pergunta quando ela estiver pronta.
267
+ edit_vote: Edite seu voto
268
+ exit_button: Sair da sala de espera
269
+ title: Aguardando a próxima pergunta
92
270
  status:
93
271
  active: Ativo
94
272
  finished: Finalizado
95
273
  not_started: Não Iniciado
96
274
  ongoing: Em andamento
275
+ published_results: Resultados publicados
276
+ scheduled: Agendado
277
+ voting_enabled: Votação em andamento
97
278
  votes:
279
+ cast:
280
+ invalid: Houve um problema ao transmitir o seu voto. Por favor, verifique as informações que você forneceu e tente novamente.
281
+ success: Seu voto foi enviado com sucesso.
282
+ check_census:
283
+ access: Acesso
284
+ election_not_open: A eleição ainda não foi aberta. Por favor, verifique as datas e tente novamente.
285
+ form_title: Verifique sua identidade
98
286
  confirm:
287
+ edit_vote: Edite seu voto
99
288
  title: Confirme seu voto
100
289
  question:
101
290
  back: Voltar
291
+ cast_vote: Transmitir voto
102
292
  next: Próxima
293
+ receipt:
294
+ edit_vote: Edite seu voto
295
+ exit_button: Sair da cabine de votação
296
+ title: Seus votos foram enviados com sucesso
103
297
  statistics:
104
298
  elections_count: Eleições
105
299
  layouts:
@@ -61,7 +61,11 @@ sv:
61
61
  title: Frågor
62
62
  questions_table:
63
63
  answer: Svar
64
+ total: Totalt
64
65
  votes: Röster
66
+ votes_count:
67
+ one: 1 röst
68
+ other: "%{count} röster"
65
69
  results:
66
70
  publish_button: Publicera resultat
67
71
  title: Resultat
@@ -137,9 +141,6 @@ sv:
137
141
  authorization_options_invalid: Tyvärr – ni har alla tillstånd som krävs, men en del av dem är inte giltiga för detta val.
138
142
  exit_button: Lämna valbåset
139
143
  invalid: Du har inte behörighet att rösta i detta val.
140
- missing: Din användare saknar vissa nödvändiga tillstånd. Kontrollera informationen och försök igen.
141
- not_authorized: '"%{adapter}" tillståndet matchar inte de obligatoriska villkoren.'
142
- not_granted: '"%{adapter}" behörighet beviljas inte.'
143
144
  resume_with_method: Återuppta verifieringen med %{name}
144
145
  verify_with_method: Verifiera med %{name}
145
146
  token_csv:
@@ -183,6 +184,7 @@ sv:
183
184
  subtitle: 'Detta är frågorna för denna omröstningsprocess:'
184
185
  show:
185
186
  active_voting_until: 'Aktiv röstning till: %{end_date}'
187
+ edit_vote_button: Redigera röst
186
188
  vote_button: Rösta
187
189
  voted: Du har redan röstat. Om du röstar igen kommer bara den senaste rösten att räknas.
188
190
  votes_count:
@@ -195,6 +197,10 @@ sv:
195
197
  per_question: Resultat finns tillgängliga per fråga. Du kan se resultaten för varje fråga efter att röstning har aktiverats och resultaten är publicerade.
196
198
  real_time: Resultaten är tillgängliga i realtid. Du kan se resultaten medan omröstningen pågår.
197
199
  title: Resultat
200
+ total: 'TOTAL:'
201
+ total_votes:
202
+ one: 1 röst
203
+ other: "%{count} röster"
198
204
  models:
199
205
  election:
200
206
  fields:
@@ -237,6 +243,7 @@ sv:
237
243
  next: Nästa
238
244
  receipt:
239
245
  description: Du kan rösta igen så länge omröstningsperioden pågår. En ny omröstning kommer att skriva över den gamla.
246
+ edit_vote: Redigera din röst
240
247
  exit_button: Lämna valbåset
241
248
  title: Tack, din röst är mottagen
242
249
  metadata:
@@ -51,14 +51,14 @@ module Decidim
51
51
 
52
52
  menu.add_item :election_questions_edit,
53
53
  I18n.t("election_questions", scope: "decidim.admin.menu.elections_menu"),
54
- @election.nil? || @election.published? ? "#" : current_component_admin_proxy&.edit_questions_election_path(@election),
55
- active: @election.present? && !@election.published? && is_active_link?(current_component_admin_proxy&.edit_questions_election_path(@election)),
54
+ @election.nil? || !@election.editable? ? "#" : current_component_admin_proxy&.edit_questions_election_path(@election),
55
+ active: @election.present? && @election.editable? && is_active_link?(current_component_admin_proxy&.edit_questions_election_path(@election)),
56
56
  icon_name: "question-answer-line"
57
57
 
58
58
  menu.add_item :election_census,
59
59
  I18n.t("election_census", scope: "decidim.admin.menu.elections_menu"),
60
- @election.nil? || @election.published? || @election.questions.blank? ? "#" : current_component_admin_proxy&.census_election_path(@election),
61
- active: @election.present? && !@election.published? && is_active_link?(current_component_admin_proxy&.census_election_path(@election)),
60
+ @election.nil? || !@election.editable? || @election.questions.blank? ? "#" : current_component_admin_proxy&.census_election_path(@election),
61
+ active: @election.present? && @election.editable? && is_active_link?(current_component_admin_proxy&.census_election_path(@election)),
62
62
  icon_name: "group-2-line"
63
63
 
64
64
  menu.add_item :election_dashboard,
@@ -31,7 +31,7 @@ shared_examples "a csv token per question votable election" do
31
31
  expect(page).to have_current_path(election_path)
32
32
  expect(page).to have_content("You have already voted.")
33
33
  expect(election.votes.where(voter_uid:).size).to eq(3)
34
- click_on "Vote"
34
+ click_on "Edit vote"
35
35
  expect(page).to have_current_path(new_election_vote_path)
36
36
  fill_in "Email", with: election.voters.first.data["email"]
37
37
  fill_in "Token", with: election.voters.first.data["token"]
@@ -73,7 +73,7 @@ shared_examples "a per question votable election" do
73
73
  expect(page).to have_current_path(election_path)
74
74
  expect(page).to have_content("You have already voted.")
75
75
  expect(election.votes.where(voter_uid:).size).to eq(2)
76
- click_on "Vote"
76
+ click_on "Edit vote"
77
77
  expect(find("input[value='#{question1.response_options.first.id}']")).to be_checked
78
78
  choose translated_attribute(question1.response_options.second.body)
79
79
  click_on "Cast vote"
@@ -114,7 +114,7 @@ shared_examples "a per question votable election with published results" do
114
114
  expect(page).to have_current_path(election_path)
115
115
  expect(page).to have_content("You have already voted.")
116
116
  expect(election.votes.where(voter_uid:).size).to eq(1)
117
- click_on "Vote"
117
+ click_on "Edit vote"
118
118
  expect(page).to have_current_path(election_vote_path(question2))
119
119
  expect(find("input[value='#{question2.response_options.first.id}']")).to be_checked
120
120
  expect(find("input[value='#{question2.response_options.second.id}']")).not_to be_checked
@@ -171,3 +171,105 @@ shared_examples "a per question votable election with already voted questions" d
171
171
  expect(page).to have_no_content("Edit your vote")
172
172
  end
173
173
  end
174
+
175
+ shared_examples "a per question votable election with automatic redirect when question closes" do
176
+ it "redirects to the waiting room when admin closes voting while user is on question page" do
177
+ expect(page).to have_content(translated_attribute(election.title))
178
+ click_on "Vote"
179
+ expect(page).to have_current_path(election_vote_path(question1))
180
+ expect(page).to have_content(strip_tags(translated_attribute(question1.description)))
181
+
182
+ # Simulate admin closing voting for question1 (publishing results)
183
+ question1.update!(published_results_at: Time.current)
184
+
185
+ # Wait for JavaScript polling to detect the change and redirect
186
+ expect(page).to have_current_path(waiting_election_votes_path, wait: 3)
187
+ expect(page).to have_content("Waiting for the next question")
188
+ end
189
+
190
+ it "redirects to next question when admin closes current question and next is available" do
191
+ # Enable question2 from the start
192
+ question2.update!(voting_enabled_at: Time.current)
193
+
194
+ expect(page).to have_content(translated_attribute(election.title))
195
+ click_on "Vote"
196
+ expect(page).to have_current_path(election_vote_path(question1))
197
+ expect(page).to have_content(strip_tags(translated_attribute(question1.description)))
198
+
199
+ # Simulate admin closing voting for question1
200
+ question1.update!(published_results_at: Time.current)
201
+
202
+ # Wait for JavaScript polling to detect the change and redirect
203
+ expect(page).to have_current_path(election_vote_path(question2), wait: 3)
204
+ expect(page).to have_content(strip_tags(translated_attribute(question2.description)))
205
+ end
206
+ end
207
+
208
+ shared_examples "a per question votable election with edit from receipt" do
209
+ it "allows editing votes from receipt page" do
210
+ click_on "Vote"
211
+ choose translated_attribute(question1.response_options.first.body)
212
+ click_on "Cast vote"
213
+ check translated_attribute(question2.response_options.first.body)
214
+ click_on "Cast vote"
215
+ expect(page).to have_current_path(receipt_election_votes_path)
216
+ expect(page).to have_link("Edit your vote")
217
+ expect(page).to have_link("Exit the voting booth")
218
+
219
+ click_on "Edit your vote"
220
+ expect(page).to have_current_path(election_vote_path(question2))
221
+ expect(find("input[value='#{question2.response_options.first.id}']")).to be_checked
222
+
223
+ click_on "Back"
224
+ expect(page).to have_current_path(election_vote_path(question1))
225
+ expect(find("input[value='#{question1.response_options.first.id}']")).to be_checked
226
+
227
+ choose translated_attribute(question1.response_options.second.body)
228
+ click_on "Cast vote"
229
+ expect(page).to have_current_path(election_vote_path(question2))
230
+
231
+ check translated_attribute(question2.response_options.second.body)
232
+ click_on "Cast vote"
233
+ expect(page).to have_current_path(receipt_election_votes_path)
234
+ expect(election.votes.where(voter_uid:).size).to eq(3)
235
+
236
+ click_on "Exit the voting booth"
237
+ expect(page).to have_current_path(election_path)
238
+ expect(page).to have_content("You have already voted.")
239
+ end
240
+ end
241
+
242
+ shared_examples "a per question votable election with edit from receipt when all questions enabled" do
243
+ it "allows editing any question from receipt page" do
244
+ click_on "Vote"
245
+ choose translated_attribute(question1.response_options.first.body)
246
+ click_on "Cast vote"
247
+ check translated_attribute(question2.response_options.first.body)
248
+ click_on "Cast vote"
249
+ expect(page).to have_current_path(receipt_election_votes_path)
250
+
251
+ click_on "Edit your vote"
252
+ expect(page).to have_current_path(election_vote_path(question2))
253
+
254
+ click_on "Back"
255
+ expect(page).to have_current_path(election_vote_path(question1))
256
+
257
+ choose translated_attribute(question1.response_options.second.body)
258
+ click_on "Cast vote"
259
+ expect(page).to have_current_path(election_vote_path(question2))
260
+ expect(find("input[value='#{question2.response_options.first.id}']")).to be_checked
261
+
262
+ click_on "Cast vote"
263
+ expect(page).to have_current_path(receipt_election_votes_path)
264
+
265
+ click_on "Edit your vote"
266
+ click_on "Back"
267
+ choose translated_attribute(question1.response_options.first.body)
268
+ click_on "Cast vote"
269
+ uncheck translated_attribute(question2.response_options.first.body)
270
+ check translated_attribute(question2.response_options.second.body)
271
+ click_on "Cast vote"
272
+ expect(page).to have_current_path(receipt_election_votes_path)
273
+ expect(election.votes.where(voter_uid:).size).to eq(2)
274
+ end
275
+ end
@@ -52,7 +52,7 @@ shared_examples "a votable election" do
52
52
  click_on "Vote"
53
53
 
54
54
  fill_in_votes
55
- click_on "Vote"
55
+ click_on "Edit vote"
56
56
  expect(page).to have_current_path(election_vote_path(election.questions.first))
57
57
  end
58
58
  end
@@ -131,7 +131,7 @@ shared_examples "a csv token votable election" do
131
131
  fill_in "Token", with: election.voters.first.data["token"]
132
132
  click_on "Access"
133
133
  fill_in_votes
134
- click_on "Vote"
134
+ click_on "Edit vote"
135
135
  expect(page).to have_current_path(new_election_vote_path)
136
136
  fill_in "Email", with: election.voters.first.data["email"]
137
137
  fill_in "Token", with: election.voters.first.data["token"]
@@ -169,7 +169,8 @@ end
169
169
 
170
170
  shared_examples "an editable votable election" do
171
171
  it "Allows the user to edit the vote" do
172
- click_on "Vote"
172
+ expect(page).to have_link("Edit vote")
173
+ click_on "Edit vote"
173
174
  expect(page).to have_current_path(election_vote_path(election.questions.first))
174
175
  expect(find("input[value='#{election.questions.first.response_options.first.id}']")).to be_checked
175
176
  expect(find("input[value='#{election.questions.first.response_options.second.id}']")).not_to be_checked
@@ -191,6 +192,7 @@ end
191
192
 
192
193
  shared_examples "a csv token editable votable election" do
193
194
  it "Allows the user to edit the vote" do
195
+ expect(page).to have_link("Vote")
194
196
  click_on "Vote"
195
197
  expect(page).to have_current_path(new_election_vote_path)
196
198
  expect(page).to have_content("Verify your identity")
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Elections
5
5
  def self.version
6
- "0.31.0"
6
+ "0.31.1"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-elections
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.0
4
+ version: 0.31.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Vergés
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-20 00:00:00.000000000 Z
11
+ date: 2026-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim-admin
@@ -16,84 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.31.0
19
+ version: 0.31.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.31.0
26
+ version: 0.31.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: decidim-core
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.31.0
33
+ version: 0.31.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.31.0
40
+ version: 0.31.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: decidim-forms
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.31.0
47
+ version: 0.31.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.31.0
54
+ version: 0.31.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: decidim-admin
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.31.0
61
+ version: 0.31.1
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.31.0
68
+ version: 0.31.1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: decidim-dev
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.31.0
75
+ version: 0.31.1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 0.31.0
82
+ version: 0.31.1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: decidim-participatory_processes
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.31.0
89
+ version: 0.31.1
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.31.0
96
+ version: 0.31.1
97
97
  description: A module that aims to provide a set of tools to create elections in Decidim.
98
98
  email:
99
99
  - ivan@pokecode.net
@@ -155,6 +155,7 @@ files:
155
155
  - app/packs/src/decidim/elections/admin/census_form.js
156
156
  - app/packs/src/decidim/elections/admin/election_form.js
157
157
  - app/packs/src/decidim/elections/live_results_update.js
158
+ - app/packs/src/decidim/elections/question_status_checker.js
158
159
  - app/packs/src/decidim/elections/waiting_room.js
159
160
  - app/packs/stylesheets/decidim/elections/elections.scss
160
161
  - app/packs/stylesheets/decidim/elections/live_results_update.scss