diff --git a/lib/spending_proposals_importer.rb b/lib/spending_proposals_importer.rb new file mode 100644 index 000000000..72a3922b8 --- /dev/null +++ b/lib/spending_proposals_importer.rb @@ -0,0 +1,69 @@ +class SpendingProposalsImporter + + def import(sp) + budget = Budget.last || Budget.create!(name: Date.today.year.to_s, currency_symbol: "€") + + group = nil + heading = nil + + if sp.geozone_id.present? + group = budget.groups.find_or_create_by!(name: "Barrios") + heading = group.headings.find_or_create_by!(name: sp.geozone.name, price: 10000000) + else + group = budget.groups.find_or_create_by!(name: "Toda la ciudad") + heading = group.headings.find_or_create_by!(name: "Toda la ciudad", price: 10000000) + end + + feasibility = case sp.feasible + when FalseClass + 'unfeasible' + when TrueClass + 'feasible' + else + 'undecided' + end + + investment = Budget::Investment.create!( + heading_id: heading.id, + author_id: sp.author_id, + administrator_id: sp.administrator_id, + title: sp.title, + description: sp.description, + external_url: sp.external_url, + price: sp.price, + price_explanation: sp.price_explanation, + internal_comments: sp.internal_comments, + duration: sp.time_scope, + feasibility: feasibility, + unfeasibility_explanation: sp.feasible_explanation, + valuation_finished: sp.valuation_finished, + price_first_year: sp.price_first_year, + cached_votes_up: sp.cached_votes_up, + physical_votes: sp.physical_votes, + created_at: sp.created_at, + updated_at: sp.updated_at, + responsible_name: sp.responsible_name, + terms_of_service: "1" + ) + + investment.valuators = sp.valuation_assignments.map(&:valuator) + + votes = ActsAsVotable::Vote.where(votable_type: 'SpendingProposal', votable_id: sp.id) + + votes.each {|v| investment.vote_by({voter: v.voter, vote: 'yes'}) } + + # Spending proposals are not commentable in Consul so we can not test this + # + # Comment.where(commentable_type: 'SpendingProposal', commentable_id: sp.id).update_all( + # commentable_type: 'Budget::Investment', commentable_id: investment.id + # ) + # Budget::Investment.reset_counters(investment.id, :comments) + + # Spending proposals have ballot_lines in Madrid, but not in consul, so we + # can not test this either + + investment + end + +end + diff --git a/spec/lib/spending_proposals_importer_spec.rb b/spec/lib/spending_proposals_importer_spec.rb new file mode 100644 index 000000000..d8cb50082 --- /dev/null +++ b/spec/lib/spending_proposals_importer_spec.rb @@ -0,0 +1,92 @@ +require 'rails_helper' + +describe SpendingProposalsImporter do + + let(:importer) { SpendingProposalsImporter.new } + + describe '#import' do + + it "Creates the budget if it doesn't exist" do + sp = create(:spending_proposal) + expect { importer.import(sp) }.to change{ Budget.count }.from(0).to(1) + importer.import(create(:spending_proposal)) + expect(Budget.count).to eq(1) + end + + it "Creates the and returns investments" do + inv = nil + sp = create(:spending_proposal) + expect { inv = importer.import(sp) }.to change{ Budget::Investment.count }.from(0).to(1) + expect(inv).to be_kind_of(Budget::Investment) + end + + it "Imports a city spending proposal" do + sp = create(:spending_proposal) + + inv = importer.import(sp) + + expect(inv.author).to eq(sp.author) + expect(inv.title).to eq(sp.title) + expect(inv.heading.name).to eq("Toda la ciudad") + expect(inv.heading.group.name).to eq("Toda la ciudad") + end + + it "Imports a city spending proposal" do + sp = create(:spending_proposal, geozone: create(:geozone, name: "Bel Air")) + + inv = importer.import(sp) + + expect(inv.author).to eq(sp.author) + expect(inv.title).to eq(sp.title) + expect(inv.heading.name).to eq("Bel Air") + expect(inv.heading.group.name).to eq("Barrios") + end + + it "Uses existing budgets, headings and groups instead of creating new ones" do + sp1 = create(:spending_proposal, geozone: create(:geozone, name: "Bel Air")) + sp2 = create(:spending_proposal, geozone: create(:geozone, name: "Bel Air")) + + inv1 = importer.import(sp1) + inv2 = importer.import(sp2) + + expect(inv2.heading).to eq(inv1.heading) + end + + it "Imports feasibility correctly" do + sp = create(:spending_proposal) + feasible = create(:spending_proposal, feasible: true) + unfeasible = create(:spending_proposal, feasible: false) + + expect(importer.import(sp).feasibility).to eq('undecided') + expect(importer.import(feasible).feasibility).to eq('feasible') + expect(importer.import(unfeasible).feasibility).to eq('unfeasible') + end + + it "Imports valuation assignments" do + sp = create(:spending_proposal) + peter = create(:valuator) + john = create(:valuator) + sp.valuators << peter << john + + inv = importer.import(sp) + + expect(inv.valuator_assignments.count).to eq(2) + expect(inv.valuators).to include(peter) + expect(inv.valuators).to include(john) + end + + it "Imports votes" do + sp = create(:spending_proposal) + votes = create_list(:vote, 4, votable: sp) + voters = votes.map(&:voter).sort_by(&:id) + + inv = importer.import(sp) + + expect(inv.total_votes).to eq(sp.total_votes) + + imported_votes = ActsAsVotable::Vote.where(votable_type: "Budget::Investment", votable_id: inv.id) + + expect(imported_votes.map(&:voter).sort_by(&:id)).to eq(voters) + end + end +end