Simplify creating follows in specs

While in theory we wouldn't need to use the `transient` nor the
`after(:create)` because there's already a `has_many :through`
association with followers, Factory Bot / ActiveRecord don't
automatically associate the followable, resulting in an invalid record
exception.
This commit is contained in:
Javi Martín
2019-09-26 22:31:15 +02:00
parent 818b442d52
commit 5ff1162038
14 changed files with 98 additions and 150 deletions

View File

@@ -184,10 +184,14 @@ FactoryBot.define do
after(:create) { |investment| create(:image, imageable: investment) }
end
transient { voters { [] } }
transient do
voters { [] }
followers { [] }
end
after(:create) do |investment, evaluator|
evaluator.voters.each { |voter| create(:vote, votable: investment, voter: voter) }
evaluator.followers.each { |follower| create(:follow, followable: investment, user: follower) }
end
end

View File

@@ -78,10 +78,14 @@ FactoryBot.define do
after(:create) { |proposal| create(:image, imageable: proposal) }
end
transient { voters { [] } }
transient do
voters { [] }
followers { [] }
end
after(:create) do |proposal, evaluator|
evaluator.voters.each { |voter| create(:vote, votable: proposal, voter: voter) }
evaluator.followers.each { |follower| create(:follow, followable: proposal, user: follower) }
end
factory :retired_proposal, traits: [:retired]

View File

@@ -64,10 +64,14 @@ FactoryBot.define do
after(:create) { |user| create(:comment, author: user) }
end
transient { votables { [] } }
transient do
votables { [] }
followables { [] }
end
after(:create) do |user, evaluator|
evaluator.votables.each { |votable| create(:vote, votable: votable, voter: user) }
evaluator.followables.each { |followable| create(:follow, followable: followable, user: user) }
end
end

View File

@@ -160,9 +160,8 @@ describe "Homepage" do
end
scenario "Recomendations" do
proposal1 = create(:proposal, tag_list: "Sport")
proposal2 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
create(:proposal, tag_list: "Sport")
visit admin_homepage_path
within("#setting_#{user_recommendations.id}") do

View File

@@ -322,9 +322,8 @@ describe "System Emails" do
proposal_notification = create(:proposal_notification, proposal: proposal,
title: "Proposal A Title",
body: "Proposal A Notification Body")
voter = create(:user, :level_two)
voter = create(:user, :level_two, followables: [proposal])
create(:notification, notifiable: proposal_notification, user: voter, emailed_at: nil)
create(:follow, user: voter, followable: proposal)
visit admin_system_emails_path

View File

@@ -450,9 +450,8 @@ describe "Debates" do
end
scenario "are shown on index header when account setting is enabled" do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit debates_path
@@ -465,9 +464,8 @@ describe "Debates" do
end
scenario "should display text when there are no results" do
user = create(:user)
proposal = create(:proposal, tag_list: "Distinct_to_sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit debates_path
@@ -489,9 +487,8 @@ describe "Debates" do
end
scenario "can be sorted when there's a logged user" do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit debates_path
@@ -510,9 +507,8 @@ describe "Debates" do
end
scenario "are not shown if account setting is disabled" do
user = create(:user, recommended_debates: false)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, recommended_debates: false, followables: [proposal])
login_as(user)
visit debates_path
@@ -522,9 +518,8 @@ describe "Debates" do
end
scenario "are automatically disabled when dismissed from index", :js do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit debates_path
@@ -959,14 +954,13 @@ describe "Debates" do
end
scenario "Reorder by recommendations results maintaing search" do
user = create(:user, recommended_debates: true)
proposal = create(:proposal, tag_list: "Sport")
user = create(:user, recommended_debates: true, followables: [proposal])
debate1 = create(:debate, title: "Show you got", cached_votes_total: 10, tag_list: "Sport")
debate2 = create(:debate, title: "Show what you got", cached_votes_total: 1, tag_list: "Sport")
debate3 = create(:debate, title: "Do not display with same tag", cached_votes_total: 100, tag_list: "Sport")
debate4 = create(:debate, title: "Do not display", cached_votes_total: 1)
proposal1 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
login_as(user)
visit debates_path

View File

@@ -25,9 +25,8 @@ describe "Home" do
describe "Recommended" do
before do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
end

View File

