Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport 'Do not import resources multiple times' to v0.27 #9943

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -84,7 +84,10 @@ def origin_component
end

def proposal_already_copied?(original_proposal)
original_proposal.linked_resources(:projects, "included_proposals").any? do |project|
# Note: we are including also projects from unpublished components
# because otherwise duplicates could be created until the component is
# published.
original_proposal.linked_resources(:projects, "included_proposals", component_published: false).any? do |project|
project.budget == form.budget
end
end
Expand Down
Expand Up @@ -96,6 +96,22 @@ module Admin
expect(first_project.title).to eq(proposal.title)
expect(last_project.title).to eq(second_proposal.title)
end

context "and the current component was not published" do
before { current_component.unpublish! }

it "doesn't import it again" do
expect do
command.call
end.to change { Project.where(budget: budget).count }.by(1)

projects = Project.where(budget: budget)
first_project = projects.first
last_project = projects.last
expect(first_project.title).to eq(proposal.title)
expect(last_project.title).to eq(second_proposal.title)
end
end
end

it "links the proposals" do
Expand Down
9 changes: 5 additions & 4 deletions decidim-core/lib/decidim/resourceable.rb
Expand Up @@ -36,8 +36,8 @@ module Resourceable
# link_name - The String name of the link between this model and the target resource.
#
# Returns an ActiveRecord::Relation.
def linked_resources(resource_name, link_name)
scope = sibling_scope(resource_name)
def linked_resources(resource_name, link_name, component_published: true)
scope = sibling_scope(resource_name, component_published: component_published)

from = scope
.joins(:resource_links_from)
Expand All @@ -56,14 +56,15 @@ def linked_resources(resource_name, link_name)
# resource_name - The String name of the resource manifest exposed by a component.
#
# Returns an ActiveRecord::Relation.
def sibling_scope(resource_name)
def sibling_scope(resource_name, component_published: true)
manifest = Decidim.find_resource_manifest(resource_name)
return self.class.none unless manifest

scope = manifest.resource_scope(component)
scope = scope.where("#{self.class.table_name}.id != ?", id) if manifest.model_class == self.class
scope = scope.not_hidden if manifest.model_class.respond_to?(:not_hidden)
scope.includes(:component).where.not(decidim_components: { published_at: nil })
scope = scope.includes(:component).where.not(decidim_components: { published_at: nil }) if component_published
scope
end

# Links the given resources to this model, replaces any previous links with the same name.
Expand Down
Expand Up @@ -77,7 +77,10 @@ def target_question
end

def proposal_already_copied?(original_proposal)
original_proposal.linked_resources(:answers, "related_proposals").any? do |answer|
# Note: we are including also answers from unpublished components
# because otherwise duplicates could be created until the component is
# published.
original_proposal.linked_resources(:answers, "related_proposals", component_published: false).any? do |answer|
answer.question == target_question
end
end
Expand Down
Expand Up @@ -81,6 +81,22 @@ module Admin
expect(first_answer.title).to eq(proposal.title)
expect(last_answer.title).to eq(proposal.title)
end

context "and the current component was not published" do
before { component.unpublish! }

it "doesn't import it again" do
expect do
command.call
end.not_to(change { Decidim::Elections::Answer.where(question: question).count })

answers = Decidim::Elections::Answer.where(question: question)
first_answer = answers.first
last_answer = answers.last
expect(first_answer.title).to eq(proposal.title)
expect(last_answer.title).to eq(proposal.title)
end
end
end

it "links the proposals" do
Expand Down
Expand Up @@ -76,7 +76,10 @@ def target_component
end

def proposal_already_copied?(original_proposal, target_component)
original_proposal.linked_resources(:proposals, "copied_from_component").any? do |proposal|
# Note: we are including also proposals from unpublished components
# because otherwise duplicates could be created until the component is
# published.
original_proposal.linked_resources(:proposals, "copied_from_component", component_published: false).any? do |proposal|
proposal.component == target_component
end
end
Expand Down
Expand Up @@ -88,6 +88,19 @@ module Admin
titles = Proposal.where(component: current_component).map(&:title)
expect(titles).to match_array([proposal.title, second_proposal.title])
end

context "and the current component was not published" do
before { current_component.unpublish! }

it "doesn't import it again" do
expect do
command.call
end.to change { Proposal.where(component: current_component).count }.by(1)

titles = Proposal.where(component: current_component).map(&:title)
expect(titles).to match_array([proposal.title, second_proposal.title])
end
end
end

it "links the proposals" do
Expand Down