diff --git a/app/controllers/concerns/decidim/anonymous_codes/surveys_controller_override.rb b/app/controllers/concerns/decidim/anonymous_codes/surveys_controller_override.rb index 43599ec..c2e67a4 100644 --- a/app/controllers/concerns/decidim/anonymous_codes/surveys_controller_override.rb +++ b/app/controllers/concerns/decidim/anonymous_codes/surveys_controller_override.rb @@ -8,6 +8,7 @@ module SurveysControllerOverride included do before_action do next unless current_settings.allow_answers? && survey.open? + next if visitor_already_answered? if token_groups.any? next if current_token&.available? @@ -23,6 +24,14 @@ module SurveysControllerOverride end end + after_action only: :answer do + next unless current_token&.available? + + # find any answer for the current user and questionnaire that would be used as a resource to link the usage counter + answer = Decidim::Forms::Answer.find_by(questionnaire: questionnaire, user: current_user, session_token: @form.context.session_token) + current_token.answers << answer if answer.present? + end + private def token_groups diff --git a/lib/decidim/anonymous_codes/test/factories.rb b/lib/decidim/anonymous_codes/test/factories.rb index c24590d..5d864b9 100644 --- a/lib/decidim/anonymous_codes/test/factories.rb +++ b/lib/decidim/anonymous_codes/test/factories.rb @@ -15,7 +15,9 @@ group { create(:anonymous_codes_group) } trait :used do - token_resources { [create(:anonymous_codes_token_resource)] } + after(:create) do |object| + object.token_resources << create(:anonymous_codes_token_resource, token: object) + end end end diff --git a/spec/lib/overrides_spec.rb b/spec/lib/overrides_spec.rb index 2042da2..d1da067 100644 --- a/spec/lib/overrides_spec.rb +++ b/spec/lib/overrides_spec.rb @@ -15,6 +15,7 @@ { package: "decidim-forms", files: { + "/app/controllers/decidim/forms/concerns/has_questionnaire.rb" => "3e68234b1e489158b3377426236db093", "/app/views/decidim/forms/questionnaires/show.html.erb" => "b54864ffbdaab74bfc82f7b047cbf170" } } diff --git a/spec/system/surveys_answering_spec.rb b/spec/system/surveys_answering_spec.rb index 3fe13d4..7736be7 100644 --- a/spec/system/surveys_answering_spec.rb +++ b/spec/system/surveys_answering_spec.rb @@ -6,16 +6,17 @@ let(:organization) { component.organization } let(:component) { survey.component } let(:user) { create :user, :confirmed, organization: organization } + let(:another_user) { create :user, :confirmed, organization: organization } let(:group) { create :anonymous_codes_group, organization: organization, expires_at: expires, resource: resource, active: active } - let!(:token) { create :anonymous_codes_token, group: group, usage_count: usage } + let!(:token) { create :anonymous_codes_token, group: group } let!(:another_token) { create :anonymous_codes_token } - let(:usage) { 0 } let(:active) { true } let(:expires) { nil } - let!(:survey) { create(:survey) } + let(:survey) { create(:survey, questionnaire: questionnaire) } + let(:questionnaire) { create(:questionnaire) } + let!(:question) { create(:questionnaire_question, body: { en: "What's the meaning of life?" }, mandatory: true, question_type: :short_answer, questionnaire: questionnaire) } let(:resource) { survey } - let(:first_question) { survey.questionnaire.questions.first } - let(:code) { token&.token } + let(:code) { token.token } let(:settings) do { allow_answers: true, @@ -49,7 +50,7 @@ def visit_component it "sends the code" do fill_in :token, with: code click_button("Continue") - expect(page).to have_content(first_question.body["en"]) + expect(page).to have_content(question.body["en"]) expect(page).to have_link("Sign in with your account") expect(page).not_to have_button("Submit") end @@ -59,20 +60,30 @@ def visit_component it "sends the code and the form" do fill_in :token, with: code click_button("Continue") - expect(page).to have_content(first_question.body["en"]) - expect(page).not_to have_link("Sign in with your account") + + expect(token).not_to be_used + + fill_in question.body["en"], with: "42" + check "questionnaire_tos_agreement" accept_confirm { click_button "Submit" } - expect(page).to have_css(".callout.alert") - expect(page).to have_content(first_question.body["en"]) + expect(page).to have_css(".callout.success") + expect(page).to have_content("Already answered") + + expect(token.reload).to be_used end end shared_examples "can be answered without codes" do it "sends the form" do - expect(page).to have_content(first_question.body["en"]) + expect(token).not_to be_used + + fill_in question.body["en"], with: "42" + check "questionnaire_tos_agreement" accept_confirm { click_button "Submit" } - expect(page).to have_css(".callout.alert") - expect(page).to have_content(first_question.body["en"]) + expect(page).to have_css(".callout.success") + expect(page).to have_content("Already answered") + + expect(token.reload).not_to be_used end end @@ -86,7 +97,7 @@ def visit_component end context "and code re-uses have exceeded" do - let(:usage) { 1 } + let!(:token) { create :anonymous_codes_token, group: group, answers: [create(:answer, questionnaire: questionnaire, user: another_user)] } it "sends the code and fails" do fill_in :token, with: code @@ -95,7 +106,7 @@ def visit_component expect(page).to have_content("The introduced code has already been used.") expect(page).to have_content("Form restricted") expect(page).to have_field("token") - expect(page).not_to have_content(first_question.body["en"]) + expect(page).not_to have_content(question.body["en"]) end end @@ -115,7 +126,7 @@ def visit_component expect(page).to have_content("The introduced code has expired.") expect(page).to have_content("Form restricted") expect(page).to have_field("token") - expect(page).not_to have_content(first_question.body["en"]) + expect(page).not_to have_content(question.body["en"]) end end end @@ -128,7 +139,7 @@ def visit_component expect(page).to have_content("The introduced code is invalid.") expect(page).to have_content("Form restricted") expect(page).to have_field("token") - expect(page).not_to have_content(first_question.body["en"]) + expect(page).not_to have_content(question.body["en"]) end it "sends another code and fails" do @@ -138,7 +149,7 @@ def visit_component expect(page).to have_content("The introduced code is invalid.") expect(page).to have_content("Form restricted") expect(page).to have_field("token") - expect(page).not_to have_content(first_question.body["en"]) + expect(page).not_to have_content(question.body["en"]) end end