@@ -38,22 +38,18 @@ describe "Proposal Notifications" do
scenario "Send a notification (Follower)" do
proposal = create(:proposal)
user_follower = create(:user)
create(:follow, :followed_proposal, user: user_follower, followable: proposal)
create(:user, :level_two, followables: [proposal])
create_proposal_notification(proposal)
expect(Notification.count).to eq(1)
end
scenario "Send a notification (Follower and Voter)" do
user_voter_follower = create(:user)
proposal = create(:proposal, voters: [user_voter_follower])
proposal = create(:proposal)
create(:follow, :followed_proposal, user: user_voter_follower, followable: proposal)
user_follower = create(:user)
create(:follow, :followed_proposal, user: user_follower, followable: proposal)
create(:user, followables: [proposal], votables: [proposal])
create(:user, followables: [proposal])
create_proposal_notification(proposal)
@@ -146,10 +142,9 @@ describe "Proposal Notifications" do
scenario "Message about receivers (Same Followers and Voters)" do
author = create(:user)
user_voter_follower = create(:user)
proposal = create(:proposal, author: author, voters: [user_voter_follower])
voter_follower = create(:user)
create(:follow, :followed_proposal, user: user_voter_follower, followable: proposal)
proposal = create(:proposal, author: author, voters: [voter_follower], followers: [voter_follower])
login_as(author)
visit new_proposal_notification_path(proposal_id: proposal.id)
@@ -254,15 +249,11 @@ describe "Proposal Notifications" do
scenario "Followers should receive a notification", :js do
author = create(:user)
user1 = create(:user)
user2 = create(:user)
user3 = create(:user)
proposal = create(:proposal, author: author)
create(:follow, :followed_proposal, user: user1, followable: proposal)
create(:follow, :followed_proposal, user: user2, followable: proposal)
user1 = create(:user, followables: [proposal])
user2 = create(:user, followables: [proposal])
user3 = create(:user)
login_as author.reload
visit root_path
@@ -358,11 +349,8 @@ describe "Proposal Notifications" do
scenario "for the same proposal", :js do
author = create(:user)
user = create(:user)
proposal = create(:proposal, author: author)
create(:follow, :followed_proposal, user: user, followable: proposal)
user = create(:user, followables: [proposal])
login_as author.reload

View File

@@ -749,9 +749,8 @@ describe "Proposals" do
end
scenario "are shown on index header when account setting is enabled" do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit proposals_path
@@ -764,9 +763,8 @@ describe "Proposals" do
end
scenario "should display text when there are no results" do
user = create(:user)
proposal = create(:proposal, tag_list: "Distinct_to_sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit proposals_path
@@ -788,9 +786,8 @@ describe "Proposals" do
end
scenario "can be sorted when there's a logged user" do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit proposals_path
@@ -809,9 +806,8 @@ describe "Proposals" do
end
scenario "are not shown if account setting is disabled" do
user = create(:user, recommended_proposals: false)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, recommended_proposals: false, followables: [proposal])
login_as(user)
visit proposals_path
@@ -821,9 +817,8 @@ describe "Proposals" do
end
scenario "are automatically disabled when dismissed from index", :js do
user = create(:user)
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
user = create(:user, followables: [proposal])
login_as(user)
visit proposals_path
@@ -996,10 +991,10 @@ describe "Proposals" do
end
scenario "do not show recommented proposal in selected proposals list" do
create(:proposal, title: "Recommended", tag_list: "Economy")
user = create(:user)
create(:follow, followable: create(:proposal, tag_list: "Economy"), user: user)
create(:proposal, tag_list: "Economy", followers: [user])
create(:proposal, title: "Recommended", tag_list: "Economy")
login_as(user)
visit proposals_path
@@ -1480,12 +1475,11 @@ describe "Proposals" do
scenario "Reorder by recommendations results maintaing search" do
user = create(:user, recommended_proposals: true)
proposal1 = create(:proposal, title: "Show you got", cached_votes_up: 10, tag_list: "Sport")
proposal2 = create(:proposal, title: "Show what you got", cached_votes_up: 1, tag_list: "Sport")
proposal3 = create(:proposal, title: "Do not display with same tag", cached_votes_up: 100, tag_list: "Sport")
proposal4 = create(:proposal, title: "Do not display", cached_votes_up: 1)
proposal5 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal5, user: user)
create(:proposal, title: "Show you got", cached_votes_up: 10, tag_list: "Sport")
create(:proposal, title: "Show what you got", cached_votes_up: 1, tag_list: "Sport")
create(:proposal, title: "Do not display with same tag", cached_votes_up: 100, tag_list: "Sport")
create(:proposal, title: "Do not display", cached_votes_up: 1)
create(:proposal, tag_list: "Sport", followers: [user])
login_as(user)
visit proposals_path

View File

