diff --git a/lib/decidim/custom_proposal_states/overrides/proposal.rb b/lib/decidim/custom_proposal_states/overrides/proposal.rb index 7dd6d2c..c3fff2e 100644 --- a/lib/decidim/custom_proposal_states/overrides/proposal.rb +++ b/lib/decidim/custom_proposal_states/overrides/proposal.rb @@ -14,7 +14,13 @@ def self.prepended(base) inverse_of: :proposals, optional: true, counter_cache: true - + scope :not_status, lambda { |status| + joins(:proposal_state).where.not(decidim_proposals_proposal_states: { token: status }) + .where(%( + ("decidim_proposals_proposals"."state_published_at" IS NULL AND "decidim_proposals_proposal_states"."answerable" = TRUE) OR + ("decidim_proposals_proposals"."state_published_at" IS NOT NULL AND "decidim_proposals_proposal_states"."answerable" = FALSE) + )) + } scope :only_status, lambda { |status| joins(:proposal_state).where(decidim_proposals_proposal_states: { token: status }) .where(%( @@ -24,9 +30,16 @@ def self.prepended(base) } scope :accepted, -> { state_published.only_status(:accepted) } + scope :rejected, -> { state_published.only_status(:rejected) } + scope :evaluating, -> { state_published.only_status(:evaluating) } scope :except_withdrawn, -> { joins(:proposal_state).where.not(decidim_proposals_proposal_states: { token: :withdrawn }) } + scope :gamified, -> { state_published.only_status(:accepted).where(decidim_proposals_proposal_states: { gamified: true }) } + scope :state_published, -> { where.not(state_published_at: nil) } + scope :except_rejected, -> { not_status(:rejected).or(state_not_published) } + scope :withdrawn, -> { joins(:proposal_state).where(decidim_proposals_proposal_states: { token: :withdrawn }) } + scope :except_withdrawn, -> { joins(:proposal_state).where.not(decidim_proposals_proposal_states: { token: :withdrawn }) } def set_default_state return if proposal_state.present? @@ -38,6 +51,31 @@ def assign_state(token) proposal_state = Decidim::CustomProposalStates::ProposalState.where(component: component, token: token).first! self.proposal_state = proposal_state end + + def state + return amendment.state if emendation? + return nil unless published_state? || withdrawn? + + raise "aaaa" + proposal_state&.token + end + + def internal_state + return amendment.state if emendation? + raise "aaaa" + + proposal_state&.token + end + + def process_amendment_state_change! + return unless %w(accepted rejected evaluating withdrawn).member?(amendment.state) + + raise "aaaa" + PaperTrail.request(enabled: false) do + assign_state(amendment.state) + update!(state_published_at: Time.current) + end + end end end end diff --git a/lib/decidim/custom_proposal_states/test/factories.rb b/lib/decidim/custom_proposal_states/test/factories.rb index b701e8f..097f5d4 100644 --- a/lib/decidim/custom_proposal_states/test/factories.rb +++ b/lib/decidim/custom_proposal_states/test/factories.rb @@ -17,6 +17,8 @@ def generate_state_title(token) transient do state { :not_answered } end + component { build(:extended_proposal_component) } + after(:build) do |proposal, evaluator| if proposal.component existing_states = Decidim::CustomProposalStates::ProposalState.where(component: proposal.component) @@ -24,7 +26,9 @@ def generate_state_title(token) Decidim::CustomProposalStates.create_default_states!(proposal.component, nil, with_traceability: false) unless existing_states.any? end - proposal.assign_state(evaluator.state) + + proposal_state = Decidim::CustomProposalStates::ProposalState.where(component: proposal.component, token: evaluator.state).first! + proposal.proposal_state = proposal_state end trait :evaluating do diff --git a/spec/proposals/cells/decidim/proposals/collaborative_draft_cell_spec.rb b/spec/proposals/cells/decidim/proposals/collaborative_draft_cell_spec.rb deleted file mode 100644 index aedd827..0000000 --- a/spec/proposals/cells/decidim/proposals/collaborative_draft_cell_spec.rb +++ /dev/null @@ -1,120 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::CollaborativeDraftCell, type: :cell do - controller Decidim::Proposals::CollaborativeDraftsController - - subject { my_cell.call(:show) } - - let(:my_cell) { cell("decidim/proposals/collaborative_draft", collaborative_draft, context: context) } - - let(:component) { create(:extended_proposal_component, :with_collaborative_drafts_enabled) } - let(:author) { create(:user, :confirmed, organization: component.organization) } - let!(:collaborative_draft) { create(:collaborative_draft, component: component) } - let(:authors) { create_list(:user, 5, organization: component.organization) } - let(:collaborative_draft_va) { create(:collaborative_draft, component: component, users: authors) } - let(:context) {} - - let(:card_label) { subject.find(".card__label") } - let(:card_content) { subject.find(".card__content") } - let(:card_footer) { subject.find(".card__footer") } - let(:card_text) { subject.find(".card__text") } - - before do - allow(controller).to receive(:current_user).and_return(author) - end - - context "when rendering a collaborative_draft" do - it "renders the card" do - expect(subject).to have_css(".card--collaborative_draft") - end - - describe "with the label option" do - let(:context) { { label: true } } - - it "renders the collaborative_draft label" do - expect(subject).to have_css(".card__label") - expect(card_label).to have_content("Collaborative draft") - end - end - - it "renders the collaborative_draft title and link" do - expect(card_content).to have_content(collaborative_draft.title) - href = Decidim::ResourceLocatorPresenter.new(collaborative_draft).path - expect(card_content).to have_link(class: "card__link", href: href) - end - - it "renders the footer link" do - expect(card_footer).to have_content("View Collaborative Draft") - href = Decidim::ResourceLocatorPresenter.new(collaborative_draft).path - expect(card_footer).to have_link(class: "card__button", href: href) - end - - it "renders the card author" do - expect(card_content).to have_content(collaborative_draft.authors.first.name) - expect(card_content).to have_css(".author__name", count: 1) - end - - # collapsible lists uses javascript which is not available when testing cells without a real browser - describe "with coauthors" do - let(:collaborative_draft) { create(:collaborative_draft, component: component, users: authors) } - - it "renders the first three authors" do - expect(card_content).to have_css(".author__name", count: 5) - end - - it "indicates number of hidden authors" do - expect(card_content).to have_css(".card__text--paragraph.collapsible-list__see-more") - expect(card_content.find(".card__text--paragraph.collapsible-list__see-more")).to have_content("and 4 more") - end - - it "renders the see_more link" do - expect(card_content).to have_css(".collapsible-list__see-more") - end - - it "renders the see_less link" do - expect(card_content).to have_css(".collapsible-list__see-less") - end - end - - context "with open state" do - let(:collaborative_draft) { create(:collaborative_draft, :open, component: component) } - - it "renders the card with the .success class" do - expect(subject).to have_css(".card.success") - end - - it "renders the open state" do - expect(card_text).to have_css(".success.card__text--status") - expect(card_text).to have_content("Open") - end - end - - context "with withdrawn state" do - let(:collaborative_draft) { create(:collaborative_draft, :withdrawn, component: component) } - - it "renders the card with the .alert class" do - expect(subject).to have_css(".card.alert") - end - - it "renders the open state" do - expect(card_text).to have_css(".alert.card__text--status") - expect(card_text).to have_content("Withdrawn") - end - end - - context "with published state" do - let(:collaborative_draft) { create(:collaborative_draft, :published, component: component) } - - it "renders the card with the .secondary class" do - expect(subject).to have_css(".card.secondary") - end - - it "renders the open state" do - expect(card_text).to have_css(".secondary.card__text--status") - expect(card_text).to have_content("Published") - end - end - end -end diff --git a/spec/proposals/cells/decidim/proposals/collaborative_drafts/reported_content_cell_spec.rb b/spec/proposals/cells/decidim/proposals/collaborative_drafts/reported_content_cell_spec.rb deleted file mode 100644 index d316283..0000000 --- a/spec/proposals/cells/decidim/proposals/collaborative_drafts/reported_content_cell_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Proposals::CollaborativeDrafts - describe ReportedContentCell, type: :cell do - controller Decidim::Proposals::CollaborativeDraftsController - - let!(:collaborative_draft) { create(:collaborative_draft, body: { "en" => "a nice body" }) } - - context "when rendering" do - it "renders the collaborative draft's body" do - html = cell("decidim/reported_content", collaborative_draft).call - expect(html).to have_content("a nice body") - end - end - end -end diff --git a/spec/proposals/cells/decidim/proposals/reported_content_cell_spec.rb b/spec/proposals/cells/decidim/proposals/reported_content_cell_spec.rb deleted file mode 100644 index 0a7fb49..0000000 --- a/spec/proposals/cells/decidim/proposals/reported_content_cell_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Proposals - describe ReportedContentCell, type: :cell do - controller Decidim::Proposals::ProposalsController - - let!(:proposal) { create(:extended_proposal, title: { "en" => "a nice title" }, body: { "en" => "let's do this!" }) } - - context "when rendering" do - it "renders the proposal's title and body" do - html = cell("decidim/reported_content", proposal).call - expect(html).to have_content("a nice title") - expect(html).to have_content("let's do this!") - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/accept_access_to_collaborative_draft_spec.rb b/spec/proposals/commands/decidim/proposals/accept_access_to_collaborative_draft_spec.rb deleted file mode 100644 index a8e9ae3..0000000 --- a/spec/proposals/commands/decidim/proposals/accept_access_to_collaborative_draft_spec.rb +++ /dev/null @@ -1,162 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe AcceptAccessToCollaborativeDraft do - let(:component) { create(:extended_proposal_component) } - let(:state) { :open } - let(:collaborative_draft) { create(:collaborative_draft, state, component: component, users: [author1, author2]) } - let(:id) { collaborative_draft.id } - let(:requester_user) { create(:user, :confirmed, organization: component.organization) } - let(:requester_user_id) { requester_user.id } - let(:author1) { create(:user, :confirmed, organization: component.organization) } - let(:author2) { create(:user, :confirmed, organization: component.organization) } - let(:current_user) { author1 } - let(:current_organization) { component.organization } - let(:form) { AcceptAccessToCollaborativeDraftForm.from_params(form_params).with_context(current_user: current_user, current_organization: current_organization) } - let(:form_params) do - { - state: state, - id: id, - requester_user_id: requester_user_id - } - end - - describe "Author (current_user) accepts access to requester to collaborate" do - let(:command) { described_class.new(form, current_user) } - - before do - collaborative_draft.collaborator_requests.create!(user: requester_user) - end - - context "when the collaborative draft is open" do - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "removes the requester from requestors of the collaborative draft" do - expect do - command.call - end.to change(collaborative_draft.requesters, :count).by(-1) - end - - it "adds the requester as a co-author of the collaborative draft" do - command.call - updated_draft = CollaborativeDraft.find(collaborative_draft.id) - expect(updated_draft.authors).to include(requester_user) - end - - it "notifies the requester and authors of the collaborative draft that access to requester has been accepted" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.collaborative_draft_access_accepted", - event_class: Decidim::Proposals::CollaborativeDraftAccessAcceptedEvent, - resource: collaborative_draft, - affected_users: collaborative_draft.notifiable_identities - [requester_user], - extra: { - requester_id: requester_user_id - } - ) - - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.collaborative_draft_access_requester_accepted", - event_class: Decidim::Proposals::CollaborativeDraftAccessRequesterAcceptedEvent, - resource: collaborative_draft, - affected_users: [requester_user] - ) - - command.call - end - end - - context "when the collaborative draft is withdrawn" do - let(:state) { :withdrawn } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't accept the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - - it "doesn't add the requester as a co-author of the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.authors, :count) - end - end - - context "when the collaborative draft is published" do - let(:state) { :published } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't accept the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - - it "doesn't add the requester as a co-author of the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.authors, :count) - end - end - - context "when the requester is missing" do - let(:requester_user_id) { nil } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't accept the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the current_user is missing" do - let(:current_user) { nil } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't accept the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the requester is not as a requestor" do - let(:not_requester_user) { create(:user, :confirmed, organization: component.organization) } - let(:requester_user_id) { not_requester_user.id } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't accept the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/assign_proposals_to_valuator_spec.rb b/spec/proposals/commands/decidim/proposals/admin/assign_proposals_to_valuator_spec.rb deleted file mode 100644 index 38715e8..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/assign_proposals_to_valuator_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe AssignProposalsToValuator do - describe "call" do - let!(:proposal) { create(:extended_proposal, component: current_component) } - let!(:current_component) { create(:extended_proposal_component) } - let(:space) { current_component.participatory_space } - let(:organization) { space.organization } - let(:user) { create :user, organization: organization } - let(:valuator_role) { create :participatory_process_user_role, role: :valuator, user: user, participatory_process: space } - let(:form) do - instance_double( - ValuationAssignmentForm, - current_user: user, - current_component: current_component, - current_organization: current_component.organization, - valuator_role: valuator_role, - proposals: [proposal], - valid?: valid - ) - end - let(:command) { described_class.new(form) } - - describe "when the form is not valid" do - let(:valid) { false } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create the assignments" do - expect do - command.call - end.not_to change(ValuationAssignment, :count) - end - end - - describe "when the form is valid" do - let(:valid) { true } - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates the valuation assignment between the user and the proposal" do - expect do - command.call - end.to change { ValuationAssignment.where(proposal: proposal, valuator_role: valuator_role).count }.by(1) - end - - it "traces the action", versioning: true do - expect(Decidim.traceability) - .to receive(:create!) - .with(Decidim::Proposals::ValuationAssignment, form.current_user, proposal: proposal, valuator_role: valuator_role) - .and_call_original - - expect { command.call }.to change(Decidim::ActionLog, :count) - action_log = Decidim::ActionLog.last - expect(action_log.version).to be_present - expect(action_log.version.event).to eq "create" - end - - context "when it raises an error while creating assignments" do - before do - allow(Decidim::Proposals::ValuationAssignment).to receive(:create!).and_raise(ActiveRecord::RecordInvalid) - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "does not create any assignment" do - expect { command.call }.not_to change(ValuationAssignment, :count) - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/discard_participatory_text_spec.rb b/spec/proposals/commands/decidim/proposals/admin/discard_participatory_text_spec.rb deleted file mode 100644 index db5fd51..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/discard_participatory_text_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe DiscardParticipatoryText do - describe "call" do - let(:current_component) do - create( - :extended_proposal_component, - participatory_space: create(:participatory_process) - ) - end - let(:proposals) do - create_list(:extended_proposal, 3, :draft, component: current_component) - end - let(:command) { described_class.new(current_component) } - - describe "when discarding" do - it "removes all drafts" do - expect { command.call }.to broadcast(:ok) - proposals = Decidim::Proposals::Proposal.drafts.where(component: current_component) - expect(proposals).to be_empty - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/merge_proposals_spec.rb b/spec/proposals/commands/decidim/proposals/admin/merge_proposals_spec.rb deleted file mode 100644 index 6ded8f8..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/merge_proposals_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe MergeProposals do - describe "call" do - let!(:proposals) { create_list(:extended_proposal, 3, component: current_component) } - let!(:current_component) { create(:extended_proposal_component) } - let!(:target_component) { create(:extended_proposal_component, participatory_space: current_component.participatory_space) } - let(:form) do - instance_double( - ProposalsMergeForm, - current_component: current_component, - current_organization: current_component.organization, - target_component: target_component, - proposals: proposals, - valid?: valid, - same_component?: same_component, - current_user: create(:user, :admin, organization: current_component.organization) - ) - end - let(:command) { described_class.new(form) } - let(:same_component) { false } - - describe "when the form is not valid" do - let(:valid) { false } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create the proposal" do - expect do - command.call - end.to change(Proposal, :count).by(0) - end - end - - describe "when the form is valid" do - let(:valid) { true } - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates a proposal in the new component" do - expect do - command.call - end.to change { Proposal.where(component: target_component).count }.by(1) - end - - it "links the proposals" do - command.call - proposal = Proposal.where(component: target_component).last - - linked = proposal.linked_resources(:proposals, "copied_from_component") - - expect(linked).to match_array(proposals) - end - - it "only merges wanted attributes" do - command.call - new_proposal = Proposal.where(component: target_component).last - proposal = proposals.first - - expect(new_proposal.title).to eq(proposal.title) - expect(new_proposal.body).to eq(proposal.body) - expect(new_proposal.creator_author).to eq(current_component.organization) - expect(new_proposal.category).to eq(proposal.category) - - expect(new_proposal.state).to be_nil - expect(new_proposal.answer).to be_nil - expect(new_proposal.answered_at).to be_nil - expect(new_proposal.reference).not_to eq(proposal.reference) - end - - context "when merging from the same component" do - let(:same_component) { true } - let(:target_component) { current_component } - - it "deletes the original proposals" do - command.call - proposal_ids = proposals.map(&:id) - - expect(Decidim::Proposals::Proposal.where(id: proposal_ids)).to be_empty - end - - it "links the merged proposal to the links the other proposals had" do - other_component = create(:extended_proposal_component, participatory_space: current_component.participatory_space) - other_proposals = create_list(:extended_proposal, 3, component: other_component) - - proposals.each_with_index do |proposal, index| - proposal.link_resources(other_proposals[index], "copied_from_component") - end - - command.call - - proposal = Proposal.where(component: target_component).last - linked = proposal.linked_resources(:proposals, "copied_from_component") - expect(linked).to match_array(other_proposals) - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/publish_participatory_text_spec.rb b/spec/proposals/commands/decidim/proposals/admin/publish_participatory_text_spec.rb deleted file mode 100644 index 2671430..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/publish_participatory_text_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe PublishParticipatoryText do - describe "call" do - let(:current_component) do - create( - :extended_proposal_component, - participatory_space: create(:participatory_process) - ) - end - let(:proposals) do - proposals = create_list(:extended_proposal, 3, :draft, component: current_component) - proposals.each_with_index do |proposal, idx| - level = Decidim::Proposals::ParticipatoryTextSection::LEVELS.keys[idx] - proposal.update(participatory_text_level: level) - proposal.versions.destroy_all - end - proposals - end - let(:proposal_modifications) do - modifs = [] - new_positions = [3, 1, 2] - proposals.each do |proposal| - modifs << Decidim::Proposals::Admin::ParticipatoryTextProposalForm.new( - id: proposal.id, - position: new_positions.shift, - title: ::Faker::Books::Lovecraft.fhtagn, - body: { en: ::Faker::Books::Lovecraft.fhtagn(number: 5) } - ).with_context( - current_participatory_space: current_component.participatory_space, - current_component: current_component - ) - end - modifs - end - let(:form) do - instance_double( - PreviewParticipatoryTextForm, - current_component: current_component, - current_user: create(:user, organization: current_component.organization), - proposals: proposal_modifications - ) - end - let!(:command) { described_class.new(form) } - - it "creates a version for each proposal", versioning: true do - expect { command.call }.to broadcast(:ok) - - proposals.each do |proposal| - expect(proposal.reload.versions.count).to eq(1) - end - end - - describe "when form modifies proposals" do - context "with valid values" do - it "persists modifications" do - expect { command.call }.to broadcast(:ok) - proposals.zip(proposal_modifications).each do |proposal, proposal_form| - proposal.reload - - expect(translated(proposal_form.title)).to eq translated(proposal.title) - if proposal.participatory_text_level == Decidim::Proposals::ParticipatoryTextSection::LEVELS[:article] - expect(translated(proposal_form.body.stringify_keys)).to eq translated(proposal.body) - end - expect(proposal_form.position).to eq proposal.position - end - end - end - - context "with invalid values" do - before do - proposal_modifications.each { |proposal_form| proposal_form.title = "" } - end - - it "does not persist modifications and broadcasts invalid" do - failures = {} - proposals.each do |proposal| - failures[proposal.id] = ["Title can't be blank"] - end - expect { command.call }.to broadcast(:invalid, failures) - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/split_proposals_spec.rb b/spec/proposals/commands/decidim/proposals/admin/split_proposals_spec.rb deleted file mode 100644 index bf33911..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/split_proposals_spec.rb +++ /dev/null @@ -1,116 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe SplitProposals do - describe "call" do - let!(:proposals) { Array(create(:extended_proposal, component: current_component)) } - let!(:current_component) { create(:extended_proposal_component) } - let!(:target_component) { create(:extended_proposal_component, participatory_space: current_component.participatory_space) } - let(:form) do - instance_double( - ProposalsSplitForm, - current_component: current_component, - current_organization: current_component.organization, - target_component: target_component, - proposals: proposals, - valid?: valid, - same_component?: same_component, - current_user: create(:user, :admin, organization: current_component.organization) - ) - end - let(:command) { described_class.new(form) } - let(:same_component) { false } - - describe "when the form is not valid" do - let(:valid) { false } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create the proposal" do - expect do - command.call - end.to change(Proposal, :count).by(0) - end - end - - describe "when the form is valid" do - let(:valid) { true } - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates two proposals for each original in the new component" do - expect do - command.call - end.to change { Proposal.where(component: target_component).count }.by(2) - end - - it "links the proposals" do - command.call - new_proposals = Proposal.where(component: target_component) - - linked = proposals.first.linked_resources(:proposals, "copied_from_component") - - expect(linked).to match_array(new_proposals) - end - - it "only copies wanted attributes" do - command.call - proposal = proposals.first - new_proposal = Proposal.where(component: target_component).last - - expect(new_proposal.title).to eq(proposal.title) - expect(new_proposal.body).to eq(proposal.body) - expect(new_proposal.creator_author).to eq(current_component.organization) - expect(new_proposal.category).to eq(proposal.category) - - expect(new_proposal.state).to be_nil - expect(new_proposal.answer).to be_nil - expect(new_proposal.answered_at).to be_nil - expect(new_proposal.reference).not_to eq(proposal.reference) - end - - context "when spliting to the same component" do - let(:same_component) { true } - let!(:target_component) { current_component } - let!(:proposals) { create_list(:extended_proposal, 2, component: current_component) } - - it "only creates one copy for each proposal" do - expect do - command.call - end.to change { Proposal.where(component: current_component).count }.by(2) - end - - context "when the original proposal has links to other proposals" do - let(:previous_component) { create(:extended_proposal_component, participatory_space: current_component.participatory_space) } - let(:previous_proposals) { create(:extended_proposal, component: previous_component) } - - before do - proposals.each do |proposal| - proposal.link_resources(previous_proposals, "copied_from_component") - end - end - - it "links the copy to the same links the proposal has" do - new_proposals = Proposal.where(component: target_component).last(2) - - new_proposals.each do |proposal| - linked = proposal.linked_resources(:proposals, "copied_from_component") - expect(linked).to eq([previous_proposals]) - end - end - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/unassign_proposals_from_valuator_spec.rb b/spec/proposals/commands/decidim/proposals/admin/unassign_proposals_from_valuator_spec.rb deleted file mode 100644 index 1a7324c..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/unassign_proposals_from_valuator_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe UnassignProposalsFromValuator do - describe "call" do - let!(:assigned_proposal) { create(:extended_proposal, component: current_component) } - let!(:unassigned_proposal) { create(:extended_proposal, component: current_component) } - let!(:current_component) { create(:extended_proposal_component) } - let(:space) { current_component.participatory_space } - let(:organization) { space.organization } - let(:user) { create :user, organization: organization } - let(:valuator) { create :user, organization: organization } - let(:valuator_role) { create :participatory_process_user_role, role: :valuator, user: valuator, participatory_process: space } - let!(:assignment) { create :valuation_assignment, proposal: assigned_proposal, valuator_role: valuator_role } - let(:form) do - instance_double( - ValuationAssignmentForm, - current_user: user, - current_component: current_component, - current_organization: current_component.organization, - valuator_role: valuator_role, - proposals: [assigned_proposal, unassigned_proposal], - valid?: valid - ) - end - let(:command) { described_class.new(form) } - - describe "when the form is not valid" do - let(:valid) { false } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't destroy the assignments" do - expect do - command.call - end.not_to change(ValuationAssignment, :count) - end - end - - describe "when the form is valid" do - let(:valid) { true } - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "destroys the valuation assignment between the user and the proposal" do - expect do - command.call - end.to change { ValuationAssignment.where(valuator_role: valuator_role).count }.from(1).to(0) - end - - it "traces the action", versioning: true do - expect(Decidim.traceability) - .to receive(:perform_action!) - .with(:delete, assignment, form.current_user, proposal_title: assigned_proposal.title) - .and_call_original - - expect { command.call }.to change(Decidim::ActionLog, :count) - action_log = Decidim::ActionLog.last - expect(action_log.version).to be_present - expect(action_log.version.event).to eq "destroy" - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin/update_participatory_text_spec.rb b/spec/proposals/commands/decidim/proposals/admin/update_participatory_text_spec.rb deleted file mode 100644 index fec6b1d..0000000 --- a/spec/proposals/commands/decidim/proposals/admin/update_participatory_text_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe UpdateParticipatoryText do - describe "call" do - let(:current_component) do - create( - :extended_proposal_component, - participatory_space: create(:participatory_process) - ) - end - let(:proposals) do - proposals = create_list(:extended_proposal, 3, component: current_component) - proposals.each_with_index do |proposal, idx| - level = Decidim::Proposals::ParticipatoryTextSection::LEVELS.keys[idx] - proposal.update(participatory_text_level: level) - proposal.versions.destroy_all - end - proposals - end - let(:proposal_modifications) do - modifs = [] - new_positions = [3, 1, 2] - proposals.each do |proposal| - modifs << Decidim::Proposals::Admin::ParticipatoryTextProposalForm.new( - id: proposal.id, - position: new_positions.shift, - title: ::Faker::Books::Lovecraft.fhtagn, - body: { en: ::Faker::Books::Lovecraft.fhtagn(number: 5) } - ).with_context( - current_participatory_space: current_component.participatory_space, - current_component: current_component - ) - end - modifs - end - let(:form) do - instance_double( - PreviewParticipatoryTextForm, - current_component: current_component, - proposals: proposal_modifications - ) - end - let(:command) { described_class.new(form) } - - it "does not create a version for each proposal", versioning: true do - expect { command.call }.to broadcast(:ok) - - proposals.each do |proposal| - expect(proposal.reload.versions.count).to be_zero - end - end - - describe "when form modifies proposals" do - context "with valid values" do - it "persists modifications" do - expect { command.call }.to broadcast(:ok) - proposals.zip(proposal_modifications).each do |proposal, proposal_form| - proposal.reload - - expect(translated(proposal_form.title)).to eq translated(proposal.title) - if proposal.participatory_text_level == Decidim::Proposals::ParticipatoryTextSection::LEVELS[:article] - expect(translated(proposal_form.body.stringify_keys)).to eq translated(proposal.body) - end - expect(proposal_form.position).to eq proposal.position - end - end - end - - context "with invalid values" do - before do - proposal_modifications.each { |proposal_form| proposal_form.title = "" } - end - - it "does not persist modifications and broadcasts invalid" do - failures = {} - proposals.each do |proposal| - failures[proposal.id] = ["Title can't be blank"] - end - expect { command.call }.to broadcast(:invalid, failures) - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/admin_create_proposal_note_spec.rb b/spec/proposals/commands/decidim/proposals/admin_create_proposal_note_spec.rb deleted file mode 100644 index 1dc0774..0000000 --- a/spec/proposals/commands/decidim/proposals/admin_create_proposal_note_spec.rb +++ /dev/null @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - module Admin - describe CreateProposalNote do - describe "call" do - let(:proposal) { create(:extended_proposal) } - let(:organization) { proposal.component.organization } - let(:current_user) { create(:user, :admin, organization: organization) } - let!(:another_admin) { create(:user, :admin, organization: organization) } - let(:valuation_assignment) { create(:valuation_assignment, proposal: proposal) } - let!(:valuator) { valuation_assignment.valuator } - let(:form) { ProposalNoteForm.from_params(form_params).with_context(current_user: current_user, current_organization: organization) } - - let(:form_params) do - { - body: "A reasonable private note" - } - end - - let(:command) { described_class.new(form, proposal) } - - describe "when the form is not valid" do - before do - expect(form).to receive(:invalid?).and_return(true) - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create the proposal note" do - expect do - command.call - end.to change(ProposalVote, :count).by(0) - end - end - - describe "when the form is valid" do - before do - expect(form).to receive(:invalid?).and_return(false) - end - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates the proposal notes" do - expect do - command.call - end.to change(ProposalNote, :count).by(1) - end - - it "traces the action", versioning: true do - expect(Decidim.traceability) - .to receive(:create!) - .with(ProposalNote, current_user, hash_including(:body, :proposal, :author), resource: hash_including(:title)) - .and_call_original - - expect { command.call }.to change(ActionLog, :count) - action_log = Decidim::ActionLog.last - expect(action_log.version).to be_present - end - - it "notifies the admins and the valuators" do - expect(Decidim::EventsManager) - .to receive(:publish) - .once - .ordered - .with( - event: "decidim.events.proposals.admin.proposal_note_created", - event_class: Decidim::Proposals::Admin::ProposalNoteCreatedEvent, - resource: proposal, - affected_users: a_collection_containing_exactly(another_admin, valuator) - ) - - command.call - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/amendable/destroy_amendment_draft_spec.rb b/spec/proposals/commands/decidim/proposals/amendable/destroy_amendment_draft_spec.rb deleted file mode 100644 index 4477761..0000000 --- a/spec/proposals/commands/decidim/proposals/amendable/destroy_amendment_draft_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Amendable - describe DestroyDraft do - let!(:component) { create(:extended_proposal_component) } - let!(:other_user) { create(:user, :confirmed, organization: component.organization) } - - let!(:amendable) { create(:extended_proposal, component: component) } - let!(:emendation) { create(:extended_proposal, :unpublished, component: component) } - let!(:amendment) { create(:amendment, :draft, amendable: amendable, emendation: emendation) } - - let(:command) { described_class.new(amendment, current_user) } - - include_examples "destroy amendment draft" - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/amendable/update_amendment_draft_spec.rb b/spec/proposals/commands/decidim/proposals/amendable/update_amendment_draft_spec.rb deleted file mode 100644 index 1bf51ed..0000000 --- a/spec/proposals/commands/decidim/proposals/amendable/update_amendment_draft_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Amendable - describe UpdateDraft do - let!(:component) { create(:extended_proposal_component) } - let!(:other_user) { create(:user, :confirmed, organization: component.organization) } - - let!(:amendable) { create(:extended_proposal, component: component) } - let!(:emendation) { create(:extended_proposal, :unpublished, component: component) } - let!(:amendment) { create(:amendment, :draft, amendable: amendable, emendation: emendation) } - - let(:title) { "More sidewalks and less roads!" } - let(:body) { "Everything would be better" } - let(:params) do - { - id: amendment.id, - emendation_params: { title: title, body: body } - } - end - - let(:current_user) { amendment.amender } - let(:context) do - { - current_user: current_user, - current_organization: component.organization - } - end - - let(:form) { Decidim::Amendable::EditForm.from_params(params).with_context(context) } - let(:command) { described_class.new(form) } - - include_examples "update amendment draft" - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/create_collaborative_draft_spec.rb b/spec/proposals/commands/decidim/proposals/create_collaborative_draft_spec.rb deleted file mode 100644 index 28b8502..0000000 --- a/spec/proposals/commands/decidim/proposals/create_collaborative_draft_spec.rb +++ /dev/null @@ -1,187 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe CreateCollaborativeDraft do - let(:form_klass) { CollaborativeDraftForm } - let(:component) { create(:extended_proposal_component, :with_collaborative_drafts_enabled, :with_extra_hashtags, suggested_hashtags: suggested_hashtags.join(" ")) } - let(:organization) { component.organization } - let(:user) { create :user, :confirmed, organization: organization } - let(:form) do - form_klass.from_params( - form_params - ).with_context( - current_user: user, - current_organization: organization, - current_participatory_space: component.participatory_space, - current_component: component - ) - end - - let(:author) { create(:user, organization: organization) } - - let(:user_group) do - create(:user_group, :verified, organization: organization, users: [author]) - end - - let(:has_address) { false } - let(:address) { nil } - let(:latitude) { 40.1234 } - let(:longitude) { 2.1234 } - let(:attachment_params) { nil } - let(:suggested_hashtags) { [] } - - describe "call" do - let(:form_params) do - { - title: "This is the collaborative draft title", - body: "This is the collaborative draft body", - address: address, - has_address: has_address, - latitude: latitude, - longitude: longitude, - attachment: attachment_params, - user_group_id: user_group.try(:id), - suggested_hashtags: suggested_hashtags - } - end - - let(:command) do - described_class.new(form, author) - end - - describe "when the form is not valid" do - before do - expect(form).to receive(:invalid?).and_return(true) - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create a collaborative draft" do - expect do - command.call - end.not_to change(Decidim::Proposals::CollaborativeDraft, :count) - end - end - - describe "when the form is valid" do - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates a new collaborative draft" do - expect do - command.call - end.to change(Decidim::Proposals::CollaborativeDraft, :count).by(1) - end - - context "with an author" do - let(:user_group) { nil } - - it "sets the author" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - - expect(collaborative_draft.coauthorships.count).to eq(1) - expect(collaborative_draft.authors.count).to eq(1) - expect(collaborative_draft.authors.first).to eq(author) - end - end - - context "with extra hashtags" do - let(:suggested_hashtags) { %w(Hashtag1 Hashtag2) } - - it "saves the extra hashtags" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - expect(collaborative_draft.body).to include("_Hashtag1") - expect(collaborative_draft.body).to include("_Hashtag2") - end - end - - context "with a user group" do - it "sets the user group" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - - expect(collaborative_draft.coauthorships.count).to eq(1) - expect(collaborative_draft.user_groups.count).to eq(1) - expect(collaborative_draft.user_groups.first).to eq(user_group) - end - end - - it "traces the action", versioning: true do - expect(Decidim.traceability) - .to receive(:perform_action!) - .with( - :create, - Decidim::Proposals::CollaborativeDraft, - user, - visibility: "public-only" - ).and_call_original - - expect { command.call }.to change(Decidim::ActionLog, :count) - action_log = Decidim::ActionLog.last - expect(action_log.version).to be_present - end - - context "when the has address checkbox is checked" do - let(:has_address) { true } - - context "when the address is present" do - let(:address) { "Some address" } - - before do - Geocoder::Lookup::Test.add_stub( - address, - [{ "latitude" => latitude, "longitude" => longitude }] - ) - end - - it "sets the latitude and longitude" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - - expect(collaborative_draft.latitude).to eq(latitude) - expect(collaborative_draft.longitude).to eq(longitude) - end - end - end - - context "when attachments are allowed" do - let(:component) { create(:extended_proposal_component, :with_attachments_allowed) } - let(:attachment_params) do - { - title: "My attachment", - file: Decidim::Dev.test_file("city.jpeg", "image/jpeg") - } - end - - it "creates an atachment for the proposal" do - expect { command.call }.to change(Decidim::Attachment, :count).by(1) - last_collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - last_attachment = Decidim::Attachment.last - expect(last_attachment.attached_to).to eq(last_collaborative_draft) - end - - context "when attachment is left blank" do - let(:attachment_params) do - { - title: "" - } - end - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/publish_proposal_spec.rb b/spec/proposals/commands/decidim/proposals/publish_proposal_spec.rb deleted file mode 100644 index d0e37cb..0000000 --- a/spec/proposals/commands/decidim/proposals/publish_proposal_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe PublishProposal do - describe "call" do - let(:component) { create(:extended_proposal_component) } - let(:organization) { component.organization } - let!(:current_user) { create(:user, organization: organization) } - let(:follower) { create(:user, organization: organization) } - let(:proposal_draft) { create(:extended_proposal, :draft, component: component, users: [current_user]) } - let!(:follow) { create :follow, followable: current_user, user: follower } - - it "broadcasts ok" do - expect { described_class.call(proposal_draft, current_user) }.to broadcast(:ok) - end - - it "scores on the proposals badge" do - expect { described_class.call(proposal_draft, current_user) }.to change { - Decidim::Gamification.status_for(current_user, :proposals).score - }.by(1) - end - - it "broadcasts invalid when the proposal is from another author" do - expect { described_class.call(proposal_draft, follower) }.to broadcast(:invalid) - end - - describe "events" do - subject do - described_class.new(proposal_draft, current_user) - end - - it "notifies the proposal is published" do - other_follower = create(:user, organization: organization) - create(:follow, followable: component.participatory_space, user: follower) - create(:follow, followable: component.participatory_space, user: other_follower) - - allow(Decidim::EventsManager).to receive(:publish) - .with(hash_including(event: "decidim.events.gamification.badge_earned")) - - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.proposal_published", - event_class: Decidim::Proposals::PublishProposalEvent, - resource: kind_of(Decidim::Proposals::Proposal), - followers: [follower] - ) - - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.proposal_published", - event_class: Decidim::Proposals::PublishProposalEvent, - resource: kind_of(Decidim::Proposals::Proposal), - followers: [other_follower], - extra: { - participatory_space: true - } - ) - - subject.call - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/reject_access_to_collaborative_draft_spec.rb b/spec/proposals/commands/decidim/proposals/reject_access_to_collaborative_draft_spec.rb deleted file mode 100644 index 7c30ce5..0000000 --- a/spec/proposals/commands/decidim/proposals/reject_access_to_collaborative_draft_spec.rb +++ /dev/null @@ -1,144 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe RejectAccessToCollaborativeDraft do - let(:component) { create(:extended_proposal_component) } - let(:state) { :open } - let(:collaborative_draft) { create(:collaborative_draft, state, component: component, users: [author1, author2]) } - let(:id) { collaborative_draft.id } - let(:requester_user) { create(:user, :confirmed, organization: component.organization) } - let(:requester_user_id) { requester_user.id } - let(:author1) { create(:user, :confirmed, organization: component.organization) } - let(:author2) { create(:user, :confirmed, organization: component.organization) } - let(:current_user) { author1 } - let(:current_organization) { component.organization } - let(:form) { RejectAccessToCollaborativeDraftForm.from_params(form_params).with_context(current_user: current_user, current_organization: current_organization) } - let(:form_params) do - { - state: state, - id: id, - requester_user_id: requester_user_id - } - end - - describe "Author (current_user) rejects access to requester to collaborate" do - let(:command) { described_class.new(form, current_user) } - - before do - collaborative_draft.collaborator_requests.create!(user: requester_user) - end - - context "when the collaborative draft is open" do - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "removes the requester from requestors of the collaborative draft" do - expect do - command.call - end.to change(collaborative_draft.requesters, :count).by(-1) - end - - it "notifies the requester and authors of the collaborative draft that access to requester has been rejected" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.collaborative_draft_access_rejected", - event_class: Decidim::Proposals::CollaborativeDraftAccessRejectedEvent, - resource: collaborative_draft, - affected_users: collaborative_draft.authors, - extra: { - requester_id: requester_user_id - } - ) - - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.collaborative_draft_access_requester_rejected", - event_class: Decidim::Proposals::CollaborativeDraftAccessRequesterRejectedEvent, - resource: collaborative_draft, - affected_users: [requester_user] - ) - - command.call - end - end - - context "when the collaborative draft is withdrawn" do - let(:state) { :withdrawn } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't reject the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the collaborative draft is published" do - let(:state) { :published } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't reject the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the requester is missing" do - let(:requester_user_id) { nil } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't reject the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the current_user is missing" do - let(:current_user) { nil } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't reject the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the requester is not as a requestor" do - let(:not_requester) { create(:user, :confirmed, organization: component.organization) } - let(:requester_user_id) { not_requester.id } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't reject the request for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/request_access_to_collaborative_draft_spec.rb b/spec/proposals/commands/decidim/proposals/request_access_to_collaborative_draft_spec.rb deleted file mode 100644 index a997296..0000000 --- a/spec/proposals/commands/decidim/proposals/request_access_to_collaborative_draft_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe RequestAccessToCollaborativeDraft do - let(:component) { create(:extended_proposal_component) } - let(:state) { :open } - - let(:collaborative_draft) { create(:collaborative_draft, state, component: component, users: [author1, author2]) } - let(:id) { collaborative_draft.id } - let(:form) { RequestAccessToCollaborativeDraftForm.from_params(form_params).with_context(current_user: current_user) } - let(:form_params) do - { - state: state, - id: id - } - end - let(:current_user) { create(:user, :confirmed, organization: component.organization) } - let(:author1) { create(:user, :confirmed, organization: component.organization) } - let(:author2) { create(:user, :confirmed, organization: component.organization) } - - describe "User requests to collaborate" do - let(:command) { described_class.new(form, current_user) } - - context "when the collaborative draft is open" do - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates a new request for the collaborative draft" do - expect do - command.call - end.to change(collaborative_draft.requesters, :count).by(1) - end - - it "notifies all authors of the collaborative_draft that access has been requested" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.collaborative_draft_access_requested", - event_class: Decidim::Proposals::CollaborativeDraftAccessRequestedEvent, - resource: collaborative_draft, - affected_users: collaborative_draft.authors, - extra: { - requester_id: current_user.id - } - ) - - command.call - end - end - - context "when the collaborative draft is withdrawn" do - let(:state) { :withdrawn } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create a new requestor for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - - context "when the collaborative draft is published" do - let(:state) { :published } - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create a new requestor for the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft.requesters, :count) - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/unvote_proposal_spec.rb b/spec/proposals/commands/decidim/proposals/unvote_proposal_spec.rb deleted file mode 100644 index 6cd7f57..0000000 --- a/spec/proposals/commands/decidim/proposals/unvote_proposal_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe UnvoteProposal do - describe "call" do - let(:proposal) { create(:extended_proposal) } - let(:current_user) { create(:user, organization: proposal.component.organization) } - let!(:proposal_vote) { create(:proposal_vote, author: current_user, proposal: proposal) } - let(:command) { described_class.new(proposal, current_user) } - - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "deletes the proposal vote for that user" do - expect do - command.call - end.to change(ProposalVote, :count).by(-1) - end - - it "decrements the right score for that user" do - Decidim::Gamification.set_score(current_user, :proposal_votes, 10) - command.call - expect(Decidim::Gamification.status_for(current_user, :proposal_votes).score).to eq(9) - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/update_collaborative_draft_spec.rb b/spec/proposals/commands/decidim/proposals/update_collaborative_draft_spec.rb deleted file mode 100644 index cf7b7e6..0000000 --- a/spec/proposals/commands/decidim/proposals/update_collaborative_draft_spec.rb +++ /dev/null @@ -1,152 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe UpdateCollaborativeDraft do - let(:form_klass) { CollaborativeDraftForm } - - let(:component) { create(:extended_proposal_component, :with_extra_hashtags, suggested_hashtags: suggested_hashtags.join(" ")) } - let(:organization) { component.organization } - let(:form) do - form_klass.from_params( - form_params - ).with_context( - current_organization: organization, - current_participatory_space: component.participatory_space, - current_component: component - ) - end - - let!(:collaborative_draft) { create :collaborative_draft, component: component, users: [author] } - let(:author) { create(:user, organization: organization) } - - let(:user_group) do - create(:user_group, :verified, organization: organization, users: [author]) - end - - let(:has_address) { false } - let(:address) { nil } - let(:latitude) { 40.1234 } - let(:longitude) { 2.1234 } - let(:suggested_hashtags) { [] } - - describe "call" do - let(:form_params) do - { - title: "This is the collaborative draft title", - body: "This is the collaborative draft body", - address: address, - has_address: has_address, - user_group_id: user_group.try(:id), - suggested_hashtags: suggested_hashtags - } - end - - let(:command) do - described_class.new(form, author, collaborative_draft) - end - - describe "when the form is not valid" do - before do - expect(form).to receive(:invalid?).and_return(true) - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't update the proposal" do - expect do - command.call - end.not_to change(collaborative_draft, :title) - end - end - - describe "when the collaborative draft is not editable by the user" do - before do - expect(collaborative_draft).to receive(:editable_by?).and_return(false) - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't update the collaborative draft" do - expect do - command.call - end.not_to change(collaborative_draft, :title) - end - end - - describe "when the form is valid" do - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "updates the collaborative draft" do - expect do - command.call - end.to change(collaborative_draft, :title) - end - - it "creates a new version for the collaborative draft", versioning: true do - expect do - command.call - end.to change { collaborative_draft.versions.count }.by(1) - expect(collaborative_draft.versions.last.whodunnit).to eq author.to_gid.to_s - end - - context "with an author" do - let(:user_group) { nil } - - it "sets the author" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - - expect(collaborative_draft.coauthorships.count).to eq(1) - expect(collaborative_draft.authors.count).to eq(1) - expect(collaborative_draft.authors.first).to eq(author) - end - end - - context "with extra hashtags" do - let(:suggested_hashtags) { %w(Hashtag1 Hashtag2) } - - it "saves the extra hashtags" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - expect(collaborative_draft.body).to include("_Hashtag1") - expect(collaborative_draft.body).to include("_Hashtag2") - end - end - - context "when geocoding is enabled" do - let(:component) { create(:extended_proposal_component, :with_geocoding_enabled) } - - context "when the has address checkbox is checked" do - let(:has_address) { true } - - context "when the address is present" do - let(:address) { "Some address" } - - before do - stub_geocoding(address, [latitude, longitude]) - end - - it "sets the latitude and longitude" do - command.call - collaborative_draft = Decidim::Proposals::CollaborativeDraft.last - - expect(collaborative_draft.latitude).to eq(latitude) - expect(collaborative_draft.longitude).to eq(longitude) - end - end - end - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/vote_proposal_spec.rb b/spec/proposals/commands/decidim/proposals/vote_proposal_spec.rb deleted file mode 100644 index 2d50a31..0000000 --- a/spec/proposals/commands/decidim/proposals/vote_proposal_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe VoteProposal do - describe "call" do - let(:proposal) { create(:extended_proposal) } - let(:current_user) { create(:user, organization: proposal.component.organization) } - let(:command) { described_class.new(proposal, current_user) } - - context "with normal conditions" do - it "broadcasts ok" do - expect { command.call }.to broadcast(:ok) - end - - it "creates a new vote for the proposal" do - expect do - command.call - end.to change(ProposalVote, :count).by(1) - end - end - - context "when the vote is not valid" do - before do - # rubocop:disable RSpec/AnyInstance - allow_any_instance_of(ProposalVote).to receive(:valid?).and_return(false) - # rubocop:enable RSpec/AnyInstance - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - - it "doesn't create a new vote for the proposal" do - expect do - command.call - end.to change(ProposalVote, :count).by(0) - end - end - - context "when the threshold have been reached" do - before do - expect(proposal).to receive(:maximum_votes_reached?).and_return(true) - end - - it "broadcasts invalid" do - expect { command.call }.to broadcast(:invalid) - end - end - - context "when the threshold have been reached but proposal can accumulate more votes" do - before do - expect(proposal).to receive(:maximum_votes_reached?).and_return(true) - expect(proposal).to receive(:can_accumulate_supports_beyond_threshold).and_return(true) - end - - it "creates a new vote for the proposal" do - expect do - command.call - end.to change(ProposalVote, :count).by(1) - end - end - end - end - end -end diff --git a/spec/proposals/commands/decidim/proposals/withdraw_collaborative_draft_spec.rb b/spec/proposals/commands/decidim/proposals/withdraw_collaborative_draft_spec.rb deleted file mode 100644 index ff3fa9a..0000000 --- a/spec/proposals/commands/decidim/proposals/withdraw_collaborative_draft_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe WithdrawCollaborativeDraft do - describe "call" do - let(:component) { create(:extended_proposal_component) } - let(:organization) { component.organization } - let!(:current_user) { create(:user, organization: organization) } - let(:follower) { create(:user, organization: organization) } - let(:other_author) { create(:user, organization: organization) } - let(:state) { :open } - let(:collaborative_draft) { create(:collaborative_draft, component: component, state: state, users: [current_user, other_author]) } - let!(:follow) { create :follow, followable: current_user, user: follower } - let(:event) { "decidim.events.proposals.collaborative_draft_withdrawn" } - let(:event_class) { Decidim::Proposals::CollaborativeDraftWithdrawnEvent } - - it "broadcasts ok" do - expect { described_class.call(collaborative_draft, current_user) }.to broadcast(:ok) - end - - it "broadcasts invalid when the user is not a coauthor" do - expect { described_class.call(collaborative_draft, follower) }.to broadcast(:invalid) - end - - context "when the resource is withdrawn" do - let(:state) { :withdrawn } - - it "broadcasts invalid" do - expect { described_class.call(collaborative_draft, follower) }.to broadcast(:invalid) - end - end - - context "when the resource is published" do - let(:state) { :published } - - it "broadcasts invalid" do - expect { described_class.call(collaborative_draft, follower) }.to broadcast(:invalid) - end - end - - describe "events" do - subject do - described_class.new(collaborative_draft, current_user) - end - - it "notifies the collaborative draft is withdrawn to coauthors" do - affected_users = collaborative_draft.authors - [current_user] - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: event, - event_class: event_class, - resource: collaborative_draft, - affected_users: affected_users.uniq, - extra: { - author_id: current_user.id - } - ).ordered - subject.call - end - end - end - end - end -end diff --git a/spec/proposals/controllers/concerns/orderable_spec.rb b/spec/proposals/controllers/concerns/orderable_spec.rbx similarity index 100% rename from spec/proposals/controllers/concerns/orderable_spec.rb rename to spec/proposals/controllers/concerns/orderable_spec.rbx diff --git a/spec/proposals/controllers/decidim/proposals/collaborative_draft_collaborator_requests_controller_spec.rb b/spec/proposals/controllers/decidim/proposals/collaborative_draft_collaborator_requests_controller_spec.rbx similarity index 100% rename from spec/proposals/controllers/decidim/proposals/collaborative_draft_collaborator_requests_controller_spec.rb rename to spec/proposals/controllers/decidim/proposals/collaborative_draft_collaborator_requests_controller_spec.rbx diff --git a/spec/proposals/controllers/decidim/proposals/collaborative_drafts_controller_spec.rb b/spec/proposals/controllers/decidim/proposals/collaborative_drafts_controller_spec.rbx similarity index 100% rename from spec/proposals/controllers/decidim/proposals/collaborative_drafts_controller_spec.rb rename to spec/proposals/controllers/decidim/proposals/collaborative_drafts_controller_spec.rbx diff --git a/spec/proposals/controllers/decidim/proposals/proposal_votes_controller_spec.rb b/spec/proposals/controllers/decidim/proposals/proposal_votes_controller_spec.rbx similarity index 100% rename from spec/proposals/controllers/decidim/proposals/proposal_votes_controller_spec.rb rename to spec/proposals/controllers/decidim/proposals/proposal_votes_controller_spec.rbx diff --git a/spec/proposals/controllers/decidim/proposals/versions_controller_spec.rb b/spec/proposals/controllers/decidim/proposals/versions_controller_spec.rbx similarity index 100% rename from spec/proposals/controllers/decidim/proposals/versions_controller_spec.rb rename to spec/proposals/controllers/decidim/proposals/versions_controller_spec.rbx diff --git a/spec/proposals/events/decidim/proposals/accepted_proposal_event_spec.rb b/spec/proposals/events/decidim/proposals/accepted_proposal_event_spec.rb index 1cae513..ccd6615 100644 --- a/spec/proposals/events/decidim/proposals/accepted_proposal_event_spec.rb +++ b/spec/proposals/events/decidim/proposals/accepted_proposal_event_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" describe Decidim::Proposals::AcceptedProposalEvent do - let(:resource) { create :proposal, :with_answer, title: "My super proposal" } + let(:resource) { create :extended_proposal, :with_answer, title: "My super proposal" } let(:resource_title) { translated(resource.title) } let(:event_name) { "decidim.events.proposals.proposal_accepted" } diff --git a/spec/proposals/events/decidim/proposals/admin/proposal_note_created_event_spec.rb b/spec/proposals/events/decidim/proposals/admin/proposal_note_created_event_spec.rb deleted file mode 100644 index af571ae..0000000 --- a/spec/proposals/events/decidim/proposals/admin/proposal_note_created_event_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::Admin::ProposalNoteCreatedEvent do - let(:resource) { create :proposal, title: ::Faker::Lorem.characters(number: 25) } - let(:resource_title) { translated(resource.title) } - let(:event_name) { "decidim.events.proposals.admin.proposal_note_created" } - let(:component) { resource.component } - let(:admin_proposal_info_path) { "/admin/participatory_processes/#{participatory_space.slug}/components/#{component.id}/manage/proposals/#{resource.id}" } - let(:admin_proposal_info_url) { "http://#{organization.host}/admin/participatory_processes/#{participatory_space.slug}/components/#{component.id}/manage/proposals/#{resource.id}" } - - include_context "when a simple event" - it_behaves_like "a simple event" - - describe "email_subject" do - let(:resource) { create :proposal, title: { en: "It's my proposal" } } - - it "is generated correctly" do - expect(subject.email_subject).to eq("Someone left a note on proposal #{resource_title}.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(Someone has left a note on the proposal "#{resource_title}". Check it out at the admin panel)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq("You have received this notification because you can valuate the proposal.") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include(%(Someone has left a note on the proposal #{resource_title}. Check it out at the admin panel)) - end - end - - context "when proposals component added to assemblies participatory space" do - let(:assembly) { create(:assembly) } - let(:proposal_component) { create :extended_proposal_component, participatory_space: assembly } - let(:resource) { create :proposal, component: proposal_component, title: ::Faker::Lorem.characters(number: 25) } - let(:admin_proposal_info_path) { "/admin/assemblies/#{participatory_space.slug}/components/#{component.id}/manage/proposals/#{resource.id}" } - let(:admin_proposal_info_url) { "http://#{organization.host}/admin/assemblies/#{participatory_space.slug}/components/#{component.id}/manage/proposals/#{resource.id}" } - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(Someone has left a note on the proposal "#{resource_title}". Check it out at the admin panel)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include(%(Someone has left a note on the proposal #{resource_title}. Check it out at the admin panel)) - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/admin/update_proposal_category_event_spec.rb b/spec/proposals/events/decidim/proposals/admin/update_proposal_category_event_spec.rb deleted file mode 100644 index 1f0017e..0000000 --- a/spec/proposals/events/decidim/proposals/admin/update_proposal_category_event_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::Admin::UpdateProposalCategoryEvent do - let(:resource) { create :proposal, title: "It's my super proposal" } - let(:event_name) { "decidim.events.proposals.proposal_update_category" } - - include_context "when a simple event" - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("The #{translated(resource.title)} proposal category has been updated") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq("An admin has updated the category of your proposal \"#{decidim_html_escape(translated(resource.title))}\", check it out in this page:") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq("You have received this notification because you are the author of the proposal.") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include("The #{decidim_html_escape(translated(resource.title))} proposal category has been updated by an admin.") - end - end -end diff --git a/spec/proposals/events/decidim/proposals/admin/update_proposal_scope_event_spec.rb b/spec/proposals/events/decidim/proposals/admin/update_proposal_scope_event_spec.rb deleted file mode 100644 index 4d2647e..0000000 --- a/spec/proposals/events/decidim/proposals/admin/update_proposal_scope_event_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::Admin::UpdateProposalScopeEvent do - let(:resource) { create :proposal, title: "It's my super proposal" } - let(:resource_title) { translated(resource.title) } - let(:event_name) { "decidim.events.proposals.proposal_update_scope" } - - include_context "when a simple event" - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("The #{decidim_sanitize(resource_title)} proposal scope has been updated") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq("An admin has updated the scope of your proposal \"#{decidim_html_escape(resource_title)}\", check it out in this page:") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq("You have received this notification because you are the author of the proposal.") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include("The #{decidim_html_escape(resource_title)} proposal scope has been updated by an admin.") - end - end -end diff --git a/spec/proposals/events/decidim/proposals/amendable/amendment_accepted_event_spec.rb b/spec/proposals/events/decidim/proposals/amendable/amendment_accepted_event_spec.rb deleted file mode 100644 index 78dcf59..0000000 --- a/spec/proposals/events/decidim/proposals/amendable/amendment_accepted_event_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Amendable - describe AmendmentAcceptedEvent do - let!(:component) { create(:extended_proposal_component) } - let!(:amendable) { create(:extended_proposal, component: component, title: amendable_title) } - let!(:emendation) { create(:extended_proposal, component: component, title: "My super emendation") } - let!(:amendment) { create :amendment, amendable: amendable, emendation: emendation } - let(:amendable_title) { "My super proposal" } - - include_examples "amendment accepted event" - end - end -end diff --git a/spec/proposals/events/decidim/proposals/amendable/amendment_created_event_spec.rb b/spec/proposals/events/decidim/proposals/amendable/amendment_created_event_spec.rb deleted file mode 100644 index d75f473..0000000 --- a/spec/proposals/events/decidim/proposals/amendable/amendment_created_event_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Amendable - describe AmendmentCreatedEvent do - let!(:component) { create(:extended_proposal_component) } - let!(:amendable) { create(:extended_proposal, component: component, title: amendable_title) } - let!(:emendation) { create(:extended_proposal, component: component, title: "My super emendation") } - let!(:amendment) { create :amendment, amendable: amendable, emendation: emendation } - let(:amendable_title) { "My super proposal" } - - include_examples "amendment created event" - end - end -end diff --git a/spec/proposals/events/decidim/proposals/amendable/amendment_promoted_event_spec.rb b/spec/proposals/events/decidim/proposals/amendable/amendment_promoted_event_spec.rb deleted file mode 100644 index 6436c4a..0000000 --- a/spec/proposals/events/decidim/proposals/amendable/amendment_promoted_event_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Amendable - describe EmendationPromotedEvent do - let!(:component) { create(:extended_proposal_component) } - let!(:amendable) { create(:extended_proposal, component: component, title: amendable_title) } - let!(:emendation) { create(:extended_proposal, component: component, title: "My super emendation") } - let!(:amendment) { create :amendment, amendable: amendable, emendation: emendation } - let(:amendable_type) { "proposal" } - let(:amendable_title) { "My super proposal" } - - include_examples "amendment promoted event" - end - end -end diff --git a/spec/proposals/events/decidim/proposals/amendable/amendment_rejected_event_spec.rb b/spec/proposals/events/decidim/proposals/amendable/amendment_rejected_event_spec.rb deleted file mode 100644 index 1e4ca1b..0000000 --- a/spec/proposals/events/decidim/proposals/amendable/amendment_rejected_event_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Amendable - describe AmendmentRejectedEvent do - let!(:component) { create(:extended_proposal_component) } - let!(:amendable) { create(:extended_proposal, component: component, title: amendable_title) } - let!(:emendation) { create(:extended_proposal, component: component, title: "My super emendation") } - let!(:amendment) { create :amendment, amendable: amendable, emendation: emendation } - let(:amendable_title) { "My super proposal" } - - include_examples "amendment rejected event" - end - end -end diff --git a/spec/proposals/events/decidim/proposals/collaborative_draft_access_accepted_event_spec.rb b/spec/proposals/events/decidim/proposals/collaborative_draft_access_accepted_event_spec.rb deleted file mode 100644 index ce23791..0000000 --- a/spec/proposals/events/decidim/proposals/collaborative_draft_access_accepted_event_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::CollaborativeDraftAccessAcceptedEvent do - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.collaborative_draft_access_accepted" } - let(:resource) { create :collaborative_draft, title: "It's my collaborative draft" } - let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - let(:resource_title) { resource.title } - let(:author) { resource.authors.first } - let(:author_id) { author.id } - let(:author_presenter) { Decidim::UserPresenter.new(author) } - let(:author_path) { author_presenter.profile_path } - let(:author_name) { author_presenter.name } - let(:author_nickname) { author_presenter.nickname } - let(:requester) { create :user, :confirmed, organization: resource.organization } - let(:requester_presenter) { Decidim::UserPresenter.new(requester) } - let(:requester_id) { requester.id } - let(:requester_name) { requester.name } - let(:requester_nickname) { requester_presenter.nickname } - let(:requester_path) { requester_presenter.profile_path } - let(:extra) { { requester_id: requester_id } } - - context "when the notification is for coauthor users" do - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("#{requester_name} has been accepted to access as a contributor of the #{resource_title}.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(#{requester_name} has been accepted to access as a contributor of the #{decidim_html_escape(resource_title)} collaborative draft.)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq(%(You have received this notification because you are a collaborator of #{decidim_html_escape(resource_title)}.)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include(%(#{requester_name} #{requester_nickname} has been accepted to access as a contributor of the #{decidim_html_escape(resource_title)} collaborative draft.)) - end - end - end - - context "when the notification is for the requester" do - let(:event_name) { "decidim.events.proposals.collaborative_draft_access_requester_accepted" } - - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("You have been accepted as a contributor of #{resource_title}.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(You have been accepted to access as a contributor of the #{decidim_html_escape(resource_title)} collaborative draft.)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq(%(You have received this notification because you requested to become a collaborator of #{decidim_html_escape(resource_title)}.)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to eq(%(You have been accepted to access as a contributor of the #{decidim_html_escape(resource_title)} collaborative draft.)) - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/collaborative_draft_access_rejected_event_spec.rb b/spec/proposals/events/decidim/proposals/collaborative_draft_access_rejected_event_spec.rb deleted file mode 100644 index aa3efd1..0000000 --- a/spec/proposals/events/decidim/proposals/collaborative_draft_access_rejected_event_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::CollaborativeDraftAccessRejectedEvent do - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.collaborative_draft_access_rejected" } - let(:resource) { create :collaborative_draft, title: "It's my collaborative draft" } - let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - let(:resource_title) { decidim_html_escape(resource.title) } - let(:author) { resource.authors.first } - let(:author_id) { author.id } - let(:author_presenter) { Decidim::UserPresenter.new(author) } - let(:author_path) { author_presenter.profile_path } - let(:author_name) { author_presenter.name } - let(:author_nickname) { author_presenter.nickname } - let(:requester) { create :user, :confirmed, organization: resource.organization } - let(:requester_presenter) { Decidim::UserPresenter.new(requester) } - let(:requester_id) { requester.id } - let(:requester_name) { requester.name } - let(:requester_nickname) { requester_presenter.nickname } - let(:requester_path) { requester_presenter.profile_path } - let(:extra) { { requester_id: requester_id } } - - context "when the notification is for coauthor users" do - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("#{requester_name} has been rejected to access as a contributor of the #{translated(resource.title)} collaborative draft.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(#{requester_name} has been rejected to access as a contributor of the #{resource_title} collaborative draft.)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq(%(You have received this notification because you are a collaborator of #{resource_title}.)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include(%(#{requester_name} #{requester_nickname} has been rejected to access as a contributor of the #{resource_title} collaborative draft.)) - end - end - end - - context "when the notification is for the requester" do - let(:event_name) { "decidim.events.proposals.collaborative_draft_access_requester_rejected" } - - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("You have been rejected as a contributor of #{translated(resource.title)}.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(You have been rejected to access as a contributor of the #{resource_title} collaborative draft.)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq(%(You have received this notification because you requested to become a collaborator of #{resource_title}.)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to eq(%(You have been rejected to access as a contributor of the #{resource_title} collaborative draft.)) - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/collaborative_draft_access_requested_event_spec.rb b/spec/proposals/events/decidim/proposals/collaborative_draft_access_requested_event_spec.rb deleted file mode 100644 index efbaf21..0000000 --- a/spec/proposals/events/decidim/proposals/collaborative_draft_access_requested_event_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::CollaborativeDraftAccessRequestedEvent do - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.collaborative_draft_access_requested" } - let(:resource) { create :collaborative_draft, title: "It's my collaborative draft" } - let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - let(:resource_title) { resource.title } - let(:author) { resource.authors.first } - let(:author_id) { author.id } - let(:author_presenter) { Decidim::UserPresenter.new(author) } - let(:author_path) { author_presenter.profile_path } - let(:author_name) { author_presenter.name } - let(:author_nickname) { author_presenter.nickname } - let(:requester) { create :user, :confirmed, organization: resource.organization } - let(:requester_name) { requester.name } - let(:requester_id) { requester.id } - let(:requester_presenter) { Decidim::UserPresenter.new(requester) } - let(:requester_path) { requester_presenter.profile_path } - let(:requester_nickname) { requester_presenter.nickname } - let(:extra) { { requester_id: requester_id } } - - context "when the notification is for coauthor users" do - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("#{requester_name} requested access to contribute to #{resource_title}.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(#{requester_name} requested access as a contributor. You can accept or reject the request from the #{decidim_html_escape(resource_title)} collaborative draft page.)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq(%(You have received this notification because you are a collaborator of #{decidim_html_escape(resource_title)}.)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include(%(#{requester_name} #{requester_nickname} requested access to contribute to the #{decidim_html_escape(resource_title)} collaborative draft. Please accept or reject the request.)) - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/collaborative_draft_withdrawn_event_spec.rb b/spec/proposals/events/decidim/proposals/collaborative_draft_withdrawn_event_spec.rb deleted file mode 100644 index 52363ed..0000000 --- a/spec/proposals/events/decidim/proposals/collaborative_draft_withdrawn_event_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::CollaborativeDraftWithdrawnEvent do - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.collaborative_draft_withdrawn" } - let(:resource) { create :collaborative_draft, title: "It's my collaborative draft" } - let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - let(:resource_title) { decidim_html_escape(resource.title) } - let(:author) { resource.authors.first } - let(:author_id) { author.id } - let(:author_presenter) { Decidim::UserPresenter.new(author) } - let(:author_path) { author_presenter.profile_path } - let(:author_url) { author_presenter.profile_url } - let(:author_name) { author_presenter.name } - let(:author_nickname) { author_presenter.nickname } - let(:extra) { { author_id: author_id } } - - context "when the notification is for coauthor users" do - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("#{author_name} #{author_nickname} withdrawn the #{decidim_sanitize(resource_title)} collaborative draft.") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq(%(#{author_name} #{author_nickname} withdrawn the #{resource_title} collaborative draft.)) - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq(%(You have received this notification because you are a collaborator of #{resource_title}.)) - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include(%(#{author_name} #{author_nickname} withdrawn the #{resource_title} collaborative draft.)) - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/creation_enabled_event_spec.rb b/spec/proposals/events/decidim/proposals/creation_enabled_event_spec.rb deleted file mode 100644 index 60686ad..0000000 --- a/spec/proposals/events/decidim/proposals/creation_enabled_event_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe CreationEnabledEvent do - include Decidim::ComponentPathHelper - - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.creation_enabled" } - let(:resource) { create(:extended_proposal_component) } - let(:participatory_space) { resource.participatory_space } - let(:resource_path) { main_component_path(resource) } - - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("Proposals now available in #{participatory_space.title["en"]}") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq("You can now create new proposals in #{participatory_space_title}! Start participating in this page:") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to include("You have received this notification because you are following #{participatory_space.title["en"]}") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to eq("You can now put forward new proposals in #{participatory_space.title["en"]}") - end - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/endorsing_enabled_event_spec.rb b/spec/proposals/events/decidim/proposals/endorsing_enabled_event_spec.rb deleted file mode 100644 index eade4c6..0000000 --- a/spec/proposals/events/decidim/proposals/endorsing_enabled_event_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe EndorsingEnabledEvent do - include Decidim::ComponentPathHelper - - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.endorsing_enabled" } - let(:resource) { create(:extended_proposal_component) } - let(:participatory_space) { resource.participatory_space } - let(:resource_path) { main_component_path(resource) } - - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("Proposals endorsing has started for #{participatory_space.title["en"]}") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq("You can endorse proposals in #{participatory_space_title}! Start participating in this page:") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to include("You have received this notification because you are following #{participatory_space.title["en"]}") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to eq("You can now start endorsing proposals in #{participatory_space.title["en"]}") - end - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/evaluating_proposal_event_spec.rb b/spec/proposals/events/decidim/proposals/evaluating_proposal_event_spec.rb index 785d480..44cbcee 100644 --- a/spec/proposals/events/decidim/proposals/evaluating_proposal_event_spec.rb +++ b/spec/proposals/events/decidim/proposals/evaluating_proposal_event_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" describe Decidim::Proposals::EvaluatingProposalEvent do - let(:resource) { create :proposal, title: "My super proposal" } + let(:resource) { create :extended_proposal, title: "My super proposal" } let(:event_name) { "decidim.events.proposals.proposal_evaluating" } include_context "when a simple event" diff --git a/spec/proposals/events/decidim/proposals/proposal_mentioned_event_spec.rb b/spec/proposals/events/decidim/proposals/proposal_mentioned_event_spec.rb deleted file mode 100644 index 87fcd4d..0000000 --- a/spec/proposals/events/decidim/proposals/proposal_mentioned_event_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::ProposalMentionedEvent do - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.proposal_mentioned" } - let(:organization) { create :organization } - let(:author) { create :user, organization: organization } - - let(:source_proposal) { create :proposal, component: create(:extended_proposal_component, organization: organization), title: "Proposal A" } - let(:mentioned_proposal) { create :proposal, component: create(:extended_proposal_component, organization: organization), title: "It's proposal B" } - let(:resource) { source_proposal } - let(:extra) do - { - mentioned_proposal_id: mentioned_proposal.id - } - end - - it_behaves_like "a simple event" - - describe "types" do - subject { described_class } - - it "supports notifications" do - expect(subject.types).to include :notification - end - - it "supports emails" do - expect(subject.types).to include :email - end - end - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("Your proposal \"#{decidim_sanitize(translated(mentioned_proposal.title))}\" has been mentioned") - end - end - - context "with content" do - let(:content) do - "Your proposal \"#{decidim_html_escape(translated(mentioned_proposal.title))}\" has been mentioned " \ - "in this space in the comments." - end - - describe "email_intro" do - let(:resource_url) { resource_locator(source_proposal).url } - - it "is generated correctly" do - expect(subject.email_intro).to eq(content) - end - end - - describe "notification_title" do - let(:resource_url) { resource_locator(source_proposal).path } - - it "is generated correctly" do - expect(subject.notification_title).to include(content) - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/publish_proposal_event_spec.rb b/spec/proposals/events/decidim/proposals/publish_proposal_event_spec.rb deleted file mode 100644 index 800a712..0000000 --- a/spec/proposals/events/decidim/proposals/publish_proposal_event_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe PublishProposalEvent do - let(:resource) { create :proposal, title: "A nice proposal" } - let(:participatory_process) { create :participatory_process, organization: organization } - let(:proposal_component) { create(:extended_proposal_component, participatory_space: participatory_process) } - let(:resource_title) { translated(resource.title) } - let(:event_name) { "decidim.events.proposals.proposal_published" } - - include_context "when a simple event" - - it_behaves_like "a simple event" - - describe "resource_text" do - it "returns the proposal body" do - expect(subject.resource_text).to eq(resource.body) - end - end - - describe "email_subject" do - context "when resource title contains apostrophes" do - let(:resource) { create :proposal, title: "It's a nice proposal" } - - it "is generated correctly" do - expect(subject.email_subject).to eq("New proposal \"#{resource_title}\" by @#{author.nickname}") - end - end - - it "is generated correctly" do - expect(subject.email_subject).to eq("New proposal \"#{resource_title}\" by @#{author.nickname}") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq("#{author.name} @#{author.nickname}, who you are following, has published a new proposal called \"#{resource_title}\". Check it out and contribute:") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to eq("You have received this notification because you are following @#{author.nickname}. You can stop receiving notifications following the previous link.") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include("The #{resource_title} proposal was published by ") - - expect(subject.notification_title) - .to include("#{author.name} @#{author.nickname}.") - end - end - - context "when the proposal is official" do - let(:resource) { create :proposal, :official, title: "A nice proposal" } - let(:extra) { { participatory_space: resource.participatory_space } } - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to include("The official proposal #{resource_title} has been added to #{participatory_space_title}") - end - end - end - - context "when the target are the participatory space followers" do - let(:event_name) { "decidim.events.proposals.proposal_published_for_space" } - let(:extra) { { participatory_space: true } } - - include_context "when a simple event" - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("New proposal \"#{resource_title}\" added to #{participatory_space_title}") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro).to eq("The proposal \"A nice proposal\" has been added to \"#{participatory_space_title}\" that you are following.") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to include("You have received this notification because you are following \"#{participatory_space_title}\"") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to eq("The proposal A nice proposal has been added to #{participatory_space_title} by #{author.name} @#{author.nickname}") - end - end - end - - describe "translated notifications" do - let(:en_body) { "A nice proposal" } - let(:body) { { "en": en_body, "machine_translations": { "ca": "Une belle idee" } } } - let(:resource) do - create :proposal, - component: proposal_component, - title: { "en": "A nice proposal", "machine_translations": { "ca": "Une belle idee" } }, - body: body - end - - let(:en_version) { subject.resource_text["en"] } - let(:machine_translated) { subject.resource_text["machine_translations"]["ca"] } - let(:translatable) { true } - - it_behaves_like "a translated event" - end - end - end -end diff --git a/spec/proposals/events/decidim/proposals/rejected_proposal_event_spec.rb b/spec/proposals/events/decidim/proposals/rejected_proposal_event_spec.rb index 1113fd4..ebfa075 100644 --- a/spec/proposals/events/decidim/proposals/rejected_proposal_event_spec.rb +++ b/spec/proposals/events/decidim/proposals/rejected_proposal_event_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" describe Decidim::Proposals::RejectedProposalEvent do - let(:resource) { create :proposal, :with_answer, title: "It's my super proposal" } + let(:resource) { create :extended_proposal, :with_answer, title: "It's my super proposal" } let(:resource_title) { translated(resource.title) } let(:event_name) { "decidim.events.proposals.proposal_rejected" } diff --git a/spec/proposals/events/decidim/proposals/voting_enabled_event_spec.rb b/spec/proposals/events/decidim/proposals/voting_enabled_event_spec.rb deleted file mode 100644 index 9063c63..0000000 --- a/spec/proposals/events/decidim/proposals/voting_enabled_event_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe VotingEnabledEvent do - include Decidim::ComponentPathHelper - - include_context "when a simple event" - - let(:event_name) { "decidim.events.proposals.voting_enabled" } - let(:resource) { create(:extended_proposal_component) } - let(:participatory_space) { resource.participatory_space } - let(:resource_path) { main_component_path(resource) } - - it_behaves_like "a simple event" - - describe "email_subject" do - it "is generated correctly" do - expect(subject.email_subject).to eq("Proposal support has started for #{participatory_space.title["en"]}") - end - end - - describe "email_intro" do - it "is generated correctly" do - expect(subject.email_intro) - .to eq("You can support proposals in #{participatory_space_title}! Start participating in this page:") - end - end - - describe "email_outro" do - it "is generated correctly" do - expect(subject.email_outro) - .to include("You have received this notification because you are following #{participatory_space.title["en"]}") - end - end - - describe "notification_title" do - it "is generated correctly" do - expect(subject.notification_title) - .to eq("You can now start supporting proposals in #{participatory_space.title["en"]}") - end - end - end - end -end diff --git a/spec/proposals/events/decidim/resource_endorsed_event_spec.rb b/spec/proposals/events/decidim/resource_endorsed_event_spec.rb deleted file mode 100644 index 5994834..0000000 --- a/spec/proposals/events/decidim/resource_endorsed_event_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::ResourceEndorsedEvent do - let(:resource) { create :proposal, :citizen_author, title: { en: "My proposal" } } - let(:resource_type) { "Proposal" } - let(:resource_text) { resource.body } - - it_behaves_like "resource endorsed event" -end diff --git a/spec/proposals/helpers/map_helper_spec.rb b/spec/proposals/helpers/map_helper_spec.rb index 0204ba4..ac0e08d 100644 --- a/spec/proposals/helpers/map_helper_spec.rb +++ b/spec/proposals/helpers/map_helper_spec.rb @@ -8,7 +8,7 @@ module Proposals include Decidim::LayoutHelper let!(:organization) { create(:organization) } - let!(:extended_proposal_component) { create(:extended_proposal_component, :with_geocoding_enabled, organization: organization) } + let!(:proposal_component) { create(:extended_proposal_component, :with_geocoding_enabled, organization: organization) } let!(:user) { create(:user, organization: organization) } let!(:proposals) { create_list(:extended_proposal, 5, address: address, latitude: latitude, longitude: longitude, component: proposal_component) } let!(:proposal) { proposals.first } diff --git a/spec/proposals/helpers/proposal_rankings_helper_spec.rb b/spec/proposals/helpers/proposal_rankings_helper_spec.rb index 57c4416..e505699 100644 --- a/spec/proposals/helpers/proposal_rankings_helper_spec.rb +++ b/spec/proposals/helpers/proposal_rankings_helper_spec.rb @@ -8,12 +8,12 @@ module Admin describe ProposalRankingsHelper do let(:component) { create(:extended_proposal_component) } - let!(:proposal1) { create :proposal, component: component, proposal_votes_count: 4 } - let!(:proposal2) { create :proposal, component: component, proposal_votes_count: 2 } - let!(:proposal3) { create :proposal, component: component, proposal_votes_count: 2 } - let!(:proposal4) { create :proposal, component: component, proposal_votes_count: 1 } + let!(:proposal1) { create :extended_proposal, component: component, proposal_votes_count: 4 } + let!(:proposal2) { create :extended_proposal, component: component, proposal_votes_count: 2 } + let!(:proposal3) { create :extended_proposal, component: component, proposal_votes_count: 2 } + let!(:proposal4) { create :extended_proposal, component: component, proposal_votes_count: 1 } - let!(:external_proposal) { create :proposal, proposal_votes_count: 8 } + let!(:external_proposal) { create :extended_proposal, proposal_votes_count: 8 } describe "ranking_for" do it "returns the ranking considering only sibling proposals" do diff --git a/spec/proposals/jobs/decidim/proposals/notify_proposals_mentioned_job_spec.rb b/spec/proposals/jobs/decidim/proposals/notify_proposals_mentioned_job_spec.rb deleted file mode 100644 index 43fbc7d..0000000 --- a/spec/proposals/jobs/decidim/proposals/notify_proposals_mentioned_job_spec.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe NotifyProposalsMentionedJob do - subject { described_class } - - include_context "when creating a comment" - - let(:comment) { create(:comment, commentable: commentable) } - let(:extended_proposal_component) { create(:extended_proposal_component, organization: organization) } - let(:proposal_metadata) { Decidim::ContentParsers::ProposalParser::Metadata.new([]) } - let(:users) { [create(:user, :confirmed, organization: organization)] } - let(:linked_proposal) { create(:extended_proposal, component: proposal_component, users: users) } - let(:linked_proposal_official) { create(:extended_proposal, :official, component: proposal_component) } - let(:author) { create(:user, organization: commentable.organization) } - - describe "integration" do - it "is correctly scheduled" do - ActiveJob::Base.queue_adapter = :test - proposal_metadata[:linked_proposals] << linked_proposal - proposal_metadata[:linked_proposals] << linked_proposal_official - comment = create(:comment) - - expect do - Decidim::Comments::CommentCreation.publish(comment, proposal: proposal_metadata) - end.to have_enqueued_job.with(comment.id, proposal_metadata.linked_proposals) - end - end - - describe "with mentioned proposals" do - let(:linked_proposals) do - [ - linked_proposal.id, - linked_proposal_official.id - ] - end - - let!(:space_admin) do - create(:process_admin, participatory_process: linked_proposal_official.component.participatory_space) - end - - it "notifies the author about it" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.proposal_mentioned", - event_class: Decidim::Proposals::ProposalMentionedEvent, - resource: commentable, - affected_users: [linked_proposal.creator_author], - extra: { - comment_id: comment.id, - mentioned_proposal_id: linked_proposal.id - } - ) - - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.proposal_mentioned", - event_class: Decidim::Proposals::ProposalMentionedEvent, - resource: commentable, - affected_users: [space_admin], - extra: { - comment_id: comment.id, - mentioned_proposal_id: linked_proposal_official.id - } - ) - - subject.perform_now(comment.id, linked_proposals) - end - - context "when the author is the same as proposal user" do - before do - comment.update(author: users.first) - end - - it "does not notify the same user" do - expect(Decidim::EventsManager) - .not_to receive(:publish) - .with( - event: "decidim.events.proposals.proposal_mentioned", - event_class: Decidim::Proposals::ProposalMentionedEvent, - resource: commentable, - affected_users: [linked_proposal.creator_author], - extra: { - comment_id: comment.id, - mentioned_proposal_id: linked_proposal.id - } - ) - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.proposal_mentioned", - event_class: Decidim::Proposals::ProposalMentionedEvent, - resource: commentable, - affected_users: [space_admin], - extra: { - comment_id: comment.id, - mentioned_proposal_id: linked_proposal_official.id - } - ) - - subject.perform_now(comment.id, linked_proposals) - end - end - end - end - end -end diff --git a/spec/proposals/jobs/decidim/proposals/settings_change_job_spec.rb b/spec/proposals/jobs/decidim/proposals/settings_change_job_spec.rb deleted file mode 100644 index 4821919..0000000 --- a/spec/proposals/jobs/decidim/proposals/settings_change_job_spec.rb +++ /dev/null @@ -1,180 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe SettingsChangeJob do - subject { described_class } - - let(:component) { create(:extended_proposal_component) } - let(:user) { create :user, organization: component.organization } - let!(:follow) { create :follow, followable: component.participatory_space, user: user } - - describe "creation enabled" do - let(:previous_settings) do - { creation_enabled: previously_allowing_creation } - end - let(:current_settings) do - { creation_enabled: currently_allowing_creation } - end - - context "when creation is enabled" do - let(:previously_allowing_creation) { false } - let(:currently_allowing_creation) { true } - - it "notifies the space followers about it" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.creation_enabled", - event_class: Decidim::Proposals::CreationEnabledEvent, - resource: component, - followers: [user] - ) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - - context "when creation is not enabled" do - let(:previously_allowing_creation) { false } - let(:currently_allowing_creation) { false } - - it "does not notify the space followers about it" do - expect(Decidim::EventsManager) - .not_to receive(:publish) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - end - - describe "voting enabled" do - let(:previous_settings) do - { - votes_enabled: previously_allowing_votes, - votes_blocked: previously_blocking_votes - } - end - let(:current_settings) do - { - votes_enabled: currently_allowing_votes, - votes_blocked: currently_blocking_votes - } - end - - context "when voting is enabled and unlocked" do - let(:previously_allowing_votes) { false } - let(:previously_blocking_votes) { false } - let(:currently_allowing_votes) { true } - let(:currently_blocking_votes) { false } - - it "notifies the space followers about it" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.voting_enabled", - event_class: Decidim::Proposals::VotingEnabledEvent, - resource: component, - followers: [user] - ) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - - context "when votes are not enabled" do - let(:previously_allowing_votes) { true } - let(:previously_blocking_votes) { false } - let(:currently_allowing_votes) { false } - let(:currently_blocking_votes) { false } - - it "does not notify the space followers about it" do - expect(Decidim::EventsManager) - .not_to receive(:publish) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - - context "when votes are blocked" do - let(:previously_allowing_votes) { false } - let(:previously_blocking_votes) { false } - let(:currently_allowing_votes) { true } - let(:currently_blocking_votes) { true } - - it "does not notify the space followers about it" do - expect(Decidim::EventsManager) - .not_to receive(:publish) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - end - - describe "endorsing enabled" do - let(:previous_settings) do - { - endorsements_enabled: previously_allowing_endorsements, - endorsements_blocked: previously_blocking_endorsements - } - end - let(:current_settings) do - { - endorsements_enabled: currently_allowing_endorsements, - endorsements_blocked: currently_blocking_endorsements - } - end - - context "when endorsing is enabled and unlocked" do - let(:previously_allowing_endorsements) { false } - let(:previously_blocking_endorsements) { false } - let(:currently_allowing_endorsements) { true } - let(:currently_blocking_endorsements) { false } - - it "notifies the space followers about it" do - expect(Decidim::EventsManager) - .to receive(:publish) - .with( - event: "decidim.events.proposals.endorsing_enabled", - event_class: Decidim::Proposals::EndorsingEnabledEvent, - resource: component, - followers: [user] - ) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - - context "when endorsements are not enabled" do - let(:previously_allowing_endorsements) { true } - let(:previously_blocking_endorsements) { false } - let(:currently_allowing_endorsements) { false } - let(:currently_blocking_endorsements) { false } - - it "does not notify the space followers about it" do - expect(Decidim::EventsManager) - .not_to receive(:publish) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - - context "when endorsements are blocked" do - let(:previously_allowing_endorsements) { false } - let(:previously_blocking_endorsements) { false } - let(:currently_allowing_endorsements) { true } - let(:currently_blocking_endorsements) { true } - - it "does not notify the space followers about it" do - expect(Decidim::EventsManager) - .not_to receive(:publish) - - subject.perform_now(component.id, previous_settings, current_settings) - end - end - end - end - end -end diff --git a/spec/proposals/lib/decidim/admin/import/importer_spec.rb b/spec/proposals/lib/decidim/admin/import/importer_spec.rb index 5368005..2881725 100644 --- a/spec/proposals/lib/decidim/admin/import/importer_spec.rb +++ b/spec/proposals/lib/decidim/admin/import/importer_spec.rb @@ -18,7 +18,7 @@ } end let(:participatory_process) { create :participatory_process, organization: organization } - let(:current_component) { create :component, manifest_name: :proposals, participatory_space: participatory_process } + let(:current_component) { create :extended_proposal_component, participatory_space: participatory_process } context "with CSV" do let(:file) { File.new Decidim::Dev.asset("import_proposals.csv") } diff --git a/spec/proposals/lib/decidim/proposals/markdown_to_proposals_spec.rb b/spec/proposals/lib/decidim/proposals/markdown_to_proposals_spec.rb deleted file mode 100644 index d9ea0c6..0000000 --- a/spec/proposals/lib/decidim/proposals/markdown_to_proposals_spec.rb +++ /dev/null @@ -1,230 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe MarkdownToProposals do - def should_parse_and_produce_proposals(num_proposals) - proposals = Decidim::Proposals::Proposal.where(component: component) - expect { parser.parse(document) }.to change { proposals.count }.by(num_proposals) - proposals - end - - def should_have_expected_states(proposal) - expect(proposal.draft?).to be true - expect(proposal.official?).to be true - end - - def proposal_should_conform(section_level, title, body) - proposal = Decidim::Proposals::Proposal.where(component: component).last - expect(proposal.participatory_text_level).to eq(Decidim::Proposals::ParticipatoryTextSection::LEVELS[section_level]) - expect(translated(proposal.title)).to eq(title) - expect(translated(proposal.body)).to eq(body) - end - - let!(:component) { create(:extended_proposal_component) } - let(:parser) { MarkdownToProposals.new(component, create(:user)) } - let(:items) { [] } - let(:document) do - items.join("\n") - end - - describe "titles create sections and sub-sections" do - context "with titles of level 1" do - let(:title) { ::Faker::Book.title } - - before do - items << "# #{title}\n" - end - - it "create sections" do - should_parse_and_produce_proposals(1) - - proposal = Proposal.last - expect(translated(proposal.title)).to eq(title) - expect(translated(proposal.body)).to eq(title) - expect(proposal.position).to eq(1) - expect(proposal.participatory_text_level).to eq(ParticipatoryTextSection::LEVELS[:section]) - should_have_expected_states(proposal) - end - end - - context "with titles of deeper levels" do - let(:titles) { (0...5).collect { |idx| "#{idx}-#{::Faker::Book.title}" } } - - before do - titles.each_with_index { |title, idx| items << "#{"#" * (2 + idx)} #{title}\n" } - end - - it "create sub-sections" do - expected_pos = 1 - - proposals = should_parse_and_produce_proposals(5) - - proposals.order(:position).each_with_index do |proposal, idx| - expect(translated(proposal.title)).to eq(titles[idx]) - expect(translated(proposal.body)).to eq(titles[idx]) - expect(proposal.position).to eq(expected_pos) - expected_pos += 1 - expect(proposal.participatory_text_level).to eq("sub-section") - should_have_expected_states(proposal) - end - end - end - end - - describe "paragraphs create articles" do - let(:paragraph) { ::Faker::Lorem.paragraph } - - before do - items << "#{paragraph}\n" - end - - it "produces a proposal like an article" do - should_parse_and_produce_proposals(1) - - proposal = Proposal.last - # proposal titled with its numbering (position) - expect(translated(proposal.title)).to eq("1") - expect(translated(proposal.body)).to eq(paragraph) - expect(proposal.position).to eq(1) - expect(proposal.participatory_text_level).to eq(ParticipatoryTextSection::LEVELS[:article]) - should_have_expected_states(proposal) - end - end - - describe "links are parsed" do - let(:text_w_link) { %[This text links to [Meta Decidim](https://meta.decidim.org "Community's meeting point").] } - - before do - items << "#{text_w_link}\n" - end - - it "contains the link as an html anchor" do - should_parse_and_produce_proposals(1) - - proposal = Proposal.last - # proposal titled with its numbering (position) - # the paragraph and proposal's body - expect(translated(proposal.title)).to eq("1") - paragraph = %q(This text links to Meta Decidim.) - expect(translated(proposal.body)).to eq(paragraph) - expect(proposal.position).to eq(1) - expect(proposal.participatory_text_level).to eq(ParticipatoryTextSection::LEVELS[:article]) - should_have_expected_states(proposal) - end - end - - describe "images are parsed" do - let(:image) { %{Text with ![Important image for Decidim](https://meta.decidim.org/assets/decidim/decidim-logo-1f39092fb3e41d23936dc8aeadd054e2119807dccf3c395de88637e4187f0a3f.svg "Img title").} } - - before do - items << "#{image}\n" - end - - it "contains the image as an html img tag" do - should_parse_and_produce_proposals(1) - - proposal = Proposal.last - expect(translated(proposal.title)).to eq("1") - paragraph = 'Text with Important image for Decidim.' - expect(translated(proposal.body)).to eq(paragraph) - expect(proposal.position).to eq(1) - expect(proposal.participatory_text_level).to eq(ParticipatoryTextSection::LEVELS[:article]) - should_have_expected_states(proposal) - end - end - - describe "formats are parsed" do - let(:paragraph) do - <<~EOPARAGRAPH - **bold text** is supported, *italics text* is supported, __underlined text__ is supported. - As explained [here](https://daringfireball.net/projects/markdown/syntax#em) Markdown treats asterisks - and underscores as indicators of emphasis. - Text wrapped with one asterisk or underscore will be wrapped with an HTML <em> tag; double asterisks or underscores will be wrapped with an HTML <strong> tag. E.g., this input: - - *single asterisks* - - _single underscores_ - - **double asterisks** - - __double underscores__ - Will produce this oputput: - - <em>single asterisks</em> - - <u>single underscores</u> - - <strong>double asterisks</strong> - - <strong>double underscores</strong> - EOPARAGRAPH - end - - before do - items << "#{paragraph}\n" - end - - it "transforms formated texts to html tags" do - should_parse_and_produce_proposals(1) - - proposal = Proposal.last - expect(translated(proposal.title)).to eq("1") - paragraph = <<~EOEXPECTED - bold text is supported, italics text is supported, underlined text is supported. - As explained here Markdown treats asterisks - and underscores as indicators of emphasis. - Text wrapped with one asterisk or underscore will be wrapped with an HTML <em> tag; double asterisks or underscores will be wrapped with an HTML <strong> tag. E.g., this input: - - single asterisks - - single underscores - - double asterisks - - double underscores - Will produce this oputput: - - <em>single asterisks</em> - - <u>single underscores</u> - - <strong>double asterisks</strong> - - <strong>double underscores</strong> - EOEXPECTED - expect(translated(proposal.body)).to eq(paragraph.strip) - expect(proposal.position).to eq(1) - expect(proposal.participatory_text_level).to eq(ParticipatoryTextSection::LEVELS[:article]) - should_have_expected_states(proposal) - end - end - - describe "lists as a whole" do - context "when unordered" do - let(:list) do - <<~EOLIST - - one - - two - - three - EOLIST - end - - before do - items << "#{list}\n" - end - - it "are articles" do - should_parse_and_produce_proposals(1) - proposal_should_conform(:article, "1", list) - end - end - - context "when ordered" do - let(:list) do - <<~EOLIST - 1. one - 2. two - 3. three - EOLIST - end - - before do - items << "#{list}\n" - end - - it "are articles" do - should_parse_and_produce_proposals(1) - proposal_should_conform(:article, "1", list) - end - end - end - end - end -end diff --git a/spec/proposals/lib/decidim/proposals/odt_to_markdown_spec.rb b/spec/proposals/lib/decidim/proposals/odt_to_markdown_spec.rb deleted file mode 100644 index 0cfa634..0000000 --- a/spec/proposals/lib/decidim/proposals/odt_to_markdown_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe OdtToMarkdown do - context "when libreoffice odt file" do - it "transforms into markdown" do - file = IO.read(Decidim::Dev.asset("participatory_text.odt")) - transformer = DocToMarkdown.new(file, DocToMarkdown::ODT_MIME_TYPE) - - expected = IO.read(Decidim::Dev.asset("participatory_text.md")) - expected.strip! - # doc2text does not support ordered lists use - instead - expected.gsub!(/^\d\. /, "- ") - # doc2text can not embed images, instead leaves the title, expect this - expected.gsub!(/^![^\n]+\n/, "Decidim Logo\n") - - actual = transformer.to_md - actual.strip! - # doc2text use '*' for lists, use '-' as expected - actual.gsub!(/^\* /, "- ") - # doc2text leaves a lot off blank lines, compact them - actual.gsub!(/\n{3,}/, "\n\n") - - expect(actual).to eq(expected) - end - end - end - end -end diff --git a/spec/proposals/lib/tasks/main_spec.rb b/spec/proposals/lib/tasks/main_spec.rb deleted file mode 100644 index f8f284e..0000000 --- a/spec/proposals/lib/tasks/main_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Task loading" do - include_examples "decidim module task loading", "decidim_proposals" -end diff --git a/spec/proposals/models/decidim/proposals/collaborative_draft_spec.rb b/spec/proposals/models/decidim/proposals/collaborative_draft_spec.rb deleted file mode 100644 index 70cfc7a..0000000 --- a/spec/proposals/models/decidim/proposals/collaborative_draft_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe CollaborativeDraft do - subject { collaborative_draft } - - let(:organization) { component.participatory_space.organization } - let(:component) { create :extended_proposal_component } - let(:collaborative_draft) { create(:collaborative_draft, component: component) } - let(:coauthorable) { collaborative_draft } - - include_examples "coauthorable" - include_examples "has scope" - include_examples "has category" - include_examples "resourceable" - - it { is_expected.to be_valid } - it { is_expected.to be_versioned } - - describe "#users_to_notify_on_comment_created" do - let!(:follows) { create_list(:follow, 3, followable: subject) } - let(:followers) { follows.map(&:user) } - let(:participatory_space) { subject.component.participatory_space } - let(:organization) { participatory_space.organization } - let!(:participatory_process_admin) do - create(:process_admin, participatory_process: participatory_space) - end - - it "returns the followers" do - expect(subject.users_to_notify_on_comment_created).to match_array(followers.push(collaborative_draft.creator_author)) - end - end - - describe "#editable_by?" do - let(:author) { create(:user, organization: organization) } - - context "when user is author" do - let(:collaborative_draft) do - cd = create :collaborative_draft, component: component, updated_at: Time.current - Decidim::Coauthorship.create(author: author, coauthorable: cd) - cd - end - - it { is_expected.to be_editable_by(author) } - end - - context "when created from user group and user is admin" do - let(:user_group) { create :user_group, :verified, users: [author], organization: author.organization } - let(:collaborative_draft) do - cd = create :collaborative_draft, component: component, updated_at: Time.current - Decidim::Coauthorship.create(author: author, decidim_user_group_id: user_group.id, coauthorable: cd) - cd - end - - it { is_expected.to be_editable_by(author) } - end - - context "when user is not the author" do - let(:collaborative_draft) { create :collaborative_draft, component: component, updated_at: Time.current } - - it { is_expected.not_to be_editable_by(author) } - end - end - end - end -end diff --git a/spec/proposals/models/decidim/proposals/proposal_note_spec.rb b/spec/proposals/models/decidim/proposals/proposal_note_spec.rb deleted file mode 100644 index 325c7e7..0000000 --- a/spec/proposals/models/decidim/proposals/proposal_note_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe ProposalNote do - subject { proposal_note } - - let!(:organization) { create(:organization) } - let!(:component) { create(:component, organization: organization, manifest_name: "proposals") } - let!(:participatory_process) { create(:participatory_process, organization: organization) } - let!(:author) { create(:user, :admin, organization: organization) } - let!(:proposal) { create(:extended_proposal, component: component, users: [author]) } - let!(:proposal_note) { build(:proposal_note, proposal: proposal, author: author) } - - it { is_expected.to be_valid } - it { is_expected.to be_versioned } - - it "has an associated author" do - expect(proposal_note.author).to be_a(Decidim::User) - end - - it "has an associated proposal" do - expect(proposal_note.proposal).to be_a(Decidim::Proposals::Proposal) - end - end - end -end diff --git a/spec/proposals/permissions/decidim/proposals/permissions_spec.rb b/spec/proposals/permissions/decidim/proposals/permissions_spec.rb index 6649529..8749e13 100644 --- a/spec/proposals/permissions/decidim/proposals/permissions_spec.rb +++ b/spec/proposals/permissions/decidim/proposals/permissions_spec.rb @@ -14,7 +14,7 @@ component_settings: component_settings } end - let(:extended_proposal_component) { create :extended_proposal_component } + let(:proposal_component) { create :extended_proposal_component } let(:proposal) { create :proposal, component: proposal_component } let(:component_settings) do double(vote_limit: 2) diff --git a/spec/proposals/presenters/decidim/proposals/admin_log/proposal_presenter_spec.rb b/spec/proposals/presenters/decidim/proposals/admin_log/proposal_presenter_spec.rb deleted file mode 100644 index 2b08649..0000000 --- a/spec/proposals/presenters/decidim/proposals/admin_log/proposal_presenter_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::AdminLog::ProposalPresenter, type: :helper do - include_examples "present admin log entry" do - let(:participatory_space) { create(:participatory_process, organization: organization) } - let(:component) { create(:extended_proposal_component, participatory_space: participatory_space) } - let(:admin_log_resource) { create(:extended_proposal, component: component) } - let(:action) { "answer" } - end -end diff --git a/spec/proposals/presenters/decidim/proposals/admin_log/valuation_assignment_presenter_spec.rb b/spec/proposals/presenters/decidim/proposals/admin_log/valuation_assignment_presenter_spec.rb deleted file mode 100644 index 225dd0b..0000000 --- a/spec/proposals/presenters/decidim/proposals/admin_log/valuation_assignment_presenter_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::AdminLog::ValuationAssignmentPresenter, type: :helper do - include_examples "present admin log entry" do - let(:participatory_space) { create(:participatory_process, organization: organization) } - let(:component) { create(:extended_proposal_component, participatory_space: participatory_space) } - let(:proposal) { create(:extended_proposal, component: component) } - let(:admin_log_resource) { create(:valuation_assignment, proposal: proposal) } - let(:action) { "delete" } - end -end diff --git a/spec/proposals/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter_spec.rb b/spec/proposals/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter_spec.rb deleted file mode 100644 index 8e51d26..0000000 --- a/spec/proposals/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::AdminLog::ValueTypes::ProposalTitleBodyPresenter do - subject { described_class.new(value, _helpers) } - - let(:value) do - { - "en" => "My value", - "es" => "My title in Spanish" - } - end - let(:_helpers) { nil } - - describe "#present" do - it "handles i18n fields" do - expect(subject.present).to eq "My value" - end - end -end diff --git a/spec/proposals/presenters/decidim/proposals/collaborative_draft_presenter_spec.rb b/spec/proposals/presenters/decidim/proposals/collaborative_draft_presenter_spec.rb deleted file mode 100644 index aba99b6..0000000 --- a/spec/proposals/presenters/decidim/proposals/collaborative_draft_presenter_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe CollaborativeDraftPresenter, type: :helper do - subject { described_class.new(collaborative_draft) } - - let(:collaborative_draft) { build(:collaborative_draft, body: content) } - - describe "when content contains urls" do - let(:content) { <<~EOCONTENT } - Content with URLs of anchor type and text urls like https://decidim.org. - And a malicous click me - EOCONTENT - let(:result) { <<~EORESULT } - Content with URLs of anchor type and text urls like https://decidim.org. - And a malicous click me - EORESULT - - it "converts all URLs to links and strips attributes in anchors" do - expect(subject.body(links: true, strip_tags: true)).to eq(result) - end - end - end - end -end diff --git a/spec/proposals/presenters/decidim/proposals/log/resource_presenter_spec.rb b/spec/proposals/presenters/decidim/proposals/log/resource_presenter_spec.rb deleted file mode 100644 index 79948a6..0000000 --- a/spec/proposals/presenters/decidim/proposals/log/resource_presenter_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::Log::ResourcePresenter, type: :helper do - let(:presenter) { described_class.new(resource, helper, extra) } - let(:resource) { create(:extended_proposal, title: Faker::Book.unique.title) } - let(:extra) do - { - "title" => Faker::Book.unique.title - } - end - let(:resource_path) { Decidim::ResourceLocatorPresenter.new(resource).path } - - before do - helper.extend(Decidim::ApplicationHelper) - helper.extend(Decidim::TranslationsHelper) - end - - context "when the resource exists" do - it "links to its public page with the name of the proposal" do - html = presenter.present - expect(html).to have_link(translated(resource.title), href: resource_path) - end - end - - context "when the resource doesn't exist" do - let(:resource) { nil } - let(:extra) do - { - "title" => "My title" - } - end - - it "doesn't link to its public page but renders its name" do - expect(presenter.present).not_to have_link("My title") - end - end -end diff --git a/spec/proposals/queries/decidim/proposals/filtered_proposals_spec.rb b/spec/proposals/queries/decidim/proposals/filtered_proposals_spec.rb deleted file mode 100644 index 0c74407..0000000 --- a/spec/proposals/queries/decidim/proposals/filtered_proposals_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::FilteredProposals do - let(:organization) { create(:organization) } - let(:participatory_process) { create(:participatory_process, organization: organization) } - let(:component) { create(:extended_proposal_component, participatory_space: participatory_process) } - let(:another_component) { create(:extended_proposal_component, participatory_space: participatory_process) } - - let(:proposals) { create_list(:extended_proposal, 3, component: component) } - let(:old_proposals) { create_list(:extended_proposal, 3, component: component, created_at: 10.days.ago) } - let(:another_proposals) { create_list(:extended_proposal, 3, component: another_component) } - - it "returns proposals included in a collection of components" do - expect(described_class.for([component, another_component])).to match_array proposals.concat(old_proposals, another_proposals) - end - - it "returns proposals created in a date range" do - expect(described_class.for([component, another_component], 2.weeks.ago, 1.week.ago)).to match_array old_proposals - end -end diff --git a/spec/proposals/queries/decidim/proposals/metrics/endorsements_metric_manage_spec.rb b/spec/proposals/queries/decidim/proposals/metrics/endorsements_metric_manage_spec.rb deleted file mode 100644 index abdb3df..0000000 --- a/spec/proposals/queries/decidim/proposals/metrics/endorsements_metric_manage_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::Metrics::EndorsementsMetricManage do - let(:organization) { create(:organization) } - let(:participatory_space) { create(:participatory_process, :with_steps, organization: organization) } - let(:component) { create(:extended_proposal_component, :published, participatory_space: participatory_space) } - let(:proposal) { create(:extended_proposal, component: component) } - let(:day) { Time.zone.today - 1.day } - let!(:endorsements) do - 5.times.collect do - create(:endorsement, resource: proposal, created_at: day, author: build(:user, organization: proposal.organization)) - end - end - let!(:old_endorsements) do - 5.times.collect do - create(:endorsement, resource: proposal, created_at: (day - 1.week), author: build(:user, organization: proposal.organization)) - end - end - - include_context "when managing metrics" - - context "when executing" do - it "creates new metric records" do - registry = generate_metric_registry - - expect(registry.collect(&:day)).to eq([day]) - expect(registry.collect(&:cumulative)).to eq([10]) - expect(registry.collect(&:quantity)).to eq([5]) - end - - it "does not create any record if there is no data" do - registry = generate_metric_registry("2017-01-01") - - expect(Decidim::Metric.count).to eq(0) - expect(registry).to be_empty - end - - it "updates metric records" do - create(:metric, metric_type: "endorsements", day: day, cumulative: 1, quantity: 1, organization: organization, category: nil, participatory_space: participatory_space, related_object: proposal) - registry = generate_metric_registry - - expect(Decidim::Metric.count).to eq(1) - expect(registry.collect(&:cumulative)).to eq([10]) - expect(registry.collect(&:quantity)).to eq([5]) - end - end -end diff --git a/spec/proposals/queries/decidim/proposals/metrics/proposal_followers_metric_measure_spec.rb b/spec/proposals/queries/decidim/proposals/metrics/proposal_followers_metric_measure_spec.rb deleted file mode 100644 index 1393e50..0000000 --- a/spec/proposals/queries/decidim/proposals/metrics/proposal_followers_metric_measure_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::Metrics::ProposalFollowersMetricMeasure do - let(:day) { Time.zone.yesterday } - let(:organization) { create(:organization) } - let(:not_valid_resource) { create(:dummy_resource) } - let(:participatory_space) { create(:participatory_process, :with_steps, organization: organization) } - let(:proposals_component) { create(:extended_proposal_component, :published, participatory_space: participatory_space) } - let(:proposal) { create(:extended_proposal, :with_endorsements, published_at: day, component: proposals_component) } - let(:draft) { create(:collaborative_draft, published_at: day, component: proposals_component) } - let!(:follows) do - create_list(:follow, 10, followable: proposal, created_at: day) - create_list(:follow, 10, followable: draft, created_at: day) - create_list(:follow, 10, followable: proposal, created_at: day - 1.week) - end - - context "when executing class" do - it "fails to create object with an invalid resource" do - manager = described_class.new(day, not_valid_resource) - - expect(manager).not_to be_valid - end - - it "calculates" do - result = described_class.new(day, proposals_component).calculate - - expect(result[:cumulative_users].count).to eq(30) - expect(result[:quantity_users].count).to eq(20) - end - - it "does not found any result for past days" do - result = described_class.new(day - 1.month, proposals_component).calculate - - expect(result[:cumulative_users].count).to eq(0) - expect(result[:quantity_users].count).to eq(0) - end - end -end diff --git a/spec/proposals/queries/decidim/proposals/similar_proposals_spec.rb b/spec/proposals/queries/decidim/proposals/similar_proposals_spec.rb deleted file mode 100644 index 30c5b73..0000000 --- a/spec/proposals/queries/decidim/proposals/similar_proposals_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe Decidim::Proposals::SimilarProposals do - let(:organization) { create(:organization, enable_machine_translations: enabled) } - let(:participatory_process) { create(:participatory_process, organization: organization) } - let(:component) { create(:extended_proposal_component, participatory_space: participatory_process) } - - let!(:proposal) { create(:extended_proposal, component: component, body: proposal_body, title: proposal_title) } - let!(:matching_proposal) { create(:extended_proposal, component: component, body: matching_body, title: matching_title) } - let!(:missed_proposal) { create(:extended_proposal, component: component, body: missing_body, title: missing_title) } - - context "when machine_translations is disabled" do - let(:enabled) { false } - let(:proposal_body) { "100% match for body" } - let(:proposal_title) { "100% match for title" } - let(:matching_body) { proposal_body } - let(:matching_title) { proposal_title } - let(:missing_body) { "Some Random body" } - let(:missing_title) { "Some random title" } - - it "finds the similar proposal" do - Decidim::Proposals.similarity_threshold = 0.85 - expect(described_class.for([component], proposal).map(&:id).sort).to eq([proposal.id, matching_proposal.id]) - end - - it "counts just the available proposals" do - Decidim::Proposals.similarity_threshold = 0.85 - expect(described_class.for([component], proposal).size).to eq(2) - end - end - - context "when machine_translations is disabled" do - let(:enabled) { true } - let(:proposal_body) { { "en": "100% match for body" } } - let(:proposal_title) { { "en": "100% match for title" } } - let(:matching_body) { missing_body.merge({ machine_translations: proposal_body }) } - let(:matching_title) { missing_title.merge({ machine_translations: proposal_title }) } - let(:missing_body) { { "ro": "Some Random body" } } - let(:missing_title) { { "ro": "Some random title" } } - - it "finds the similar proposal" do - Decidim::Proposals.similarity_threshold = 0.85 - I18n.with_locale(:en) do - expect(described_class.for([component], proposal).map(&:id).sort).to eq([proposal.id, matching_proposal.id]) - end - end - - it "counts just the available proposals" do - Decidim::Proposals.similarity_threshold = 0.85 - I18n.with_locale(:en) do - expect(described_class.for([component], proposal).size).to eq(2) - end - end - end -end diff --git a/spec/proposals/services/decidim/proposals/collaborative_draft_search_spec.rb b/spec/proposals/services/decidim/proposals/collaborative_draft_search_spec.rb deleted file mode 100644 index 860c2ce..0000000 --- a/spec/proposals/services/decidim/proposals/collaborative_draft_search_spec.rb +++ /dev/null @@ -1,114 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module Proposals - describe CollaborativeDraftSearch do - subject { described_class.new(params).results } - - let(:component) { create(:component, manifest_name: "proposals") } - let(:default_params) { { component: component, user: user } } - let(:params) { default_params } - let(:participatory_process) { component.participatory_space } - let(:user) { create(:user, organization: component.organization) } - - it_behaves_like "a resource search", :collaborative_draft - it_behaves_like "a resource search with scopes", :collaborative_draft - it_behaves_like "a resource search with categories", :collaborative_draft - - describe "results" do - let!(:collaborative_draft) { create(:collaborative_draft, component: component) } - - describe "search_text filter" do - let(:params) { default_params.merge(search_text: search_text) } - let(:search_text) { "giraffe" } - - it "returns the drafts containing the search in the title or the body" do - create_list(:collaborative_draft, 3, component: component) - create(:collaborative_draft, title: { en: "A giraffe" }, component: component) - create(:collaborative_draft, body: { en: "There is a giraffe in the office" }, component: component) - - expect(subject.size).to eq(2) - end - end - - describe "state filter" do - let(:params) { default_params.merge(state: states) } - - context "when filtering open collaborative_drafts" do - let(:states) { %w(open) } - - it "returns only open collaborative_drafts" do - open_drafts = create_list(:collaborative_draft, 3, :open, component: component) - create_list(:collaborative_draft, 2, :published, component: component) - - expect(subject.size).to eq(4) - expect(subject).to match_array([collaborative_draft] + open_drafts) - end - end - - context "when filtering withdrawn collaborative_drafts" do - let(:states) { %w(withdrawn) } - - it "returns only withdrawn collaborative_drafts" do - create_list(:collaborative_draft, 3, component: component) - withdrawn_drafts = create_list(:collaborative_draft, 3, :withdrawn, component: component) - - expect(subject.size).to eq(3) - expect(subject).to match_array(withdrawn_drafts) - end - end - - context "when filtering published collaborative_drafts" do - let(:states) { %w(published) } - - it "returns only published collaborative_drafts" do - create_list(:collaborative_draft, 3, component: component) - published_drafts = create_list(:collaborative_draft, 3, :published, component: component) - - expect(subject.size).to eq(3) - expect(subject).to match_array(published_drafts) - end - end - end - - describe "related_to filter" do - let(:params) { default_params.merge(related_to: related_to) } - - context "when filtering by related to meetings" do - let(:related_to) { "Decidim::Meetings::Meeting".underscore } - let(:meetings_component) { create(:component, manifest_name: "meetings", participatory_space: participatory_process) } - let(:meeting) { create :meeting, component: meetings_component } - - it "returns only collaborative_drafts related to meetings" do - related_draft = create(:collaborative_draft, component: component) - related_draft2 = create(:collaborative_draft, component: component) - create_list(:collaborative_draft, 3, component: component) - meeting.link_resources([related_draft], "drafts_from_meeting") - related_draft2.link_resources([meeting], "drafts_from_meeting") - - expect(subject).to match_array([related_draft, related_draft2]) - end - end - - context "when filtering by related to resources" do - let(:related_to) { "Decidim::DummyResources::DummyResource".underscore } - let(:dummy_component) { create(:component, manifest_name: "dummy", participatory_space: participatory_process) } - let(:dummy_resource) { create :dummy_resource, component: dummy_component } - - it "returns only collaborative_drafts related to results" do - related_draft = create(:collaborative_draft, component: component) - related_draft2 = create(:collaborative_draft, component: component) - create_list(:collaborative_draft, 3, component: component) - dummy_resource.link_resources([related_draft], "included_collaborative_drafts") - related_draft2.link_resources([dummy_resource], "included_collaborative_drafts") - - expect(subject).to match_array([related_draft, related_draft2]) - end - end - end - end - end - end -end diff --git a/spec/proposals/services/decidim/proposals/proposal_search_spec.rb b/spec/proposals/services/decidim/proposals/proposal_search_spec.rb index b3a9128..197de7f 100644 --- a/spec/proposals/services/decidim/proposals/proposal_search_spec.rb +++ b/spec/proposals/services/decidim/proposals/proposal_search_spec.rb @@ -7,7 +7,7 @@ module Proposals describe ProposalSearch do subject { described_class.new(params).results } - let(:component) { create(:component, manifest_name: "proposals") } + let(:component) { create(:extended_proposal_component) } let(:default_params) { { component: component, user: user } } let(:params) { default_params } let(:participatory_process) { component.participatory_space } diff --git a/spec/proposals/services/decidim/proposals/searchable_proposal_resource_spec.rb b/spec/proposals/services/decidim/proposals/searchable_proposal_resource_spec.rb deleted file mode 100644 index 0925197..0000000 --- a/spec/proposals/services/decidim/proposals/searchable_proposal_resource_spec.rb +++ /dev/null @@ -1,180 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - describe Search do - subject { described_class.new(params) } - - include_context "when a resource is ready for global search" - - let(:participatory_space) { create(:participatory_process, :published, :with_steps, organization: organization) } - let(:current_component) { create :extended_proposal_component, organization: organization, participatory_space: participatory_space } - let!(:proposal) do - create( - :proposal, - :draft, - skip_injection: true, - component: current_component, - scope: scope1, - body: description_1, - users: [author] - ) - end - - describe "Indexing of proposals" do - context "when implementing Searchable" do - context "when on create" do - context "when proposals are NOT official" do - let(:proposal2) do - create(:extended_proposal, skip_injection: true, component: current_component) - end - - it "does not index a SearchableResource after Proposal creation when it is not official" do - searchables = SearchableResource.where(resource_type: proposal.class.name, resource_id: [proposal.id, proposal2.id]) - expect(searchables).to be_empty - end - end - - context "when proposals ARE official" do - let(:author) { organization } - - before do - proposal.update(published_at: Time.current) - end - - it "does indexes a SearchableResource after Proposal creation when it is official" do - organization.available_locales.each do |locale| - searchable = SearchableResource.find_by(resource_type: proposal.class.name, resource_id: proposal.id, locale: locale) - expect_searchable_resource_to_correspond_to_proposal(searchable, proposal, locale) - end - end - end - end - - context "when on update" do - context "when it is NOT published" do - it "does not index a SearchableResource when Proposal changes but is not published" do - searchables = SearchableResource.where(resource_type: proposal.class.name, resource_id: proposal.id) - expect(searchables).to be_empty - end - end - - context "when it IS published" do - before do - proposal.update published_at: Time.current - end - - it "inserts a SearchableResource after Proposal is published" do - organization.available_locales.each do |locale| - searchable = SearchableResource.find_by(resource_type: proposal.class.name, resource_id: proposal.id, locale: locale) - expect_searchable_resource_to_correspond_to_proposal(searchable, proposal, locale) - end - end - - it "updates the associated SearchableResource after published Proposal update" do - searchable = SearchableResource.find_by(resource_type: proposal.class.name, resource_id: proposal.id) - created_at = searchable.created_at - updated_title = { "en" => "Brand new title", "machine_translations" => {} } - proposal.update(title: updated_title) - - proposal.save! - searchable.reload - - organization.available_locales.each do |locale| - searchable = SearchableResource.find_by(resource_type: proposal.class.name, resource_id: proposal.id, locale: locale) - expect(searchable.content_a).to eq updated_title[locale.to_s].to_s - expect(searchable.updated_at).to be > created_at - end - end - - it "removes the associated SearchableResource after unpublishing a published Proposal on update" do - proposal.update(published_at: nil) - - searchables = SearchableResource.where(resource_type: proposal.class.name, resource_id: proposal.id) - expect(searchables).to be_empty - end - end - end - - context "when on destroy" do - it "destroys the associated SearchableResource after Proposal destroy" do - proposal.destroy - - searchables = SearchableResource.where(resource_type: proposal.class.name, resource_id: proposal.id) - - expect(searchables.any?).to be false - end - end - end - end - - describe "Search" do - context "when searching by Proposal resource_type" do - let!(:proposal2) do - create( - :proposal, - component: current_component, - scope: scope1, - title: Decidim::Faker.name, - body: "Chewie, I'll be waiting for your signal. Take care, you two. May the Force be with you. Ow!" - ) - end - - before do - proposal.update(published_at: Time.current) - proposal2.update(published_at: Time.current) - end - - it "returns Proposal results" do - Decidim::Search.call("Ow", organization, resource_type: proposal.class.name) do - on(:ok) do |results_by_type| - results = results_by_type[proposal.class.name] - expect(results[:count]).to eq 2 - expect(results[:results]).to match_array [proposal, proposal2] - end - on(:invalid) { raise("Should not happen") } - end - end - - it "allows searching by prefix characters" do - Decidim::Search.call("wait", organization, resource_type: proposal.class.name) do - on(:ok) do |results_by_type| - results = results_by_type[proposal.class.name] - expect(results[:count]).to eq 1 - expect(results[:results]).to eq [proposal2] - end - on(:invalid) { raise("Should not happen") } - end - end - end - end - - private - - def expect_searchable_resource_to_correspond_to_proposal(searchable, proposal, locale) - attrs = searchable.attributes.clone - attrs.delete("id") - attrs.delete("created_at") - attrs.delete("updated_at") - expect(attrs.delete("datetime").to_s(:short)).to eq(proposal.published_at.to_s(:short)) - expect(attrs).to eq(expected_searchable_resource_attrs(proposal, locale)) - end - - def expected_searchable_resource_attrs(proposal, locale) - { - "content_a" => I18n.transliterate(translated(proposal.title, locale: locale)), - "content_b" => "", - "content_c" => "", - "content_d" => I18n.transliterate(translated(proposal.body, locale: locale)), - "locale" => locale, - "decidim_organization_id" => proposal.component.organization.id, - "decidim_participatory_space_id" => current_component.participatory_space_id, - "decidim_participatory_space_type" => current_component.participatory_space_type, - "decidim_scope_id" => proposal.decidim_scope_id, - "resource_id" => proposal.id, - "resource_type" => "Decidim::Proposals::Proposal" - } - end - end -end diff --git a/spec/proposals/types/proposal_input_filter_spec.rb b/spec/proposals/types/proposal_input_filter_spec.rb deleted file mode 100644 index 94a267c..0000000 --- a/spec/proposals/types/proposal_input_filter_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/api/test/type_context" -require "decidim/core/test" -require "decidim/core/test/shared_examples/input_filter_examples" - -module Decidim - module Proposals - describe ProposalInputFilter, type: :graphql do - include_context "with a graphql class type" - let(:type_class) { Decidim::Proposals::ProposalsType } - - let(:model) { create(:extended_proposal_component) } - let!(:models) { create_list(:extended_proposal, 3, :published, component: model) } - - context "when filtered by published_at" do - include_examples "connection has before/since input filter", "proposals", "published" - end - end - end -end diff --git a/spec/proposals/types/proposals_type_spec.rb b/spec/proposals/types/proposals_type_spec.rb deleted file mode 100644 index 7e9e812..0000000 --- a/spec/proposals/types/proposals_type_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/api/test/type_context" -require "decidim/core/test" - -module Decidim - module Proposals - describe ProposalsType, type: :graphql do - include_context "with a graphql class type" - let(:model) { create(:extended_proposal_component) } - - it_behaves_like "a component query type" - - describe "proposals" do - let!(:draft_proposals) { create_list(:extended_proposal, 2, :draft, component: model) } - let!(:published_proposals) { create_list(:extended_proposal, 2, component: model) } - let!(:other_proposals) { create_list(:extended_proposal, 2) } - - let(:query) { "{ proposals { edges { node { id } } } }" } - - it "returns the published proposals" do - ids = response["proposals"]["edges"].map { |edge| edge["node"]["id"] } - # We expect the default order to be ascending by ID, so the array - # needs to match exactly the ordered IDs array. - expect(ids).to eq(published_proposals.map(&:id).sort.map(&:to_s)) - expect(ids).not_to include(*draft_proposals.map(&:id).map(&:to_s)) - expect(ids).not_to include(*other_proposals.map(&:id).map(&:to_s)) - end - - context "when querying proposals with categories" do - let(:category) { create(:category, participatory_space: model.participatory_space) } - let!(:proposal_with_category) { create(:extended_proposal, component: model, category: category) } - let(:all_proposals) { published_proposals + [proposal_with_category] } - - let(:query) { "{ proposals { edges { node { id, category { id } } } } }" } - - it "return proposals with and without categories" do - ids = response["proposals"]["edges"].map { |edge| edge["node"]["id"] } - expect(ids.count).to eq(3) - expect(ids).to eq(all_proposals.map(&:id).sort.map(&:to_s)) - end - end - end - - describe "proposal" do - let(:query) { "query Proposal($id: ID!){ proposal(id: $id) { id } }" } - let(:variables) { { id: proposal.id.to_s } } - - context "when the proposal belongs to the component" do - let!(:proposal) { create(:extended_proposal, component: model) } - - it "finds the proposal" do - expect(response["proposal"]["id"]).to eq(proposal.id.to_s) - end - end - - context "when the proposal doesn't belong to the component" do - let!(:proposal) { create(:extended_proposal, component: create(:extended_proposal_component)) } - - it "returns null" do - expect(response["proposal"]).to be_nil - end - end - - context "when the proposal is not published" do - let!(:proposal) { create(:extended_proposal, :draft, component: model) } - - it "returns null" do - expect(response["proposal"]).to be_nil - end - end - end - end - end -end diff --git a/spec/proposals/validators/proposal_length_validator_spec.rb b/spec/proposals/validators/proposal_length_validator_spec.rb deleted file mode 100644 index 96a1b53..0000000 --- a/spec/proposals/validators/proposal_length_validator_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe ProposalLengthValidator do - subject { validatable.new(body: body) } - - let(:validatable) do - Class.new do - def self.model_name - ActiveModel::Name.new(self, nil, "Validatable") - end - - include Virtus.model - include ActiveModel::Validations - - attribute :body - - validates :body, proposal_length: { - minimum: 15, - maximum: ->(_record) { 100 } - } - end - end - - context "when the text is too short" do - let(:body) { "Lorem ipsum d" } - - it { is_expected.to be_invalid } - end - - context "when the text is too long" do - let(:body) { "a" * 101 } - - it { is_expected.to be_invalid } - end - - context "when the text is written in HTML" do - let(:body) do - data = File.read(Decidim::Dev.asset("avatar.jpg")) - encoded = Base64.encode64(data) - - <<~HTML -

Text before the image.

-

-

Some other text after the image.

- HTML - end - - it { is_expected.to be_valid } - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3ff74bd..c07dbbb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,12 @@ /railties/, /omniauth/, /puma/, - /rack/ + /rack/, + /cells/, + /bundler/, + /tilt/, + /warden/, + /rspec-expectations/, + /rspec-core/ ] end