diff --git a/config/application.rb b/config/application.rb index c08cae0cf7..afe09321fb 100644 --- a/config/application.rb +++ b/config/application.rb @@ -44,6 +44,7 @@ class Application < Rails::Application require "extends/services/decidim/iframe_disabler_extends" require "extends/helpers/decidim/icon_helper_extends" require "extends/commands/decidim/initiatives/admin/update_initiative_answer_extends" + require "extends/controllers/decidim/initiatives/committee_requests_controller_extends" Decidim::GraphiQL::Rails.config.tap do |config| config.initial_query = "{\n deployment {\n version\n branch\n remote\n upToDate\n currentCommit\n latestCommit\n locallyModified\n }\n}".html_safe diff --git a/lib/extends/controllers/decidim/initiatives/committee_requests_controller_extends.rb b/lib/extends/controllers/decidim/initiatives/committee_requests_controller_extends.rb new file mode 100644 index 0000000000..dc3706b08b --- /dev/null +++ b/lib/extends/controllers/decidim/initiatives/committee_requests_controller_extends.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module CommitteeRequestsControllerExtends + def new + return if authorized?(current_user) + + authorization_method = Decidim::Verifications::Adapter.from_element(current_initiative.document_number_authorization_handler) + redirect_url = new_initiative_committee_request_path(current_initiative) + redirect_to authorization_method.root_path(redirect_url: redirect_url) + end + + private + + def authorized?(user) + authorization = current_initiative.document_number_authorization_handler + Decidim::Authorization.exists?(user: user, name: authorization) + end +end + +Decidim::Initiatives::CommitteeRequestsController.class_eval do + prepend(CommitteeRequestsControllerExtends) +end diff --git a/spec/controllers/decidim/initiatives/committee_requests_controller_spec.rb b/spec/controllers/decidim/initiatives/committee_requests_controller_spec.rb new file mode 100644 index 0000000000..1df7aa36d9 --- /dev/null +++ b/spec/controllers/decidim/initiatives/committee_requests_controller_spec.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Initiatives + describe CommitteeRequestsController, type: :controller do + routes { Decidim::Initiatives::Engine.routes } + + let(:organization) { create(:organization) } + let!(:initiative) { create(:initiative, :created, organization: organization) } + let(:admin_user) { create(:user, :admin, :confirmed, organization: organization) } + let(:user) { create(:user, :confirmed, organization: organization) } + + before do + request.env["decidim.current_organization"] = organization + end + + context "when GET spawn" do + let(:user) { create(:user, :confirmed, organization: organization) } + + before do + create(:authorization, user: user) + sign_in user, scope: :user + end + + context "and created initiative" do + it "Membership request is created" do + expect do + get :spawn, params: { initiative_slug: initiative.slug } + end.to change(InitiativesCommitteeMember, :count).by(1) + end + + it "Duplicated requests finish with an error" do + expect do + get :spawn, params: { initiative_slug: initiative.slug } + end.to change(InitiativesCommitteeMember, :count).by(1) + + expect do + get :spawn, params: { initiative_slug: initiative.slug } + end.not_to change(InitiativesCommitteeMember, :count) + end + end + + context "and published initiative" do + let!(:published_initiative) { create(:initiative, :published, organization: organization) } + + it "Membership request is not created" do + expect do + get :spawn, params: { initiative_slug: published_initiative.slug } + end.not_to change(InitiativesCommitteeMember, :count) + end + end + end + + context "when GET approve" do + let(:membership_request) { create(:initiatives_committee_member, initiative: initiative, state: "requested") } + + context "and Owner" do + before do + sign_in initiative.author, scope: :user + end + + it "request gets approved" do + get :approve, params: { initiative_slug: membership_request.initiative.to_param, id: membership_request.to_param } + membership_request.reload + expect(membership_request).to be_accepted + end + end + + context "and other users" do + let(:user) { create(:user, :confirmed, organization: organization) } + + before do + create(:authorization, user: user) + sign_in user, scope: :user + end + + it "Action is denied" do + get :approve, params: { initiative_slug: membership_request.initiative.to_param, id: membership_request.to_param } + expect(flash[:alert]).not_to be_empty + expect(response).to have_http_status(:found) + end + end + + context "and Admin" do + before do + sign_in admin_user, scope: :user + end + + it "request gets approved" do + get :approve, params: { initiative_slug: membership_request.initiative.to_param, id: membership_request.to_param } + membership_request.reload + expect(membership_request).to be_accepted + end + end + end + + context "when DELETE revoke" do + let(:membership_request) { create(:initiatives_committee_member, initiative: initiative, state: "requested") } + + context "and Owner" do + before do + sign_in initiative.author, scope: :user + end + + it "request gets approved" do + delete :revoke, params: { initiative_slug: membership_request.initiative.to_param, id: membership_request.to_param } + membership_request.reload + expect(membership_request).to be_rejected + end + end + + context "and Other users" do + let(:user) { create(:user, :confirmed, organization: organization) } + + before do + create(:authorization, user: user) + sign_in user, scope: :user + end + + it "Action is denied" do + delete :revoke, params: { initiative_slug: membership_request.initiative.to_param, id: membership_request.to_param } + expect(flash[:alert]).not_to be_empty + expect(response).to have_http_status(:found) + end + end + + context "and Admin" do + before do + sign_in admin_user, scope: :user + end + + it "request gets approved" do + delete :revoke, params: { initiative_slug: membership_request.initiative.to_param, id: membership_request.to_param } + membership_request.reload + expect(membership_request).to be_rejected + end + end + end + end + end +end \ No newline at end of file