@@ -239,8 +239,7 @@ describe "Users" do
end
scenario "Display interests" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
login_as(@user)
visit account_path
@@ -255,8 +254,7 @@ describe "Users" do
end
scenario "Not display interests when proposal has been destroyed" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
proposal = create(:proposal, tag_list: "Sport", followers: [@user])
proposal.destroy
login_as(@user)
@@ -279,8 +277,7 @@ describe "Users" do
end
scenario "User can display public page" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
login_as(@user)
visit account_path
@@ -296,8 +293,7 @@ describe "Users" do
end
scenario "Is always visible for the owner" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
login_as(@user)
visit account_path
@@ -310,8 +306,7 @@ describe "Users" do
end
scenario "Is always visible for admins" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
login_as(@user)
visit account_path
@@ -327,8 +322,7 @@ describe "Users" do
end
scenario "Is always visible for moderators" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
login_as(@user)
visit account_path
@@ -344,8 +338,7 @@ describe "Users" do
end
scenario "Should display generic interests title" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
@user.update(public_interests: true)
visit user_path(@user, filter: "follows", page: "1")
@@ -354,8 +347,7 @@ describe "Users" do
end
scenario "Should display custom interests title when user is visiting own user page" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
create(:proposal, tag_list: "Sport", followers: [@user])
@user.update(public_interests: true)
login_as(@user)
@@ -431,8 +423,7 @@ describe "Users" do
end
scenario "Active following tab by default when follows filters selected", :js do
proposal = create(:proposal, author: @user)
create(:follow, followable: proposal, user: @user)
create(:proposal, author: @user, followers: [@user])
visit user_path(@user, filter: "follows")
@@ -440,13 +431,9 @@ describe "Users" do
end
scenario "Gracefully handle followables that have been hidden" do
active_proposal = create(:proposal)
hidden_proposal = create(:proposal)
create(:proposal, followers: [@user])
create(:proposal, followers: [@user]) { |proposal| proposal.hide }
create(:follow, followable: active_proposal, user: @user)
create(:follow, followable: hidden_proposal, user: @user)
hidden_proposal.hide
visit user_path(@user)
expect(page).to have_content("1 Following")
@@ -455,8 +442,7 @@ describe "Users" do
describe "Proposals" do
scenario "Display following tab when user is following one proposal at least" do
proposal = create(:proposal)
create(:follow, followable: proposal, user: @user)
create(:proposal, followers: [@user])
visit user_path(@user)
@@ -464,8 +450,7 @@ describe "Users" do
end
scenario "Display proposal tab when user is following one proposal at least" do
proposal = create(:proposal)
create(:follow, followable: proposal, user: @user)
create(:proposal, followers: [@user])
visit user_path(@user, filter: "follows")
@@ -479,8 +464,8 @@ describe "Users" do
end
scenario "Display proposals with link to proposal" do
proposal = create(:proposal, author: @user)
create(:follow, followable: proposal, user: @user)
proposal = create(:proposal, author: @user, followers: [@user])
login_as @user
visit user_path(@user, filter: "follows")
@@ -514,8 +499,7 @@ describe "Users" do
describe "Budget Investments" do
scenario "Display following tab when user is following one budget investment at least" do
budget_investment = create(:budget_investment)
create(:follow, followable: budget_investment, user: @user)
create(:budget_investment, followers: [@user])
visit user_path(@user)
@@ -523,8 +507,7 @@ describe "Users" do
end
scenario "Display budget investment tab when user is following one budget investment at least" do
budget_investment = create(:budget_investment)
create(:follow, followable: budget_investment, user: @user)
create(:budget_investment, followers: [@user])
visit user_path(@user, filter: "follows")
@@ -539,8 +522,7 @@ describe "Users" do
scenario "Display budget investment with link to budget investment" do
user = create(:user, :level_two)
budget_investment = create(:budget_investment, author: user)
create(:follow, followable: budget_investment, user: user)
budget_investment = create(:budget_investment, author: user, followers: [user])
visit user_path(user, filter: "follows")
click_link "Investments"

View File

@@ -749,11 +749,11 @@ describe Debate do
end
it "returns debates related to the user's interests ordered by cached_votes_total" do
create(:proposal, tag_list: "Sport", followers: [user])
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)
results = Debate.recommendations(user).sort_by_recommendations
@@ -761,9 +761,8 @@ describe Debate do
end
it "does not return debates unrelated to user interests" do
proposal1 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
debate2 = create(:debate, tag_list: "Politics")
create(:proposal, tag_list: "Sport", followers: [user])
create(:debate, tag_list: "Politics")
results = Debate.recommendations(user)
@@ -771,9 +770,8 @@ describe Debate do
end
it "does not return debates when user is the author" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
debate1 = create(:debate, author: user, tag_list: "Sport")
create(:proposal, tag_list: "Sport", followers: [user])
create(:debate, author: user, tag_list: "Sport")
results = Debate.recommendations(user)

View File

