Merged with master and solved conflicts
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Administrator" do
|
||||
describe Abilities::Administrator do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
|
||||
let(:user) { administrator.user }
|
||||
let(:administrator) { create(:administrator) }
|
||||
|
||||
@@ -20,6 +21,9 @@ describe "Abilities::Administrator" do
|
||||
let(:budget_investment_document) { build(:document, documentable: budget_investment) }
|
||||
let(:poll_question_document) { build(:document, documentable: poll_question) }
|
||||
|
||||
let(:proposal_image) { build(:image, imageable: proposal) }
|
||||
let(:budget_investment_image) { build(:image, imageable: budget_investment) }
|
||||
|
||||
let(:hidden_debate) { create(:debate, :hidden) }
|
||||
let(:hidden_comment) { create(:comment, :hidden) }
|
||||
let(:hidden_proposal) { create(:proposal, :hidden) }
|
||||
@@ -69,6 +73,7 @@ describe "Abilities::Administrator" do
|
||||
|
||||
it { should be_able_to(:create, Budget) }
|
||||
it { should be_able_to(:update, Budget) }
|
||||
it { should be_able_to(:read_results, Budget) }
|
||||
|
||||
it { should be_able_to(:create, Budget::ValuatorAssignment) }
|
||||
|
||||
@@ -78,15 +83,11 @@ describe "Abilities::Administrator" do
|
||||
it { should be_able_to(:valuate, create(:budget_investment, budget: create(:budget, phase: 'valuating'))) }
|
||||
it { should be_able_to(:valuate, create(:budget_investment, budget: create(:budget, phase: 'finished'))) }
|
||||
|
||||
it { should be_able_to(:new, proposal_document) }
|
||||
it { should be_able_to(:create, proposal_document) }
|
||||
it { should be_able_to(:destroy, proposal_document) }
|
||||
|
||||
it { should be_able_to(:new, budget_investment_document) }
|
||||
it { should be_able_to(:create, budget_investment_document) }
|
||||
it { should be_able_to(:destroy, budget_investment_document) }
|
||||
|
||||
it { should be_able_to(:new, poll_question_document) }
|
||||
it { should be_able_to(:create, poll_question_document) }
|
||||
it { should be_able_to(:destroy, poll_question_document) }
|
||||
|
||||
it { should be_able_to(:destroy, proposal_image) }
|
||||
it { should be_able_to(:destroy, budget_investment_image) }
|
||||
|
||||
end
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Common" do
|
||||
describe Abilities::Common do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
|
||||
let(:geozone) { create(:geozone) }
|
||||
|
||||
let(:user) { create(:user, geozone: geozone) }
|
||||
@@ -59,6 +60,11 @@ describe "Abilities::Common" do
|
||||
let(:own_budget_investment_document) { build(:document, documentable: own_investment_in_accepting_budget) }
|
||||
let(:budget_investment_document) { build(:document, documentable: investment_in_accepting_budget) }
|
||||
|
||||
let(:own_proposal_image) { build(:image, imageable: own_proposal) }
|
||||
let(:proposal_image) { build(:image, imageable: proposal) }
|
||||
let(:own_budget_investment_image) { build(:image, imageable: own_investment_in_accepting_budget) }
|
||||
let(:budget_investment_image) { build(:image, imageable: investment_in_accepting_budget) }
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should be_able_to(:vote, debate) }
|
||||
@@ -87,25 +93,18 @@ describe "Abilities::Common" do
|
||||
it { should_not be_able_to(:create, DirectMessage) }
|
||||
it { should_not be_able_to(:show, DirectMessage) }
|
||||
|
||||
it { should be_able_to(:new_nested, Document) }
|
||||
it { should be_able_to(:destroy_upload, Document) }
|
||||
|
||||
it { should be_able_to(:new, own_proposal_document) }
|
||||
it { should be_able_to(:create, own_proposal_document) }
|
||||
it { should be_able_to(:destroy, own_proposal_document) }
|
||||
|
||||
it { should_not be_able_to(:new, proposal_document) }
|
||||
it { should_not be_able_to(:create, proposal_document) }
|
||||
it { should_not be_able_to(:destroy, proposal_document) }
|
||||
|
||||
it { should be_able_to(:new, own_budget_investment_document) }
|
||||
it { should be_able_to(:create, own_budget_investment_document) }
|
||||
it { should be_able_to(:destroy, own_budget_investment_document) }
|
||||
|
||||
it { should_not be_able_to(:new, budget_investment_document) }
|
||||
it { should_not be_able_to(:create, budget_investment_document) }
|
||||
it { should_not be_able_to(:destroy, budget_investment_document) }
|
||||
|
||||
it { should be_able_to(:destroy, own_proposal_image) }
|
||||
it { should_not be_able_to(:destroy, proposal_image) }
|
||||
|
||||
it { should be_able_to(:destroy, own_budget_investment_image) }
|
||||
it { should_not be_able_to(:destroy, budget_investment_image) }
|
||||
|
||||
describe 'flagging content' do
|
||||
it { should be_able_to(:flag, debate) }
|
||||
it { should be_able_to(:unflag, debate) }
|
||||
@@ -159,6 +158,7 @@ describe "Abilities::Common" do
|
||||
let(:own_spending_proposal) { create(:spending_proposal, author: user) }
|
||||
|
||||
let(:own_direct_message) { create(:direct_message, sender: user) }
|
||||
|
||||
before{ user.update(residence_verified_at: Time.current, confirmed_phone: "1") }
|
||||
|
||||
describe "Proposal" do
|
||||
@@ -197,7 +197,7 @@ describe "Abilities::Common" do
|
||||
it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone) }
|
||||
|
||||
context "without geozone" do
|
||||
before(:each) { user.geozone = nil }
|
||||
before { user.geozone = nil }
|
||||
|
||||
it { should_not be_able_to(:answer, poll_question_from_own_geozone) }
|
||||
it { should be_able_to(:answer, poll_question_from_all_geozones) }
|
||||
@@ -230,7 +230,7 @@ describe "Abilities::Common" do
|
||||
it { should be_able_to(:destroy, own_investment_in_accepting_budget) }
|
||||
it { should be_able_to(:destroy, own_investment_in_reviewing_budget) }
|
||||
it { should_not be_able_to(:destroy, own_investment_in_selecting_budget) }
|
||||
it { should_not be_able_to(:destroy, investment_in_balloting_budget) }
|
||||
it { should_not be_able_to(:destroy, own_investment_in_balloting_budget) }
|
||||
|
||||
it { should_not be_able_to(:create, ballot_in_accepting_budget) }
|
||||
it { should_not be_able_to(:create, ballot_in_selecting_budget) }
|
||||
@@ -241,6 +241,7 @@ describe "Abilities::Common" do
|
||||
describe "when level 3 verified" do
|
||||
let(:own_spending_proposal) { create(:spending_proposal, author: user) }
|
||||
let(:own_direct_message) { create(:direct_message, sender: user) }
|
||||
|
||||
before{ user.update(verified_at: Time.current) }
|
||||
|
||||
it { should be_able_to(:vote, Proposal) }
|
||||
@@ -272,7 +273,7 @@ describe "Abilities::Common" do
|
||||
it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone) }
|
||||
|
||||
context "without geozone" do
|
||||
before(:each) { user.geozone = nil }
|
||||
before { user.geozone = nil }
|
||||
it { should_not be_able_to(:answer, poll_question_from_own_geozone) }
|
||||
it { should be_able_to(:answer, poll_question_from_all_geozones) }
|
||||
it { should_not be_able_to(:answer, poll_question_from_other_geozone) }
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Everyone" do
|
||||
describe Abilities::Everyone do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
|
||||
let(:user) { nil }
|
||||
let(:debate) { create(:debate) }
|
||||
let(:proposal) { create(:proposal) }
|
||||
|
||||
let(:reviewing_ballot_budget) { create(:budget, phase: 'reviewing_ballots') }
|
||||
let(:finished_budget) { create(:budget, phase: 'finished') }
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should_not be_able_to(:edit, Debate) }
|
||||
@@ -28,4 +31,7 @@ describe "Abilities::Everyone" do
|
||||
it { should_not be_able_to(:create, SpendingProposal) }
|
||||
|
||||
it { should be_able_to(:index, Budget) }
|
||||
end
|
||||
|
||||
it { should be_able_to(:read_results, finished_budget) }
|
||||
it { should_not be_able_to(:read_results, reviewing_ballot_budget) }
|
||||
end
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Moderator" do
|
||||
describe Abilities::Moderator do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
|
||||
let(:user) { moderator.user }
|
||||
let(:moderator) { create(:moderator) }
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Organization" do
|
||||
describe 'Abilities::Organization' do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
|
||||
let(:user) { organization.user }
|
||||
let(:organization) { create(:organization) }
|
||||
let(:debate) { create(:debate) }
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
require 'rails_helper'
|
||||
require 'cancan/matchers'
|
||||
|
||||
describe "Abilities::Valuator" do
|
||||
describe Abilities::Valuator do
|
||||
subject(:ability) { Ability.new(user) }
|
||||
|
||||
let(:user) { valuator.user }
|
||||
let(:valuator) { create(:valuator) }
|
||||
let(:non_assigned_investment) { create(:budget_investment) }
|
||||
|
||||
let(:assigned_investment) { create(:budget_investment, budget: create(:budget, phase: 'valuating')) }
|
||||
before(:each) { assigned_investment.valuators << valuator }
|
||||
|
||||
let(:finished_assigned_investment) { create(:budget_investment, budget: create(:budget, phase: 'finished')) }
|
||||
before(:each) { finished_assigned_investment.valuators << valuator }
|
||||
|
||||
before do
|
||||
assigned_investment.valuators << valuator
|
||||
finished_assigned_investment.valuators << valuator
|
||||
end
|
||||
|
||||
it { should be_able_to(:read, SpendingProposal) }
|
||||
it { should be_able_to(:update, SpendingProposal) }
|
||||
|
||||
@@ -2,28 +2,28 @@ require 'rails_helper'
|
||||
|
||||
describe Activity do
|
||||
|
||||
it "should be valid for different actionables" do
|
||||
it "is valid for different actionables" do
|
||||
expect(build(:activity, actionable: create(:proposal))).to be_valid
|
||||
expect(build(:activity, actionable: create(:debate))).to be_valid
|
||||
expect(build(:activity, actionable: create(:comment))).to be_valid
|
||||
expect(build(:activity, actionable: create(:user))).to be_valid
|
||||
end
|
||||
|
||||
it "should be a valid only with allowed actions" do
|
||||
it "is a valid only with allowed actions" do
|
||||
expect(build(:activity, action: "hide")).to be_valid
|
||||
expect(build(:activity, action: "block")).to be_valid
|
||||
expect(build(:activity, action: "restore")).to be_valid
|
||||
expect(build(:activity, action: "dissapear")).to_not be_valid
|
||||
expect(build(:activity, action: "dissapear")).not_to be_valid
|
||||
end
|
||||
|
||||
describe "log" do
|
||||
it "should create an activity entry" do
|
||||
it "creates an activity entry" do
|
||||
user = create(:user)
|
||||
proposal = create(:proposal)
|
||||
|
||||
expect{ Activity.log(user, :hide, proposal) }.to change { Activity.count }.by(1)
|
||||
expect{ described_class.log(user, :hide, proposal) }.to change { described_class.count }.by(1)
|
||||
|
||||
activity = Activity.last
|
||||
activity = described_class.last
|
||||
expect(activity.user_id).to eq(user.id)
|
||||
expect(activity.action).to eq("hide")
|
||||
expect(activity.actionable).to eq(proposal)
|
||||
@@ -31,7 +31,7 @@ describe Activity do
|
||||
end
|
||||
|
||||
describe "on" do
|
||||
it "should list all activity on an actionable object" do
|
||||
it "lists all activity on an actionable object" do
|
||||
proposal = create(:proposal)
|
||||
activity1 = create(:activity, action: "hide", actionable: proposal)
|
||||
activity2 = create(:activity, action: "restore", actionable: proposal)
|
||||
@@ -41,15 +41,15 @@ describe Activity do
|
||||
create(:activity, action: "hide", actionable: create(:comment))
|
||||
create(:activity, action: "block", actionable: create(:user))
|
||||
|
||||
expect(Activity.on(proposal).size).to eq 3
|
||||
expect(described_class.on(proposal).size).to eq 3
|
||||
[activity1, activity2, activity3].each do |a|
|
||||
expect(Activity.on(proposal)).to include(a)
|
||||
expect(described_class.on(proposal)).to include(a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "by" do
|
||||
it "should list all activity of a user" do
|
||||
it "lists all activity of a user" do
|
||||
user1 = create(:user)
|
||||
activity1 = create(:activity, user: user1)
|
||||
activity2 = create(:activity, user: user1, action: "restore", actionable: create(:debate))
|
||||
@@ -59,33 +59,33 @@ describe Activity do
|
||||
activity6 = create(:activity, user: user1, action: "valuate", actionable: create(:budget_investment))
|
||||
create_list(:activity, 3)
|
||||
|
||||
expect(Activity.by(user1).size).to eq 6
|
||||
expect(described_class.by(user1).size).to eq 6
|
||||
|
||||
[activity1, activity2, activity3, activity4, activity5, activity6].each do |a|
|
||||
expect(Activity.by(user1)).to include(a)
|
||||
expect(described_class.by(user1)).to include(a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "scopes by actionable" do
|
||||
it "should filter by actionable type" do
|
||||
it "filters by actionable type" do
|
||||
on_proposal = create(:activity, actionable: create(:proposal))
|
||||
on_debate = create(:activity, actionable: create(:debate))
|
||||
on_comment = create(:activity, actionable: create(:comment))
|
||||
on_user = create(:activity, actionable: create(:user))
|
||||
on_investment = create(:activity, actionable: create(:budget_investment))
|
||||
|
||||
expect(Activity.on_proposals.size).to eq 1
|
||||
expect(Activity.on_debates.size).to eq 1
|
||||
expect(Activity.on_comments.size).to eq 1
|
||||
expect(Activity.on_users.size).to eq 1
|
||||
expect(Activity.on_budget_investments.size).to eq 1
|
||||
expect(described_class.on_proposals.size).to eq 1
|
||||
expect(described_class.on_debates.size).to eq 1
|
||||
expect(described_class.on_comments.size).to eq 1
|
||||
expect(described_class.on_users.size).to eq 1
|
||||
expect(described_class.on_budget_investments.size).to eq 1
|
||||
|
||||
expect(Activity.on_proposals.first).to eq on_proposal
|
||||
expect(Activity.on_debates.first).to eq on_debate
|
||||
expect(Activity.on_comments.first).to eq on_comment
|
||||
expect(Activity.on_users.first).to eq on_user
|
||||
expect(Activity.on_budget_investments.first).to eq on_investment
|
||||
expect(described_class.on_proposals.first).to eq on_proposal
|
||||
expect(described_class.on_debates.first).to eq on_debate
|
||||
expect(described_class.on_comments.first).to eq on_comment
|
||||
expect(described_class.on_users.first).to eq on_user
|
||||
expect(described_class.on_budget_investments.first).to eq on_investment
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
|
||||
describe Ahoy::DataSource do
|
||||
describe '#build' do
|
||||
before :each do
|
||||
before do
|
||||
time_1 = DateTime.parse("2015-01-01").in_time_zone
|
||||
time_2 = DateTime.parse("2015-01-02").in_time_zone
|
||||
time_3 = DateTime.parse("2015-01-03").in_time_zone
|
||||
@@ -15,19 +15,19 @@ describe Ahoy::DataSource do
|
||||
create :ahoy_event, name: 'bar', time: time_3
|
||||
end
|
||||
|
||||
it 'should work without data sources' do
|
||||
ds = Ahoy::DataSource.new
|
||||
it 'works without data sources' do
|
||||
ds = described_class.new
|
||||
expect(ds.build).to eq x: []
|
||||
end
|
||||
|
||||
it 'should work with single data sources' do
|
||||
ds = Ahoy::DataSource.new
|
||||
it 'works with single data sources' do
|
||||
ds = described_class.new
|
||||
ds.add 'foo', Ahoy::Event.where(name: 'foo').group_by_day(:time).count
|
||||
expect(ds.build).to eq :x => ["2015-01-01", "2015-01-02"], "foo" => [2, 1]
|
||||
end
|
||||
|
||||
it 'should combine data sources' do
|
||||
ds = Ahoy::DataSource.new
|
||||
it 'combines data sources' do
|
||||
ds = described_class.new
|
||||
ds.add 'foo', Ahoy::Event.where(name: 'foo').group_by_day(:time).count
|
||||
ds.add 'bar', Ahoy::Event.where(name: 'bar').group_by_day(:time).count
|
||||
expect(ds.build).to eq :x => ["2015-01-01", "2015-01-02", "2015-01-03"], "foo" => [2, 1, 0], "bar" => [1, 0, 2]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe "Budget::Ballot::Line" do
|
||||
describe Budget::Ballot::Line do
|
||||
|
||||
let(:budget){ create(:budget) }
|
||||
let(:group){ create(:budget_group, budget: budget) }
|
||||
@@ -11,7 +11,7 @@ describe "Budget::Ballot::Line" do
|
||||
|
||||
describe 'Validations' do
|
||||
|
||||
it "should be valid and automatically denormallyze budget, group and heading when validated" do
|
||||
it "is valid and automatically denormallyze budget, group and heading when validated" do
|
||||
expect(ballot_line).to be_valid
|
||||
expect(ballot_line.budget).to eq(budget)
|
||||
expect(ballot_line.group).to eq(group)
|
||||
@@ -19,24 +19,24 @@ describe "Budget::Ballot::Line" do
|
||||
end
|
||||
|
||||
describe 'Money' do
|
||||
it "should not be valid if insufficient funds" do
|
||||
it "is not valid if insufficient funds" do
|
||||
investment.update(price: heading.price + 1)
|
||||
expect(ballot_line).to_not be_valid
|
||||
expect(ballot_line).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if sufficient funds" do
|
||||
it "is valid if sufficient funds" do
|
||||
investment.update(price: heading.price - 1)
|
||||
expect(ballot_line).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Selectibility' do
|
||||
it "should not be valid if investment is unselected" do
|
||||
it "is not valid if investment is unselected" do
|
||||
investment.update(selected: false)
|
||||
expect(ballot_line).to_not be_valid
|
||||
expect(ballot_line).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if investment is selected" do
|
||||
it "is valid if investment is selected" do
|
||||
investment.update(selected: true, price: 20000)
|
||||
expect(ballot_line).to be_valid
|
||||
end
|
||||
@@ -48,7 +48,7 @@ describe "Budget::Ballot::Line" do
|
||||
|
||||
describe "by_investment" do
|
||||
|
||||
it "should return ballot lines for an investment" do
|
||||
it "returns ballot lines for an investment" do
|
||||
investment1 = create(:budget_investment, :selected, heading: heading)
|
||||
investment2 = create(:budget_investment, :selected, heading: heading)
|
||||
|
||||
@@ -60,11 +60,11 @@ describe "Budget::Ballot::Line" do
|
||||
ballot_line2 = create(:budget_ballot_line, ballot: ballot2, investment: investment1)
|
||||
ballot_line3 = create(:budget_ballot_line, ballot: ballot3, investment: investment2)
|
||||
|
||||
ballot_lines_by_investment = Budget::Ballot::Line.by_investment(investment1.id)
|
||||
ballot_lines_by_investment = described_class.by_investment(investment1.id)
|
||||
|
||||
expect(ballot_lines_by_investment).to include ballot_line1
|
||||
expect(ballot_lines_by_investment).to include ballot_line2
|
||||
expect(ballot_lines_by_investment).to_not include ballot_line3
|
||||
expect(ballot_lines_by_investment).not_to include ballot_line3
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,14 +4,14 @@ describe Budget::Ballot do
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
budget = create(:budget)
|
||||
ballot = create(:budget_ballot, budget: budget)
|
||||
|
||||
expect(ballot).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid with the same investment twice" do
|
||||
it "is not valid with the same investment twice" do
|
||||
budget = create(:budget)
|
||||
group = create(:budget_group, budget: budget)
|
||||
heading = create(:budget_heading, group: group)
|
||||
|
||||
@@ -2,10 +2,10 @@ require 'rails_helper'
|
||||
|
||||
describe Budget::Group do
|
||||
|
||||
it_behaves_like "sluggable"
|
||||
|
||||
let(:budget) { create(:budget) }
|
||||
|
||||
it_behaves_like "sluggable"
|
||||
|
||||
describe "name" do
|
||||
before do
|
||||
create(:budget_group, budget: budget, name: 'object name')
|
||||
|
||||
@@ -2,11 +2,11 @@ require 'rails_helper'
|
||||
|
||||
describe Budget::Heading do
|
||||
|
||||
it_behaves_like "sluggable"
|
||||
|
||||
let(:budget) { create(:budget) }
|
||||
let(:group) { create(:budget_group, budget: budget) }
|
||||
|
||||
it_behaves_like "sluggable"
|
||||
|
||||
describe "name" do
|
||||
before do
|
||||
create(:budget_heading, group: group, name: 'object name')
|
||||
@@ -25,6 +25,25 @@ describe Budget::Heading do
|
||||
end
|
||||
end
|
||||
|
||||
describe "Save population" do
|
||||
it "Allows population == nil" do
|
||||
expect(create(:budget_heading, group: group, name: 'Population is nil', population: nil)).to be_valid
|
||||
end
|
||||
|
||||
it "Doesn't allow population <= 0" do
|
||||
heading = create(:budget_heading, group: group, name: 'Population is > 0')
|
||||
|
||||
heading.population = 0
|
||||
expect(heading).not_to be_valid
|
||||
|
||||
heading.population = -10
|
||||
expect(heading).not_to be_valid
|
||||
|
||||
heading.population = 10
|
||||
expect(heading).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "heading" do
|
||||
it "can be deleted if no budget's investments associated" do
|
||||
heading1 = create(:budget_heading, group: group, name: 'name')
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe "Budget::Investment::Milestone" do
|
||||
describe Budget::Investment::Milestone do
|
||||
|
||||
describe "Validations" do
|
||||
let(:milestone) { build(:budget_investment_milestone) }
|
||||
|
||||
it "Should be valid" do
|
||||
it "is valid" do
|
||||
expect(milestone).to be_valid
|
||||
end
|
||||
|
||||
it "Should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
milestone.title = nil
|
||||
expect(milestone).to_not be_valid
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
|
||||
it "Should not be valid without an investment" do
|
||||
it "is not valid without a description" do
|
||||
milestone.description = nil
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without an investment" do
|
||||
milestone.investment_id = nil
|
||||
expect(milestone).to_not be_valid
|
||||
expect(milestone).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,32 +3,38 @@ require 'rails_helper'
|
||||
describe Budget::Investment do
|
||||
let(:investment) { build(:budget_investment) }
|
||||
|
||||
it "should be valid" do
|
||||
describe "Concerns" do
|
||||
it_behaves_like "notifiable"
|
||||
end
|
||||
|
||||
it "is valid" do
|
||||
expect(investment).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an author" do
|
||||
it "is not valid without an author" do
|
||||
investment.author = nil
|
||||
expect(investment).to_not be_valid
|
||||
expect(investment).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
investment.title = nil
|
||||
expect(investment).to_not be_valid
|
||||
expect(investment).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very short" do
|
||||
it "is not valid when very short" do
|
||||
investment.title = "abc"
|
||||
expect(investment).to_not be_valid
|
||||
expect(investment).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
investment.title = "a" * 81
|
||||
expect(investment).to_not be_valid
|
||||
expect(investment).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "acts as imageable", "budget_investment_image"
|
||||
|
||||
it "sanitizes description" do
|
||||
investment.description = "<script>alert('danger');</script>"
|
||||
investment.valid?
|
||||
@@ -55,35 +61,35 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "#unfeasibility_explanation blank" do
|
||||
it "should be valid if valuation not finished" do
|
||||
it "is valid if valuation not finished" do
|
||||
investment.unfeasibility_explanation = ""
|
||||
investment.valuation_finished = false
|
||||
expect(investment).to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if valuation finished and feasible" do
|
||||
it "is valid if valuation finished and feasible" do
|
||||
investment.unfeasibility_explanation = ""
|
||||
investment.feasibility = "feasible"
|
||||
investment.valuation_finished = true
|
||||
expect(investment).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid if valuation finished and unfeasible" do
|
||||
it "is not valid if valuation finished and unfeasible" do
|
||||
investment.unfeasibility_explanation = ""
|
||||
investment.feasibility = "unfeasible"
|
||||
investment.valuation_finished = true
|
||||
expect(investment).to_not be_valid
|
||||
expect(investment).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#price blank" do
|
||||
it "should be valid if valuation not finished" do
|
||||
it "is valid if valuation not finished" do
|
||||
investment.price = ""
|
||||
investment.valuation_finished = false
|
||||
expect(investment).to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if valuation finished and unfeasible" do
|
||||
it "is valid if valuation finished and unfeasible" do
|
||||
investment.price = ""
|
||||
investment.unfeasibility_explanation = "reason"
|
||||
investment.feasibility = "unfeasible"
|
||||
@@ -91,11 +97,11 @@ describe Budget::Investment do
|
||||
expect(investment).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid if valuation finished and feasible" do
|
||||
it "is not valid if valuation finished and feasible" do
|
||||
investment.price = ""
|
||||
investment.feasibility = "feasible"
|
||||
investment.valuation_finished = true
|
||||
expect(investment).to_not be_valid
|
||||
expect(investment).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -103,7 +109,7 @@ describe Budget::Investment do
|
||||
let(:investment) { create(:budget_investment) }
|
||||
|
||||
it "returns the proposal id" do
|
||||
expect(investment.code).to include((investment.id).to_s)
|
||||
expect(investment.code).to include(investment.id.to_s)
|
||||
end
|
||||
|
||||
it "returns the administrator id when assigned" do
|
||||
@@ -116,7 +122,7 @@ describe Budget::Investment do
|
||||
let(:investment) { create(:budget_investment) }
|
||||
|
||||
it "sets the time when the unfeasible email was sent" do
|
||||
expect(investment.unfeasible_email_sent_at).to_not be
|
||||
expect(investment.unfeasible_email_sent_at).not_to be
|
||||
investment.send_unfeasible_email
|
||||
expect(investment.unfeasible_email_sent_at).to be
|
||||
end
|
||||
@@ -222,11 +228,11 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "by_admin" do
|
||||
it "should return investments assigned to specific administrator" do
|
||||
it "returns investments assigned to specific administrator" do
|
||||
investment1 = create(:budget_investment, administrator_id: 33)
|
||||
create(:budget_investment)
|
||||
|
||||
by_admin = Budget::Investment.by_admin(33)
|
||||
by_admin = described_class.by_admin(33)
|
||||
|
||||
expect(by_admin.size).to eq(1)
|
||||
expect(by_admin.first).to eq(investment1)
|
||||
@@ -234,7 +240,7 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "by_valuator" do
|
||||
it "should return investments assigned to specific valuator" do
|
||||
it "returns investments assigned to specific valuator" do
|
||||
investment1 = create(:budget_investment)
|
||||
investment2 = create(:budget_investment)
|
||||
investment3 = create(:budget_investment)
|
||||
@@ -246,7 +252,7 @@ describe Budget::Investment do
|
||||
investment2.valuators << valuator2
|
||||
investment3.valuators << [valuator1, valuator2]
|
||||
|
||||
by_valuator = Budget::Investment.by_valuator(valuator1.id)
|
||||
by_valuator = described_class.by_valuator(valuator1.id)
|
||||
|
||||
expect(by_valuator.size).to eq(2)
|
||||
expect(by_valuator.sort).to eq([investment1, investment3].sort)
|
||||
@@ -255,11 +261,11 @@ describe Budget::Investment do
|
||||
|
||||
describe "scopes" do
|
||||
describe "valuation_open" do
|
||||
it "should return all investments with false valuation_finished" do
|
||||
it "returns all investments with false valuation_finished" do
|
||||
investment1 = create(:budget_investment, valuation_finished: true)
|
||||
investment2 = create(:budget_investment)
|
||||
|
||||
valuation_open = Budget::Investment.valuation_open
|
||||
valuation_open = described_class.valuation_open
|
||||
|
||||
expect(valuation_open.size).to eq(1)
|
||||
expect(valuation_open.first).to eq(investment2)
|
||||
@@ -267,12 +273,12 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "without_admin" do
|
||||
it "should return all open investments without assigned admin" do
|
||||
it "returns all open investments without assigned admin" do
|
||||
investment1 = create(:budget_investment, valuation_finished: true)
|
||||
investment2 = create(:budget_investment, administrator: create(:administrator))
|
||||
investment3 = create(:budget_investment)
|
||||
|
||||
without_admin = Budget::Investment.without_admin
|
||||
without_admin = described_class.without_admin
|
||||
|
||||
expect(without_admin.size).to eq(1)
|
||||
expect(without_admin.first).to eq(investment3)
|
||||
@@ -280,13 +286,13 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "managed" do
|
||||
it "should return all open investments with assigned admin but without assigned valuators" do
|
||||
it "returns all open investments with assigned admin but without assigned valuators" do
|
||||
investment1 = create(:budget_investment, administrator: create(:administrator))
|
||||
investment2 = create(:budget_investment, administrator: create(:administrator), valuation_finished: true)
|
||||
investment3 = create(:budget_investment, administrator: create(:administrator))
|
||||
investment1.valuators << create(:valuator)
|
||||
|
||||
managed = Budget::Investment.managed
|
||||
managed = described_class.managed
|
||||
|
||||
expect(managed.size).to eq(1)
|
||||
expect(managed.first).to eq(investment3)
|
||||
@@ -294,7 +300,7 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "valuating" do
|
||||
it "should return all investments with assigned valuator but valuation not finished" do
|
||||
it "returns all investments with assigned valuator but valuation not finished" do
|
||||
investment1 = create(:budget_investment)
|
||||
investment2 = create(:budget_investment)
|
||||
investment3 = create(:budget_investment, valuation_finished: true)
|
||||
@@ -302,7 +308,7 @@ describe Budget::Investment do
|
||||
investment2.valuators << create(:valuator)
|
||||
investment3.valuators << create(:valuator)
|
||||
|
||||
valuating = Budget::Investment.valuating
|
||||
valuating = described_class.valuating
|
||||
|
||||
expect(valuating.size).to eq(1)
|
||||
expect(valuating.first).to eq(investment2)
|
||||
@@ -310,7 +316,7 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "valuation_finished" do
|
||||
it "should return all investments with valuation finished" do
|
||||
it "returns all investments with valuation finished" do
|
||||
investment1 = create(:budget_investment)
|
||||
investment2 = create(:budget_investment)
|
||||
investment3 = create(:budget_investment, valuation_finished: true)
|
||||
@@ -318,7 +324,7 @@ describe Budget::Investment do
|
||||
investment2.valuators << create(:valuator)
|
||||
investment3.valuators << create(:valuator)
|
||||
|
||||
valuation_finished = Budget::Investment.valuation_finished
|
||||
valuation_finished = described_class.valuation_finished
|
||||
|
||||
expect(valuation_finished.size).to eq(1)
|
||||
expect(valuation_finished.first).to eq(investment3)
|
||||
@@ -326,60 +332,60 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "feasible" do
|
||||
it "should return all feasible investments" do
|
||||
it "returns all feasible investments" do
|
||||
feasible_investment = create(:budget_investment, :feasible)
|
||||
create(:budget_investment)
|
||||
|
||||
expect(Budget::Investment.feasible).to eq [feasible_investment]
|
||||
expect(described_class.feasible).to eq [feasible_investment]
|
||||
end
|
||||
end
|
||||
|
||||
describe "unfeasible" do
|
||||
it "should return all unfeasible investments" do
|
||||
it "returns all unfeasible investments" do
|
||||
unfeasible_investment = create(:budget_investment, :unfeasible)
|
||||
create(:budget_investment, :feasible)
|
||||
|
||||
expect(Budget::Investment.unfeasible).to eq [unfeasible_investment]
|
||||
expect(described_class.unfeasible).to eq [unfeasible_investment]
|
||||
end
|
||||
end
|
||||
|
||||
describe "not_unfeasible" do
|
||||
it "should return all feasible and undecided investments" do
|
||||
it "returns all feasible and undecided investments" do
|
||||
unfeasible_investment = create(:budget_investment, :unfeasible)
|
||||
undecided_investment = create(:budget_investment, :undecided)
|
||||
feasible_investment = create(:budget_investment, :feasible)
|
||||
|
||||
expect(Budget::Investment.not_unfeasible.sort).to eq [undecided_investment, feasible_investment].sort
|
||||
expect(described_class.not_unfeasible.sort).to eq [undecided_investment, feasible_investment].sort
|
||||
end
|
||||
end
|
||||
|
||||
describe "undecided" do
|
||||
it "should return all undecided investments" do
|
||||
it "returns all undecided investments" do
|
||||
unfeasible_investment = create(:budget_investment, :unfeasible)
|
||||
undecided_investment = create(:budget_investment, :undecided)
|
||||
feasible_investment = create(:budget_investment, :feasible)
|
||||
|
||||
expect(Budget::Investment.undecided).to eq [undecided_investment]
|
||||
expect(described_class.undecided).to eq [undecided_investment]
|
||||
end
|
||||
end
|
||||
|
||||
describe "selected" do
|
||||
it "should return all selected investments" do
|
||||
it "returns all selected investments" do
|
||||
selected_investment = create(:budget_investment, :selected)
|
||||
unselected_investment = create(:budget_investment, :unselected)
|
||||
|
||||
expect(Budget::Investment.selected).to eq [selected_investment]
|
||||
expect(described_class.selected).to eq [selected_investment]
|
||||
end
|
||||
end
|
||||
|
||||
describe "unselected" do
|
||||
it "should return all unselected not_unfeasible investments" do
|
||||
it "returns all unselected not_unfeasible investments" do
|
||||
selected_investment = create(:budget_investment, :selected)
|
||||
unselected_unfeasible_investment = create(:budget_investment, :unselected, :unfeasible)
|
||||
unselected_undecided_investment = create(:budget_investment, :unselected, :undecided)
|
||||
unselected_feasible_investment = create(:budget_investment, :unselected, :feasible)
|
||||
|
||||
expect(Budget::Investment.unselected.sort).to eq [unselected_undecided_investment, unselected_feasible_investment].sort
|
||||
expect(described_class.unselected.sort).to eq [unselected_undecided_investment, unselected_feasible_investment].sort
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -393,11 +399,11 @@ describe Budget::Investment do
|
||||
investment2 = create(:budget_investment, :feasible, budget: budget)
|
||||
investment3 = create(:budget_investment, :unfeasible, budget: budget)
|
||||
|
||||
results = Budget::Investment::apply_filters_and_search(budget, {}, :feasible)
|
||||
results = described_class.apply_filters_and_search(budget, {}, :feasible)
|
||||
|
||||
expect(results).to include investment1
|
||||
expect(results).to include investment2
|
||||
expect(results).to_not include investment3
|
||||
expect(results).not_to include investment3
|
||||
end
|
||||
|
||||
it "returns unfeasible investments" do
|
||||
@@ -405,11 +411,11 @@ describe Budget::Investment do
|
||||
investment2 = create(:budget_investment, :unfeasible, budget: budget)
|
||||
investment3 = create(:budget_investment, :feasible, budget: budget)
|
||||
|
||||
results = Budget::Investment::apply_filters_and_search(budget, {}, :unfeasible)
|
||||
results = described_class.apply_filters_and_search(budget, {}, :unfeasible)
|
||||
|
||||
expect(results).to include investment1
|
||||
expect(results).to include investment2
|
||||
expect(results).to_not include investment3
|
||||
expect(results).not_to include investment3
|
||||
end
|
||||
|
||||
it "returns selected investments" do
|
||||
@@ -419,11 +425,11 @@ describe Budget::Investment do
|
||||
investment2 = create(:budget_investment, :feasible, :selected, budget: budget)
|
||||
investment3 = create(:budget_investment, :feasible, :unselected, budget: budget)
|
||||
|
||||
results = Budget::Investment::apply_filters_and_search(budget, {}, :selected)
|
||||
results = described_class.apply_filters_and_search(budget, {}, :selected)
|
||||
|
||||
expect(results).to include investment1
|
||||
expect(results).to include investment2
|
||||
expect(results).to_not include investment3
|
||||
expect(results).not_to include investment3
|
||||
end
|
||||
|
||||
it "returns unselected investments" do
|
||||
@@ -433,11 +439,11 @@ describe Budget::Investment do
|
||||
investment2 = create(:budget_investment, :feasible, :unselected, budget: budget)
|
||||
investment3 = create(:budget_investment, :feasible, :selected, budget: budget)
|
||||
|
||||
results = Budget::Investment::apply_filters_and_search(budget, {}, :unselected)
|
||||
results = described_class.apply_filters_and_search(budget, {}, :unselected)
|
||||
|
||||
expect(results).to include investment1
|
||||
expect(results).to include investment2
|
||||
expect(results).to_not include investment3
|
||||
expect(results).not_to include investment3
|
||||
end
|
||||
|
||||
it "returns investmens by heading" do
|
||||
@@ -450,11 +456,11 @@ describe Budget::Investment do
|
||||
investment2 = create(:budget_investment, heading: heading1, budget: budget)
|
||||
investment3 = create(:budget_investment, heading: heading2, budget: budget)
|
||||
|
||||
results = Budget::Investment::apply_filters_and_search(budget, heading_id: heading1.id)
|
||||
results = described_class.apply_filters_and_search(budget, heading_id: heading1.id)
|
||||
|
||||
expect(results).to include investment1
|
||||
expect(results).to include investment2
|
||||
expect(results).to_not include investment3
|
||||
expect(results).not_to include investment3
|
||||
end
|
||||
|
||||
it "returns investments by search string" do
|
||||
@@ -462,11 +468,11 @@ describe Budget::Investment do
|
||||
investment2 = create(:budget_investment, title: "improved health", budget: budget)
|
||||
investment3 = create(:budget_investment, title: "finance", budget: budget)
|
||||
|
||||
results = Budget::Investment::apply_filters_and_search(budget, search: "health")
|
||||
results = described_class.apply_filters_and_search(budget, search: "health")
|
||||
|
||||
expect(results).to include investment1
|
||||
expect(results).to include investment2
|
||||
expect(results).to_not include investment3
|
||||
expect(results).not_to include investment3
|
||||
end
|
||||
end
|
||||
|
||||
@@ -476,10 +482,10 @@ describe Budget::Investment do
|
||||
it "searches by tags" do
|
||||
investment = create(:budget_investment, tag_list: 'Latina')
|
||||
|
||||
results = Budget::Investment.search('Latina')
|
||||
results = described_class.search('Latina')
|
||||
expect(results.first).to eq(investment)
|
||||
|
||||
results = Budget::Investment.search('Latin')
|
||||
results = described_class.search('Latin')
|
||||
expect(results.first).to eq(investment)
|
||||
end
|
||||
end
|
||||
@@ -574,26 +580,26 @@ describe Budget::Investment do
|
||||
describe "Order" do
|
||||
describe "#sort_by_confidence_score" do
|
||||
|
||||
it "should order by confidence_score" do
|
||||
it "orders by confidence_score" do
|
||||
least_voted = create(:budget_investment, cached_votes_up: 1)
|
||||
most_voted = create(:budget_investment, cached_votes_up: 10)
|
||||
some_votes = create(:budget_investment, cached_votes_up: 5)
|
||||
|
||||
expect(Budget::Investment.sort_by_confidence_score.first).to eq most_voted
|
||||
expect(Budget::Investment.sort_by_confidence_score.second).to eq some_votes
|
||||
expect(Budget::Investment.sort_by_confidence_score.third).to eq least_voted
|
||||
expect(described_class.sort_by_confidence_score.first).to eq most_voted
|
||||
expect(described_class.sort_by_confidence_score.second).to eq some_votes
|
||||
expect(described_class.sort_by_confidence_score.third).to eq least_voted
|
||||
end
|
||||
|
||||
it "should order by confidence_score and then by id" do
|
||||
it "orders by confidence_score and then by id" do
|
||||
least_voted = create(:budget_investment, cached_votes_up: 1)
|
||||
most_voted = create(:budget_investment, cached_votes_up: 10)
|
||||
most_voted2 = create(:budget_investment, cached_votes_up: 10)
|
||||
least_voted2 = create(:budget_investment, cached_votes_up: 1)
|
||||
|
||||
expect(Budget::Investment.sort_by_confidence_score.first).to eq most_voted2
|
||||
expect(Budget::Investment.sort_by_confidence_score.second).to eq most_voted
|
||||
expect(Budget::Investment.sort_by_confidence_score.third).to eq least_voted2
|
||||
expect(Budget::Investment.sort_by_confidence_score.fourth).to eq least_voted
|
||||
expect(described_class.sort_by_confidence_score.first).to eq most_voted2
|
||||
expect(described_class.sort_by_confidence_score.second).to eq most_voted
|
||||
expect(described_class.sort_by_confidence_score.third).to eq least_voted2
|
||||
expect(described_class.sort_by_confidence_score.fourth).to eq least_voted
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -631,13 +637,13 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
describe "#with_supports" do
|
||||
it "should return proposals with supports" do
|
||||
it "returns proposals with supports" do
|
||||
inv1 = create(:budget_investment)
|
||||
inv2 = create(:budget_investment)
|
||||
create(:vote, votable: inv1)
|
||||
|
||||
expect(Budget::Investment.with_supports).to include(inv1)
|
||||
expect(Budget::Investment.with_supports).to_not include(inv2)
|
||||
expect(described_class.with_supports).to include(inv1)
|
||||
expect(described_class.with_supports).not_to include(inv2)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,29 +5,29 @@ describe Budget::ReclassifiedVote do
|
||||
describe "Validations" do
|
||||
let(:reclassified_vote) { build(:budget_reclassified_vote) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(reclassified_vote).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a user" do
|
||||
it "is not valid without a user" do
|
||||
reclassified_vote.user_id = nil
|
||||
expect(reclassified_vote).to_not be_valid
|
||||
expect(reclassified_vote).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an investment" do
|
||||
it "is not valid without an investment" do
|
||||
reclassified_vote.investment_id = nil
|
||||
expect(reclassified_vote).to_not be_valid
|
||||
expect(reclassified_vote).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a valid reason" do
|
||||
it "is not valid without a valid reason" do
|
||||
reclassified_vote.reason = nil
|
||||
expect(reclassified_vote).to_not be_valid
|
||||
expect(reclassified_vote).not_to be_valid
|
||||
|
||||
reclassified_vote.reason = ""
|
||||
expect(reclassified_vote).to_not be_valid
|
||||
expect(reclassified_vote).not_to be_valid
|
||||
|
||||
reclassified_vote.reason = "random"
|
||||
expect(reclassified_vote).to_not be_valid
|
||||
expect(reclassified_vote).not_to be_valid
|
||||
|
||||
reclassified_vote.reason = "heading_changed"
|
||||
expect(reclassified_vote).to be_valid
|
||||
|
||||
@@ -36,10 +36,13 @@ describe Budget do
|
||||
end
|
||||
|
||||
budget.phase = 'inexisting'
|
||||
expect(budget).to_not be_valid
|
||||
expect(budget).not_to be_valid
|
||||
end
|
||||
|
||||
it "produces auxiliary methods" do
|
||||
budget.phase = "drafting"
|
||||
expect(budget).to be_drafting
|
||||
|
||||
budget.phase = "accepting"
|
||||
expect(budget).to be_accepting
|
||||
|
||||
@@ -63,40 +66,46 @@ describe Budget do
|
||||
end
|
||||
|
||||
it "on_hold?" do
|
||||
budget.phase = "drafting"
|
||||
expect(budget).not_to be_on_hold
|
||||
|
||||
budget.phase = "accepting"
|
||||
expect(budget).to_not be_on_hold
|
||||
expect(budget).not_to be_on_hold
|
||||
|
||||
budget.phase = "reviewing"
|
||||
expect(budget).to be_on_hold
|
||||
|
||||
budget.phase = "selecting"
|
||||
expect(budget).to_not be_on_hold
|
||||
expect(budget).not_to be_on_hold
|
||||
|
||||
budget.phase = "valuating"
|
||||
expect(budget).to be_on_hold
|
||||
|
||||
budget.phase = "balloting"
|
||||
expect(budget).to_not be_on_hold
|
||||
expect(budget).not_to be_on_hold
|
||||
|
||||
budget.phase = "reviewing_ballots"
|
||||
expect(budget).to be_on_hold
|
||||
|
||||
budget.phase = "finished"
|
||||
expect(budget).to_not be_on_hold
|
||||
expect(budget).not_to be_on_hold
|
||||
end
|
||||
|
||||
it "balloting_or_later?" do
|
||||
budget.phase = "drafting"
|
||||
expect(budget).not_to be_balloting_or_later
|
||||
|
||||
budget.phase = "accepting"
|
||||
expect(budget).to_not be_balloting_or_later
|
||||
expect(budget).not_to be_balloting_or_later
|
||||
|
||||
budget.phase = "reviewing"
|
||||
expect(budget).to_not be_balloting_or_later
|
||||
expect(budget).not_to be_balloting_or_later
|
||||
|
||||
budget.phase = "selecting"
|
||||
expect(budget).to_not be_balloting_or_later
|
||||
expect(budget).not_to be_balloting_or_later
|
||||
|
||||
budget.phase = "valuating"
|
||||
expect(budget).to_not be_balloting_or_later
|
||||
expect(budget).not_to be_balloting_or_later
|
||||
|
||||
budget.phase = "balloting"
|
||||
expect(budget).to be_balloting_or_later
|
||||
@@ -125,6 +134,7 @@ describe Budget do
|
||||
|
||||
describe "investments_orders" do
|
||||
let(:budget) { create(:budget) }
|
||||
|
||||
it "is random when accepting and reviewing" do
|
||||
budget.phase = 'accepting'
|
||||
expect(budget.investments_orders).to eq(['random'])
|
||||
|
||||
@@ -129,8 +129,8 @@ describe Comment do
|
||||
create(:comment, administrator_id: create(:administrator).id)
|
||||
create(:comment, moderator_id: create(:moderator).id)
|
||||
|
||||
expect(Comment.not_as_admin_or_moderator.size).to eq(1)
|
||||
expect(Comment.not_as_admin_or_moderator.first).to eq(comment1)
|
||||
expect(described_class.not_as_admin_or_moderator.size).to eq(1)
|
||||
expect(described_class.not_as_admin_or_moderator.first).to eq(comment1)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -138,54 +138,54 @@ describe Comment do
|
||||
it "returns comments" do
|
||||
comment = create(:comment)
|
||||
|
||||
expect(Comment.public_for_api).to include(comment)
|
||||
expect(described_class.public_for_api).to include(comment)
|
||||
end
|
||||
|
||||
it "does not return hidden comments" do
|
||||
hidden_comment = create(:comment, :hidden)
|
||||
|
||||
expect(Comment.public_for_api).not_to include(hidden_comment)
|
||||
expect(described_class.public_for_api).not_to include(hidden_comment)
|
||||
end
|
||||
|
||||
it "returns comments on debates" do
|
||||
debate = create(:debate)
|
||||
comment = create(:comment, commentable: debate)
|
||||
|
||||
expect(Comment.public_for_api).to include(comment)
|
||||
expect(described_class.public_for_api).to include(comment)
|
||||
end
|
||||
|
||||
it "does not return comments on hidden debates" do
|
||||
hidden_debate = create(:debate, :hidden)
|
||||
comment = create(:comment, commentable: hidden_debate)
|
||||
|
||||
expect(Comment.public_for_api).not_to include(comment)
|
||||
expect(described_class.public_for_api).not_to include(comment)
|
||||
end
|
||||
|
||||
it "returns comments on proposals" do
|
||||
proposal = create(:proposal)
|
||||
comment = create(:comment, commentable: proposal)
|
||||
|
||||
expect(Comment.public_for_api).to include(comment)
|
||||
expect(described_class.public_for_api).to include(comment)
|
||||
end
|
||||
|
||||
it "does not return comments on hidden proposals" do
|
||||
hidden_proposal = create(:proposal, :hidden)
|
||||
comment = create(:comment, commentable: hidden_proposal)
|
||||
|
||||
expect(Comment.public_for_api).not_to include(comment)
|
||||
expect(described_class.public_for_api).not_to include(comment)
|
||||
end
|
||||
|
||||
it 'does not return comments on elements which are not debates or proposals' do
|
||||
budget_investment = create(:budget_investment)
|
||||
comment = create(:comment, commentable: budget_investment)
|
||||
|
||||
expect(Comment.public_for_api).not_to include(comment)
|
||||
expect(described_class.public_for_api).not_to include(comment)
|
||||
end
|
||||
|
||||
it 'does not return comments with no commentable' do
|
||||
comment = build(:comment, commentable: nil).save!(validate: false)
|
||||
|
||||
expect(Comment.public_for_api).to_not include(comment)
|
||||
expect(described_class.public_for_api).not_to include(comment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe Community, type: :model do
|
||||
|
||||
it "should be valid when create proposal" do
|
||||
it "is valid when create proposal" do
|
||||
proposal = create(:proposal)
|
||||
|
||||
expect(proposal.community).to be_valid
|
||||
@@ -10,7 +10,7 @@ RSpec.describe Community, type: :model do
|
||||
|
||||
describe "#participants" do
|
||||
|
||||
it "should return participants without duplicates" do
|
||||
it "returns participants without duplicates" do
|
||||
proposal = create(:proposal)
|
||||
community = proposal.community
|
||||
user1 = create(:user)
|
||||
|
||||
@@ -7,7 +7,7 @@ describe Verification::Residence do
|
||||
describe "verification" do
|
||||
|
||||
describe "postal code" do
|
||||
it "should be valid with postal codes starting with 280" do
|
||||
it "is valid with postal codes starting with 280" do
|
||||
residence.postal_code = "28012"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(0)
|
||||
@@ -17,7 +17,7 @@ describe Verification::Residence do
|
||||
expect(residence.errors[:postal_code].size).to eq(0)
|
||||
end
|
||||
|
||||
it "should not be valid with postal codes not starting with 280" do
|
||||
it "is not valid with postal codes not starting with 280" do
|
||||
residence.postal_code = "12345"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(1)
|
||||
@@ -4,102 +4,106 @@ require 'rails_helper'
|
||||
describe Debate do
|
||||
let(:debate) { build(:debate) }
|
||||
|
||||
it_behaves_like "has_public_author"
|
||||
describe "Concerns" do
|
||||
it_behaves_like "has_public_author"
|
||||
it_behaves_like "notifiable"
|
||||
end
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(debate).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an author" do
|
||||
it "is not valid without an author" do
|
||||
debate.author = nil
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
debate.title = nil
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very short" do
|
||||
it "is not valid when very short" do
|
||||
debate.title = "abc"
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
debate.title = "a" * 81
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#description" do
|
||||
it "should not be valid without a description" do
|
||||
it "is not valid without a description" do
|
||||
debate.description = nil
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be sanitized" do
|
||||
it "is sanitized" do
|
||||
debate.description = "<script>alert('danger');</script>"
|
||||
debate.valid?
|
||||
expect(debate.description).to eq("alert('danger');")
|
||||
end
|
||||
|
||||
it "should be html_safe" do
|
||||
it "is html_safe" do
|
||||
debate.description = "<script>alert('danger');</script>"
|
||||
expect(debate.description).to be_html_safe
|
||||
end
|
||||
|
||||
it "should not be valid when very short" do
|
||||
it "is not valid when very short" do
|
||||
debate.description = "abc"
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
debate.description = "a" * 6001
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#tag_list" do
|
||||
it "should sanitize the tag list" do
|
||||
it "sanitizes the tag list" do
|
||||
debate.tag_list = "user_id=1"
|
||||
debate.valid?
|
||||
expect(debate.tag_list).to eq(['user_id1'])
|
||||
end
|
||||
|
||||
it "should not be valid with a tag list of more than 6 elements" do
|
||||
it "is not valid with a tag list of more than 6 elements" do
|
||||
debate.tag_list = ["Hacienda", "Economía", "Medio Ambiente", "Corrupción", "Fiestas populares", "Prensa", "Huelgas"]
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid with a tag list of 6 elements" do
|
||||
it "is valid with a tag list of 6 elements" do
|
||||
debate.tag_list = ["Hacienda", "Economía", "Medio Ambiente", "Corrupción", "Fiestas populares", "Prensa"]
|
||||
expect(debate).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it "should not be valid without accepting terms of service" do
|
||||
it "is not valid without accepting terms of service" do
|
||||
debate.terms_of_service = nil
|
||||
expect(debate).to_not be_valid
|
||||
expect(debate).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#editable?" do
|
||||
let(:debate) { create(:debate) }
|
||||
before(:each) { Setting["max_votes_for_debate_edit"] = 3 }
|
||||
after(:each) { Setting["max_votes_for_debate_edit"] = 1000 }
|
||||
|
||||
it "should be true if debate has no votes yet" do
|
||||
before { Setting["max_votes_for_debate_edit"] = 3 }
|
||||
after { Setting["max_votes_for_debate_edit"] = 1000 }
|
||||
|
||||
it "is true if debate has no votes yet" do
|
||||
expect(debate.total_votes).to eq(0)
|
||||
expect(debate.editable?).to be true
|
||||
end
|
||||
|
||||
it "should be true if debate has less than limit votes" do
|
||||
it "is true if debate has less than limit votes" do
|
||||
create_list(:vote, 2, votable: debate)
|
||||
expect(debate.total_votes).to eq(2)
|
||||
expect(debate.editable?).to be true
|
||||
end
|
||||
|
||||
it "should be false if debate has more than limit votes" do
|
||||
it "is false if debate has more than limit votes" do
|
||||
create_list(:vote, 4, votable: debate)
|
||||
expect(debate.total_votes).to eq(4)
|
||||
expect(debate.editable?).to be false
|
||||
@@ -108,19 +112,20 @@ describe Debate do
|
||||
|
||||
describe "#editable_by?" do
|
||||
let(:debate) { create(:debate) }
|
||||
before(:each) { Setting["max_votes_for_debate_edit"] = 1 }
|
||||
after(:each) { Setting["max_votes_for_debate_edit"] = 1000 }
|
||||
|
||||
it "should be true if user is the author and debate is editable" do
|
||||
before { Setting["max_votes_for_debate_edit"] = 1 }
|
||||
after { Setting["max_votes_for_debate_edit"] = 1000 }
|
||||
|
||||
it "is true if user is the author and debate is editable" do
|
||||
expect(debate.editable_by?(debate.author)).to be true
|
||||
end
|
||||
|
||||
it "should be false if debate is not editable" do
|
||||
it "is false if debate is not editable" do
|
||||
create_list(:vote, 2, votable: debate)
|
||||
expect(debate.editable_by?(debate.author)).to be false
|
||||
end
|
||||
|
||||
it "should be false if user is not the author" do
|
||||
it "is false if user is not the author" do
|
||||
expect(debate.editable_by?(create(:user))).to be false
|
||||
end
|
||||
end
|
||||
@@ -128,33 +133,33 @@ describe Debate do
|
||||
describe "#votable_by?" do
|
||||
let(:debate) { create(:debate) }
|
||||
|
||||
before(:each) do
|
||||
before do
|
||||
Setting["max_ratio_anon_votes_on_debates"] = 50
|
||||
end
|
||||
|
||||
it "should be true for level two verified users" do
|
||||
it "is true for level two verified users" do
|
||||
user = create(:user, residence_verified_at: Time.current, confirmed_phone: "666333111")
|
||||
expect(debate.votable_by?(user)).to be true
|
||||
end
|
||||
|
||||
it "should be true for level three verified users" do
|
||||
it "is true for level three verified users" do
|
||||
user = create(:user, verified_at: Time.current)
|
||||
expect(debate.votable_by?(user)).to be true
|
||||
end
|
||||
|
||||
it "should be true for anonymous users if allowed anonymous votes" do
|
||||
it "is true for anonymous users if allowed anonymous votes" do
|
||||
debate.update(cached_anonymous_votes_total: 420, cached_votes_total: 1000)
|
||||
user = create(:user)
|
||||
expect(debate.votable_by?(user)).to be true
|
||||
end
|
||||
|
||||
it "should be true for anonymous users if less than 100 votes" do
|
||||
it "is true for anonymous users if less than 100 votes" do
|
||||
debate.update(cached_anonymous_votes_total: 90, cached_votes_total: 92)
|
||||
user = create(:user)
|
||||
expect(debate.votable_by?(user)).to be true
|
||||
end
|
||||
|
||||
it "should be false for anonymous users if too many anonymous votes" do
|
||||
it "is false for anonymous users if too many anonymous votes" do
|
||||
debate.update(cached_anonymous_votes_total: 520, cached_votes_total: 1000)
|
||||
user = create(:user)
|
||||
expect(debate.votable_by?(user)).to be false
|
||||
@@ -164,59 +169,59 @@ describe Debate do
|
||||
describe "#register_vote" do
|
||||
let(:debate) { create(:debate) }
|
||||
|
||||
before(:each) do
|
||||
before do
|
||||
Setting["max_ratio_anon_votes_on_debates"] = 50
|
||||
end
|
||||
|
||||
describe "from level two verified users" do
|
||||
it "should register vote" do
|
||||
it "registers vote" do
|
||||
user = create(:user, residence_verified_at: Time.current, confirmed_phone: "666333111")
|
||||
expect {debate.register_vote(user, 'yes')}.to change{debate.reload.votes_for.size}.by(1)
|
||||
end
|
||||
|
||||
it "should not increase anonymous votes counter " do
|
||||
it "does not increase anonymous votes counter " do
|
||||
user = create(:user, residence_verified_at: Time.current, confirmed_phone: "666333111")
|
||||
expect {debate.register_vote(user, 'yes')}.to_not change{debate.reload.cached_anonymous_votes_total}
|
||||
expect {debate.register_vote(user, 'yes')}.not_to change{debate.reload.cached_anonymous_votes_total}
|
||||
end
|
||||
end
|
||||
|
||||
describe "from level three verified users" do
|
||||
it "should register vote" do
|
||||
it "registers vote" do
|
||||
user = create(:user, verified_at: Time.current)
|
||||
expect {debate.register_vote(user, 'yes')}.to change{debate.reload.votes_for.size}.by(1)
|
||||
end
|
||||
|
||||
it "should not increase anonymous votes counter " do
|
||||
it "does not increase anonymous votes counter " do
|
||||
user = create(:user, verified_at: Time.current)
|
||||
expect {debate.register_vote(user, 'yes')}.to_not change{debate.reload.cached_anonymous_votes_total}
|
||||
expect {debate.register_vote(user, 'yes')}.not_to change{debate.reload.cached_anonymous_votes_total}
|
||||
end
|
||||
end
|
||||
|
||||
describe "from anonymous users when anonymous votes are allowed" do
|
||||
before(:each) {debate.update(cached_anonymous_votes_total: 42, cached_votes_total: 100)}
|
||||
before {debate.update(cached_anonymous_votes_total: 42, cached_votes_total: 100)}
|
||||
|
||||
it "should register vote " do
|
||||
it "registers vote" do
|
||||
user = create(:user)
|
||||
expect {debate.register_vote(user, 'yes')}.to change {debate.reload.votes_for.size}.by(1)
|
||||
end
|
||||
|
||||
it "should increase anonymous votes counter " do
|
||||
it "increases anonymous votes counter" do
|
||||
user = create(:user)
|
||||
expect {debate.register_vote(user, 'yes')}.to change {debate.reload.cached_anonymous_votes_total}.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "from anonymous users when there are too many anonymous votes" do
|
||||
before(:each) {debate.update(cached_anonymous_votes_total: 520, cached_votes_total: 1000)}
|
||||
before {debate.update(cached_anonymous_votes_total: 520, cached_votes_total: 1000)}
|
||||
|
||||
it "should not register vote " do
|
||||
it "does not register vote " do
|
||||
user = create(:user)
|
||||
expect {debate.register_vote(user, 'yes')}.to_not change {debate.reload.votes_for.size}
|
||||
expect {debate.register_vote(user, 'yes')}.not_to change {debate.reload.votes_for.size}
|
||||
end
|
||||
|
||||
it "should not increase anonymous votes counter " do
|
||||
it "does not increase anonymous votes counter " do
|
||||
user = create(:user)
|
||||
expect {debate.register_vote(user, 'yes')}.to_not change {debate.reload.cached_anonymous_votes_total}
|
||||
expect {debate.register_vote(user, 'yes')}.not_to change {debate.reload.cached_anonymous_votes_total}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -329,47 +334,47 @@ describe Debate do
|
||||
describe "cache" do
|
||||
let(:debate) { create(:debate) }
|
||||
|
||||
it "should expire cache when it has a new comment" do
|
||||
it "expires cache when it has a new comment" do
|
||||
expect { create(:comment, commentable: debate) }
|
||||
.to change { debate.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when it has a new vote" do
|
||||
it "expires cache when it has a new vote" do
|
||||
expect { create(:vote, votable: debate) }
|
||||
.to change { debate.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when it has a new flag" do
|
||||
it "expires cache when it has a new flag" do
|
||||
expect { create(:flag, flaggable: debate) }
|
||||
.to change { debate.reload.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when it has a new tag" do
|
||||
it "expires cache when it has a new tag" do
|
||||
expect { debate.update(tag_list: "new tag") }
|
||||
.to change { debate.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when hidden" do
|
||||
it "expires cache when hidden" do
|
||||
expect { debate.hide }
|
||||
.to change { debate.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when the author is hidden" do
|
||||
it "expires cache when the author is hidden" do
|
||||
expect { debate.author.hide }
|
||||
.to change { [debate.reload.updated_at, debate.author.updated_at] }
|
||||
end
|
||||
|
||||
it "should expire cache when the author is erased" do
|
||||
it "expires cache when the author is erased" do
|
||||
expect { debate.author.erase }
|
||||
.to change { [debate.reload.updated_at, debate.author.updated_at] }
|
||||
end
|
||||
|
||||
it "should expire cache when its author changes" do
|
||||
it "expires cache when its author changes" do
|
||||
expect { debate.author.update(username: "Eva") }
|
||||
.to change { [debate.reload.updated_at, debate.author.updated_at] }
|
||||
end
|
||||
|
||||
it "should expire cache when the author's organization get verified" do
|
||||
it "expires cache when the author's organization get verified" do
|
||||
create(:organization, user: debate.author)
|
||||
expect { debate.author.organization.verify }
|
||||
.to change { [debate.reload.updated_at, debate.author.updated_at] }
|
||||
@@ -392,7 +397,7 @@ describe Debate do
|
||||
|
||||
describe "conflictive debates" do
|
||||
|
||||
it "should return true when it has more than 1 flag for 5 positive votes" do
|
||||
it "returns true when it has more than 1 flag for 5 positive votes" do
|
||||
debate.update(cached_votes_up: 4)
|
||||
debate.update(flags_count: 1)
|
||||
expect(debate).to be_conflictive
|
||||
@@ -410,28 +415,28 @@ describe Debate do
|
||||
expect(debate).to be_conflictive
|
||||
end
|
||||
|
||||
it "should return false when it has less than or equal to 1 flag for 5 positive votes" do
|
||||
it "returns false when it has less than or equal to 1 flag for 5 positive votes" do
|
||||
debate.update(cached_votes_up: 5)
|
||||
debate.update(flags_count: 1)
|
||||
expect(debate).to_not be_conflictive
|
||||
expect(debate).not_to be_conflictive
|
||||
|
||||
debate.update(cached_votes_up: 10)
|
||||
debate.update(flags_count: 2)
|
||||
expect(debate).to_not be_conflictive
|
||||
expect(debate).not_to be_conflictive
|
||||
|
||||
debate.update(cached_votes_up: 100)
|
||||
debate.update(flags_count: 2)
|
||||
expect(debate).to_not be_conflictive
|
||||
expect(debate).not_to be_conflictive
|
||||
end
|
||||
|
||||
it "should return false when it has no flags" do
|
||||
it "returns false when it has no flags" do
|
||||
debate.update(flags_count: 0)
|
||||
expect(debate).to_not be_conflictive
|
||||
expect(debate).not_to be_conflictive
|
||||
end
|
||||
|
||||
it "should return false when it has not votes up" do
|
||||
it "returns false when it has not votes up" do
|
||||
debate.update(cached_votes_up: 0)
|
||||
expect(debate).to_not be_conflictive
|
||||
expect(debate).not_to be_conflictive
|
||||
end
|
||||
|
||||
end
|
||||
@@ -442,27 +447,27 @@ describe Debate do
|
||||
|
||||
it "searches by title" do
|
||||
debate = create(:debate, title: 'save the world')
|
||||
results = Debate.search('save the world')
|
||||
results = described_class.search('save the world')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
it "searches by description" do
|
||||
debate = create(:debate, description: 'in order to save the world one must think about...')
|
||||
results = Debate.search('one must think')
|
||||
results = described_class.search('one must think')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
it "searches by author name" do
|
||||
author = create(:user, username: 'Danny Trejo')
|
||||
debate = create(:debate, author: author)
|
||||
results = Debate.search('Danny')
|
||||
results = described_class.search('Danny')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
it "searches by geozone" do
|
||||
geozone = create(:geozone, name: 'California')
|
||||
debate = create(:debate, geozone: geozone)
|
||||
results = Debate.search('California')
|
||||
results = described_class.search('California')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
@@ -473,13 +478,13 @@ describe Debate do
|
||||
it "searches word stems" do
|
||||
debate = create(:debate, title: 'limpiar')
|
||||
|
||||
results = Debate.search('limpiará')
|
||||
results = described_class.search('limpiará')
|
||||
expect(results).to eq([debate])
|
||||
|
||||
results = Debate.search('limpiémos')
|
||||
results = described_class.search('limpiémos')
|
||||
expect(results).to eq([debate])
|
||||
|
||||
results = Debate.search('limpió')
|
||||
results = described_class.search('limpió')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
@@ -490,15 +495,15 @@ describe Debate do
|
||||
it "searches with accents" do
|
||||
debate = create(:debate, title: 'difusión')
|
||||
|
||||
results = Debate.search('difusion')
|
||||
results = described_class.search('difusion')
|
||||
expect(results).to eq([debate])
|
||||
|
||||
debate2 = create(:debate, title: 'estadisticas')
|
||||
results = Debate.search('estadísticas')
|
||||
results = described_class.search('estadísticas')
|
||||
expect(results).to eq([debate2])
|
||||
|
||||
debate3 = create(:debate, title: 'público')
|
||||
results = Debate.search('publico')
|
||||
results = described_class.search('publico')
|
||||
expect(results).to eq([debate3])
|
||||
end
|
||||
|
||||
@@ -508,11 +513,11 @@ describe Debate do
|
||||
it "searches case insensite" do
|
||||
debate = create(:debate, title: 'SHOUT')
|
||||
|
||||
results = Debate.search('shout')
|
||||
results = described_class.search('shout')
|
||||
expect(results).to eq([debate])
|
||||
|
||||
debate2 = create(:debate, title: "scream")
|
||||
results = Debate.search("SCREAM")
|
||||
results = described_class.search("SCREAM")
|
||||
expect(results).to eq([debate2])
|
||||
end
|
||||
end
|
||||
@@ -521,10 +526,10 @@ describe Debate do
|
||||
it "searches by tags" do
|
||||
debate = create(:debate, tag_list: 'Latina')
|
||||
|
||||
results = Debate.search('Latina')
|
||||
results = described_class.search('Latina')
|
||||
expect(results.first).to eq(debate)
|
||||
|
||||
results = Debate.search('Latin')
|
||||
results = described_class.search('Latin')
|
||||
expect(results.first).to eq(debate)
|
||||
end
|
||||
end
|
||||
@@ -535,7 +540,7 @@ describe Debate do
|
||||
debate_description = create(:debate, description: 'stop corruption')
|
||||
debate_title = create(:debate, title: 'stop corruption')
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(debate_title)
|
||||
expect(results.second).to eq(debate_description)
|
||||
@@ -547,7 +552,7 @@ describe Debate do
|
||||
title_most_voted = create(:debate, title: 'stop corruption', cached_votes_up: 10)
|
||||
description_most_voted = create(:debate, description: 'stop corruption', cached_votes_up: 10)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(title_most_voted)
|
||||
expect(results.second).to eq(title_some_votes)
|
||||
@@ -559,7 +564,7 @@ describe Debate do
|
||||
exact_title_few_votes = create(:debate, title: 'stop corruption', cached_votes_up: 5)
|
||||
similar_title_many_votes = create(:debate, title: 'stop some of the corruption', cached_votes_up: 500)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(exact_title_few_votes)
|
||||
expect(results.second).to eq(similar_title_many_votes)
|
||||
@@ -569,7 +574,7 @@ describe Debate do
|
||||
|
||||
context "reorder" do
|
||||
|
||||
it "should be able to reorder by hot_score after searching" do
|
||||
it "is able to reorder by hot_score after searching" do
|
||||
lowest_score = create(:debate, title: 'stop corruption', cached_votes_up: 1)
|
||||
highest_score = create(:debate, title: 'stop corruption', cached_votes_up: 2)
|
||||
average_score = create(:debate, title: 'stop corruption', cached_votes_up: 3)
|
||||
@@ -578,7 +583,7 @@ describe Debate do
|
||||
highest_score.update_column(:hot_score, 100)
|
||||
average_score.update_column(:hot_score, 10)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(average_score)
|
||||
expect(results.second).to eq(highest_score)
|
||||
@@ -591,7 +596,7 @@ describe Debate do
|
||||
expect(results.third).to eq(lowest_score)
|
||||
end
|
||||
|
||||
it "should be able to reorder by confidence_score after searching" do
|
||||
it "is able to reorder by confidence_score after searching" do
|
||||
lowest_score = create(:debate, title: 'stop corruption', cached_votes_up: 1)
|
||||
highest_score = create(:debate, title: 'stop corruption', cached_votes_up: 2)
|
||||
average_score = create(:debate, title: 'stop corruption', cached_votes_up: 3)
|
||||
@@ -600,7 +605,7 @@ describe Debate do
|
||||
highest_score.update_column(:confidence_score, 100)
|
||||
average_score.update_column(:confidence_score, 10)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(average_score)
|
||||
expect(results.second).to eq(highest_score)
|
||||
@@ -613,12 +618,12 @@ describe Debate do
|
||||
expect(results.third).to eq(lowest_score)
|
||||
end
|
||||
|
||||
it "should be able to reorder by created_at after searching" do
|
||||
it "is able to reorder by created_at after searching" do
|
||||
recent = create(:debate, title: 'stop corruption', cached_votes_up: 1, created_at: 1.week.ago)
|
||||
newest = create(:debate, title: 'stop corruption', cached_votes_up: 2, created_at: Time.current)
|
||||
oldest = create(:debate, title: 'stop corruption', cached_votes_up: 3, created_at: 1.month.ago)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(oldest)
|
||||
expect(results.second).to eq(newest)
|
||||
@@ -631,12 +636,12 @@ describe Debate do
|
||||
expect(results.third).to eq(oldest)
|
||||
end
|
||||
|
||||
it "should be able to reorder by most commented after searching" do
|
||||
it "is able to reorder by most commented after searching" do
|
||||
least_commented = create(:debate, title: 'stop corruption', cached_votes_up: 1, comments_count: 1)
|
||||
most_commented = create(:debate, title: 'stop corruption', cached_votes_up: 2, comments_count: 100)
|
||||
some_comments = create(:debate, title: 'stop corruption', cached_votes_up: 3, comments_count: 10)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(some_comments)
|
||||
expect(results.second).to eq(most_commented)
|
||||
@@ -656,28 +661,28 @@ describe Debate do
|
||||
it "no words match" do
|
||||
debate = create(:debate, title: 'save world')
|
||||
|
||||
results = Debate.search('destroy planet')
|
||||
results = described_class.search('destroy planet')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
it "too many typos" do
|
||||
debate = create(:debate, title: 'fantastic')
|
||||
|
||||
results = Debate.search('frantac')
|
||||
results = described_class.search('frantac')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
it "too much stemming" do
|
||||
debate = create(:debate, title: 'reloj')
|
||||
|
||||
results = Debate.search('superrelojimetro')
|
||||
results = described_class.search('superrelojimetro')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
it "empty" do
|
||||
debate = create(:debate, title: 'great')
|
||||
|
||||
results = Debate.search('')
|
||||
results = described_class.search('')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
@@ -685,19 +690,19 @@ describe Debate do
|
||||
end
|
||||
|
||||
describe "#last_week" do
|
||||
it "should return debates created this week" do
|
||||
it "returns debates created this week" do
|
||||
debate = create(:debate)
|
||||
expect(Debate.last_week.all).to include (debate)
|
||||
expect(described_class.last_week.all).to include debate
|
||||
end
|
||||
|
||||
it "should not show debates created more than a week ago" do
|
||||
it "does not show debates created more than a week ago" do
|
||||
debate = create(:debate, created_at: 8.days.ago)
|
||||
expect(Debate.last_week.all).to_not include (debate)
|
||||
expect(described_class.last_week.all).not_to include debate
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_param" do
|
||||
it "should return a friendly url" do
|
||||
it "returns a friendly url" do
|
||||
expect(debate.to_param).to eq "#{debate.id} #{debate.title}".parameterize
|
||||
end
|
||||
end
|
||||
@@ -705,13 +710,63 @@ describe Debate do
|
||||
describe 'public_for_api scope' do
|
||||
it 'returns debates' do
|
||||
debate = create(:debate)
|
||||
expect(Debate.public_for_api).to include(debate)
|
||||
expect(described_class.public_for_api).to include(debate)
|
||||
end
|
||||
|
||||
it 'does not return hidden debates' do
|
||||
debate = create(:debate, :hidden)
|
||||
expect(Debate.public_for_api).to_not include(debate)
|
||||
expect(described_class.public_for_api).not_to include(debate)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recommendations" do
|
||||
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it "does not return any debates when user has not interests" do
|
||||
create(:debate)
|
||||
|
||||
expect(described_class.recommendations(user).size).to eq 0
|
||||
end
|
||||
|
||||
it "returns debates ordered by cached_votes_total" do
|
||||
debate1 = create(:debate, cached_votes_total: 1, tag_list: "Sport")
|
||||
debate2 = create(:debate, cached_votes_total: 5, tag_list: "Sport")
|
||||
debate3 = create(:debate, cached_votes_total: 10, tag_list: "Sport")
|
||||
proposal = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal, user: user)
|
||||
|
||||
result = described_class.recommendations(user).sort_by_recommendations
|
||||
|
||||
expect(result.first).to eq debate3
|
||||
expect(result.second).to eq debate2
|
||||
expect(result.third).to eq debate1
|
||||
end
|
||||
|
||||
it "returns debates related with user interests" do
|
||||
debate1 = create(:debate, tag_list: "Sport")
|
||||
debate2 = create(:debate, tag_list: "Politics")
|
||||
proposal1 = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal1, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
|
||||
expect(result.size).to eq 1
|
||||
expect(result).to eq [debate1]
|
||||
end
|
||||
|
||||
it "does not return debates when user is the author" do
|
||||
debate1 = create(:debate, author: user, tag_list: "Sport")
|
||||
debate2 = create(:debate, tag_list: "Sport")
|
||||
proposal = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
|
||||
expect(result.size).to eq 1
|
||||
expect(result).to eq [debate2]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,79 +4,91 @@ describe DirectMessage do
|
||||
|
||||
let(:direct_message) { build(:direct_message) }
|
||||
|
||||
before(:each) do
|
||||
Setting[:direct_message_max_per_day] = 3
|
||||
end
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(direct_message).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
direct_message.title = nil
|
||||
expect(direct_message).to_not be_valid
|
||||
expect(direct_message).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a body" do
|
||||
it "is not valid without a body" do
|
||||
direct_message.body = nil
|
||||
expect(direct_message).to_not be_valid
|
||||
expect(direct_message).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an associated sender" do
|
||||
it "is not valid without an associated sender" do
|
||||
direct_message.sender = nil
|
||||
expect(direct_message).to_not be_valid
|
||||
expect(direct_message).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an associated receiver" do
|
||||
it "is not valid without an associated receiver" do
|
||||
direct_message.receiver = nil
|
||||
expect(direct_message).to_not be_valid
|
||||
expect(direct_message).not_to be_valid
|
||||
end
|
||||
|
||||
describe "maximum number of direct messages per day" do
|
||||
context "when set" do
|
||||
before do
|
||||
Setting[:direct_message_max_per_day] = 3
|
||||
end
|
||||
|
||||
it "should not be valid if above maximum" do
|
||||
sender = create(:user)
|
||||
direct_message1 = create(:direct_message, sender: sender)
|
||||
direct_message2 = create(:direct_message, sender: sender)
|
||||
direct_message3 = create(:direct_message, sender: sender)
|
||||
it "is not valid if above maximum" do
|
||||
sender = create(:user)
|
||||
direct_message1 = create(:direct_message, sender: sender)
|
||||
direct_message2 = create(:direct_message, sender: sender)
|
||||
direct_message3 = create(:direct_message, sender: sender)
|
||||
|
||||
direct_message4 = build(:direct_message, sender: sender)
|
||||
expect(direct_message4).to_not be_valid
|
||||
direct_message4 = build(:direct_message, sender: sender)
|
||||
expect(direct_message4).not_to be_valid
|
||||
end
|
||||
|
||||
it "is valid if below maximum" do
|
||||
sender = create(:user)
|
||||
direct_message1 = create(:direct_message, sender: sender)
|
||||
direct_message2 = create(:direct_message, sender: sender)
|
||||
|
||||
direct_message3 = build(:direct_message)
|
||||
expect(direct_message).to be_valid
|
||||
end
|
||||
|
||||
it "is valid if no direct_messages sent" do
|
||||
direct_message = build(:direct_message)
|
||||
|
||||
expect(direct_message).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it "should be valid if below maximum" do
|
||||
sender = create(:user)
|
||||
direct_message1 = create(:direct_message, sender: sender)
|
||||
direct_message2 = create(:direct_message, sender: sender)
|
||||
context "when unset" do
|
||||
before do
|
||||
Setting[:direct_message_max_per_day] = nil
|
||||
end
|
||||
|
||||
direct_message3 = build(:direct_message)
|
||||
expect(direct_message).to be_valid
|
||||
it "is valid" do
|
||||
direct_message = build(:direct_message)
|
||||
|
||||
expect(direct_message).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it "should be valid if no direct_messages sent" do
|
||||
direct_message = build(:direct_message)
|
||||
|
||||
expect(direct_message).to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
|
||||
describe "today" do
|
||||
it "should return direct messages created today" do
|
||||
it "returns direct messages created today" do
|
||||
direct_message1 = create(:direct_message, created_at: Time.now.utc.beginning_of_day + 3.hours)
|
||||
direct_message2 = create(:direct_message, created_at: Time.now.utc)
|
||||
direct_message3 = create(:direct_message, created_at: Time.now.utc.end_of_day)
|
||||
|
||||
expect(DirectMessage.today.count).to eq 3
|
||||
expect(described_class.today.count).to eq 3
|
||||
end
|
||||
|
||||
it "should not return direct messages created another day" do
|
||||
it "does not return direct messages created another day" do
|
||||
direct_message1 = create(:direct_message, created_at: 1.day.ago)
|
||||
direct_message2 = create(:direct_message, created_at: 1.day.from_now)
|
||||
|
||||
expect(DirectMessage.today.count).to eq 0
|
||||
expect(described_class.today.count).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
65
spec/models/direct_upload_spec.rb
Normal file
65
spec/models/direct_upload_spec.rb
Normal file
@@ -0,0 +1,65 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe DirectUpload do
|
||||
|
||||
context "configurations" do
|
||||
|
||||
it "is valid for different kind of combinations when attachment is valid" do
|
||||
expect(build(:direct_upload, :proposal, :documents)).to be_valid
|
||||
expect(build(:direct_upload, :proposal, :image)).to be_valid
|
||||
expect(build(:direct_upload, :budget_investment, :documents)).to be_valid
|
||||
expect(build(:direct_upload, :budget_investment, :image)).to be_valid
|
||||
end
|
||||
|
||||
it "is not valid for different kind of combinations with invalid atttachment content types" do
|
||||
expect(build(:direct_upload, :proposal, :documents, attachment: File.new("spec/fixtures/files/clippy.png"))).not_to be_valid
|
||||
expect(build(:direct_upload, :proposal, :image, attachment: File.new("spec/fixtures/files/empty.pdf"))).not_to be_valid
|
||||
expect(build(:direct_upload, :budget_investment, :documents, attachment: File.new("spec/fixtures/files/clippy.png"))).not_to be_valid
|
||||
expect(build(:direct_upload, :budget_investment, :image, attachment: File.new("spec/fixtures/files/empty.pdf"))).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without resource_type" do
|
||||
expect(build(:direct_upload, :proposal, :documents, resource_type: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without resource_relation" do
|
||||
expect(build(:direct_upload, :proposal, :documents, resource_relation: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without attachment" do
|
||||
expect(build(:direct_upload, :proposal, :documents, attachment: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without user" do
|
||||
expect(build(:direct_upload, :proposal, :documents, user: nil)).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "save_attachment" do
|
||||
|
||||
it "saves uploaded file" do
|
||||
proposal_document_direct_upload = build(:direct_upload, :proposal, :documents)
|
||||
|
||||
proposal_document_direct_upload.save_attachment
|
||||
|
||||
expect(File.exist?(proposal_document_direct_upload.relation.attachment.path)).to eq(true)
|
||||
expect(proposal_document_direct_upload.relation.attachment.path).to include('cached_attachments')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "destroy_attachment" do
|
||||
|
||||
it "removes uploaded file" do
|
||||
proposal_document_direct_upload = build(:direct_upload, :proposal, :documents)
|
||||
|
||||
proposal_document_direct_upload.save_attachment
|
||||
uploaded_path = proposal_document_direct_upload.relation.attachment.path
|
||||
proposal_document_direct_upload.destroy_attachment
|
||||
|
||||
expect(File.exist?(uploaded_path)).to eq(false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -8,15 +8,15 @@ describe Flag do
|
||||
describe '.flag' do
|
||||
|
||||
it 'creates a flag when there is none' do
|
||||
expect { described_class.flag(user, comment) }.to change{ Flag.count }.by(1)
|
||||
expect(Flag.last.user).to eq(user)
|
||||
expect(Flag.last.flaggable).to eq(comment)
|
||||
expect { described_class.flag(user, comment) }.to change{ described_class.count }.by(1)
|
||||
expect(described_class.last.user).to eq(user)
|
||||
expect(described_class.last.flaggable).to eq(comment)
|
||||
end
|
||||
|
||||
it 'does nothing if the flag already exists' do
|
||||
described_class.flag(user, comment)
|
||||
expect(described_class.flag(user, comment)).to eq(false)
|
||||
expect(Flag.by_user_and_flaggable(user, comment).count).to eq(1)
|
||||
expect(described_class.by_user_and_flaggable(user, comment).count).to eq(1)
|
||||
end
|
||||
|
||||
it 'increases the flag count' do
|
||||
@@ -30,10 +30,10 @@ describe Flag do
|
||||
end
|
||||
|
||||
describe 'when the flag already exists' do
|
||||
before(:each) { described_class.flag(user, comment) }
|
||||
before { described_class.flag(user, comment) }
|
||||
|
||||
it 'removes an existing flag' do
|
||||
expect { described_class.unflag(user, comment) }.to change{ Flag.count }.by(-1)
|
||||
expect { described_class.unflag(user, comment) }.to change{ described_class.count }.by(-1)
|
||||
end
|
||||
|
||||
it 'decreases the flag count' do
|
||||
@@ -44,7 +44,7 @@ describe Flag do
|
||||
|
||||
describe '.flagged?' do
|
||||
it 'returns false when the user has not flagged the comment' do
|
||||
expect(described_class.flagged?(user, comment)).to_not be
|
||||
expect(described_class.flagged?(user, comment)).not_to be
|
||||
end
|
||||
|
||||
it 'returns true when the user has flagged the comment' do
|
||||
|
||||
@@ -4,23 +4,23 @@ describe Follow do
|
||||
|
||||
let(:follow) { build(:follow, :followed_proposal) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(follow).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a user_id" do
|
||||
it "is not valid without a user_id" do
|
||||
follow.user_id = nil
|
||||
expect(follow).to_not be_valid
|
||||
expect(follow).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a followable_id" do
|
||||
it "is not valid without a followable_id" do
|
||||
follow.followable_id = nil
|
||||
expect(follow).to_not be_valid
|
||||
expect(follow).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a followable_type" do
|
||||
it "is not valid without a followable_type" do
|
||||
follow.followable_type = nil
|
||||
expect(follow).to_not be_valid
|
||||
expect(follow).not_to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -3,40 +3,40 @@ require 'rails_helper'
|
||||
describe Geozone do
|
||||
let(:geozone) { build(:geozone) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(geozone).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a name" do
|
||||
it "is not valid without a name" do
|
||||
geozone.name = nil
|
||||
expect(geozone).to_not be_valid
|
||||
expect(geozone).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#safe_to_destroy?" do
|
||||
let(:geozone) { create(:geozone) }
|
||||
|
||||
it "is true when not linked to other models" do
|
||||
expect(geozone.safe_to_destroy?).to be_truthy
|
||||
expect(geozone).to be_safe_to_destroy
|
||||
end
|
||||
|
||||
it "is false when already linked to user" do
|
||||
create(:user, geozone: geozone)
|
||||
expect(geozone.safe_to_destroy?).to be_falsey
|
||||
expect(geozone).not_to be_safe_to_destroy
|
||||
end
|
||||
|
||||
it "is false when already linked to proposal" do
|
||||
create(:proposal, geozone: geozone)
|
||||
expect(geozone.safe_to_destroy?).to be_falsey
|
||||
expect(geozone).not_to be_safe_to_destroy
|
||||
end
|
||||
|
||||
it "is false when already linked to spending proposal" do
|
||||
create(:spending_proposal, geozone: geozone)
|
||||
expect(geozone.safe_to_destroy?).to be_falsey
|
||||
expect(geozone).not_to be_safe_to_destroy
|
||||
end
|
||||
|
||||
it "is false when already linked to debate" do
|
||||
create(:debate, geozone: geozone)
|
||||
expect(geozone.safe_to_destroy?).to be_falsey
|
||||
expect(geozone).not_to be_safe_to_destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'rails_helper'
|
||||
RSpec.describe Identity, type: :model do
|
||||
let(:identity) { build(:identity) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(identity).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
8
spec/models/image_spec.rb
Normal file
8
spec/models/image_spec.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Image do
|
||||
|
||||
it_behaves_like "image validations", "budget_investment_image"
|
||||
it_behaves_like "image validations", "proposal_image"
|
||||
|
||||
end
|
||||
@@ -4,7 +4,7 @@ RSpec.describe Legislation::Annotation, type: :model do
|
||||
let(:draft_version) { create(:legislation_draft_version) }
|
||||
let(:annotation) { create(:legislation_annotation, draft_version: draft_version) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(draft_version).to be_valid
|
||||
expect(annotation).to be_valid
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'rails_helper'
|
||||
RSpec.describe Legislation::Answer, type: :model do
|
||||
let(:legislation_answer) { build(:legislation_answer) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(legislation_answer).to be_valid
|
||||
end
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'rails_helper'
|
||||
RSpec.describe Legislation::DraftVersion, type: :model do
|
||||
let(:legislation_draft_version) { build(:legislation_draft_version) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(legislation_draft_version).to be_valid
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Legislation::Process, type: :model do
|
||||
describe Legislation::Process do
|
||||
let(:process) { create(:legislation_process) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(process).to be_valid
|
||||
end
|
||||
|
||||
@@ -69,7 +69,7 @@ RSpec.describe Legislation::Process, type: :model do
|
||||
end
|
||||
|
||||
describe "filter scopes" do
|
||||
before(:each) do
|
||||
before do
|
||||
@process_1 = create(:legislation_process, start_date: Date.current - 2.days, end_date: Date.current + 1.day)
|
||||
@process_2 = create(:legislation_process, start_date: Date.current + 1.day, end_date: Date.current + 3.days)
|
||||
@process_3 = create(:legislation_process, start_date: Date.current - 4.days, end_date: Date.current - 3.days)
|
||||
@@ -79,40 +79,41 @@ RSpec.describe Legislation::Process, type: :model do
|
||||
open_processes = ::Legislation::Process.open
|
||||
|
||||
expect(open_processes).to include(@process_1)
|
||||
expect(open_processes).to_not include(@process_2)
|
||||
expect(open_processes).to_not include(@process_3)
|
||||
expect(open_processes).not_to include(@process_2)
|
||||
expect(open_processes).not_to include(@process_3)
|
||||
end
|
||||
|
||||
it "filters next" do
|
||||
next_processes = ::Legislation::Process.next
|
||||
|
||||
expect(next_processes).to include(@process_2)
|
||||
expect(next_processes).to_not include(@process_1)
|
||||
expect(next_processes).to_not include(@process_3)
|
||||
expect(next_processes).not_to include(@process_1)
|
||||
expect(next_processes).not_to include(@process_3)
|
||||
end
|
||||
|
||||
it "filters past" do
|
||||
past_processes = ::Legislation::Process.past
|
||||
|
||||
expect(past_processes).to include(@process_3)
|
||||
expect(past_processes).to_not include(@process_2)
|
||||
expect(past_processes).to_not include(@process_1)
|
||||
expect(past_processes).not_to include(@process_2)
|
||||
expect(past_processes).not_to include(@process_1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#status" do
|
||||
it "should detect planned phase" do
|
||||
it "detects planned phase" do
|
||||
process.update_attributes(start_date: Date.current + 2.days)
|
||||
expect(process.status).to eq(:planned)
|
||||
end
|
||||
|
||||
it "should detect closed phase" do
|
||||
it "detects closed phase" do
|
||||
process.update_attributes(end_date: Date.current - 2.days)
|
||||
expect(process.status).to eq(:closed)
|
||||
end
|
||||
|
||||
it "should detect open phase" do
|
||||
it "detects open phase" do
|
||||
expect(process.status).to eq(:open)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
30
spec/models/legislation/proposal_spec.rb
Normal file
30
spec/models/legislation/proposal_spec.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Legislation::Proposal do
|
||||
let(:proposal) { build(:legislation_proposal) }
|
||||
|
||||
it "is valid" do
|
||||
expect(proposal).to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a process" do
|
||||
proposal.process = nil
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without an author" do
|
||||
proposal.author = nil
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a title" do
|
||||
proposal.title = nil
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a summary" do
|
||||
proposal.summary = nil
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
@@ -3,16 +3,16 @@ require 'rails_helper'
|
||||
RSpec.describe Legislation::QuestionOption, type: :model do
|
||||
let(:legislation_question_option) { build(:legislation_question_option) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(legislation_question_option).to be_valid
|
||||
end
|
||||
|
||||
it "should be unique per question" do
|
||||
it "is unique per question" do
|
||||
question = create(:legislation_question)
|
||||
valid_question_option = create(:legislation_question_option, question: question, value: "uno")
|
||||
|
||||
invalid_question_option = build(:legislation_question_option, question: question, value: "uno")
|
||||
|
||||
expect(invalid_question_option).to_not be_valid
|
||||
expect(invalid_question_option).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Legislation::Question, type: :model do
|
||||
describe Legislation::Question do
|
||||
let(:question) { create(:legislation_question) }
|
||||
|
||||
it "should be valid" do
|
||||
describe "Concerns" do
|
||||
it_behaves_like "notifiable"
|
||||
end
|
||||
|
||||
it "is valid" do
|
||||
expect(question).to be_valid
|
||||
end
|
||||
|
||||
@@ -13,7 +17,7 @@ RSpec.describe Legislation::Question, type: :model do
|
||||
|
||||
expect do
|
||||
question.destroy
|
||||
end.to change { Legislation::Question.count }.by(-1)
|
||||
end.to change { described_class.count }.by(-1)
|
||||
end
|
||||
|
||||
example "when it has options but no answers" do
|
||||
@@ -22,7 +26,7 @@ RSpec.describe Legislation::Question, type: :model do
|
||||
|
||||
expect do
|
||||
question.destroy
|
||||
end.to change { Legislation::Question.count }.by(-1)
|
||||
end.to change { described_class.count }.by(-1)
|
||||
end
|
||||
|
||||
example "when it has options and answers" do
|
||||
@@ -33,7 +37,7 @@ RSpec.describe Legislation::Question, type: :model do
|
||||
|
||||
expect do
|
||||
question.destroy
|
||||
end.to change { Legislation::Question.count }.by(-1)
|
||||
end.to change { described_class.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,11 +45,11 @@ RSpec.describe Legislation::Question, type: :model do
|
||||
let!(:question1) { create(:legislation_question) }
|
||||
let!(:question2) { create(:legislation_question, legislation_process_id: question1.legislation_process_id) }
|
||||
|
||||
it "should return the next question" do
|
||||
it "returns the next question" do
|
||||
expect(question1.next_question_id).to eq(question2.id)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
it "returns nil" do
|
||||
expect(question2.next_question_id).to be_nil
|
||||
end
|
||||
end
|
||||
@@ -54,9 +58,14 @@ RSpec.describe Legislation::Question, type: :model do
|
||||
let!(:question1) { create(:legislation_question) }
|
||||
let!(:question2) { create(:legislation_question, legislation_process_id: question1.legislation_process_id) }
|
||||
|
||||
it "should return the first question" do
|
||||
it "returns the first question" do
|
||||
expect(question1.first_question_id).to eq(question1.id)
|
||||
expect(question2.first_question_id).to eq(question1.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "notifications" do
|
||||
it_behaves_like 'notifiable'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
36
spec/models/map_location_spec.rb
Normal file
36
spec/models/map_location_spec.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe MapLocation do
|
||||
|
||||
let(:map_location) { build(:map_location, :proposal_map_location) }
|
||||
|
||||
it "is valid" do
|
||||
expect(map_location).to be_valid
|
||||
end
|
||||
|
||||
context "#available?" do
|
||||
|
||||
it "returns true when latitude, longitude and zoom defined" do
|
||||
expect(map_location.available?).to be(true)
|
||||
end
|
||||
|
||||
it "returns false when longitude is nil" do
|
||||
map_location.longitude = nil
|
||||
|
||||
expect(map_location.available?).to be(false)
|
||||
end
|
||||
|
||||
it "returns false when latitude is nil" do
|
||||
map_location.latitude = nil
|
||||
|
||||
expect(map_location.available?).to be(false)
|
||||
end
|
||||
|
||||
it "returns false when zoom is nil" do
|
||||
map_location.zoom = nil
|
||||
|
||||
expect(map_location.available?).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -5,7 +5,7 @@ describe Notification do
|
||||
describe "#unread (scope)" do
|
||||
it "returns only unread notifications" do
|
||||
2.times { create :notification }
|
||||
expect(Notification.unread.size).to be 2
|
||||
expect(described_class.unread.size).to be 2
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ describe Notification do
|
||||
old_notification = create :notification
|
||||
new_notification = create :notification
|
||||
|
||||
sorted_notifications = Notification.recent
|
||||
sorted_notifications = described_class.recent
|
||||
expect(sorted_notifications.size).to be 2
|
||||
expect(sorted_notifications.first).to eq new_notification
|
||||
expect(sorted_notifications.last).to eq old_notification
|
||||
@@ -23,8 +23,8 @@ describe Notification do
|
||||
|
||||
describe "#for_render (scope)" do
|
||||
it "returns notifications including notifiable and user" do
|
||||
expect(Notification).to receive(:includes).with(:notifiable).exactly(:once)
|
||||
Notification.for_render
|
||||
allow(described_class).to receive(:includes).with(:notifiable).exactly(:once)
|
||||
described_class.for_render
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,42 +40,29 @@ describe Notification do
|
||||
describe "#mark_as_read" do
|
||||
it "destroys notification" do
|
||||
notification = create :notification
|
||||
expect(Notification.unread.size).to eq 1
|
||||
expect(described_class.unread.size).to eq 1
|
||||
|
||||
notification.mark_as_read
|
||||
expect(Notification.unread.size).to eq 0
|
||||
expect(described_class.unread.size).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "#notification_action" do
|
||||
let(:notifiable) { create(:proposal) }
|
||||
|
||||
context "when action was comment on a debate" do
|
||||
it "returns correct text when someone comments on your debate" do
|
||||
debate = create(:debate)
|
||||
notification = create :notification, notifiable: debate
|
||||
it "returns correct action when someone comments on your commentable" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
expect(notification.notifiable_action).to eq "comments_on"
|
||||
end
|
||||
expect(notification.notifiable_action).to eq "comments_on"
|
||||
end
|
||||
|
||||
context "when action was comment on a debate" do
|
||||
it "returns correct text when someone replies to your comment" do
|
||||
debate = create(:debate)
|
||||
debate_comment = create :comment, commentable: debate
|
||||
notification = create :notification, notifiable: debate_comment
|
||||
it "returns correct action when someone replies to your comment" do
|
||||
comment = create(:comment, commentable: notifiable)
|
||||
notification = create(:notification, notifiable: comment)
|
||||
|
||||
expect(notification.notifiable_action).to eq "replies_to"
|
||||
end
|
||||
expect(notification.notifiable_action).to eq "replies_to"
|
||||
end
|
||||
|
||||
context "when action was proposal notification" do
|
||||
it "returns correct text when the author created a proposal notification" do
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification = create :notification, notifiable: proposal_notification
|
||||
|
||||
expect(notification.notifiable_action).to eq "proposal_notification"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -7,34 +7,34 @@ describe Officing::Residence do
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(residence).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a document number" do
|
||||
it "is not valid without a document number" do
|
||||
residence.document_number = nil
|
||||
expect(residence).to_not be_valid
|
||||
expect(residence).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a document type" do
|
||||
it "is not valid without a document type" do
|
||||
residence.document_type = nil
|
||||
expect(residence).to_not be_valid
|
||||
expect(residence).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a year of birth" do
|
||||
it "is not valid without a year of birth" do
|
||||
residence.year_of_birth = nil
|
||||
expect(residence).to_not be_valid
|
||||
expect(residence).not_to be_valid
|
||||
end
|
||||
|
||||
describe "allowed age" do
|
||||
it "should not be valid if user is under allowed age" do
|
||||
allow_any_instance_of(Officing::Residence).to receive(:date_of_birth).and_return(15.years.ago)
|
||||
expect(residence).to_not be_valid
|
||||
it "is not valid if user is under allowed age" do
|
||||
allow_any_instance_of(described_class).to receive(:date_of_birth).and_return(15.years.ago)
|
||||
expect(residence).not_to be_valid
|
||||
expect(residence.errors[:year_of_birth]).to include("You don't have the required age to participate")
|
||||
end
|
||||
|
||||
it "should be valid if user is above allowed age" do
|
||||
allow_any_instance_of(Officing::Residence).to receive(:date_of_birth).and_return(16.years.ago)
|
||||
it "is valid if user is above allowed age" do
|
||||
allow_any_instance_of(described_class).to receive(:date_of_birth).and_return(16.years.ago)
|
||||
expect(residence).to be_valid
|
||||
expect(residence.errors[:year_of_birth]).to be_empty
|
||||
end
|
||||
@@ -43,20 +43,20 @@ describe Officing::Residence do
|
||||
end
|
||||
|
||||
describe "new" do
|
||||
it "should upcase document number" do
|
||||
residence = Officing::Residence.new(document_number: "x1234567z")
|
||||
it "upcases document number" do
|
||||
residence = described_class.new(document_number: "x1234567z")
|
||||
expect(residence.document_number).to eq("X1234567Z")
|
||||
end
|
||||
|
||||
it "should remove all characters except numbers and letters" do
|
||||
residence = Officing::Residence.new(document_number: " 12.345.678 - B")
|
||||
it "removes all characters except numbers and letters" do
|
||||
residence = described_class.new(document_number: " 12.345.678 - B")
|
||||
expect(residence.document_number).to eq("12345678B")
|
||||
end
|
||||
end
|
||||
|
||||
describe "save" do
|
||||
|
||||
it "should store document number, document type, geozone, date of birth and gender" do
|
||||
it "stores document number, document type, geozone, date of birth and gender" do
|
||||
residence.save
|
||||
user = residence.user
|
||||
|
||||
@@ -69,7 +69,7 @@ describe Officing::Residence do
|
||||
expect(user.geozone).to eq(geozone)
|
||||
end
|
||||
|
||||
it "should find existing user and use demographic information" do
|
||||
it "finds existing user and use demographic information" do
|
||||
geozone = create(:geozone)
|
||||
create(:user, document_number: "12345678Z",
|
||||
document_type: "1",
|
||||
|
||||
@@ -45,29 +45,29 @@ describe Organization do
|
||||
end
|
||||
|
||||
describe "self.search" do
|
||||
before(:all) {@organization = create(:organization, name: "Watershed", user: create(:user, phone_number: "333"))}
|
||||
let!(:organization) { create(:organization, name: "Watershed", user: create(:user, phone_number: "333")) }
|
||||
|
||||
it "returns no results if search term is empty" do
|
||||
expect(Organization.search(" ").size).to eq(0)
|
||||
expect(described_class.search(" ").size).to eq(0)
|
||||
end
|
||||
|
||||
it "finds fuzzily by name" do
|
||||
expect(Organization.search("Greenpeace").size).to eq 0
|
||||
search = Organization.search("Tershe")
|
||||
expect(described_class.search("Greenpeace").size).to eq 0
|
||||
search = described_class.search("Tershe")
|
||||
expect(search.size).to eq 1
|
||||
expect(search.first).to eq @organization
|
||||
expect(search.first).to eq organization
|
||||
end
|
||||
|
||||
scenario "finds by users email" do
|
||||
search = Organization.search(@organization.user.email)
|
||||
search = described_class.search(organization.user.email)
|
||||
expect(search.size).to eq 1
|
||||
expect(search.first).to eq @organization
|
||||
expect(search.first).to eq organization
|
||||
end
|
||||
|
||||
scenario "finds by users phone number" do
|
||||
search = Organization.search(@organization.user.phone_number)
|
||||
search = described_class.search(organization.user.phone_number)
|
||||
expect(search.size).to eq 1
|
||||
expect(search.first).to eq @organization
|
||||
expect(search.first).to eq organization
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,27 +3,75 @@ require 'rails_helper'
|
||||
describe Poll::Answer do
|
||||
|
||||
describe "validations" do
|
||||
it "validates that the answers are included in the Poll::Question's list" do
|
||||
q = create(:poll_question, valid_answers: 'One, Two, Three')
|
||||
expect(build(:poll_answer, question: q, answer: 'One')).to be_valid
|
||||
expect(build(:poll_answer, question: q, answer: 'Two')).to be_valid
|
||||
expect(build(:poll_answer, question: q, answer: 'Three')).to be_valid
|
||||
|
||||
expect(build(:poll_answer, question: q, answer: 'Four')).to_not be_valid
|
||||
let(:answer) { build(:poll_answer) }
|
||||
|
||||
it "is valid" do
|
||||
expect(answer).to be_valid
|
||||
end
|
||||
|
||||
it "is not valid wihout a question" do
|
||||
answer.question = nil
|
||||
expect(answer).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without an author" do
|
||||
answer.author = nil
|
||||
expect(answer).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without an answer" do
|
||||
answer.answer = nil
|
||||
expect(answer).not_to be_valid
|
||||
end
|
||||
|
||||
it "is valid for answers included in the Poll::Question's question_answers list" do
|
||||
question = create(:poll_question)
|
||||
create(:poll_question_answer, title: 'One', question: question)
|
||||
create(:poll_question_answer, title: 'Two', question: question)
|
||||
create(:poll_question_answer, title: 'Three', question: question)
|
||||
|
||||
expect(build(:poll_answer, question: question, answer: 'One')).to be_valid
|
||||
expect(build(:poll_answer, question: question, answer: 'Two')).to be_valid
|
||||
expect(build(:poll_answer, question: question, answer: 'Three')).to be_valid
|
||||
|
||||
expect(build(:poll_answer, question: question, answer: 'Four')).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#record_voter_participation" do
|
||||
|
||||
let(:author) { create(:user, :level_two) }
|
||||
let(:poll) { create(:poll) }
|
||||
let(:question) { create(:poll_question, :with_answers, poll: poll) }
|
||||
|
||||
it "creates a poll_voter with user and poll data" do
|
||||
answer = create(:poll_answer)
|
||||
answer = create(:poll_answer, question: question, author: author, answer: "Yes")
|
||||
expect(answer.poll.voters).to be_blank
|
||||
|
||||
answer.record_voter_participation
|
||||
expect(answer.poll.reload.voters.size).to eq(1)
|
||||
voter = answer.poll.voters.first
|
||||
answer.record_voter_participation('token')
|
||||
expect(poll.reload.voters.size).to eq(1)
|
||||
voter = poll.voters.first
|
||||
|
||||
expect(voter.document_number).to eq(answer.author.document_number)
|
||||
expect(voter.poll_id).to eq(answer.poll.id)
|
||||
expect(voter.officer_id).to eq(nil)
|
||||
end
|
||||
|
||||
it "updates a poll_voter with user and poll data" do
|
||||
answer = create(:poll_answer, question: question, author: author, answer: "Yes")
|
||||
answer.record_voter_participation('token')
|
||||
|
||||
expect(poll.reload.voters.size).to eq(1)
|
||||
|
||||
answer = create(:poll_answer, question: question, author: author, answer: "No")
|
||||
answer.record_voter_participation('token')
|
||||
|
||||
expect(poll.reload.voters.size).to eq(1)
|
||||
|
||||
voter = poll.voters.first
|
||||
expect(voter.document_number).to eq(answer.author.document_number)
|
||||
expect(voter.poll_id).to eq(answer.poll.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
29
spec/models/poll/booth_assignment_spec.rb
Normal file
29
spec/models/poll/booth_assignment_spec.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Poll::BoothAssignment do
|
||||
let(:poll){create(:poll)}
|
||||
let(:booth){create(:poll_booth)}
|
||||
let(:booth1){create(:poll_booth)}
|
||||
|
||||
it "checks if there are shifts" do
|
||||
assignment_with_shifts = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
assignment_without_shifts = create(:poll_booth_assignment, poll: poll, booth: booth1)
|
||||
officer = create(:poll_officer)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: assignment_with_shifts)
|
||||
create(:poll_shift, booth: booth, officer: officer)
|
||||
|
||||
expect(assignment_with_shifts.shifts?).to eq(true)
|
||||
expect(assignment_without_shifts.shifts?).to eq(false)
|
||||
end
|
||||
|
||||
it "deletes shifts associated to booth assignments" do
|
||||
assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
officer = create(:poll_officer)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: assignment)
|
||||
create(:poll_shift, booth: booth, officer: officer)
|
||||
|
||||
assignment.destroy
|
||||
|
||||
expect(Poll::Shift.all.count).to eq(0)
|
||||
end
|
||||
end
|
||||
@@ -1,26 +1,26 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :booth do
|
||||
describe Poll::Booth do
|
||||
|
||||
let(:booth) { build(:poll_booth) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(booth).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a name" do
|
||||
it "is not valid without a name" do
|
||||
booth.name = nil
|
||||
expect(booth).to_not be_valid
|
||||
expect(booth).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#search" do
|
||||
it "should find booths searching by name or location" do
|
||||
it "finds booths searching by name or location" do
|
||||
booth1 = create(:poll_booth, name: "Booth number 1", location: "City center")
|
||||
booth2 = create(:poll_booth, name: "Central", location: "Town hall")
|
||||
|
||||
expect(Poll::Booth.search("number")).to eq([booth1])
|
||||
expect(Poll::Booth.search("hall")).to eq([booth2])
|
||||
expect(Poll::Booth.search("cen").size).to eq 2
|
||||
expect(described_class.search("number")).to eq([booth1])
|
||||
expect(described_class.search("hall")).to eq([booth2])
|
||||
expect(described_class.search("cen").size).to eq 2
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,10 +39,10 @@ describe :booth do
|
||||
create(:poll_booth_assignment, poll: incoming_poll, booth: booth_for_incoming_poll)
|
||||
create(:poll_booth_assignment, poll: expired_poll, booth: booth_for_expired_poll)
|
||||
|
||||
expect(Poll::Booth.available).to include(booth_for_current_poll)
|
||||
expect(Poll::Booth.available).to include(booth_for_incoming_poll)
|
||||
expect(Poll::Booth.available).to_not include(booth_for_expired_poll)
|
||||
expect(described_class.available).to include(booth_for_current_poll)
|
||||
expect(described_class.available).to include(booth_for_incoming_poll)
|
||||
expect(described_class.available).not_to include(booth_for_expired_poll)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Poll::NullResult do
|
||||
|
||||
describe "logging changes" do
|
||||
it "should update amount_log if amount changes" do
|
||||
null_result = create(:poll_null_result, amount: 33)
|
||||
|
||||
expect(null_result.amount_log).to eq("")
|
||||
|
||||
null_result.amount = 33
|
||||
null_result.save
|
||||
null_result.amount = 32
|
||||
null_result.save
|
||||
null_result.amount = 34
|
||||
null_result.save
|
||||
|
||||
expect(null_result.amount_log).to eq(":33:32")
|
||||
end
|
||||
|
||||
it "should update officer_assignment_id_log if amount changes" do
|
||||
null_result = create(:poll_null_result, amount: 33)
|
||||
|
||||
expect(null_result.amount_log).to eq("")
|
||||
expect(null_result.officer_assignment_id_log).to eq("")
|
||||
|
||||
null_result.amount = 33
|
||||
null_result.officer_assignment = create(:poll_officer_assignment, id: 101)
|
||||
null_result.save
|
||||
|
||||
null_result.amount = 32
|
||||
null_result.officer_assignment = create(:poll_officer_assignment, id: 102)
|
||||
null_result.save
|
||||
|
||||
null_result.amount = 34
|
||||
null_result.officer_assignment = create(:poll_officer_assignment, id: 103)
|
||||
null_result.save
|
||||
|
||||
expect(null_result.amount_log).to eq(":33:32")
|
||||
expect(null_result.officer_assignment_id_log).to eq(":101:102")
|
||||
end
|
||||
|
||||
it "should update author_id if amount changes" do
|
||||
null_result = create(:poll_null_result, amount: 33)
|
||||
|
||||
expect(null_result.amount_log).to eq("")
|
||||
expect(null_result.author_id_log).to eq("")
|
||||
|
||||
author_A = create(:poll_officer).user
|
||||
author_B = create(:poll_officer).user
|
||||
author_C = create(:poll_officer).user
|
||||
|
||||
null_result.amount = 33
|
||||
null_result.author_id = author_A.id
|
||||
null_result.save!
|
||||
|
||||
null_result.amount = 32
|
||||
null_result.author_id = author_B.id
|
||||
null_result.save!
|
||||
|
||||
null_result.amount = 34
|
||||
null_result.author_id = author_C.id
|
||||
null_result.save!
|
||||
|
||||
expect(null_result.amount_log).to eq(":33:32")
|
||||
expect(null_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :officer_assignment do
|
||||
it "should log user data on creation" do
|
||||
describe Poll::OfficerAssignment do
|
||||
it "logs user data on creation" do
|
||||
user = create(:user, username: "Larry Bird", email: "larry@lege.nd")
|
||||
officer = create(:poll_officer, user: user)
|
||||
|
||||
@@ -9,4 +9,4 @@ describe :officer_assignment do
|
||||
|
||||
expect(oa.reload.user_data_log).to eq "#{user.id} - Larry Bird (larry@lege.nd)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :officer do
|
||||
describe Poll::Officer do
|
||||
|
||||
describe "#voting_days_assigned_polls" do
|
||||
it "should return all polls with this officer assigned during voting days" do
|
||||
it "returns all polls with this officer assigned during voting days" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
poll_1 = create(:poll)
|
||||
@@ -25,7 +25,7 @@ describe :officer do
|
||||
expect(assigned_polls.include?(poll_3)).to eq(false)
|
||||
end
|
||||
|
||||
it "should not return polls with this officer assigned for final recount/results" do
|
||||
it "does not return polls with this officer assigned for final recount/results" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
poll_1 = create(:poll)
|
||||
@@ -43,7 +43,7 @@ describe :officer do
|
||||
expect(assigned_polls.include?(poll_2)).to eq(false)
|
||||
end
|
||||
|
||||
it "should return polls ordered by end date (desc)" do
|
||||
it "returns polls ordered by end date (desc)" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
poll_1 = create(:poll, ends_at: 1.day.ago)
|
||||
@@ -63,7 +63,7 @@ describe :officer do
|
||||
end
|
||||
|
||||
describe "#final_days_assigned_polls" do
|
||||
it "should return all polls with this officer assigned for final recount/results" do
|
||||
it "returns all polls with this officer assigned for final recount/results" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
poll_1 = create(:poll)
|
||||
@@ -85,7 +85,7 @@ describe :officer do
|
||||
expect(assigned_polls.include?(poll_3)).to eq(false)
|
||||
end
|
||||
|
||||
it "should not return polls with this officer assigned for voting days" do
|
||||
it "does not return polls with this officer assigned for voting days" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
poll_1 = create(:poll)
|
||||
@@ -103,7 +103,7 @@ describe :officer do
|
||||
expect(assigned_polls.include?(poll_2)).to eq(true)
|
||||
end
|
||||
|
||||
it "should return polls ordered by end date (desc)" do
|
||||
it "returns polls ordered by end date (desc)" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
poll_1 = create(:poll, ends_at: 1.day.ago)
|
||||
@@ -121,4 +121,4 @@ describe :officer do
|
||||
expect(assigned_polls.last).to eq(poll_3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,17 +4,21 @@ describe Poll::PartialResult do
|
||||
|
||||
describe "validations" do
|
||||
it "validates that the answers are included in the Poll::Question's list" do
|
||||
q = create(:poll_question, valid_answers: 'One, Two, Three')
|
||||
expect(build(:poll_partial_result, question: q, answer: 'One')).to be_valid
|
||||
expect(build(:poll_partial_result, question: q, answer: 'Two')).to be_valid
|
||||
expect(build(:poll_partial_result, question: q, answer: 'Three')).to be_valid
|
||||
question = create(:poll_question)
|
||||
create(:poll_question_answer, title: 'One', question: question)
|
||||
create(:poll_question_answer, title: 'Two', question: question)
|
||||
create(:poll_question_answer, title: 'Three', question: question)
|
||||
|
||||
expect(build(:poll_partial_result, question: q, answer: 'Four')).to_not be_valid
|
||||
expect(build(:poll_partial_result, question: question, answer: 'One')).to be_valid
|
||||
expect(build(:poll_partial_result, question: question, answer: 'Two')).to be_valid
|
||||
expect(build(:poll_partial_result, question: question, answer: 'Three')).to be_valid
|
||||
|
||||
expect(build(:poll_partial_result, question: question, answer: 'Four')).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "logging changes" do
|
||||
it "should update amount_log if amount changes" do
|
||||
it "updates amount_log if amount changes" do
|
||||
partial_result = create(:poll_partial_result, amount: 33)
|
||||
|
||||
expect(partial_result.amount_log).to eq("")
|
||||
@@ -29,7 +33,7 @@ describe Poll::PartialResult do
|
||||
expect(partial_result.amount_log).to eq(":33:32")
|
||||
end
|
||||
|
||||
it "should update officer_assignment_id_log if amount changes" do
|
||||
it "updates officer_assignment_id_log if amount changes" do
|
||||
partial_result = create(:poll_partial_result, amount: 33)
|
||||
|
||||
expect(partial_result.amount_log).to eq("")
|
||||
@@ -51,30 +55,30 @@ describe Poll::PartialResult do
|
||||
expect(partial_result.officer_assignment_id_log).to eq(":10:20")
|
||||
end
|
||||
|
||||
it "should update author_id if amount changes" do
|
||||
it "updates author_id if amount changes" do
|
||||
partial_result = create(:poll_partial_result, amount: 33)
|
||||
|
||||
expect(partial_result.amount_log).to eq("")
|
||||
expect(partial_result.author_id_log).to eq("")
|
||||
|
||||
author_A = create(:poll_officer).user
|
||||
author_B = create(:poll_officer).user
|
||||
author_C = create(:poll_officer).user
|
||||
author1 = create(:poll_officer).user
|
||||
author2 = create(:poll_officer).user
|
||||
author3 = create(:poll_officer).user
|
||||
|
||||
partial_result.amount = 33
|
||||
partial_result.author_id = author_A.id
|
||||
partial_result.author_id = author1.id
|
||||
partial_result.save!
|
||||
|
||||
partial_result.amount = 32
|
||||
partial_result.author_id = author_B.id
|
||||
partial_result.author_id = author2.id
|
||||
partial_result.save!
|
||||
|
||||
partial_result.amount = 34
|
||||
partial_result.author_id = author_C.id
|
||||
partial_result.author_id = author3.id
|
||||
partial_result.save!
|
||||
|
||||
expect(partial_result.amount_log).to eq(":33:32")
|
||||
expect(partial_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}")
|
||||
expect(partial_result.author_id_log).to eq(":#{author1.id}:#{author2.id}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,40 +1,44 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :poll do
|
||||
describe Poll do
|
||||
|
||||
let(:poll) { build(:poll) }
|
||||
|
||||
describe "Concerns" do
|
||||
it_behaves_like "notifiable"
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(poll).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a name" do
|
||||
it "is not valid without a name" do
|
||||
poll.name = nil
|
||||
expect(poll).to_not be_valid
|
||||
expect(poll).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a start date" do
|
||||
it "is not valid without a start date" do
|
||||
poll.starts_at = nil
|
||||
expect(poll).to_not be_valid
|
||||
expect(poll).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an end date" do
|
||||
it "is not valid without an end date" do
|
||||
poll.ends_at = nil
|
||||
expect(poll).to_not be_valid
|
||||
expect(poll).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a proper start/end date range" do
|
||||
it "is not valid without a proper start/end date range" do
|
||||
poll.starts_at = 1.week.ago
|
||||
poll.ends_at = 2.months.ago
|
||||
expect(poll).to_not be_valid
|
||||
expect(poll).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#opened?" do
|
||||
it "returns true only when it isn't too early or too late" do
|
||||
expect(create(:poll, :incoming)).to_not be_current
|
||||
expect(create(:poll, :expired)).to_not be_current
|
||||
expect(create(:poll, :incoming)).not_to be_current
|
||||
expect(create(:poll, :expired)).not_to be_current
|
||||
expect(create(:poll)).to be_current
|
||||
end
|
||||
end
|
||||
@@ -42,22 +46,22 @@ describe :poll do
|
||||
describe "#incoming?" do
|
||||
it "returns true only when it is too early" do
|
||||
expect(create(:poll, :incoming)).to be_incoming
|
||||
expect(create(:poll, :expired)).to_not be_incoming
|
||||
expect(create(:poll)).to_not be_incoming
|
||||
expect(create(:poll, :expired)).not_to be_incoming
|
||||
expect(create(:poll)).not_to be_incoming
|
||||
end
|
||||
end
|
||||
|
||||
describe "#expired?" do
|
||||
it "returns true only when it is too late" do
|
||||
expect(create(:poll, :incoming)).to_not be_expired
|
||||
expect(create(:poll, :incoming)).not_to be_expired
|
||||
expect(create(:poll, :expired)).to be_expired
|
||||
expect(create(:poll)).to_not be_expired
|
||||
expect(create(:poll)).not_to be_expired
|
||||
end
|
||||
end
|
||||
|
||||
describe "#published?" do
|
||||
it "returns true only when published is true" do
|
||||
expect(create(:poll)).to_not be_published
|
||||
expect(create(:poll)).not_to be_published
|
||||
expect(create(:poll, :published)).to be_published
|
||||
end
|
||||
end
|
||||
@@ -68,11 +72,43 @@ describe :poll do
|
||||
incoming = create(:poll, :incoming)
|
||||
expired = create(:poll, :expired)
|
||||
|
||||
current_or_incoming = Poll.current_or_incoming
|
||||
current_or_incoming = described_class.current_or_incoming
|
||||
|
||||
expect(current_or_incoming).to include(current)
|
||||
expect(current_or_incoming).to include(incoming)
|
||||
expect(current_or_incoming).to_not include(expired)
|
||||
expect(current_or_incoming).not_to include(expired)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recounting" do
|
||||
it "returns polls in recount & scrutiny phase" do
|
||||
current = create(:poll, :current)
|
||||
incoming = create(:poll, :incoming)
|
||||
expired = create(:poll, :expired)
|
||||
recounting = create(:poll, :recounting)
|
||||
|
||||
recounting_polls = described_class.recounting
|
||||
|
||||
expect(recounting_polls).not_to include(current)
|
||||
expect(recounting_polls).not_to include(incoming)
|
||||
expect(recounting_polls).not_to include(expired)
|
||||
expect(recounting_polls).to include(recounting)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#current_or_recounting_or_incoming" do
|
||||
it "returns current or recounting or incoming polls" do
|
||||
current = create(:poll, :current)
|
||||
incoming = create(:poll, :incoming)
|
||||
expired = create(:poll, :expired)
|
||||
recounting = create(:poll, :recounting)
|
||||
|
||||
current_or_recounting_or_incoming = described_class.current_or_recounting_or_incoming
|
||||
|
||||
expect(current_or_recounting_or_incoming).to include(current)
|
||||
expect(current_or_recounting_or_incoming).to include(recounting)
|
||||
expect(current_or_recounting_or_incoming).to include(incoming)
|
||||
expect(current_or_recounting_or_incoming).not_to include(expired)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,15 +133,15 @@ describe :poll do
|
||||
describe 'instance method' do
|
||||
it "rejects non-users and level 1 users" do
|
||||
all_polls.each do |poll|
|
||||
expect(poll).to_not be_answerable_by(non_user)
|
||||
expect(poll).to_not be_answerable_by(level1)
|
||||
expect(poll).not_to be_answerable_by(non_user)
|
||||
expect(poll).not_to be_answerable_by(level1)
|
||||
end
|
||||
end
|
||||
|
||||
it "rejects everyone when not current" do
|
||||
non_current_polls.each do |poll|
|
||||
all_users.each do |user|
|
||||
expect(poll).to_not be_answerable_by(user)
|
||||
expect(poll).not_to be_answerable_by(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -116,26 +152,56 @@ describe :poll do
|
||||
end
|
||||
|
||||
it "accepts level 2 users only from the same geozone when restricted by geozone" do
|
||||
expect(current_restricted_poll).to_not be_answerable_by(level2)
|
||||
expect(current_restricted_poll).not_to be_answerable_by(level2)
|
||||
expect(current_restricted_poll).to be_answerable_by(level2_from_geozone)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'class method' do
|
||||
it "returns no polls for non-users and level 1 users" do
|
||||
expect(Poll.answerable_by(nil)).to be_empty
|
||||
expect(Poll.answerable_by(level1)).to be_empty
|
||||
expect(described_class.answerable_by(nil)).to be_empty
|
||||
expect(described_class.answerable_by(level1)).to be_empty
|
||||
end
|
||||
|
||||
it "returns unrestricted polls for level 2 users" do
|
||||
expect(Poll.answerable_by(level2).to_a).to eq([current_poll])
|
||||
expect(described_class.answerable_by(level2).to_a).to eq([current_poll])
|
||||
end
|
||||
|
||||
it "returns restricted & unrestricted polls for level 2 users of the correct geozone" do
|
||||
list = Poll.answerable_by(level2_from_geozone)
|
||||
.order(:geozone_restricted)
|
||||
list = described_class.answerable_by(level2_from_geozone)
|
||||
.order(:geozone_restricted)
|
||||
expect(list.to_a).to eq([current_poll, current_restricted_poll])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#voted_in_booth?" do
|
||||
|
||||
it "returns true if the user has already voted in booth" do
|
||||
user = create(:user, :level_two)
|
||||
poll = create(:poll)
|
||||
|
||||
create(:poll_voter, poll: poll, user: user, origin: "booth")
|
||||
|
||||
expect(poll.voted_in_booth?(user)).to be
|
||||
end
|
||||
|
||||
it "returns false if the user has not already voted in a booth" do
|
||||
user = create(:user, :level_two)
|
||||
poll = create(:poll)
|
||||
|
||||
expect(poll.voted_in_booth?(user)).not_to be
|
||||
end
|
||||
|
||||
it "returns false if the user has voted in web" do
|
||||
user = create(:user, :level_two)
|
||||
poll = create(:poll)
|
||||
|
||||
create(:poll_voter, poll: poll, user: user, origin: "web")
|
||||
|
||||
expect(poll.voted_in_booth?(user)).not_to be
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -3,20 +3,13 @@ require 'rails_helper'
|
||||
RSpec.describe Poll::Question, type: :model do
|
||||
let(:poll_question) { build(:poll_question) }
|
||||
|
||||
describe "#valid_answers" do
|
||||
it "gets a comma-separated string, but returns an array" do
|
||||
poll_question.valid_answers = "Yes, No"
|
||||
expect(poll_question.valid_answers).to eq(["Yes", "No"])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#poll_question_id" do
|
||||
it "should be invalid if a poll is not selected" do
|
||||
it "is invalid if a poll is not selected" do
|
||||
poll_question.poll_id = nil
|
||||
expect(poll_question).to_not be_valid
|
||||
expect(poll_question).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if a poll is selected" do
|
||||
it "is valid if a poll is selected" do
|
||||
poll_question.poll_id = 1
|
||||
expect(poll_question).to be_valid
|
||||
end
|
||||
@@ -27,7 +20,6 @@ RSpec.describe Poll::Question, type: :model do
|
||||
create_list(:geozone, 3)
|
||||
p = create(:proposal)
|
||||
poll_question.copy_attributes_from_proposal(p)
|
||||
expect(poll_question.valid_answers).to eq(['Yes', 'No'])
|
||||
expect(poll_question.author).to eq(p.author)
|
||||
expect(poll_question.author_visible_name).to eq(p.author.name)
|
||||
expect(poll_question.proposal_id).to eq(p.id)
|
||||
|
||||
104
spec/models/poll/recount_spec.rb
Normal file
104
spec/models/poll/recount_spec.rb
Normal file
@@ -0,0 +1,104 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Poll::Recount do
|
||||
|
||||
describe "logging changes" do
|
||||
let(:author) { create(:user) }
|
||||
let(:officer_assignment) { create(:poll_officer_assignment) }
|
||||
let(:poll_recount) { create(:poll_recount, author: author, officer_assignment: officer_assignment) }
|
||||
|
||||
it "updates white_amount_log if white_amount changes" do
|
||||
poll_recount.white_amount = 33
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq("")
|
||||
|
||||
poll_recount.white_amount = 33
|
||||
poll_recount.save
|
||||
poll_recount.white_amount = 32
|
||||
poll_recount.save
|
||||
poll_recount.white_amount = 34
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq(":0:33:32")
|
||||
end
|
||||
|
||||
it "updates null_amount_log if null_amount changes" do
|
||||
poll_recount.null_amount = 33
|
||||
|
||||
expect(poll_recount.null_amount_log).to eq("")
|
||||
|
||||
poll_recount.null_amount = 33
|
||||
poll_recount.save
|
||||
poll_recount.null_amount = 32
|
||||
poll_recount.save
|
||||
poll_recount.null_amount = 34
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.null_amount_log).to eq(":0:33:32")
|
||||
end
|
||||
|
||||
it "updates total_amount_log if total_amount changes" do
|
||||
poll_recount.total_amount = 33
|
||||
|
||||
expect(poll_recount.total_amount_log).to eq("")
|
||||
|
||||
poll_recount.total_amount = 33
|
||||
poll_recount.save
|
||||
poll_recount.total_amount = 32
|
||||
poll_recount.save
|
||||
poll_recount.total_amount = 34
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.total_amount_log).to eq(":0:33:32")
|
||||
end
|
||||
|
||||
it "updates officer_assignment_id_log if amount changes" do
|
||||
poll_recount.white_amount = 33
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq("")
|
||||
expect(poll_recount.officer_assignment_id_log).to eq("")
|
||||
|
||||
poll_recount.white_amount = 33
|
||||
poll_recount.officer_assignment = create(:poll_officer_assignment, id: 101)
|
||||
poll_recount.save
|
||||
|
||||
poll_recount.white_amount = 32
|
||||
poll_recount.officer_assignment = create(:poll_officer_assignment, id: 102)
|
||||
poll_recount.save
|
||||
|
||||
poll_recount.white_amount = 34
|
||||
poll_recount.officer_assignment = create(:poll_officer_assignment, id: 103)
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq(":0:33:32")
|
||||
expect(poll_recount.officer_assignment_id_log).to eq(":#{officer_assignment.id}:101:102")
|
||||
end
|
||||
|
||||
it "updates author_id if amount changes" do
|
||||
poll_recount.white_amount = 33
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq("")
|
||||
expect(poll_recount.author_id_log).to eq("")
|
||||
|
||||
first_author = create(:poll_officer).user
|
||||
second_author = create(:poll_officer).user
|
||||
third_author = create(:poll_officer).user
|
||||
|
||||
poll_recount.white_amount = 33
|
||||
poll_recount.author_id = first_author.id
|
||||
poll_recount.save!
|
||||
|
||||
poll_recount.white_amount = 32
|
||||
poll_recount.author_id = second_author.id
|
||||
poll_recount.save!
|
||||
|
||||
poll_recount.white_amount = 34
|
||||
poll_recount.author_id = third_author.id
|
||||
poll_recount.save!
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq(":0:33:32")
|
||||
expect(poll_recount.author_id_log).to eq(":#{author.id}:#{first_author.id}:#{second_author.id}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,77 +1,117 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :shift do
|
||||
let(:shift) { build(:poll_shift) }
|
||||
describe Poll::Shift do
|
||||
let(:poll) { create(:poll) }
|
||||
let(:booth) { create(:poll_booth) }
|
||||
let(:user) { create(:user, username: "Ana", email: "ana@example.com") }
|
||||
let(:officer) { create(:poll_officer, user: user) }
|
||||
let(:recount_shift) { build(:poll_shift, booth: booth, officer: officer, date: Date.current, task: :recount_scrutiny) }
|
||||
|
||||
describe "validations" do
|
||||
let(:shift) { build(:poll_shift) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(shift).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a booth" do
|
||||
it "is not valid without a booth" do
|
||||
shift.booth = nil
|
||||
expect(shift).to_not be_valid
|
||||
expect(shift).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an officer" do
|
||||
it "is not valid without an officer" do
|
||||
shift.officer = nil
|
||||
expect(shift).to_not be_valid
|
||||
expect(shift).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a date" do
|
||||
it "is not valid without a date" do
|
||||
shift.date = nil
|
||||
expect(shift).to_not be_valid
|
||||
expect(shift).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a task" do
|
||||
shift.task = nil
|
||||
expect(shift).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid with same booth, officer, date and task" do
|
||||
recount_shift.save
|
||||
|
||||
expect(build(:poll_shift, booth: booth, officer: officer, date: Date.current, task: :recount_scrutiny)).not_to be_valid
|
||||
end
|
||||
|
||||
it "is valid with same booth, officer and date but different task" do
|
||||
recount_shift.save
|
||||
|
||||
expect(build(:poll_shift, booth: booth, officer: officer, date: Date.current, task: :vote_collection)).to be_valid
|
||||
end
|
||||
|
||||
it "is valid with same booth, officer and task but different date" do
|
||||
recount_shift.save
|
||||
|
||||
expect(build(:poll_shift, booth: booth, officer: officer, date: Date.tomorrow, task: :recount_scrutiny)).to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "officer_assignments" do
|
||||
|
||||
it "should create corresponding officer_assignments" do
|
||||
poll1 = create(:poll)
|
||||
it "creates and destroy corresponding officer_assignments" do
|
||||
poll2 = create(:poll)
|
||||
poll3 = create(:poll)
|
||||
|
||||
booth = create(:poll_booth)
|
||||
officer = create(:poll_officer)
|
||||
|
||||
booth_assignment1 = create(:poll_booth_assignment, poll: poll1, booth: booth)
|
||||
booth_assignment1 = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
booth_assignment2 = create(:poll_booth_assignment, poll: poll2, booth: booth)
|
||||
|
||||
shift = create(:poll_shift, booth: booth, officer: officer, date: Date.current)
|
||||
expect { create(:poll_shift, booth: booth, officer: officer, date: Date.current) }.to change {Poll::OfficerAssignment.all.count}.by(2)
|
||||
|
||||
officer_assignments = Poll::OfficerAssignment.all
|
||||
expect(officer_assignments.count).to eq(2)
|
||||
|
||||
oa1 = officer_assignments.first
|
||||
oa2 = officer_assignments.second
|
||||
|
||||
expect(oa1.officer).to eq(officer)
|
||||
expect(oa1.date).to eq(Date.current)
|
||||
expect(oa1.booth_assignment).to eq(booth_assignment1)
|
||||
expect(oa1.final).to be_falsey
|
||||
|
||||
expect(oa2.officer).to eq(officer)
|
||||
expect(oa2.date).to eq(Date.current)
|
||||
expect(oa2.booth_assignment).to eq(booth_assignment2)
|
||||
expect(oa2.final).to be_falsey
|
||||
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment1, date: Date.tomorrow)
|
||||
|
||||
expect { described_class.last.destroy }.to change {Poll::OfficerAssignment.all.count}.by(-2)
|
||||
end
|
||||
|
||||
it "creates final officer_assignments" do
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
recount_shift.save
|
||||
|
||||
officer_assignments = Poll::OfficerAssignment.all
|
||||
expect(officer_assignments.count).to eq(1)
|
||||
|
||||
officer_assignment = officer_assignments.first
|
||||
|
||||
expect(officer_assignment.officer).to eq(officer)
|
||||
expect(officer_assignment.date).to eq(Date.current)
|
||||
expect(officer_assignment.booth_assignment).to eq(booth_assignment)
|
||||
expect(officer_assignment.final).to be_truthy
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#persist_data" do
|
||||
let(:shift) { create(:poll_shift, officer: officer, booth: booth) }
|
||||
|
||||
let(:user) { create(:user, username: "Ana", email: "ana@example.com") }
|
||||
let(:officer) { create(:poll_officer, user: user) }
|
||||
let(:shift) { create(:poll_shift, officer: officer) }
|
||||
|
||||
it "should maintain officer data after destroying associated user" do
|
||||
it "maintains officer data after destroying associated user" do
|
||||
shift.officer.user.destroy
|
||||
|
||||
expect(shift.officer_name).to eq "Ana"
|
||||
expect(shift.officer_email).to eq "ana@example.com"
|
||||
end
|
||||
|
||||
it "should maintain officer data after destroying officer role" do
|
||||
it "maintains officer data after destroying officer role" do
|
||||
shift.officer.destroy
|
||||
|
||||
expect(shift.officer_name).to eq "Ana"
|
||||
|
||||
45
spec/models/poll/stats_spec.rb
Normal file
45
spec/models/poll/stats_spec.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Poll::Stats do
|
||||
|
||||
describe "Calculate stats" do
|
||||
it "Generate the correct stats" do
|
||||
poll = create(:poll)
|
||||
booth = create(:poll_booth)
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
create(:poll_voter, poll: poll, origin: 'web')
|
||||
3.times {create(:poll_voter, poll: poll, origin: 'booth')}
|
||||
create(:poll_voter, poll: poll)
|
||||
create(:poll_recount, origin: 'booth', white_amount: 1, null_amount: 0, total_amount: 2, booth_assignment_id: booth_assignment.id)
|
||||
stats = described_class.new(poll).generate
|
||||
|
||||
expect(stats[:total_participants]).to eq(5)
|
||||
expect(stats[:total_participants_web]).to eq(2)
|
||||
expect(stats[:total_participants_booth]).to eq(3)
|
||||
expect(stats[:total_valid_votes]).to eq(4)
|
||||
expect(stats[:total_white_votes]).to eq(1)
|
||||
expect(stats[:total_null_votes]).to eq(0)
|
||||
|
||||
expect(stats[:total_web_valid]).to eq(2)
|
||||
expect(stats[:total_web_white]).to eq(0)
|
||||
expect(stats[:total_web_null]).to eq(0)
|
||||
|
||||
expect(stats[:total_booth_valid]).to eq(2)
|
||||
expect(stats[:total_booth_white]).to eq(1)
|
||||
expect(stats[:total_booth_null]).to eq(0)
|
||||
|
||||
expect(stats[:total_participants_web_percentage]).to eq(40)
|
||||
expect(stats[:total_participants_booth_percentage]).to eq(60)
|
||||
expect(stats[:valid_percentage_web]).to eq(50)
|
||||
expect(stats[:white_percentage_web]).to eq(0)
|
||||
expect(stats[:null_percentage_web]).to eq(0)
|
||||
expect(stats[:valid_percentage_booth]).to eq(50)
|
||||
expect(stats[:white_percentage_booth]).to eq(100)
|
||||
expect(stats[:null_percentage_booth]).to eq(0)
|
||||
expect(stats[:total_valid_percentage]).to eq(80)
|
||||
expect(stats[:total_white_percentage]).to eq(20)
|
||||
expect(stats[:total_null_percentage]).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,70 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Poll::TotalResult do
|
||||
|
||||
describe "logging changes" do
|
||||
it "should update amount_log if amount changes" do
|
||||
total_result = create(:poll_total_result, amount: 33)
|
||||
|
||||
expect(total_result.amount_log).to eq("")
|
||||
|
||||
total_result.amount = 33
|
||||
total_result.save
|
||||
total_result.amount = 32
|
||||
total_result.save
|
||||
total_result.amount = 34
|
||||
total_result.save
|
||||
|
||||
expect(total_result.amount_log).to eq(":33:32")
|
||||
end
|
||||
|
||||
it "should update officer_assignment_id_log if amount changes" do
|
||||
total_result = create(:poll_total_result, amount: 33)
|
||||
|
||||
expect(total_result.amount_log).to eq("")
|
||||
expect(total_result.officer_assignment_id_log).to eq("")
|
||||
|
||||
total_result.amount = 33
|
||||
total_result.officer_assignment = create(:poll_officer_assignment, id: 101)
|
||||
total_result.save
|
||||
|
||||
total_result.amount = 32
|
||||
total_result.officer_assignment = create(:poll_officer_assignment, id: 102)
|
||||
total_result.save
|
||||
|
||||
total_result.amount = 34
|
||||
total_result.officer_assignment = create(:poll_officer_assignment, id: 103)
|
||||
total_result.save
|
||||
|
||||
expect(total_result.amount_log).to eq(":33:32")
|
||||
expect(total_result.officer_assignment_id_log).to eq(":101:102")
|
||||
end
|
||||
|
||||
it "should update author_id if amount changes" do
|
||||
total_result = create(:poll_total_result, amount: 33)
|
||||
|
||||
expect(total_result.amount_log).to eq("")
|
||||
expect(total_result.author_id_log).to eq("")
|
||||
|
||||
author_A = create(:poll_officer).user
|
||||
author_B = create(:poll_officer).user
|
||||
author_C = create(:poll_officer).user
|
||||
|
||||
total_result.amount = 33
|
||||
total_result.author_id = author_A.id
|
||||
total_result.save!
|
||||
|
||||
total_result.amount = 32
|
||||
total_result.author_id = author_B.id
|
||||
total_result.save!
|
||||
|
||||
total_result.amount = 34
|
||||
total_result.author_id = author_C.id
|
||||
total_result.save!
|
||||
|
||||
expect(total_result.amount_log).to eq(":33:32")
|
||||
expect(total_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :voter do
|
||||
describe Poll::Voter do
|
||||
|
||||
let(:poll) { create(:poll) }
|
||||
let(:booth) { create(:poll_booth) }
|
||||
@@ -9,47 +9,47 @@ describe :voter do
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a user" do
|
||||
it "is not valid without a user" do
|
||||
voter.user = nil
|
||||
expect(voter).to_not be_valid
|
||||
expect(voter).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a poll" do
|
||||
it "is not valid without a poll" do
|
||||
voter.poll = nil
|
||||
expect(voter).to_not be_valid
|
||||
expect(voter).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if has not voted" do
|
||||
it "is valid if has not voted" do
|
||||
voter = build(:poll_voter, :valid_document)
|
||||
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid if the user has already voted in the same poll or booth_assignment" do
|
||||
it "is not valid if the user has already voted in the same poll or booth_assignment" do
|
||||
user = create(:user, :level_two)
|
||||
|
||||
voter1 = create(:poll_voter, user: user, poll: poll)
|
||||
voter2 = build(:poll_voter, user: user, poll: poll)
|
||||
|
||||
expect(voter2).to_not be_valid
|
||||
expect(voter2).not_to be_valid
|
||||
expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"])
|
||||
end
|
||||
|
||||
it "should not be valid if the user has already voted in the same poll/booth" do
|
||||
it "is not valid if the user has already voted in the same poll/booth" do
|
||||
user = create(:user, :level_two)
|
||||
|
||||
voter1 = create(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment)
|
||||
voter2 = build(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment)
|
||||
|
||||
expect(voter2).to_not be_valid
|
||||
expect(voter2).not_to be_valid
|
||||
expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"])
|
||||
end
|
||||
|
||||
it "should not be valid if the user has already voted in different booth in the same poll" do
|
||||
it "is not valid if the user has already voted in different booth in the same poll" do
|
||||
booth_assignment1 = create(:poll_booth_assignment, poll: poll)
|
||||
booth_assignment2 = create(:poll_booth_assignment, poll: poll)
|
||||
|
||||
@@ -58,11 +58,11 @@ describe :voter do
|
||||
voter1 = create(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment1)
|
||||
voter2 = build(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment2)
|
||||
|
||||
expect(voter2).to_not be_valid
|
||||
expect(voter2).not_to be_valid
|
||||
expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"])
|
||||
end
|
||||
|
||||
it "should be valid if the user has already voted in the same booth in different poll" do
|
||||
it "is valid if the user has already voted in the same booth in different poll" do
|
||||
booth_assignment1 = create(:poll_booth_assignment, booth: booth)
|
||||
booth_assignment2 = create(:poll_booth_assignment, booth: booth, poll: poll)
|
||||
|
||||
@@ -74,15 +74,73 @@ describe :voter do
|
||||
expect(voter2).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid if the user has voted via web" do
|
||||
it "is not valid if the user has voted via web" do
|
||||
answer = create(:poll_answer)
|
||||
answer.record_voter_participation
|
||||
answer.record_voter_participation('token')
|
||||
|
||||
voter = build(:poll_voter, poll: answer.question.poll, user: answer.author)
|
||||
expect(voter).to_not be_valid
|
||||
expect(voter).not_to be_valid
|
||||
expect(voter.errors.messages[:document_number]).to eq(["User has already voted"])
|
||||
end
|
||||
|
||||
context "origin" do
|
||||
|
||||
it "is not valid without an origin" do
|
||||
voter.origin = nil
|
||||
expect(voter).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a valid origin" do
|
||||
voter.origin = "invalid_origin"
|
||||
expect(voter).not_to be_valid
|
||||
end
|
||||
|
||||
it "is valid with a booth origin" do
|
||||
voter.origin = "booth"
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
it "is valid with a web origin" do
|
||||
voter.origin = "web"
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
|
||||
describe "#web" do
|
||||
it "returns voters with a web origin" do
|
||||
voter1 = create(:poll_voter, origin: "web")
|
||||
voter2 = create(:poll_voter, origin: "web")
|
||||
voter3 = create(:poll_voter, origin: "booth")
|
||||
|
||||
web_voters = described_class.web
|
||||
|
||||
expect(web_voters.count).to eq(2)
|
||||
expect(web_voters).to include(voter1)
|
||||
expect(web_voters).to include(voter2)
|
||||
expect(web_voters).not_to include(voter3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#booth" do
|
||||
it "returns voters with a booth origin" do
|
||||
voter1 = create(:poll_voter, origin: "booth")
|
||||
voter2 = create(:poll_voter, origin: "booth")
|
||||
voter3 = create(:poll_voter, origin: "web")
|
||||
|
||||
booth_voters = described_class.booth
|
||||
|
||||
expect(booth_voters.count).to eq(2)
|
||||
expect(booth_voters).to include(voter1)
|
||||
expect(booth_voters).to include(voter2)
|
||||
expect(booth_voters).not_to include(voter3)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "save" do
|
||||
@@ -104,11 +162,12 @@ describe :voter do
|
||||
|
||||
it "sets user info" do
|
||||
user = create(:user, document_number: "1234A", document_type: "1")
|
||||
voter = build(:poll_voter, user: user)
|
||||
voter = build(:poll_voter, user: user, token: "1234abcd")
|
||||
voter.save
|
||||
|
||||
expect(voter.document_number).to eq("1234A")
|
||||
expect(voter.document_type).to eq("1")
|
||||
expect(voter.token).to eq("1234abcd")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Poll::WhiteResult do
|
||||
|
||||
describe "logging changes" do
|
||||
it "should update amount_log if amount changes" do
|
||||
white_result = create(:poll_white_result, amount: 33)
|
||||
|
||||
expect(white_result.amount_log).to eq("")
|
||||
|
||||
white_result.amount = 33
|
||||
white_result.save
|
||||
white_result.amount = 32
|
||||
white_result.save
|
||||
white_result.amount = 34
|
||||
white_result.save
|
||||
|
||||
expect(white_result.amount_log).to eq(":33:32")
|
||||
end
|
||||
|
||||
it "should update officer_assignment_id_log if amount changes" do
|
||||
white_result = create(:poll_white_result, amount: 33)
|
||||
|
||||
expect(white_result.amount_log).to eq("")
|
||||
expect(white_result.officer_assignment_id_log).to eq("")
|
||||
|
||||
white_result.amount = 33
|
||||
white_result.officer_assignment = create(:poll_officer_assignment, id: 21)
|
||||
white_result.save
|
||||
|
||||
white_result.amount = 32
|
||||
white_result.officer_assignment = create(:poll_officer_assignment, id: 22)
|
||||
white_result.save
|
||||
|
||||
white_result.amount = 34
|
||||
white_result.officer_assignment = create(:poll_officer_assignment, id: 23)
|
||||
white_result.save
|
||||
|
||||
expect(white_result.amount_log).to eq(":33:32")
|
||||
expect(white_result.officer_assignment_id_log).to eq(":21:22")
|
||||
end
|
||||
|
||||
it "should update author_id if amount changes" do
|
||||
white_result = create(:poll_white_result, amount: 33)
|
||||
|
||||
expect(white_result.amount_log).to eq("")
|
||||
expect(white_result.author_id_log).to eq("")
|
||||
|
||||
author_A = create(:poll_officer).user
|
||||
author_B = create(:poll_officer).user
|
||||
author_C = create(:poll_officer).user
|
||||
|
||||
white_result.amount = 33
|
||||
white_result.author_id = author_A.id
|
||||
white_result.save!
|
||||
|
||||
white_result.amount = 32
|
||||
white_result.author_id = author_B.id
|
||||
white_result.save!
|
||||
|
||||
white_result.amount = 34
|
||||
white_result.author_id = author_C.id
|
||||
white_result.save!
|
||||
|
||||
expect(white_result.amount_log).to eq(":33:32")
|
||||
expect(white_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -3,23 +3,23 @@ require 'rails_helper'
|
||||
describe ProposalNotification do
|
||||
let(:notification) { build(:proposal_notification) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(notification).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
notification.title = nil
|
||||
expect(notification).to_not be_valid
|
||||
expect(notification).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a body" do
|
||||
it "is not valid without a body" do
|
||||
notification.body = nil
|
||||
expect(notification).to_not be_valid
|
||||
expect(notification).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an associated proposal" do
|
||||
it "is not valid without an associated proposal" do
|
||||
notification.proposal = nil
|
||||
expect(notification).to_not be_valid
|
||||
expect(notification).not_to be_valid
|
||||
end
|
||||
|
||||
describe "public_for_api scope" do
|
||||
@@ -27,40 +27,40 @@ describe ProposalNotification do
|
||||
proposal = create(:proposal)
|
||||
notification = create(:proposal_notification, proposal: proposal)
|
||||
|
||||
expect(ProposalNotification.public_for_api).to include(notification)
|
||||
expect(described_class.public_for_api).to include(notification)
|
||||
end
|
||||
|
||||
it "blocks proposal notifications whose proposal is hidden" do
|
||||
proposal = create(:proposal, :hidden)
|
||||
notification = create(:proposal_notification, proposal: proposal)
|
||||
|
||||
expect(ProposalNotification.public_for_api).not_to include(notification)
|
||||
expect(described_class.public_for_api).not_to include(notification)
|
||||
end
|
||||
|
||||
it "blocks proposal notifications without proposal" do
|
||||
proposal = build(:proposal_notification, proposal: nil).save!(validate: false)
|
||||
|
||||
expect(ProposalNotification.public_for_api).not_to include(notification)
|
||||
expect(described_class.public_for_api).not_to include(notification)
|
||||
end
|
||||
end
|
||||
|
||||
describe "minimum interval between notifications" do
|
||||
|
||||
before(:each) do
|
||||
before do
|
||||
Setting[:proposal_notification_minimum_interval_in_days] = 3
|
||||
end
|
||||
|
||||
it "should not be valid if below minium interval" do
|
||||
it "is not valid if below minium interval" do
|
||||
proposal = create(:proposal)
|
||||
|
||||
notification1 = create(:proposal_notification, proposal: proposal)
|
||||
notification2 = build(:proposal_notification, proposal: proposal)
|
||||
|
||||
proposal.reload
|
||||
expect(notification2).to_not be_valid
|
||||
expect(notification2).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if notifications above minium interval" do
|
||||
it "is valid if notifications above minium interval" do
|
||||
proposal = create(:proposal)
|
||||
|
||||
notification1 = create(:proposal_notification, proposal: proposal, created_at: 4.days.ago)
|
||||
@@ -70,7 +70,7 @@ describe ProposalNotification do
|
||||
expect(notification2).to be_valid
|
||||
end
|
||||
|
||||
it "should be valid if no notifications sent" do
|
||||
it "is valid if no notifications sent" do
|
||||
notification1 = build(:proposal_notification)
|
||||
|
||||
expect(notification1).to be_valid
|
||||
@@ -78,4 +78,79 @@ describe ProposalNotification do
|
||||
|
||||
end
|
||||
|
||||
describe "notifications in-app" do
|
||||
|
||||
let(:notifiable) { create(model_name(described_class)) }
|
||||
let(:proposal) { notifiable.proposal }
|
||||
|
||||
describe "#notification_title" do
|
||||
|
||||
it "returns the proposal title" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
expect(notification.notifiable_title).to eq notifiable.proposal.title
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#notification_action" do
|
||||
|
||||
it "returns the correct action" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
expect(notification.notifiable_action).to eq "proposal_notification"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "notifiable_available?" do
|
||||
|
||||
it "returns true when the proposal is available" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
expect(notification.notifiable_available?).to be(true)
|
||||
end
|
||||
|
||||
it "returns false when the proposal is not available" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
notifiable.proposal.destroy
|
||||
|
||||
expect(notification.notifiable_available?).to be(false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "check_availability" do
|
||||
|
||||
it "returns true if the resource is present, not hidden, nor retired" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
expect(notification.check_availability(proposal)).to be(true)
|
||||
end
|
||||
|
||||
it "returns false if the resource is not present" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
notifiable.proposal.really_destroy!
|
||||
expect(notification.check_availability(proposal)).to be(false)
|
||||
end
|
||||
|
||||
it "returns false if the resource is hidden" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
notifiable.proposal.hide
|
||||
expect(notification.check_availability(proposal)).to be(false)
|
||||
end
|
||||
|
||||
it "returns false if the resource is retired" do
|
||||
notification = create(:notification, notifiable: notifiable)
|
||||
|
||||
notifiable.proposal.update(retired_at: Time.current)
|
||||
expect(notification.check_availability(proposal)).to be(false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,98 +4,102 @@ require 'rails_helper'
|
||||
describe Proposal do
|
||||
let(:proposal) { build(:proposal) }
|
||||
|
||||
it_behaves_like "has_public_author"
|
||||
describe "Concerns" do
|
||||
it_behaves_like "has_public_author"
|
||||
it_behaves_like "notifiable"
|
||||
it_behaves_like "map validations"
|
||||
end
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(proposal).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an author" do
|
||||
it "is not valid without an author" do
|
||||
proposal.author = nil
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a summary" do
|
||||
it "is not valid without a summary" do
|
||||
proposal.summary = nil
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
proposal.title = nil
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very short" do
|
||||
it "is not valid when very short" do
|
||||
proposal.title = "abc"
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
proposal.title = "a" * 81
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#description" do
|
||||
it "should be sanitized" do
|
||||
it "is sanitized" do
|
||||
proposal.description = "<script>alert('danger');</script>"
|
||||
proposal.valid?
|
||||
expect(proposal.description).to eq("alert('danger');")
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
proposal.description = "a" * 6001
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#question" do
|
||||
it "should not be valid without a question" do
|
||||
it "is not valid without a question" do
|
||||
proposal.question = nil
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very short" do
|
||||
it "is not valid when very short" do
|
||||
proposal.question = "abc"
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
proposal.question = "a" * 141
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#video_url" do
|
||||
it "should not be valid when URL is not from Youtube or Vimeo" do
|
||||
it "is not valid when URL is not from Youtube or Vimeo" do
|
||||
proposal.video_url = "https://twitter.com"
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid when URL is from Youtube or Vimeo" do
|
||||
it "is valid when URL is from Youtube or Vimeo" do
|
||||
proposal.video_url = "https://vimeo.com/112681885"
|
||||
expect(proposal).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#responsible_name" do
|
||||
it "should be mandatory" do
|
||||
it "is mandatory" do
|
||||
proposal.responsible_name = nil
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very short" do
|
||||
it "is not valid when very short" do
|
||||
proposal.responsible_name = "abc"
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid when very long" do
|
||||
it "is not valid when very long" do
|
||||
proposal.responsible_name = "a" * 61
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be the document_number if level two user" do
|
||||
it "is the document_number if level two user" do
|
||||
author = create(:user, :level_two, document_number: "12345678Z")
|
||||
proposal.author = author
|
||||
proposal.responsible_name = nil
|
||||
@@ -104,7 +108,7 @@ describe Proposal do
|
||||
proposal.responsible_name = "12345678Z"
|
||||
end
|
||||
|
||||
it "should be the document_number if level two user" do
|
||||
it "is the document_number if level three user" do
|
||||
author = create(:user, :level_three, document_number: "12345678Z")
|
||||
proposal.author = author
|
||||
proposal.responsible_name = nil
|
||||
@@ -113,7 +117,7 @@ describe Proposal do
|
||||
proposal.responsible_name = "12345678Z"
|
||||
end
|
||||
|
||||
it "should not be updated when the author is deleted" do
|
||||
it "is not updated when the author is deleted" do
|
||||
author = create(:user, :level_three, document_number: "12345678Z")
|
||||
proposal.author = author
|
||||
proposal.save
|
||||
@@ -126,29 +130,29 @@ describe Proposal do
|
||||
end
|
||||
|
||||
describe "tag_list" do
|
||||
it "should sanitize the tag list" do
|
||||
it "sanitizes the tag list" do
|
||||
proposal.tag_list = "user_id=1"
|
||||
proposal.valid?
|
||||
expect(proposal.tag_list).to eq(['user_id1'])
|
||||
end
|
||||
|
||||
it "should not be valid with a tag list of more than 6 elements" do
|
||||
it "is not valid with a tag list of more than 6 elements" do
|
||||
proposal.tag_list = ["Hacienda", "Economía", "Medio Ambiente", "Corrupción", "Fiestas populares", "Prensa", "Huelgas"]
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid with a tag list of up to 6 elements" do
|
||||
it "is valid with a tag list of up to 6 elements" do
|
||||
proposal.tag_list = ["Hacienda", "Economía", "Medio Ambiente", "Corrupción", "Fiestas populares", "Prensa"]
|
||||
expect(proposal).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it "should not be valid without accepting terms of service" do
|
||||
it "is not valid without accepting terms of service" do
|
||||
proposal.terms_of_service = nil
|
||||
expect(proposal).to_not be_valid
|
||||
expect(proposal).not_to be_valid
|
||||
end
|
||||
|
||||
it "should have a code" do
|
||||
it "has a code" do
|
||||
Setting["proposal_code_prefix"] = "TEST"
|
||||
proposal = create(:proposal)
|
||||
expect(proposal.code).to eq "TEST-#{proposal.created_at.strftime('%Y-%m')}-#{proposal.id}"
|
||||
@@ -158,21 +162,22 @@ describe Proposal do
|
||||
|
||||
describe "#editable?" do
|
||||
let(:proposal) { create(:proposal) }
|
||||
before(:each) {Setting["max_votes_for_proposal_edit"] = 5}
|
||||
after(:each) {Setting["max_votes_for_proposal_edit"] = 1000}
|
||||
|
||||
it "should be true if proposal has no votes yet" do
|
||||
before {Setting["max_votes_for_proposal_edit"] = 5}
|
||||
after {Setting["max_votes_for_proposal_edit"] = 1000}
|
||||
|
||||
it "is true if proposal has no votes yet" do
|
||||
expect(proposal.total_votes).to eq(0)
|
||||
expect(proposal.editable?).to be true
|
||||
end
|
||||
|
||||
it "should be true if proposal has less than limit votes" do
|
||||
it "is true if proposal has less than limit votes" do
|
||||
create_list(:vote, 4, votable: proposal)
|
||||
expect(proposal.total_votes).to eq(4)
|
||||
expect(proposal.editable?).to be true
|
||||
end
|
||||
|
||||
it "should be false if proposal has more than limit votes" do
|
||||
it "is false if proposal has more than limit votes" do
|
||||
create_list(:vote, 6, votable: proposal)
|
||||
expect(proposal.total_votes).to eq(6)
|
||||
expect(proposal.editable?).to be false
|
||||
@@ -182,17 +187,17 @@ describe Proposal do
|
||||
describe "#votable_by?" do
|
||||
let(:proposal) { create(:proposal) }
|
||||
|
||||
it "should be true for level two verified users" do
|
||||
it "is true for level two verified users" do
|
||||
user = create(:user, residence_verified_at: Time.current, confirmed_phone: "666333111")
|
||||
expect(proposal.votable_by?(user)).to be true
|
||||
end
|
||||
|
||||
it "should be true for level three verified users" do
|
||||
it "is true for level three verified users" do
|
||||
user = create(:user, verified_at: Time.current)
|
||||
expect(proposal.votable_by?(user)).to be true
|
||||
end
|
||||
|
||||
it "should be false for anonymous users" do
|
||||
it "is false for anonymous users" do
|
||||
user = create(:user)
|
||||
expect(proposal.votable_by?(user)).to be false
|
||||
end
|
||||
@@ -202,27 +207,27 @@ describe Proposal do
|
||||
let(:proposal) { create(:proposal) }
|
||||
|
||||
describe "from level two verified users" do
|
||||
it "should register vote" do
|
||||
it "registers vote" do
|
||||
user = create(:user, residence_verified_at: Time.current, confirmed_phone: "666333111")
|
||||
expect {proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "from level three verified users" do
|
||||
it "should register vote" do
|
||||
it "registers vote" do
|
||||
user = create(:user, verified_at: Time.current)
|
||||
expect {proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "from anonymous users" do
|
||||
it "should not register vote" do
|
||||
it "does not register vote" do
|
||||
user = create(:user)
|
||||
expect {proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(0)
|
||||
end
|
||||
end
|
||||
|
||||
it "should not register vote for archived proposals" do
|
||||
it "does not register vote for archived proposals" do
|
||||
user = create(:user, verified_at: Time.current)
|
||||
archived_proposal = create(:proposal, :archived)
|
||||
|
||||
@@ -234,7 +239,7 @@ describe Proposal do
|
||||
|
||||
describe "with deprecated long tag list" do
|
||||
|
||||
it "should increase number of cached_total_votes" do
|
||||
it "increases number of cached_total_votes" do
|
||||
proposal = create(:proposal)
|
||||
|
||||
tag_list = ["tag1", "tag2", "tag3", "tag4", "tag5", "tag6", "tag7"]
|
||||
@@ -344,47 +349,47 @@ describe Proposal do
|
||||
describe "cache" do
|
||||
let(:proposal) { create(:proposal) }
|
||||
|
||||
it "should expire cache when it has a new comment" do
|
||||
it "expires cache when it has a new comment" do
|
||||
expect { create(:comment, commentable: proposal) }
|
||||
.to change { proposal.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when it has a new vote" do
|
||||
it "expires cache when it has a new vote" do
|
||||
expect { create(:vote, votable: proposal) }
|
||||
.to change { proposal.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when it has a new flag" do
|
||||
it "expires cache when it has a new flag" do
|
||||
expect { create(:flag, flaggable: proposal) }
|
||||
.to change { proposal.reload.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when it has a new tag" do
|
||||
it "expires cache when it has a new tag" do
|
||||
expect { proposal.update(tag_list: "new tag") }
|
||||
.to change { proposal.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when hidden" do
|
||||
it "expires cache when hidden" do
|
||||
expect { proposal.hide }
|
||||
.to change { proposal.updated_at }
|
||||
end
|
||||
|
||||
it "should expire cache when the author is hidden" do
|
||||
it "expires cache when the author is hidden" do
|
||||
expect { proposal.author.hide }
|
||||
.to change { [proposal.reload.updated_at, proposal.author.updated_at] }
|
||||
end
|
||||
|
||||
it "should expire cache when the author is erased" do
|
||||
it "expires cache when the author is erased" do
|
||||
expect { proposal.author.erase }
|
||||
.to change { [proposal.reload.updated_at, proposal.author.updated_at] }
|
||||
end
|
||||
|
||||
it "should expire cache when its author changes" do
|
||||
it "expires cache when its author changes" do
|
||||
expect { proposal.author.update(username: "Eva") }
|
||||
.to change { [proposal.reload.updated_at, proposal.author.updated_at] }
|
||||
end
|
||||
|
||||
it "should expire cache when the author's organization get verified" do
|
||||
it "expires cache when the author's organization get verified" do
|
||||
create(:organization, user: proposal.author)
|
||||
expect { proposal.author.organization.verify }
|
||||
.to change { [proposal.reload.updated_at, proposal.author.updated_at] }
|
||||
@@ -404,7 +409,7 @@ describe Proposal do
|
||||
|
||||
expect(proposal.voters).to include(voter1)
|
||||
expect(proposal.voters).to include(voter2)
|
||||
expect(proposal.voters).to_not include(voter3)
|
||||
expect(proposal.voters).not_to include(voter3)
|
||||
end
|
||||
|
||||
it "does not return users that have been erased" do
|
||||
@@ -417,7 +422,7 @@ describe Proposal do
|
||||
voter2.erase
|
||||
|
||||
expect(proposal.voters).to include(voter1)
|
||||
expect(proposal.voters).to_not include(voter2)
|
||||
expect(proposal.voters).not_to include(voter2)
|
||||
end
|
||||
|
||||
it "does not return users that have been blocked" do
|
||||
@@ -430,7 +435,7 @@ describe Proposal do
|
||||
voter2.block
|
||||
|
||||
expect(proposal.voters).to include(voter1)
|
||||
expect(proposal.voters).to_not include(voter2)
|
||||
expect(proposal.voters).not_to include(voter2)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -441,39 +446,39 @@ describe Proposal do
|
||||
|
||||
it "searches by title" do
|
||||
proposal = create(:proposal, title: 'save the world')
|
||||
results = Proposal.search('save the world')
|
||||
results = described_class.search('save the world')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
it "searches by summary" do
|
||||
proposal = create(:proposal, summary: 'basically...')
|
||||
results = Proposal.search('basically')
|
||||
results = described_class.search('basically')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
it "searches by description" do
|
||||
proposal = create(:proposal, description: 'in order to save the world one must think about...')
|
||||
results = Proposal.search('one must think')
|
||||
results = described_class.search('one must think')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
it "searches by question" do
|
||||
proposal = create(:proposal, question: 'to be or not to be')
|
||||
results = Proposal.search('to be or not to be')
|
||||
results = described_class.search('to be or not to be')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
it "searches by author name" do
|
||||
author = create(:user, username: 'Danny Trejo')
|
||||
proposal = create(:proposal, author: author)
|
||||
results = Proposal.search('Danny')
|
||||
results = described_class.search('Danny')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
it "searches by geozone" do
|
||||
geozone = create(:geozone, name: 'California')
|
||||
proposal = create(:proposal, geozone: geozone)
|
||||
results = Proposal.search('California')
|
||||
results = described_class.search('California')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
@@ -484,13 +489,13 @@ describe Proposal do
|
||||
it "searches word stems" do
|
||||
proposal = create(:proposal, summary: 'Economía')
|
||||
|
||||
results = Proposal.search('economía')
|
||||
results = described_class.search('economía')
|
||||
expect(results).to eq([proposal])
|
||||
|
||||
results = Proposal.search('econo')
|
||||
results = described_class.search('econo')
|
||||
expect(results).to eq([proposal])
|
||||
|
||||
results = Proposal.search('eco')
|
||||
results = described_class.search('eco')
|
||||
expect(results).to eq([proposal])
|
||||
end
|
||||
|
||||
@@ -500,15 +505,15 @@ describe Proposal do
|
||||
it "searches with accents" do
|
||||
proposal = create(:proposal, summary: 'difusión')
|
||||
|
||||
results = Proposal.search('difusion')
|
||||
results = described_class.search('difusion')
|
||||
expect(results).to eq([proposal])
|
||||
|
||||
proposal2 = create(:proposal, summary: 'estadisticas')
|
||||
results = Proposal.search('estadísticas')
|
||||
results = described_class.search('estadísticas')
|
||||
expect(results).to eq([proposal2])
|
||||
|
||||
proposal3 = create(:proposal, summary: 'público')
|
||||
results = Proposal.search('publico')
|
||||
results = described_class.search('publico')
|
||||
expect(results).to eq([proposal3])
|
||||
end
|
||||
end
|
||||
@@ -517,11 +522,11 @@ describe Proposal do
|
||||
it "searches case insensite" do
|
||||
proposal = create(:proposal, title: 'SHOUT')
|
||||
|
||||
results = Proposal.search('shout')
|
||||
results = described_class.search('shout')
|
||||
expect(results).to eq([proposal])
|
||||
|
||||
proposal2 = create(:proposal, title: "scream")
|
||||
results = Proposal.search("SCREAM")
|
||||
results = described_class.search("SCREAM")
|
||||
expect(results).to eq([proposal2])
|
||||
end
|
||||
end
|
||||
@@ -530,10 +535,10 @@ describe Proposal do
|
||||
it "searches by tags" do
|
||||
proposal = create(:proposal, tag_list: 'Latina')
|
||||
|
||||
results = Proposal.search('Latina')
|
||||
results = described_class.search('Latina')
|
||||
expect(results.first).to eq(proposal)
|
||||
|
||||
results = Proposal.search('Latin')
|
||||
results = described_class.search('Latin')
|
||||
expect(results.first).to eq(proposal)
|
||||
end
|
||||
end
|
||||
@@ -546,7 +551,7 @@ describe Proposal do
|
||||
proposal_description = create(:proposal, description: 'stop corruption')
|
||||
proposal_summary = create(:proposal, summary: 'stop corruption')
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(proposal_title)
|
||||
expect(results.second).to eq(proposal_question)
|
||||
@@ -561,7 +566,7 @@ describe Proposal do
|
||||
|
||||
summary_most_voted = create(:proposal, summary: 'stop corruption', cached_votes_up: 10)
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(title_most_voted)
|
||||
expect(results.second).to eq(title_some_votes)
|
||||
@@ -573,7 +578,7 @@ describe Proposal do
|
||||
exact_title_few_votes = create(:proposal, title: 'stop corruption', cached_votes_up: 5)
|
||||
similar_title_many_votes = create(:proposal, title: 'stop some of the corruption', cached_votes_up: 500)
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(exact_title_few_votes)
|
||||
expect(results.second).to eq(similar_title_many_votes)
|
||||
@@ -583,7 +588,7 @@ describe Proposal do
|
||||
|
||||
context "reorder" do
|
||||
|
||||
it "should be able to reorder by hot_score after searching" do
|
||||
it "is able to reorder by hot_score after searching" do
|
||||
lowest_score = create(:proposal, title: 'stop corruption', cached_votes_up: 1)
|
||||
highest_score = create(:proposal, title: 'stop corruption', cached_votes_up: 2)
|
||||
average_score = create(:proposal, title: 'stop corruption', cached_votes_up: 3)
|
||||
@@ -592,7 +597,7 @@ describe Proposal do
|
||||
highest_score.update_column(:hot_score, 100)
|
||||
average_score.update_column(:hot_score, 10)
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(average_score)
|
||||
expect(results.second).to eq(highest_score)
|
||||
@@ -605,7 +610,7 @@ describe Proposal do
|
||||
expect(results.third).to eq(lowest_score)
|
||||
end
|
||||
|
||||
it "should be able to reorder by confidence_score after searching" do
|
||||
it "is able to reorder by confidence_score after searching" do
|
||||
lowest_score = create(:proposal, title: 'stop corruption', cached_votes_up: 1)
|
||||
highest_score = create(:proposal, title: 'stop corruption', cached_votes_up: 2)
|
||||
average_score = create(:proposal, title: 'stop corruption', cached_votes_up: 3)
|
||||
@@ -614,7 +619,7 @@ describe Proposal do
|
||||
highest_score.update_column(:confidence_score, 100)
|
||||
average_score.update_column(:confidence_score, 10)
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(average_score)
|
||||
expect(results.second).to eq(highest_score)
|
||||
@@ -627,12 +632,12 @@ describe Proposal do
|
||||
expect(results.third).to eq(lowest_score)
|
||||
end
|
||||
|
||||
it "should be able to reorder by created_at after searching" do
|
||||
it "is able to reorder by created_at after searching" do
|
||||
recent = create(:proposal, title: 'stop corruption', cached_votes_up: 1, created_at: 1.week.ago)
|
||||
newest = create(:proposal, title: 'stop corruption', cached_votes_up: 2, created_at: Time.current)
|
||||
oldest = create(:proposal, title: 'stop corruption', cached_votes_up: 3, created_at: 1.month.ago)
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(oldest)
|
||||
expect(results.second).to eq(newest)
|
||||
@@ -645,12 +650,12 @@ describe Proposal do
|
||||
expect(results.third).to eq(oldest)
|
||||
end
|
||||
|
||||
it "should be able to reorder by most commented after searching" do
|
||||
it "is able to reorder by most commented after searching" do
|
||||
least_commented = create(:proposal, title: 'stop corruption', cached_votes_up: 1, comments_count: 1)
|
||||
most_commented = create(:proposal, title: 'stop corruption', cached_votes_up: 2, comments_count: 100)
|
||||
some_comments = create(:proposal, title: 'stop corruption', cached_votes_up: 3, comments_count: 10)
|
||||
|
||||
results = Proposal.search('stop corruption')
|
||||
results = described_class.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(some_comments)
|
||||
expect(results.second).to eq(most_commented)
|
||||
@@ -670,28 +675,28 @@ describe Proposal do
|
||||
it "no words match" do
|
||||
create(:proposal, title: 'save world')
|
||||
|
||||
results = Proposal.search('destroy planet')
|
||||
results = described_class.search('destroy planet')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
it "too many typos" do
|
||||
create(:proposal, title: 'fantastic')
|
||||
|
||||
results = Proposal.search('frantac')
|
||||
results = described_class.search('frantac')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
it "too much stemming" do
|
||||
create(:proposal, title: 'reloj')
|
||||
|
||||
results = Proposal.search('superrelojimetro')
|
||||
results = described_class.search('superrelojimetro')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
it "empty" do
|
||||
create(:proposal, title: 'great')
|
||||
|
||||
results = Proposal.search('')
|
||||
results = described_class.search('')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
@@ -699,14 +704,14 @@ describe Proposal do
|
||||
end
|
||||
|
||||
describe "#last_week" do
|
||||
it "should return proposals created this week" do
|
||||
it "returns proposals created this week" do
|
||||
proposal = create(:proposal)
|
||||
expect(Proposal.last_week).to include(proposal)
|
||||
expect(described_class.last_week).to include(proposal)
|
||||
end
|
||||
|
||||
it "should not return proposals created more than a week ago" do
|
||||
it "does not return proposals created more than a week ago" do
|
||||
proposal = create(:proposal, created_at: 8.days.ago)
|
||||
expect(Proposal.last_week).to_not include(proposal)
|
||||
expect(described_class.last_week).not_to include(proposal)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -714,64 +719,64 @@ describe Proposal do
|
||||
|
||||
context "categories" do
|
||||
|
||||
it "should return proposals tagged with a category" do
|
||||
it "returns proposals tagged with a category" do
|
||||
create(:tag, :category, name: 'culture')
|
||||
proposal = create(:proposal, tag_list: 'culture')
|
||||
|
||||
expect(Proposal.for_summary.values.flatten).to include(proposal)
|
||||
expect(described_class.for_summary.values.flatten).to include(proposal)
|
||||
end
|
||||
|
||||
it "should not return proposals tagged without a category" do
|
||||
it "does not return proposals tagged without a category" do
|
||||
create(:tag, :category, name: 'culture')
|
||||
proposal = create(:proposal, tag_list: 'parks')
|
||||
|
||||
expect(Proposal.for_summary.values.flatten).to_not include(proposal)
|
||||
expect(described_class.for_summary.values.flatten).not_to include(proposal)
|
||||
end
|
||||
end
|
||||
|
||||
context "districts" do
|
||||
|
||||
it "should return proposals with a geozone" do
|
||||
it "returns proposals with a geozone" do
|
||||
california = create(:geozone, name: 'california')
|
||||
proposal = create(:proposal, geozone: california)
|
||||
|
||||
expect(Proposal.for_summary.values.flatten).to include(proposal)
|
||||
expect(described_class.for_summary.values.flatten).to include(proposal)
|
||||
end
|
||||
|
||||
it "should not return proposals without a geozone" do
|
||||
it "does not return proposals without a geozone" do
|
||||
create(:geozone, name: 'california')
|
||||
proposal = create(:proposal)
|
||||
|
||||
expect(Proposal.for_summary.values.flatten).to_not include(proposal)
|
||||
expect(described_class.for_summary.values.flatten).not_to include(proposal)
|
||||
end
|
||||
end
|
||||
|
||||
it "should return proposals created this week" do
|
||||
it "returns proposals created this week" do
|
||||
create(:tag, :category, name: 'culture')
|
||||
proposal = create(:proposal, tag_list: 'culture')
|
||||
expect(Proposal.for_summary.values.flatten).to include(proposal)
|
||||
expect(described_class.for_summary.values.flatten).to include(proposal)
|
||||
end
|
||||
|
||||
it "should not return proposals created more than a week ago" do
|
||||
it "does not return proposals created more than a week ago" do
|
||||
create(:tag, :category, name: 'culture')
|
||||
proposal = create(:proposal, tag_list: 'culture', created_at: 8.days.ago)
|
||||
expect(Proposal.for_summary.values.flatten).to_not include(proposal)
|
||||
expect(described_class.for_summary.values.flatten).not_to include(proposal)
|
||||
end
|
||||
|
||||
it "should order proposals by votes" do
|
||||
it "orders proposals by votes" do
|
||||
create(:tag, :category, name: 'culture')
|
||||
create(:proposal, tag_list: 'culture').update_column(:confidence_score, 2)
|
||||
create(:proposal, tag_list: 'culture').update_column(:confidence_score, 10)
|
||||
create(:proposal, tag_list: 'culture').update_column(:confidence_score, 5)
|
||||
|
||||
results = Proposal.for_summary.values.flatten
|
||||
results = described_class.for_summary.values.flatten
|
||||
|
||||
expect(results.first.confidence_score).to be(10)
|
||||
expect(results.second.confidence_score).to be(5)
|
||||
expect(results.third.confidence_score).to be(2)
|
||||
end
|
||||
|
||||
it "should order groups alphabetically" do
|
||||
it "orders groups alphabetically" do
|
||||
create(:tag, :category, name: 'health')
|
||||
create(:tag, :category, name: 'culture')
|
||||
create(:tag, :category, name: 'social services')
|
||||
@@ -780,14 +785,14 @@ describe Proposal do
|
||||
culture_proposal = create(:proposal, tag_list: 'culture')
|
||||
social_proposal = create(:proposal, tag_list: 'social services')
|
||||
|
||||
results = Proposal.for_summary.values.flatten
|
||||
results = described_class.for_summary.values.flatten
|
||||
|
||||
expect(results.first).to eq(culture_proposal)
|
||||
expect(results.second).to eq(health_proposal)
|
||||
expect(results.third).to eq(social_proposal)
|
||||
end
|
||||
|
||||
it "should return proposals grouped by tag" do
|
||||
it "returns proposals grouped by tag" do
|
||||
create(:tag, :category, name: 'culture')
|
||||
create(:tag, :category, name: 'health')
|
||||
|
||||
@@ -799,12 +804,12 @@ describe Proposal do
|
||||
proposal1.update_column(:confidence_score, 10)
|
||||
proposal2.update_column(:confidence_score, 9)
|
||||
|
||||
expect(Proposal.for_summary).to include('culture' => [proposal1, proposal2], 'health' => [proposal3])
|
||||
expect(described_class.for_summary).to include('culture' => [proposal1, proposal2], 'health' => [proposal3])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_param" do
|
||||
it "should return a friendly url" do
|
||||
it "returns a friendly url" do
|
||||
expect(proposal.to_param).to eq "#{proposal.id} #{proposal.title}".parameterize
|
||||
end
|
||||
end
|
||||
@@ -819,14 +824,14 @@ describe Proposal do
|
||||
end
|
||||
|
||||
it "scope retired" do
|
||||
retired = Proposal.retired
|
||||
retired = described_class.retired
|
||||
|
||||
expect(retired.size).to eq(1)
|
||||
expect(retired.first).to eq(proposal2)
|
||||
end
|
||||
|
||||
it "scope not_retired" do
|
||||
not_retired = Proposal.not_retired
|
||||
not_retired = described_class.not_retired
|
||||
|
||||
expect(not_retired.size).to eq(1)
|
||||
expect(not_retired.first).to eq(proposal1)
|
||||
@@ -843,14 +848,14 @@ describe Proposal do
|
||||
end
|
||||
|
||||
it "scope archived" do
|
||||
archived = Proposal.archived
|
||||
archived = described_class.archived
|
||||
|
||||
expect(archived.size).to eq(1)
|
||||
expect(archived.first).to eq(archived_proposal)
|
||||
end
|
||||
|
||||
it "scope archived" do
|
||||
not_archived = Proposal.not_archived
|
||||
it "scope not archived" do
|
||||
not_archived = described_class.not_archived
|
||||
|
||||
expect(not_archived.size).to eq(1)
|
||||
expect(not_archived.first).to eq(new_proposal)
|
||||
@@ -860,18 +865,18 @@ describe Proposal do
|
||||
describe 'public_for_api scope' do
|
||||
it 'returns proposals' do
|
||||
proposal = create(:proposal)
|
||||
expect(Proposal.public_for_api).to include(proposal)
|
||||
expect(described_class.public_for_api).to include(proposal)
|
||||
end
|
||||
|
||||
it 'does not return hidden proposals' do
|
||||
proposal = create(:proposal, :hidden)
|
||||
expect(Proposal.public_for_api).to_not include(proposal)
|
||||
expect(described_class.public_for_api).not_to include(proposal)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#user_to_notify" do
|
||||
|
||||
it "should return voters and followers" do
|
||||
it "returns voters and followers" do
|
||||
proposal = create(:proposal)
|
||||
voter = create(:user, :level_two)
|
||||
follower = create(:user, :level_two)
|
||||
@@ -881,7 +886,7 @@ describe Proposal do
|
||||
expect(proposal.users_to_notify).to eq([voter, follower])
|
||||
end
|
||||
|
||||
it "should return voters and followers discarding duplicates" do
|
||||
it "returns voters and followers discarding duplicates" do
|
||||
proposal = create(:proposal)
|
||||
voter_and_follower = create(:user, :level_two)
|
||||
follow = create(:follow, user: voter_and_follower, followable: proposal)
|
||||
@@ -891,4 +896,87 @@ describe Proposal do
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#recommendations" do
|
||||
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it "does not return any proposals when user has not interests" do
|
||||
create(:proposal)
|
||||
|
||||
expect(described_class.recommendations(user).size).to eq 0
|
||||
end
|
||||
|
||||
it "returns proposals ordered by cached_votes_up" do
|
||||
proposal1 = create(:proposal, cached_votes_up: 1, tag_list: "Sport")
|
||||
proposal2 = create(:proposal, cached_votes_up: 5, tag_list: "Sport")
|
||||
proposal3 = create(:proposal, cached_votes_up: 10, tag_list: "Sport")
|
||||
proposal4 = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal4, user: user)
|
||||
|
||||
result = described_class.recommendations(user).sort_by_recommendations
|
||||
|
||||
expect(result.first).to eq proposal3
|
||||
expect(result.second).to eq proposal2
|
||||
expect(result.third).to eq proposal1
|
||||
end
|
||||
|
||||
it "returns proposals related with user interests" do
|
||||
proposal1 = create(:proposal, tag_list: "Sport")
|
||||
proposal2 = create(:proposal, tag_list: "Sport")
|
||||
proposal3 = create(:proposal, tag_list: "Politics")
|
||||
create(:follow, followable: proposal1, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
|
||||
expect(result.size).to eq 1
|
||||
expect(result).to eq [proposal2]
|
||||
end
|
||||
|
||||
it "does not return proposals when user is follower" do
|
||||
proposal1 = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal1, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
|
||||
expect(result.size).to eq 0
|
||||
end
|
||||
|
||||
it "does not return proposals when user is the author" do
|
||||
proposal1 = create(:proposal, author: user, tag_list: "Sport")
|
||||
proposal2 = create(:proposal, tag_list: "Sport")
|
||||
proposal3 = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal3, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
|
||||
expect(result.size).to eq 1
|
||||
expect(result).to eq [proposal2]
|
||||
end
|
||||
|
||||
it "does not return archived proposals" do
|
||||
proposal1 = create(:proposal, cached_votes_up: 5, tag_list: "Sport")
|
||||
proposal2 = create(:proposal, cached_votes_up: 5, tag_list: "Sport")
|
||||
archived_proposal = create(:proposal, :archived)
|
||||
create(:follow, followable: proposal1, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
expect(result.size).to eq(1)
|
||||
expect(result).to eq([proposal2])
|
||||
end
|
||||
|
||||
it "does not return already supported proposals" do
|
||||
proposal1 = create(:proposal, cached_votes_up: 5, tag_list: "Health")
|
||||
proposal2 = create(:proposal, cached_votes_up: 5, tag_list: "Health")
|
||||
proposal3 = create(:proposal, cached_votes_up: 5, tag_list: "Health")
|
||||
create(:vote, votable: proposal1, voter: user)
|
||||
create(:follow, followable: proposal2, user: user)
|
||||
|
||||
result = described_class.recommendations(user)
|
||||
expect(result.size).to eq(1)
|
||||
expect(result).to eq([proposal3])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
62
spec/models/related_content_spec.rb
Normal file
62
spec/models/related_content_spec.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe RelatedContent do
|
||||
|
||||
let(:parent_relationable) { create([:proposal, :debate].sample) }
|
||||
let(:child_relationable) { create([:proposal, :debate].sample) }
|
||||
|
||||
it "allows relationables from various classes" do
|
||||
expect(build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)).to be_valid
|
||||
expect(build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)).to be_valid
|
||||
expect(build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable)).to be_valid
|
||||
end
|
||||
|
||||
it "does not allow empty relationables" do
|
||||
expect(build(:related_content)).not_to be_valid
|
||||
expect(build(:related_content, parent_relationable: parent_relationable)).not_to be_valid
|
||||
expect(build(:related_content, child_relationable: child_relationable)).not_to be_valid
|
||||
end
|
||||
|
||||
it "does not allow repeated related contents" do
|
||||
related_content = create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable, author: build(:user))
|
||||
new_related_content = build(:related_content, parent_relationable: related_content.parent_relationable, child_relationable: related_content.child_relationable)
|
||||
expect(new_related_content).not_to be_valid
|
||||
end
|
||||
|
||||
describe 'create_opposite_related_content' do
|
||||
let(:parent_relationable) { create(:proposal) }
|
||||
let(:child_relationable) { create(:debate) }
|
||||
let(:related_content) { build(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable, author: build(:user)) }
|
||||
|
||||
it 'creates an opposite related_content' do
|
||||
expect { related_content.save }.to change { described_class.count }.by(2)
|
||||
expect(related_content.opposite_related_content.child_relationable_id).to eq(parent_relationable.id)
|
||||
expect(related_content.opposite_related_content.child_relationable_type).to eq(parent_relationable.class.name)
|
||||
expect(related_content.opposite_related_content.parent_relationable_id).to eq(child_relationable.id)
|
||||
expect(related_content.opposite_related_content.parent_relationable_type).to eq(child_relationable.class.name)
|
||||
expect(related_content.opposite_related_content.opposite_related_content.id).to eq(related_content.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#relationed_contents' do
|
||||
before do
|
||||
related_content = create(:related_content, parent_relationable: parent_relationable, child_relationable: create(:proposal), author: build(:user))
|
||||
create(:related_content, parent_relationable: parent_relationable, child_relationable: child_relationable, author: build(:user))
|
||||
|
||||
2.times do
|
||||
related_content.send("score_positive", build(:user))
|
||||
end
|
||||
|
||||
6.times do
|
||||
related_content.send("score_negative", build(:user))
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns not hidden by reports related contents' do
|
||||
expect(parent_relationable.relationed_contents.count).to eq(1)
|
||||
expect(parent_relationable.relationed_contents.first.class.name).to eq(child_relationable.class.name)
|
||||
expect(parent_relationable.relationed_contents.first.id).to eq(child_relationable.id)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -2,36 +2,36 @@ require 'rails_helper'
|
||||
|
||||
describe Setting do
|
||||
before do
|
||||
Setting["official_level_1_name"] = 'Stormtrooper'
|
||||
described_class["official_level_1_name"] = 'Stormtrooper'
|
||||
end
|
||||
|
||||
it "should return the overriden setting" do
|
||||
expect(Setting['official_level_1_name']).to eq('Stormtrooper')
|
||||
it "returns the overriden setting" do
|
||||
expect(described_class['official_level_1_name']).to eq('Stormtrooper')
|
||||
end
|
||||
|
||||
it "should should return nil" do
|
||||
expect(Setting['undefined_key']).to eq(nil)
|
||||
it "shoulds return nil" do
|
||||
expect(described_class['undefined_key']).to eq(nil)
|
||||
end
|
||||
|
||||
it "should persist a setting on the db" do
|
||||
expect(Setting.where(key: 'official_level_1_name', value: 'Stormtrooper')).to exist
|
||||
it "persists a setting on the db" do
|
||||
expect(described_class.where(key: 'official_level_1_name', value: 'Stormtrooper')).to exist
|
||||
end
|
||||
|
||||
describe "#feature_flag?" do
|
||||
it "should be true if key starts with 'feature.'" do
|
||||
setting = Setting.create(key: 'feature.whatever')
|
||||
it "is true if key starts with 'feature.'" do
|
||||
setting = described_class.create(key: 'feature.whatever')
|
||||
expect(setting.feature_flag?).to eq true
|
||||
end
|
||||
|
||||
it "should be false if key does not start with 'feature.'" do
|
||||
setting = Setting.create(key: 'whatever')
|
||||
it "is false if key does not start with 'feature.'" do
|
||||
setting = described_class.create(key: 'whatever')
|
||||
expect(setting.feature_flag?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#enabled?" do
|
||||
it "should be true if feature_flag and value present" do
|
||||
setting = Setting.create(key: 'feature.whatever', value: 1)
|
||||
it "is true if feature_flag and value present" do
|
||||
setting = described_class.create(key: 'feature.whatever', value: 1)
|
||||
expect(setting.enabled?).to eq true
|
||||
|
||||
setting.value = "true"
|
||||
@@ -41,40 +41,40 @@ describe Setting do
|
||||
expect(setting.enabled?).to eq true
|
||||
end
|
||||
|
||||
it "should be false if feature_flag and value blank" do
|
||||
setting = Setting.create(key: 'feature.whatever')
|
||||
it "is false if feature_flag and value blank" do
|
||||
setting = described_class.create(key: 'feature.whatever')
|
||||
expect(setting.enabled?).to eq false
|
||||
|
||||
setting.value = ""
|
||||
expect(setting.enabled?).to eq false
|
||||
end
|
||||
|
||||
it "should be false if not feature_flag" do
|
||||
setting = Setting.create(key: 'whatever', value: "whatever")
|
||||
it "is false if not feature_flag" do
|
||||
setting = described_class.create(key: 'whatever', value: "whatever")
|
||||
expect(setting.enabled?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#banner_style?" do
|
||||
it "should be true if key starts with 'banner-style.'" do
|
||||
setting = Setting.create(key: 'banner-style.whatever')
|
||||
it "is true if key starts with 'banner-style.'" do
|
||||
setting = described_class.create(key: 'banner-style.whatever')
|
||||
expect(setting.banner_style?).to eq true
|
||||
end
|
||||
|
||||
it "should be false if key does not start with 'banner-style.'" do
|
||||
setting = Setting.create(key: 'whatever')
|
||||
it "is false if key does not start with 'banner-style.'" do
|
||||
setting = described_class.create(key: 'whatever')
|
||||
expect(setting.banner_style?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#banner_img?" do
|
||||
it "should be true if key starts with 'banner-img.'" do
|
||||
setting = Setting.create(key: 'banner-img.whatever')
|
||||
it "is true if key starts with 'banner-img.'" do
|
||||
setting = described_class.create(key: 'banner-img.whatever')
|
||||
expect(setting.banner_img?).to eq true
|
||||
end
|
||||
|
||||
it "should be false if key does not start with 'banner-img.'" do
|
||||
setting = Setting.create(key: 'whatever')
|
||||
it "is false if key does not start with 'banner-img.'" do
|
||||
setting = described_class.create(key: 'whatever')
|
||||
expect(setting.banner_img?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,11 +6,11 @@ describe SignatureSheet do
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(signature_sheet).to be_valid
|
||||
end
|
||||
|
||||
it "should be valid with a valid signable" do
|
||||
it "is valid with a valid signable" do
|
||||
signature_sheet.signable = create(:proposal)
|
||||
expect(signature_sheet).to be_valid
|
||||
|
||||
@@ -18,24 +18,24 @@ describe SignatureSheet do
|
||||
expect(signature_sheet).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without signable" do
|
||||
it "is not valid without signable" do
|
||||
signature_sheet.signable = nil
|
||||
expect(signature_sheet).to_not be_valid
|
||||
expect(signature_sheet).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a valid signable" do
|
||||
it "is not valid without a valid signable" do
|
||||
signature_sheet.signable = create(:comment)
|
||||
expect(signature_sheet).to_not be_valid
|
||||
expect(signature_sheet).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without document numbers" do
|
||||
it "is not valid without document numbers" do
|
||||
signature_sheet.document_numbers = nil
|
||||
expect(signature_sheet).to_not be_valid
|
||||
expect(signature_sheet).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an author" do
|
||||
it "is not valid without an author" do
|
||||
signature_sheet.author = nil
|
||||
expect(signature_sheet).to_not be_valid
|
||||
expect(signature_sheet).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,24 +6,24 @@ describe Signature do
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(signature).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a document number" do
|
||||
it "is not valid without a document number" do
|
||||
signature.document_number = nil
|
||||
expect(signature).to_not be_valid
|
||||
expect(signature).not_to be_valid
|
||||
|
||||
signature.document_number = ""
|
||||
expect(signature).to_not be_valid
|
||||
expect(signature).not_to be_valid
|
||||
|
||||
signature.document_number = " "
|
||||
expect(signature).to_not be_valid
|
||||
expect(signature).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an associated signature sheet" do
|
||||
it "is not valid without an associated signature sheet" do
|
||||
signature.signature_sheet = nil
|
||||
expect(signature).to_not be_valid
|
||||
expect(signature).not_to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
@@ -89,7 +89,7 @@ describe Signature do
|
||||
|
||||
signature.verify
|
||||
|
||||
expect(user.voted_for?(investment)).to_not be
|
||||
expect(user.voted_for?(investment)).not_to be
|
||||
expect(Vote.count).to eq(0)
|
||||
end
|
||||
|
||||
@@ -185,7 +185,7 @@ describe Signature do
|
||||
it "calls assign_vote_to_user" do
|
||||
signature = create(:signature, document_number: "12345678Z")
|
||||
|
||||
expect(signature).to receive(:assign_vote_to_user)
|
||||
allow(signature).to receive(:assign_vote_to_user)
|
||||
signature.verify
|
||||
end
|
||||
|
||||
@@ -205,7 +205,7 @@ describe Signature do
|
||||
it "does not call assign_vote_to_user" do
|
||||
signature = create(:signature, document_number: "123A")
|
||||
|
||||
expect(signature).to_not receive(:assign_vote_to_user)
|
||||
expect(signature).not_to receive(:assign_vote_to_user)
|
||||
signature.verify
|
||||
end
|
||||
|
||||
@@ -213,10 +213,10 @@ describe Signature do
|
||||
signature = create(:signature, document_number: "123A")
|
||||
|
||||
signature.verify
|
||||
expect(signature).to_not be_verified
|
||||
expect(signature).not_to be_verified
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'rails_helper'
|
||||
RSpec.describe SiteCustomization::ContentBlock, type: :model do
|
||||
let(:block) { build(:site_customization_content_block) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(block).to be_valid
|
||||
end
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ require 'rails_helper'
|
||||
RSpec.describe SiteCustomization::Page, type: :model do
|
||||
let(:custom_page) { build(:site_customization_page) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(custom_page).to be_valid
|
||||
end
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'participation')
|
||||
create(:debate, tag_list: 'world hunger')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('participation')
|
||||
end
|
||||
@@ -17,7 +17,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'participation')
|
||||
create(:debate, tag_list: 'world hunger')
|
||||
|
||||
tag_cloud = TagCloud.new(Debate)
|
||||
tag_cloud = described_class.new(Debate)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('world hunger')
|
||||
end
|
||||
@@ -26,7 +26,7 @@ describe TagCloud do
|
||||
create(:budget_investment, tag_list: 'participation')
|
||||
create(:debate, tag_list: 'world hunger')
|
||||
|
||||
tag_cloud = TagCloud.new(Budget::Investment)
|
||||
tag_cloud = described_class.new(Budget::Investment)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('participation')
|
||||
end
|
||||
@@ -35,7 +35,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'participation', created_at: 1.day.ago)
|
||||
create(:proposal, tag_list: 'corruption', created_at: 2.weeks.ago)
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('participation')
|
||||
end
|
||||
@@ -47,7 +47,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'education, parks')
|
||||
create(:proposal, tag_list: 'participation, water')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks', 'water')
|
||||
end
|
||||
@@ -59,7 +59,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'parks, California')
|
||||
create(:proposal, tag_list: 'water, New York')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks', 'water')
|
||||
end
|
||||
@@ -71,7 +71,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'education, parks')
|
||||
create(:proposal, tag_list: 'participation, water')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal, 'Education')
|
||||
tag_cloud = described_class.new(Proposal, 'Education')
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks')
|
||||
end
|
||||
@@ -83,7 +83,7 @@ describe TagCloud do
|
||||
create(:proposal, tag_list: 'parks, California')
|
||||
create(:proposal, tag_list: 'water, New York')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal, 'California')
|
||||
tag_cloud = described_class.new(Proposal, 'California')
|
||||
|
||||
expect(tag_names(tag_cloud)).to contain_exactly('parks')
|
||||
end
|
||||
@@ -95,7 +95,7 @@ describe TagCloud do
|
||||
3.times { create(:proposal, tag_list: 'participation') }
|
||||
create(:proposal, tag_list: 'corruption')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud).first).to eq 'participation'
|
||||
expect(tag_names(tag_cloud).second).to eq 'corruption'
|
||||
@@ -106,7 +106,7 @@ describe TagCloud do
|
||||
3.times { create(:proposal, tag_list: 'health') }
|
||||
create(:proposal, tag_list: 'corruption')
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud).first).to eq 'health'
|
||||
expect(tag_names(tag_cloud).second).to eq 'participation'
|
||||
@@ -116,7 +116,7 @@ describe TagCloud do
|
||||
it "returns a maximum of 10 tags" do
|
||||
12.times { |i| create(:proposal, tag_list: "Tag #{i}") }
|
||||
|
||||
tag_cloud = TagCloud.new(Proposal)
|
||||
tag_cloud = described_class.new(Proposal)
|
||||
|
||||
expect(tag_names(tag_cloud).count).to eq(10)
|
||||
end
|
||||
|
||||
@@ -3,23 +3,27 @@ require 'rails_helper'
|
||||
describe Topic do
|
||||
let(:topic) { build(:topic) }
|
||||
|
||||
it "should be valid" do
|
||||
describe "Concerns" do
|
||||
it_behaves_like "notifiable"
|
||||
end
|
||||
|
||||
it "is valid" do
|
||||
expect(topic).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an author" do
|
||||
it "is not valid without an author" do
|
||||
topic.author = nil
|
||||
expect(topic).to_not be_valid
|
||||
expect(topic).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a title" do
|
||||
it "is not valid without a title" do
|
||||
topic.title = nil
|
||||
expect(topic).to_not be_valid
|
||||
expect(topic).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a description" do
|
||||
it "is not valid without a description" do
|
||||
topic.description = nil
|
||||
expect(topic).to_not be_valid
|
||||
expect(topic).not_to be_valid
|
||||
end
|
||||
|
||||
context "order" do
|
||||
@@ -71,4 +75,7 @@ describe Topic do
|
||||
|
||||
end
|
||||
|
||||
describe "notifications" do
|
||||
it_behaves_like 'notifiable'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ describe User do
|
||||
flagged = user.comment_flags([comment1, comment2, comment3])
|
||||
|
||||
expect(flagged[comment1.id]).to be
|
||||
expect(flagged[comment2.id]).to_not be
|
||||
expect(flagged[comment2.id]).not_to be
|
||||
expect(flagged[comment3.id]).to be
|
||||
end
|
||||
end
|
||||
@@ -55,7 +55,7 @@ describe User do
|
||||
describe "#terms" do
|
||||
it "is not valid without accepting the terms of service" do
|
||||
subject.terms_of_service = nil
|
||||
expect(subject).to_not be_valid
|
||||
expect(subject).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,37 +74,37 @@ describe User do
|
||||
|
||||
describe 'preferences' do
|
||||
describe 'email_on_comment' do
|
||||
it 'should be false by default' do
|
||||
it 'is false by default' do
|
||||
expect(subject.email_on_comment).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'email_on_comment_reply' do
|
||||
it 'should be false by default' do
|
||||
it 'is false by default' do
|
||||
expect(subject.email_on_comment_reply).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'subscription_to_website_newsletter' do
|
||||
it 'should be true by default' do
|
||||
it 'is true by default' do
|
||||
expect(subject.newsletter).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'email_digest' do
|
||||
it 'should be true by default' do
|
||||
it 'is true by default' do
|
||||
expect(subject.email_digest).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'email_on_direct_message' do
|
||||
it 'should be true by default' do
|
||||
it 'is true by default' do
|
||||
expect(subject.email_on_direct_message).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'official_position_badge' do
|
||||
it 'should be false by default' do
|
||||
it 'is false by default' do
|
||||
expect(subject.official_position_badge).to eq(false)
|
||||
end
|
||||
end
|
||||
@@ -176,7 +176,7 @@ describe User do
|
||||
end
|
||||
|
||||
describe 'when it is an organization' do
|
||||
before(:each) { create(:organization, user: subject) }
|
||||
before { create(:organization, user: subject) }
|
||||
|
||||
it "is true when the user is an organization" do
|
||||
expect(subject.organization?).to be true
|
||||
@@ -190,14 +190,14 @@ describe User do
|
||||
|
||||
describe "verified_organization?" do
|
||||
it "is falsy when the user is not an organization" do
|
||||
expect(subject).to_not be_verified_organization
|
||||
expect(subject).not_to be_verified_organization
|
||||
end
|
||||
|
||||
describe 'when it is an organization' do
|
||||
before(:each) { create(:organization, user: subject) }
|
||||
before { create(:organization, user: subject) }
|
||||
|
||||
it "is false when the user is not a verified organization" do
|
||||
expect(subject).to_not be_verified_organization
|
||||
expect(subject).not_to be_verified_organization
|
||||
end
|
||||
|
||||
it "is true when the user is a verified organization" do
|
||||
@@ -208,7 +208,7 @@ describe User do
|
||||
end
|
||||
|
||||
describe "organization_attributes" do
|
||||
before(:each) { subject.organization_attributes = {name: 'org', responsible_name: 'julia'} }
|
||||
before { subject.organization_attributes = {name: 'org', responsible_name: 'julia'} }
|
||||
|
||||
it "triggers the creation of an associated organization" do
|
||||
expect(subject.organization).to be
|
||||
@@ -221,7 +221,7 @@ describe User do
|
||||
expect(subject).to be_valid
|
||||
|
||||
subject.organization.name = nil
|
||||
expect(subject).to_not be_valid
|
||||
expect(subject).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -278,7 +278,7 @@ describe User do
|
||||
create(:user, official_position: "Manager", official_level: 5)
|
||||
2.times { create(:user) }
|
||||
|
||||
officials = User.officials
|
||||
officials = described_class.officials
|
||||
expect(officials.size).to eq(4)
|
||||
officials.each do |user|
|
||||
expect(user.official_level).to be > 0
|
||||
@@ -353,9 +353,9 @@ describe User do
|
||||
user2 = create(:user, erased_at: nil)
|
||||
user3 = create(:user, erased_at: Time.current)
|
||||
|
||||
expect(User.active).to include(user1)
|
||||
expect(User.active).to include(user2)
|
||||
expect(User.active).to_not include(user3)
|
||||
expect(described_class.active).to include(user1)
|
||||
expect(described_class.active).to include(user2)
|
||||
expect(described_class.active).not_to include(user3)
|
||||
end
|
||||
|
||||
it "returns users that have not been blocked" do
|
||||
@@ -364,9 +364,9 @@ describe User do
|
||||
user3 = create(:user)
|
||||
user3.block
|
||||
|
||||
expect(User.active).to include(user1)
|
||||
expect(User.active).to include(user2)
|
||||
expect(User.active).to_not include(user3)
|
||||
expect(described_class.active).to include(user1)
|
||||
expect(described_class.active).to include(user2)
|
||||
expect(described_class.active).not_to include(user3)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -378,9 +378,9 @@ describe User do
|
||||
user2 = create(:user, erased_at: Time.current)
|
||||
user3 = create(:user, erased_at: nil)
|
||||
|
||||
expect(User.erased).to include(user1)
|
||||
expect(User.erased).to include(user2)
|
||||
expect(User.erased).to_not include(user3)
|
||||
expect(described_class.erased).to include(user1)
|
||||
expect(described_class.erased).to include(user2)
|
||||
expect(described_class.erased).not_to include(user3)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -390,7 +390,7 @@ describe User do
|
||||
it "find users by email" do
|
||||
user1 = create(:user, email: "larry@consul.dev")
|
||||
create(:user, email: "bird@consul.dev")
|
||||
search = User.search("larry@consul.dev")
|
||||
search = described_class.search("larry@consul.dev")
|
||||
expect(search.size).to eq(1)
|
||||
expect(search.first).to eq(user1)
|
||||
end
|
||||
@@ -398,13 +398,13 @@ describe User do
|
||||
it "find users by name" do
|
||||
user1 = create(:user, username: "Larry Bird")
|
||||
create(:user, username: "Robert Parish")
|
||||
search = User.search("larry")
|
||||
search = described_class.search("larry")
|
||||
expect(search.size).to eq(1)
|
||||
expect(search.first).to eq(user1)
|
||||
end
|
||||
|
||||
it "returns no results if no search term provided" do
|
||||
expect(User.search(" ").size).to eq(0)
|
||||
expect(described_class.search(" ").size).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -415,17 +415,17 @@ describe User do
|
||||
describe "cache" do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it "should expire cache with becoming a moderator" do
|
||||
it "expires cache with becoming a moderator" do
|
||||
expect { create(:moderator, user: user) }
|
||||
.to change { user.updated_at}
|
||||
end
|
||||
|
||||
it "should expire cache with becoming an admin" do
|
||||
it "expires cache with becoming an admin" do
|
||||
expect { create(:administrator, user: user) }
|
||||
.to change { user.updated_at}
|
||||
end
|
||||
|
||||
it "should expire cache with becoming a veridied organization" do
|
||||
it "expires cache with becoming a veridied organization" do
|
||||
create(:organization, user: user)
|
||||
expect { user.organization.verify }
|
||||
.to change { user.reload.updated_at}
|
||||
@@ -433,14 +433,14 @@ describe User do
|
||||
end
|
||||
|
||||
describe "document_number" do
|
||||
it "should upcase document number" do
|
||||
user = User.new(document_number: "x1234567z")
|
||||
it "upcases document number" do
|
||||
user = described_class.new(document_number: "x1234567z")
|
||||
user.valid?
|
||||
expect(user.document_number).to eq("X1234567Z")
|
||||
end
|
||||
|
||||
it "should remove all characters except numbers and letters" do
|
||||
user = User.new(document_number: " 12.345.678 - B")
|
||||
it "removes all characters except numbers and letters" do
|
||||
user = described_class.new(document_number: " 12.345.678 - B")
|
||||
user.valid?
|
||||
expect(user.document_number).to eq("12345678B")
|
||||
end
|
||||
@@ -497,7 +497,7 @@ describe User do
|
||||
|
||||
user.erase('an identity test')
|
||||
|
||||
expect(Identity.exists?(identity.id)).to_not be
|
||||
expect(Identity.exists?(identity.id)).not_to be
|
||||
end
|
||||
|
||||
end
|
||||
@@ -660,14 +660,14 @@ describe User do
|
||||
describe "#interests" do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it "should return followed object tags" do
|
||||
it "returns followed object tags" do
|
||||
proposal = create(:proposal, tag_list: "Sport")
|
||||
create(:follow, followable: proposal, user: user)
|
||||
|
||||
expect(user.interests).to eq ["Sport"]
|
||||
end
|
||||
|
||||
it "should discard followed objects duplicated tags" do
|
||||
it "discards followed objects duplicated tags" do
|
||||
proposal1 = create(:proposal, tag_list: "Sport")
|
||||
proposal2 = create(:proposal, tag_list: "Sport")
|
||||
budget_investment = create(:budget_investment, tag_list: "Sport")
|
||||
|
||||
@@ -3,13 +3,13 @@ require 'rails_helper'
|
||||
describe Valuator do
|
||||
|
||||
describe "#description_or_email" do
|
||||
it "should return description if present" do
|
||||
it "returns description if present" do
|
||||
valuator = create(:valuator, description: "Urbanism manager")
|
||||
|
||||
expect(valuator.description_or_email).to eq("Urbanism manager")
|
||||
end
|
||||
|
||||
it "should return email if not description present" do
|
||||
it "returns email if not description present" do
|
||||
valuator = create(:valuator)
|
||||
|
||||
expect(valuator.description_or_email).to eq(valuator.email)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Verification::Letter' do
|
||||
describe Verification::Letter do
|
||||
|
||||
let(:user) { create(:user) }
|
||||
|
||||
@@ -8,20 +8,20 @@ describe 'Verification::Letter' do
|
||||
|
||||
let(:letter) { build(:verification_letter) }
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(letter).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a user" do
|
||||
it "is not valid without a user" do
|
||||
letter.user = nil
|
||||
expect(letter).to_not be_valid
|
||||
expect(letter).not_to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "save" do
|
||||
|
||||
it "should update letter_requested" do
|
||||
it "updates letter_requested" do
|
||||
letter = build(:verification_letter)
|
||||
letter.save
|
||||
expect(letter.user.letter_requested_at).to be
|
||||
@@ -1,40 +1,42 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Verification::Management::Document do
|
||||
let(:min_age) { User.minimum_required_age }
|
||||
let(:over_minium_age_date_of_birth) { Date.new((min_age + 10).years.ago.year, 12, 31) }
|
||||
let(:under_minium_age_date_of_birth) { Date.new(min_age.years.ago.year, 12, 31) }
|
||||
let(:just_minium_age_date_of_birth) { Date.new(min_age.years.ago.year, min_age.years.ago.month, min_age.years.ago.day) }
|
||||
|
||||
describe "#valid_age?" do
|
||||
it "returns false when the user is younger than the user's minimum required age" do
|
||||
census_response = double(date_of_birth: Date.new(User.minimum_required_age.years.ago.year, 12, 31))
|
||||
expect(Verification::Management::Document.new.valid_age?(census_response)).to be false
|
||||
census_response = instance_double('CensusApi::Response', date_of_birth: under_minium_age_date_of_birth)
|
||||
expect(described_class.new.valid_age?(census_response)).to be false
|
||||
end
|
||||
|
||||
it "returns true when the user has the user's minimum required age" do
|
||||
census_response = double(date_of_birth: Date.new(User.minimum_required_age.years.ago.year, 16.years.ago.month, 16.years.ago.day))
|
||||
expect(Verification::Management::Document.new.valid_age?(census_response)).to be true
|
||||
census_response = instance_double('CensusApi::Response', date_of_birth: just_minium_age_date_of_birth)
|
||||
expect(described_class.new.valid_age?(census_response)).to be true
|
||||
end
|
||||
|
||||
it "returns true when the user is older than the user's minimum required age" do
|
||||
census_response = double(date_of_birth: Date.new((User.minimum_required_age + 10).years.ago.year, 12, 31))
|
||||
expect(Verification::Management::Document.new.valid_age?(census_response)).to be true
|
||||
census_response = instance_double('CensusApi::Response', date_of_birth: over_minium_age_date_of_birth)
|
||||
expect(described_class.new.valid_age?(census_response)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe "#under_age?" do
|
||||
it "returns true when the user is younger than the user's minimum required age" do
|
||||
census_response = double(date_of_birth: Date.new(User.minimum_required_age.years.ago.year, 12, 31))
|
||||
expect(Verification::Management::Document.new.under_age?(census_response)).to be true
|
||||
census_response = instance_double('CensusApi::Response', date_of_birth: under_minium_age_date_of_birth)
|
||||
expect(described_class.new.under_age?(census_response)).to be true
|
||||
end
|
||||
|
||||
it "returns false when the user is user's minimum required age" do
|
||||
date_of_birth = Date.new(User.minimum_required_age.years.ago.year,
|
||||
User.minimum_required_age.years.ago.month,
|
||||
User.minimum_required_age.years.ago.day)
|
||||
census_response = double(date_of_birth: date_of_birth)
|
||||
expect(Verification::Management::Document.new.under_age?(census_response)).to be false
|
||||
census_response = instance_double('CensusApi::Response', date_of_birth: just_minium_age_date_of_birth)
|
||||
expect(described_class.new.under_age?(census_response)).to be false
|
||||
end
|
||||
|
||||
it "returns false when the user is older than user's minimum required age" do
|
||||
census_response = double(date_of_birth: Date.new((User.minimum_required_age + 10).years.ago.year, 12, 31))
|
||||
expect(Verification::Management::Document.new.under_age?(census_response)).to be false
|
||||
census_response = instance_double('CensusApi::Response', date_of_birth: over_minium_age_date_of_birth)
|
||||
expect(described_class.new.under_age?(census_response)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,25 +4,26 @@ describe Verification::Management::Email do
|
||||
|
||||
describe "#user" do
|
||||
subject { described_class.new(document_type: "1", document_number: "1234", email: "inexisting@gmail.com") }
|
||||
|
||||
it "returns nil/false when the user does not exist" do
|
||||
expect(subject.user).to be_nil
|
||||
expect(subject.user?).to_not be
|
||||
expect(subject.user?).not_to be
|
||||
end
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it "is not valid if the user does not exist" do
|
||||
expect(described_class.new(document_type: "1", document_number: "1234", email: "inexisting@gmail.com")).to_not be_valid
|
||||
expect(described_class.new(document_type: "1", document_number: "1234", email: "inexisting@gmail.com")).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid if the user is already level 3" do
|
||||
user = create(:user, :level_three)
|
||||
expect(described_class.new(document_type: "1", document_number: "1234", email: user.email)).to_not be_valid
|
||||
expect(described_class.new(document_type: "1", document_number: "1234", email: user.email)).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid if the user already has a different document number" do
|
||||
user = create(:user, document_number: "1234", document_type: "1")
|
||||
expect(described_class.new(document_type: "1", document_number: "5678", email: user.email)).to_not be_valid
|
||||
expect(described_class.new(document_type: "1", document_number: "5678", email: user.email)).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,9 +39,9 @@ describe Verification::Management::Email do
|
||||
mail = double(:mail)
|
||||
|
||||
allow(validation).to receive(:user).and_return user
|
||||
expect(mail).to receive(:deliver_later)
|
||||
expect(Devise.token_generator).to receive(:generate).with(User, :email_verification_token).and_return(["1", "2"])
|
||||
expect(Mailer).to receive(:email_verification).with(user, user.email, "2", "1", "1234").and_return(mail)
|
||||
allow(mail).to receive(:deliver_later)
|
||||
allow(Devise.token_generator).to receive(:generate).with(User, :email_verification_token).and_return(["1", "2"])
|
||||
allow(Mailer).to receive(:email_verification).with(user, user.email, "2", "1", "1234").and_return(mail)
|
||||
|
||||
validation.save
|
||||
|
||||
|
||||
@@ -7,32 +7,32 @@ describe Verification::Residence do
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
expect(residence).to be_valid
|
||||
end
|
||||
|
||||
describe "dates" do
|
||||
it "should be valid with a valid date of birth" do
|
||||
residence = Verification::Residence.new("date_of_birth(3i)" => "1", "date_of_birth(2i)" => "1", "date_of_birth(1i)" => "1980")
|
||||
it "is valid with a valid date of birth" do
|
||||
residence = described_class.new("date_of_birth(3i)" => "1", "date_of_birth(2i)" => "1", "date_of_birth(1i)" => "1980")
|
||||
expect(residence.errors[:date_of_birth].size).to eq(0)
|
||||
end
|
||||
|
||||
it "should not be valid without a date of birth" do
|
||||
residence = Verification::Residence.new("date_of_birth(3i)" => "", "date_of_birth(2i)" => "", "date_of_birth(1i)" => "")
|
||||
expect(residence).to_not be_valid
|
||||
it "is not valid without a date of birth" do
|
||||
residence = described_class.new("date_of_birth(3i)" => "", "date_of_birth(2i)" => "", "date_of_birth(1i)" => "")
|
||||
expect(residence).not_to be_valid
|
||||
expect(residence.errors[:date_of_birth]).to include("can't be blank")
|
||||
end
|
||||
end
|
||||
|
||||
it "should validate user has allowed age" do
|
||||
residence = Verification::Residence.new("date_of_birth(3i)" => "1",
|
||||
"date_of_birth(2i)" => "1",
|
||||
"date_of_birth(1i)" => (5.years.ago.year).to_s)
|
||||
expect(residence).to_not be_valid
|
||||
it "validates user has allowed age" do
|
||||
residence = described_class.new("date_of_birth(3i)" => "1",
|
||||
"date_of_birth(2i)" => "1",
|
||||
"date_of_birth(1i)" => 5.years.ago.year.to_s)
|
||||
expect(residence).not_to be_valid
|
||||
expect(residence.errors[:date_of_birth]).to include("You don't have the required age to participate")
|
||||
end
|
||||
|
||||
it "should validate uniquness of document_number" do
|
||||
it "validates uniquness of document_number" do
|
||||
user = create(:user)
|
||||
residence.user = user
|
||||
residence.save
|
||||
@@ -43,28 +43,28 @@ describe Verification::Residence do
|
||||
expect(residence.errors[:document_number]).to include("has already been taken")
|
||||
end
|
||||
|
||||
it "should validate census terms" do
|
||||
it "validates census terms" do
|
||||
residence.terms_of_service = nil
|
||||
expect(residence).to_not be_valid
|
||||
expect(residence).not_to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "new" do
|
||||
it "should upcase document number" do
|
||||
residence = Verification::Residence.new(document_number: "x1234567z")
|
||||
it "upcases document number" do
|
||||
residence = described_class.new(document_number: "x1234567z")
|
||||
expect(residence.document_number).to eq("X1234567Z")
|
||||
end
|
||||
|
||||
it "should remove all characters except numbers and letters" do
|
||||
residence = Verification::Residence.new(document_number: " 12.345.678 - B")
|
||||
it "removes all characters except numbers and letters" do
|
||||
residence = described_class.new(document_number: " 12.345.678 - B")
|
||||
expect(residence.document_number).to eq("12345678B")
|
||||
end
|
||||
end
|
||||
|
||||
describe "save" do
|
||||
|
||||
it "should store document number, document type, geozone, date of birth and gender" do
|
||||
it "stores document number, document type, geozone, date of birth and gender" do
|
||||
user = create(:user)
|
||||
residence.user = user
|
||||
residence.save
|
||||
@@ -82,13 +82,13 @@ describe Verification::Residence do
|
||||
end
|
||||
|
||||
describe "tries" do
|
||||
it "should increase tries after a call to the Census" do
|
||||
it "increases tries after a call to the Census" do
|
||||
residence.postal_code = "28011"
|
||||
residence.valid?
|
||||
expect(residence.user.lock.tries).to eq(1)
|
||||
end
|
||||
|
||||
it "should not increase tries after a validation error" do
|
||||
it "does not increase tries after a validation error" do
|
||||
residence.postal_code = ""
|
||||
residence.valid?
|
||||
expect(residence.user.lock).to be nil
|
||||
@@ -1,22 +1,22 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Verification::Sms do
|
||||
it "should be valid" do
|
||||
it "is valid" do
|
||||
sms = build(:verification_sms)
|
||||
expect(sms).to be_valid
|
||||
end
|
||||
|
||||
it "should validate uniqness of phone" do
|
||||
it "validates uniqness of phone" do
|
||||
create(:user, confirmed_phone: "699999999")
|
||||
sms = Verification::Sms.new(phone: "699999999")
|
||||
expect(sms).to_not be_valid
|
||||
sms = described_class.new(phone: "699999999")
|
||||
expect(sms).not_to be_valid
|
||||
end
|
||||
|
||||
it "only allows spaces, numbers and the + sign" do
|
||||
expect(build(:verification_sms, phone: "0034 666666666")).to be_valid
|
||||
expect(build(:verification_sms, phone: "+34 666666666")).to be_valid
|
||||
expect(build(:verification_sms, phone: "hello there")).to_not be_valid
|
||||
expect(build(:verification_sms, phone: "555; DROP TABLE USERS")).to_not be_valid
|
||||
expect(build(:verification_sms, phone: "hello there")).not_to be_valid
|
||||
expect(build(:verification_sms, phone: "555; DROP TABLE USERS")).not_to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Vote' do
|
||||
describe Vote do
|
||||
|
||||
describe '#for_debates' do
|
||||
it 'does not returns votes for other votables' do
|
||||
@@ -8,7 +8,7 @@ describe 'Vote' do
|
||||
comment = create(:comment)
|
||||
create(:vote, votable: comment)
|
||||
|
||||
expect(Vote.for_debates(debate).count).to eq(0)
|
||||
expect(described_class.for_debates(debate).count).to eq(0)
|
||||
end
|
||||
|
||||
it 'returns votes only for debates in parameters' do
|
||||
@@ -16,8 +16,8 @@ describe 'Vote' do
|
||||
debate2 = create(:debate)
|
||||
create(:vote, votable: debate1)
|
||||
|
||||
expect(Vote.for_debates(debate1).count).to eq(1)
|
||||
expect(Vote.for_debates(debate2).count).to eq(0)
|
||||
expect(described_class.for_debates(debate1).count).to eq(1)
|
||||
expect(described_class.for_debates(debate2).count).to eq(0)
|
||||
end
|
||||
|
||||
it 'accepts more than 1 debate' do
|
||||
@@ -27,7 +27,7 @@ describe 'Vote' do
|
||||
create(:vote, votable: debate1)
|
||||
create(:vote, votable: debate3)
|
||||
|
||||
expect(Vote.for_debates([debate1, debate2]).count).to eq(1)
|
||||
expect(described_class.for_debates([debate1, debate2]).count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,42 +46,42 @@ describe 'Vote' do
|
||||
debate = create(:debate)
|
||||
vote = create(:vote, votable: debate)
|
||||
|
||||
expect(Vote.public_for_api).to include(vote)
|
||||
expect(described_class.public_for_api).to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks votes on hidden debates' do
|
||||
debate = create(:debate, :hidden)
|
||||
vote = create(:vote, votable: debate)
|
||||
|
||||
expect(Vote.public_for_api).not_to include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
|
||||
it 'returns votes on proposals' do
|
||||
proposal = create(:proposal)
|
||||
vote = create(:vote, votable: proposal)
|
||||
|
||||
expect(Vote.public_for_api).to include(vote)
|
||||
expect(described_class.public_for_api).to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks votes on hidden proposals' do
|
||||
proposal = create(:proposal, :hidden)
|
||||
vote = create(:vote, votable: proposal)
|
||||
|
||||
expect(Vote.public_for_api).not_to include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
|
||||
it 'returns votes on comments' do
|
||||
comment = create(:comment)
|
||||
vote = create(:vote, votable: comment)
|
||||
|
||||
expect(Vote.public_for_api).to include(vote)
|
||||
expect(described_class.public_for_api).to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks votes on hidden comments' do
|
||||
comment = create(:comment, :hidden)
|
||||
vote = create(:vote, votable: comment)
|
||||
|
||||
expect(Vote.public_for_api).not_to include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks votes on comments on hidden proposals' do
|
||||
@@ -89,7 +89,7 @@ describe 'Vote' do
|
||||
comment_on_hidden_proposal = create(:comment, commentable: hidden_proposal)
|
||||
vote = create(:vote, votable: comment_on_hidden_proposal)
|
||||
|
||||
expect(Vote.public_for_api).to_not include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks votes on comments on hidden debates' do
|
||||
@@ -97,20 +97,20 @@ describe 'Vote' do
|
||||
comment_on_hidden_debate = create(:comment, commentable: hidden_debate)
|
||||
vote = create(:vote, votable: comment_on_hidden_debate)
|
||||
|
||||
expect(Vote.public_for_api).to_not include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks any other kind of votes' do
|
||||
spending_proposal = create(:spending_proposal)
|
||||
vote = create(:vote, votable: spending_proposal)
|
||||
|
||||
expect(Vote.public_for_api).not_to include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
|
||||
it 'blocks votes without votable' do
|
||||
vote = build(:vote, votable: nil).save!(validate: false)
|
||||
|
||||
expect(Vote.public_for_api).not_to include(vote)
|
||||
expect(described_class.public_for_api).not_to include(vote)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user