Merge branch 'budget' into budget-public-controllers
This commit is contained in:
@@ -193,6 +193,10 @@ FactoryGirl.define do
|
||||
currency_symbol "€"
|
||||
phase 'on_hold'
|
||||
|
||||
trait :accepting do
|
||||
phase 'accepting'
|
||||
end
|
||||
|
||||
trait :selecting do
|
||||
phase 'selecting'
|
||||
end
|
||||
|
||||
158
spec/features/admin/budgets_spec.rb
Normal file
158
spec/features/admin/budgets_spec.rb
Normal file
@@ -0,0 +1,158 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Admin budgets' do
|
||||
|
||||
background do
|
||||
admin = create(:administrator)
|
||||
login_as(admin.user)
|
||||
end
|
||||
|
||||
context 'Feature flag' do
|
||||
|
||||
xscenario 'Disabled with a feature flag' do
|
||||
Setting['feature.budgets'] = nil
|
||||
expect{ visit admin_budgets_path }.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'Index' do
|
||||
|
||||
scenario 'Displaying budgets' do
|
||||
budget = create(:budget)
|
||||
visit admin_budgets_path
|
||||
|
||||
expect(page).to have_content(budget.name)
|
||||
expect(page).to have_content(I18n.t("budget.phase.#{budget.phase}"))
|
||||
end
|
||||
|
||||
scenario 'Filters by phase' do
|
||||
budget1 = create(:budget)
|
||||
budget2 = create(:budget, :accepting)
|
||||
budget3 = create(:budget, :selecting)
|
||||
budget4 = create(:budget, :balloting)
|
||||
budget5 = create(:budget, :finished)
|
||||
|
||||
visit admin_budgets_path
|
||||
expect(page).to have_content(budget1.name)
|
||||
expect(page).to have_content(budget2.name)
|
||||
expect(page).to have_content(budget3.name)
|
||||
expect(page).to have_content(budget4.name)
|
||||
expect(page).to_not have_content(budget5.name)
|
||||
|
||||
click_link 'Finished'
|
||||
expect(page).to_not have_content(budget1.name)
|
||||
expect(page).to_not have_content(budget2.name)
|
||||
expect(page).to_not have_content(budget3.name)
|
||||
expect(page).to_not have_content(budget4.name)
|
||||
expect(page).to have_content(budget5.name)
|
||||
|
||||
click_link 'Open'
|
||||
expect(page).to have_content(budget1.name)
|
||||
expect(page).to have_content(budget2.name)
|
||||
expect(page).to have_content(budget3.name)
|
||||
expect(page).to have_content(budget4.name)
|
||||
expect(page).to_not have_content(budget5.name)
|
||||
end
|
||||
|
||||
scenario 'Current filter is properly highlighted' do
|
||||
filters_links = {'open' => 'Open', 'finished' => 'Finished'}
|
||||
|
||||
visit admin_budgets_path
|
||||
|
||||
expect(page).to_not have_link(filters_links.values.first)
|
||||
filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) }
|
||||
|
||||
filters_links.each_pair do |current_filter, link|
|
||||
visit admin_budgets_path(filter: current_filter)
|
||||
|
||||
expect(page).to_not have_link(link)
|
||||
|
||||
(filters_links.keys - [current_filter]).each do |filter|
|
||||
expect(page).to have_link(filters_links[filter])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'New' do
|
||||
|
||||
scenario 'Create budget' do
|
||||
visit admin_budgets_path
|
||||
click_link 'Create new'
|
||||
|
||||
fill_in 'budget_name', with: 'M30 - Summer campaign'
|
||||
fill_in 'budget_description', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30'
|
||||
select 'Accepting proposals', from: 'budget[phase]'
|
||||
|
||||
click_button 'Create budget'
|
||||
|
||||
expect(page).to have_content 'New participatory budget created successfully!'
|
||||
expect(page).to have_content 'M30 - Summer campaign'
|
||||
end
|
||||
|
||||
scenario 'Name is mandatory' do
|
||||
visit new_admin_budget_path
|
||||
click_button 'Create budget'
|
||||
|
||||
expect(page).to_not have_content 'New participatory budget created successfully!'
|
||||
expect(page).to have_css("label.error", text: "Budget's name")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'Manage groups and headings' do
|
||||
|
||||
scenario 'Create group', :js do
|
||||
create(:budget, name: 'Yearly participatory budget')
|
||||
|
||||
visit admin_budgets_path
|
||||
click_link 'Yearly participatory budget'
|
||||
|
||||
expect(page).to have_content 'No groups created yet.'
|
||||
|
||||
click_link 'Add new group'
|
||||
|
||||
fill_in 'budget_group_name', with: 'General improvments'
|
||||
click_button 'Create group'
|
||||
|
||||
expect(page).to have_content 'Yearly participatory budget'
|
||||
expect(page).to_not have_content 'No groups created yet.'
|
||||
|
||||
visit admin_budgets_path
|
||||
click_link 'Yearly participatory budget'
|
||||
|
||||
expect(page).to have_content 'Yearly participatory budget'
|
||||
expect(page).to_not have_content 'No groups created yet.'
|
||||
end
|
||||
|
||||
scenario 'Create heading', :js do
|
||||
budget = create(:budget, name: 'Yearly participatory budget')
|
||||
group = create(:budget_group, budget: budget, name: 'Districts improvments')
|
||||
|
||||
visit admin_budget_path(budget)
|
||||
|
||||
within("#budget_group_#{group.id}") do
|
||||
expect(page).to have_content 'This group has no assigned heading.'
|
||||
click_link 'Add heading'
|
||||
|
||||
fill_in 'budget_heading_name', with: 'District 9 reconstruction'
|
||||
fill_in 'budget_heading_price', with: '6785'
|
||||
click_button 'Save heading'
|
||||
end
|
||||
|
||||
expect(page).to_not have_content 'This group has no assigned heading.'
|
||||
|
||||
visit admin_budget_path(budget)
|
||||
within("#budget_group_#{group.id}") do
|
||||
expect(page).to_not have_content 'This group has no assigned heading.'
|
||||
|
||||
expect(page).to have_content 'District 9 reconstruction'
|
||||
expect(page).to have_content '6785'
|
||||
expect(page).to have_content 'All city'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -201,8 +201,9 @@ feature 'Emails' do
|
||||
notification2 = create_proposal_notification(proposal2)
|
||||
notification3 = create_proposal_notification(proposal3)
|
||||
|
||||
email_digest = EmailDigest.new
|
||||
email_digest.create
|
||||
email_digest = EmailDigest.new(user)
|
||||
email_digest.deliver
|
||||
email_digest.mark_as_emailed
|
||||
|
||||
email = open_last_email
|
||||
expect(email).to have_subject("Proposal notifications in Consul")
|
||||
@@ -227,6 +228,11 @@ feature 'Emails' do
|
||||
|
||||
expect(email).to_not have_body_text(proposal3.title)
|
||||
expect(email).to have_body_text(/#{account_path}/)
|
||||
|
||||
notification1.reload
|
||||
notification2.reload
|
||||
expect(notification1.emailed_at).to be
|
||||
expect(notification2.emailed_at).to be
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -180,9 +180,10 @@ feature "Notifications" do
|
||||
|
||||
find(".icon-notification").click
|
||||
|
||||
notification_for_user1 = Notification.where(user: user1).first
|
||||
expect(page).to have_css ".notification", count: 1
|
||||
expect(page).to have_content "There is one new notification on #{proposal.title}"
|
||||
expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']"
|
||||
expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user1)}']"
|
||||
|
||||
logout
|
||||
login_as user2
|
||||
@@ -190,9 +191,10 @@ feature "Notifications" do
|
||||
|
||||
find(".icon-notification").click
|
||||
|
||||
notification_for_user2 = Notification.where(user: user2).first
|
||||
expect(page).to have_css ".notification", count: 1
|
||||
expect(page).to have_content "There is one new notification on #{proposal.title}"
|
||||
expect(page).to have_xpath "//a[@href='#{notification_path(Notification.first)}']"
|
||||
expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user2)}']"
|
||||
|
||||
logout
|
||||
login_as user3
|
||||
|
||||
@@ -24,6 +24,44 @@ feature 'Proposal Notifications' do
|
||||
expect(page).to have_content "Please share it with others so we can make it happen!"
|
||||
end
|
||||
|
||||
scenario "Send a notification (Active voter)" do
|
||||
author = create(:user)
|
||||
proposal = create(:proposal, author: author)
|
||||
|
||||
voter = create(:user, :level_two)
|
||||
create(:vote, voter: voter, votable: proposal)
|
||||
|
||||
create_proposal_notification(proposal)
|
||||
|
||||
expect(Notification.count).to eq(1)
|
||||
end
|
||||
|
||||
scenario "Send a notification (Blocked voter)" do
|
||||
author = create(:user)
|
||||
proposal = create(:proposal, author: author)
|
||||
|
||||
voter = create(:user, :level_two)
|
||||
create(:vote, voter: voter, votable: proposal)
|
||||
voter.block
|
||||
|
||||
create_proposal_notification(proposal)
|
||||
|
||||
expect(Notification.count).to eq(0)
|
||||
end
|
||||
|
||||
scenario "Send a notification (Erased voter)" do
|
||||
author = create(:user)
|
||||
proposal = create(:proposal, author: author)
|
||||
|
||||
voter = create(:user, :level_two)
|
||||
create(:vote, voter: voter, votable: proposal)
|
||||
voter.erase
|
||||
|
||||
create_proposal_notification(proposal)
|
||||
|
||||
expect(Notification.count).to eq(0)
|
||||
end
|
||||
|
||||
scenario "Show notifications" do
|
||||
proposal = create(:proposal)
|
||||
notification1 = create(:proposal_notification, proposal: proposal, title: "Hey guys", body: "Just wanted to let you know that...")
|
||||
|
||||
@@ -31,4 +31,19 @@ describe GeozonesHelper do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#geozone_name_from_id" do
|
||||
|
||||
it "returns geozone name if present" do
|
||||
g1 = create(:geozone, name: "AAA")
|
||||
g2 = create(:geozone, name: "BBB")
|
||||
|
||||
expect(geozone_name_from_id(g1.id)).to eq "AAA"
|
||||
expect(geozone_name_from_id(g2.id)).to eq "BBB"
|
||||
end
|
||||
|
||||
it "returns default string for no geozone if geozone is blank" do
|
||||
expect(geozone_name_from_id(nil)).to eq "All city"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -2,8 +2,126 @@ require 'rails_helper'
|
||||
|
||||
describe EmailDigest do
|
||||
|
||||
describe "create" do
|
||||
pending "only send unread notifications"
|
||||
describe "notifications" do
|
||||
|
||||
it "returns notifications for a user" do
|
||||
user1 = create(:user)
|
||||
user2 = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification1 = create(:notification, notifiable: proposal_notification, user: user1)
|
||||
notification2 = create(:notification, notifiable: proposal_notification, user: user2)
|
||||
|
||||
email_digest = EmailDigest.new(user1)
|
||||
|
||||
expect(email_digest.notifications).to include(notification1)
|
||||
expect(email_digest.notifications).to_not include(notification2)
|
||||
end
|
||||
|
||||
it "returns only proposal notifications" do
|
||||
user = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
comment = create(:comment)
|
||||
|
||||
notification1 = create(:notification, notifiable: proposal_notification, user: user)
|
||||
notification2 = create(:notification, notifiable: comment, user: user)
|
||||
|
||||
email_digest = EmailDigest.new(user)
|
||||
|
||||
expect(email_digest.notifications).to include(notification1)
|
||||
expect(email_digest.notifications).to_not include(notification2)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "pending_notifications?" do
|
||||
|
||||
it "returns true when notifications have not been emailed" do
|
||||
user = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification = create(:notification, notifiable: proposal_notification, user: user)
|
||||
|
||||
email_digest = EmailDigest.new(user)
|
||||
expect(email_digest.pending_notifications?).to be
|
||||
end
|
||||
|
||||
it "returns false when notifications have been emailed" do
|
||||
user = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification = create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
|
||||
|
||||
email_digest = EmailDigest.new(user)
|
||||
expect(email_digest.pending_notifications?).to_not be
|
||||
end
|
||||
|
||||
it "returns false when there are no notifications for a user" do
|
||||
user = create(:user)
|
||||
email_digest = EmailDigest.new(user)
|
||||
expect(email_digest.pending_notifications?).to_not be
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "deliver" do
|
||||
|
||||
it "delivers email if notifications pending" do
|
||||
user = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification = create(:notification, notifiable: proposal_notification, user: user)
|
||||
|
||||
reset_mailer
|
||||
email_digest = EmailDigest.new(user)
|
||||
email_digest.deliver
|
||||
|
||||
email = open_last_email
|
||||
expect(email).to have_subject("Proposal notifications in Consul")
|
||||
end
|
||||
|
||||
it "does not deliver email if no notifications pending" do
|
||||
user = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification = create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
|
||||
|
||||
reset_mailer
|
||||
email_digest = EmailDigest.new(user)
|
||||
email_digest.deliver
|
||||
|
||||
expect(all_emails.count).to eq(0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "mark_as_emailed" do
|
||||
|
||||
it "marks notifications as emailed" do
|
||||
user1 = create(:user)
|
||||
user2 = create(:user)
|
||||
|
||||
proposal_notification = create(:proposal_notification)
|
||||
notification1 = create(:notification, notifiable: proposal_notification, user: user1)
|
||||
notification2 = create(:notification, notifiable: proposal_notification, user: user1)
|
||||
notification3 = create(:notification, notifiable: proposal_notification, user: user2)
|
||||
|
||||
expect(notification1.emailed_at).to_not be
|
||||
expect(notification2.emailed_at).to_not be
|
||||
expect(notification3.emailed_at).to_not be
|
||||
|
||||
email_digest = EmailDigest.new(user1)
|
||||
email_digest.mark_as_emailed
|
||||
|
||||
notification1.reload
|
||||
notification2.reload
|
||||
notification3.reload
|
||||
expect(notification1.emailed_at).to be
|
||||
expect(notification2.emailed_at).to be
|
||||
expect(notification3.emailed_at).to_not be
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
0
spec/models/custom/.keep
Normal file
0
spec/models/custom/.keep
Normal file
34
spec/models/custom/residence_spec.rb
Normal file
34
spec/models/custom/residence_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Verification::Residence do
|
||||
|
||||
let(:residence) { build(:verification_residence, document_number: "12345678Z") }
|
||||
|
||||
describe "verification" do
|
||||
|
||||
describe "postal code" do
|
||||
it "should be valid with postal codes starting with 280" do
|
||||
residence.postal_code = "28012"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(0)
|
||||
|
||||
residence.postal_code = "28023"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(0)
|
||||
end
|
||||
|
||||
it "should not be valid with postal codes not starting with 280" do
|
||||
residence.postal_code = "12345"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(1)
|
||||
|
||||
residence.postal_code = "13280"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(1)
|
||||
expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -367,6 +367,50 @@ describe Proposal do
|
||||
end
|
||||
end
|
||||
|
||||
describe "voters" do
|
||||
|
||||
it "returns users that have voted for the proposal" do
|
||||
proposal = create(:proposal)
|
||||
voter1 = create(:user, :level_two)
|
||||
voter2 = create(:user, :level_two)
|
||||
voter3 = create(:user, :level_two)
|
||||
|
||||
create(:vote, voter: voter1, votable: proposal)
|
||||
create(:vote, voter: voter2, votable: proposal)
|
||||
|
||||
expect(proposal.voters).to include(voter1)
|
||||
expect(proposal.voters).to include(voter2)
|
||||
expect(proposal.voters).to_not include(voter3)
|
||||
end
|
||||
|
||||
it "does not return users that have been erased" do
|
||||
proposal = create(:proposal)
|
||||
voter1 = create(:user, :level_two)
|
||||
voter2 = create(:user, :level_two)
|
||||
|
||||
create(:vote, voter: voter1, votable: proposal)
|
||||
create(:vote, voter: voter2, votable: proposal)
|
||||
voter2.erase
|
||||
|
||||
expect(proposal.voters).to include(voter1)
|
||||
expect(proposal.voters).to_not include(voter2)
|
||||
end
|
||||
|
||||
it "does not return users that have been blocked" do
|
||||
proposal = create(:proposal)
|
||||
voter1 = create(:user, :level_two)
|
||||
voter2 = create(:user, :level_two)
|
||||
|
||||
create(:vote, voter: voter1, votable: proposal)
|
||||
create(:vote, voter: voter2, votable: proposal)
|
||||
voter2.block
|
||||
|
||||
expect(proposal.voters).to include(voter1)
|
||||
expect(proposal.voters).to_not include(voter2)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "search" do
|
||||
|
||||
context "attributes" do
|
||||
|
||||
@@ -30,29 +30,6 @@ describe Verification::Residence do
|
||||
expect(residence.errors[:date_of_birth]).to include("You must be at least 16 years old")
|
||||
end
|
||||
|
||||
describe "postal code" do
|
||||
it "should be valid with postal codes starting with 280" do
|
||||
residence.postal_code = "28012"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(0)
|
||||
|
||||
residence.postal_code = "28023"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(0)
|
||||
end
|
||||
|
||||
it "should not be valid with postal codes not starting with 280" do
|
||||
residence.postal_code = "12345"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(1)
|
||||
|
||||
residence.postal_code = "13280"
|
||||
residence.valid?
|
||||
expect(residence.errors[:postal_code].size).to eq(1)
|
||||
expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered.")
|
||||
end
|
||||
end
|
||||
|
||||
it "should validate uniquness of document_number" do
|
||||
user = create(:user)
|
||||
residence.user = user
|
||||
|
||||
@@ -325,6 +325,34 @@ describe User do
|
||||
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
|
||||
describe "active" do
|
||||
|
||||
it "returns users that have not been erased" do
|
||||
user1 = create(:user, erased_at: nil)
|
||||
user2 = create(:user, erased_at: nil)
|
||||
user3 = create(:user, erased_at: Time.now)
|
||||
|
||||
expect(User.active).to include(user1)
|
||||
expect(User.active).to include(user2)
|
||||
expect(User.active).to_not include(user3)
|
||||
end
|
||||
|
||||
it "returns users that have not been blocked" do
|
||||
user1 = create(:user)
|
||||
user2 = create(:user)
|
||||
user3 = create(:user)
|
||||
user3.block
|
||||
|
||||
expect(User.active).to include(user1)
|
||||
expect(User.active).to include(user2)
|
||||
expect(User.active).to_not include(user3)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe "self.search" do
|
||||
it "find users by email" do
|
||||
user1 = create(:user, email: "larry@consul.dev")
|
||||
|
||||
Reference in New Issue
Block a user