@@ -914,27 +914,24 @@ describe Proposal do
it "returns voters and followers" do
proposal = create(:proposal)
voter = create(:user, :level_two, votables: [proposal])
follower = create(:user, :level_two)
follow = create(:follow, user: follower, followable: proposal)
follower = create(:user, :level_two, followables: [proposal])
expect(proposal.users_to_notify).to eq([voter, follower])
end
it "returns voters and followers discarding duplicates" do
proposal = create(:proposal)
voter_and_follower = create(:user, :level_two, votables: [proposal])
follow = create(:follow, user: voter_and_follower, followable: proposal)
voter_and_follower = create(:user, :level_two, votables: [proposal], followables: [proposal])
expect(proposal.users_to_notify).to eq([voter_and_follower])
end
it "returns voters and followers except the proposal author" do
author = create(:user, :level_two)
proposal = create(:proposal, author: author, voters: [author])
voter_and_follower = create(:user, :level_two, votables: [proposal])
create(:follow, user: author, followable: proposal)
create(:follow, user: voter_and_follower, followable: proposal)
voter_and_follower = create(:user, :level_two)
proposal = create(:proposal, author: author,
voters: [author, voter_and_follower],
followers: [author, voter_and_follower])
expect(proposal.users_to_notify).to eq([voter_and_follower])
end
@@ -952,11 +949,11 @@ describe Proposal do
end
it "returns proposals related to the user's interests ordered by cached_votes_up" do
create(:proposal, tag_list: "Sport", followers: [user])
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)
results = Proposal.recommendations(user).sort_by_recommendations
@@ -964,9 +961,8 @@ describe Proposal do
end
it "does not return proposals unrelated to user interests" do
proposal1 = create(:proposal, tag_list: "Sport")
proposal2 = create(:proposal, tag_list: "Politics")
create(:follow, followable: proposal1, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
create(:proposal, tag_list: "Politics")
results = Proposal.recommendations(user)
@@ -974,8 +970,7 @@ describe Proposal do
end
it "does not return proposals when user is follower" do
proposal1 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
results = Proposal.recommendations(user)
@@ -983,9 +978,8 @@ describe Proposal do
end
it "does not return proposals when user is the author" do
proposal1 = create(:proposal, tag_list: "Sport")
proposal2 = create(:proposal, author: user, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
create(:proposal, author: user, tag_list: "Sport")
results = Proposal.recommendations(user)
@@ -993,9 +987,8 @@ describe Proposal do
end
it "does not return archived proposals" do
proposal1 = create(:proposal, tag_list: "Sport")
archived_proposal = create(:proposal, :archived, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
create(:proposal, :archived, tag_list: "Sport")
results = Proposal.recommendations(user)
@@ -1003,9 +996,8 @@ describe Proposal do
end
it "does not return already supported proposals" do
proposal1 = create(:proposal, tag_list: "Health", voters: [user])
proposal2 = create(:proposal, tag_list: "Health")
create(:follow, followable: proposal2, user: user)
create(:proposal, tag_list: "Health", followers: [user])
create(:proposal, tag_list: "Health", voters: [user])
results = Proposal.recommendations(user)

View File

@@ -690,15 +690,13 @@ describe User do
let(:user) { create(:user) }
it "returns followed object tags" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
expect(user.interests).to eq ["Sport"]
end
it "deals gracefully with hidden proposals" do
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
proposal = create(:proposal, tag_list: "Sport", followers: [user])
proposal.hide
@@ -706,13 +704,9 @@ describe User do
end
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")
create(:follow, followable: proposal1, user: user)
create(:follow, followable: proposal2, user: user)
create(:follow, followable: budget_investment, user: user)
create(:proposal, tag_list: "Sport", followers: [user])
create(:proposal, tag_list: "Sport", followers: [user])
create(:budget_investment, tag_list: "Sport", followers: [user])
expect(user.interests).to eq ["Sport"]
end

View File

@@ -67,8 +67,7 @@ shared_examples "followable" do |followable_class_name, followable_path, followa
end
scenario "Display unfollow button when user already following" do
user = create(:user)
follow = create(:follow, user: user, followable: followable)
user = create(:user, followables: [followable])
login_as(user)
visit send(followable_path, arguments)
@@ -77,8 +76,7 @@ shared_examples "followable" do |followable_class_name, followable_path, followa
end
scenario "Updates follow button & show destroy notice after unfollow button is clicked", :js do
user = create(:user)
follow = create(:follow, user: user, followable: followable)
user = create(:user, followables: [followable])
login_as(user)
visit send(followable_path, arguments)
@@ -91,8 +89,7 @@ shared_examples "followable" do |followable_class_name, followable_path, followa
end
scenario "Should display destroy follower notice after user clicks on unfollow button", :js do
user = create(:user)
follow = create(:follow, user: user, followable: followable)
user = create(:user, followables: [followable])
login_as(user)
destroy_notice_message = t("shared.followable.#{followable_class_name}.destroy.notice_html")