Files
grecia/spec/system/comments/budget_investments_valuation_spec.rb
Javi Martín cac24b0159 Extract component to show moderation actions
Note that in proposal notifications we're writing the call to
render the component in the same line as the <div class="reply">
definition in order to be able to use the `:empty` selector when the
component renders nothing. No browser matches whitespace with the
`:empty` selector, so we can't add newline characters inside the tag. A
more elegant solution would be extracting the proposal notification
actions to a component and only rendering it if the moderation actions
component is rendered.
2021-12-30 15:50:03 +01:00

357 lines
14 KiB
Ruby

require "rails_helper"
describe "Internal valuation comments on Budget::Investments" do
let(:user) { create(:user) }
let(:valuator_user) { create(:valuator).user }
let(:admin_user) { create(:administrator).user }
let(:budget) { create(:budget, :valuating) }
let(:investment) { create(:budget_investment, budget: budget, valuators: [valuator_user.valuator]) }
before do
login_as(valuator_user)
end
context "Show valuation comments" do
context "Show valuation comments without public comments" do
before do
public_comment = create(:comment, commentable: investment, body: "Public comment")
create(:comment, commentable: investment, author: valuator_user,
body: "Public valuator comment")
create(:comment, commentable: investment, author: admin_user, parent: public_comment)
valuator_valuation = create(:comment, :valuation, commentable: investment,
author: valuator_user,
body: "Valuator Valuation")
create(:comment, :valuation, commentable: investment, author: admin_user,
body: "Admin Valuation")
admin_response = create(:comment, :valuation, commentable: investment, author: admin_user,
body: "Admin Valuation response",
parent: valuator_valuation)
create(:comment, :valuation, commentable: investment, author: admin_user,
body: "Valuator Valuation response", parent: admin_response)
end
scenario "Valuation Show page without public comments" do
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content("Comment as admin")
expect(page).not_to have_content("Public comment")
expect(page).not_to have_content("Public valuator comment")
expect(page).to have_content("Leave your comment")
expect(page).to have_content("Valuator Valuation")
expect(page).to have_content("Admin Valuation")
expect(page).to have_content("Admin Valuation response")
expect(page).to have_content("Valuator Valuation response")
end
scenario "Valuation Edit page without public comments" do
visit edit_valuation_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content("Comment as admin")
expect(page).not_to have_content("Public comment")
expect(page).not_to have_content("Public valuator comment")
expect(page).to have_content("Leave your comment")
expect(page).to have_content("Valuator Valuation")
expect(page).to have_content("Admin Valuation")
expect(page).to have_content("Admin Valuation response")
expect(page).to have_content("Valuator Valuation response")
end
end
scenario "Collapsable comments" do
parent_comment = create(:comment, :valuation, author: valuator_user, body: "Main comment",
commentable: investment)
child_comment = create(:comment, :valuation, author: valuator_user, body: "First subcomment",
commentable: investment, parent: parent_comment)
grandchild_comment = create(:comment, :valuation, author: valuator_user,
parent: child_comment,
body: "Last child",
commentable: investment)
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).to have_css(".comment", count: 3)
expect(page).to have_content("1 response (collapse)", count: 2)
within ".comment .comment", text: "First subcomment" do
click_link text: "1 response (collapse)"
end
expect(page).to have_css(".comment", count: 2)
expect(page).to have_content("1 response (collapse)")
expect(page).to have_content("1 response (show)")
expect(page).not_to have_content grandchild_comment.body
within ".comment .comment", text: "First subcomment" do
click_link text: "1 response (show)"
end
expect(page).to have_css(".comment", count: 3)
expect(page).to have_content("1 response (collapse)", count: 2)
expect(page).to have_content grandchild_comment.body
within ".comment", text: "Main comment" do
click_link text: "1 response (collapse)", match: :first
end
expect(page).to have_css(".comment", count: 1)
expect(page).to have_content("1 response (show)")
expect(page).not_to have_content child_comment.body
expect(page).not_to have_content grandchild_comment.body
end
scenario "Comment order" do
create(:comment, :valuation, commentable: investment,
author: valuator_user,
body: "Valuator Valuation",
created_at: Time.current - 1)
admin_valuation = create(:comment, :valuation, commentable: investment,
author: admin_user,
body: "Admin Valuation",
created_at: Time.current - 2)
visit valuation_budget_budget_investment_path(budget, investment)
expect(admin_valuation.body).to appear_before("Valuator Valuation")
end
scenario "Turns links into html links" do
create(:comment, :valuation, author: admin_user, commentable: investment,
body: "Check http://rubyonrails.org/")
visit valuation_budget_budget_investment_path(budget, investment)
within first(".comment") do
expect(page).to have_content("Check http://rubyonrails.org/")
expect(page).to have_link("http://rubyonrails.org/", href: "http://rubyonrails.org/")
expect(find_link("http://rubyonrails.org/")[:rel]).to eq("nofollow")
expect(find_link("http://rubyonrails.org/")[:target]).to eq("_blank")
end
end
scenario "Sanitizes comment body for security" do
comment_with_js = "<script>alert('hola')</script> <a href=\"javascript:alert('sorpresa!')\">"\
"click me<a/> http://www.url.com"
create(:comment, :valuation, author: admin_user, commentable: investment,
body: comment_with_js)
visit valuation_budget_budget_investment_path(budget, investment)
within first(".comment") do
expect(page).to have_content("click me http://www.url.com")
expect(page).to have_link("http://www.url.com", href: "http://www.url.com")
expect(page).not_to have_link("click me")
end
end
scenario "Paginated comments" do
per_page = 10
(per_page + 2).times do
create(:comment, :valuation, commentable: investment, author: valuator_user)
end
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).to have_css(".comment", count: per_page)
within("ul.pagination") do
expect(page).to have_content("1")
expect(page).to have_content("2")
expect(page).not_to have_content("3")
click_link "Next", exact: false
end
expect(page).to have_css(".comment", count: 2)
expect(page).to have_current_path(/#comments/, url: true)
end
end
context "Valuation comment creation" do
scenario "Normal users cannot create valuation comments altering public comments form" do
comment = build(:comment, body: "HACKERMAN IS HERE", valuation: true, author: user)
expect(comment).not_to be_valid
expect(comment.errors.size).to eq(1)
end
scenario "Create comment" do
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "Leave your comment", with: "Have you thought about...?"
click_button "Publish comment"
within "#comments" do
expect(page).to have_content("Have you thought about...?")
end
visit budget_investment_path(investment.budget, investment)
expect(page).not_to have_content("Have you thought about...?")
end
scenario "Errors on create without comment text" do
visit valuation_budget_budget_investment_path(budget, investment)
click_button "Publish comment"
expect(page).to have_content "Can't be blank"
end
scenario "Reply to existing valuation" do
comment = create(:comment, :valuation, author: admin_user, commentable: investment)
login_as(valuator_user)
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in "Leave your comment", with: "It will be done next week."
click_button "Publish reply"
end
within "#comment_#{comment.id}" do
expect(page).to have_content "It will be done next week."
end
expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}")
visit budget_investment_path(investment.budget, investment)
expect(page).not_to have_content("It will be done next week.")
end
scenario "Reply update parent comment responses count" do
comment = create(:comment, :valuation, author: admin_user, commentable: investment)
login_as(valuator_user)
visit valuation_budget_budget_investment_path(budget, investment)
within ".comment", text: comment.body do
click_link "Reply"
fill_in "Leave your comment", with: "It will be done next week."
click_button "Publish reply"
expect(page).to have_content("1 response (collapse)")
end
end
scenario "Reply show parent comments responses when hidden" do
comment = create(:comment, :valuation, author: admin_user, commentable: investment)
create(:comment, :valuation, author: admin_user, commentable: investment, parent: comment)
login_as(valuator_user)
visit valuation_budget_budget_investment_path(budget, investment)
within ".comment", text: comment.body do
click_link text: "1 response (collapse)"
click_link "Reply"
fill_in "Leave your comment", with: "It will be done next week."
click_button "Publish reply"
expect(page).to have_content("It will be done next week.")
end
end
scenario "Errors on reply without comment text" do
comment = create(:comment, :valuation, author: admin_user, commentable: investment)
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
click_button "Publish reply"
expect(page).to have_content "Can't be blank"
end
end
scenario "Multiple nested replies" do
parent = create(:comment, :valuation, author: valuator_user, commentable: investment)
7.times do
create(:comment, :valuation, author: admin_user, commentable: investment, parent: parent)
parent = parent.children.first
end
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
expect(page).to have_no_css(".comment-votes")
expect(page).to have_no_css(".js-flag-actions")
expect(page).to have_no_css(".moderation-actions")
end
end
scenario "Erasing a comment's author" do
comment = create(:comment, :valuation, author: valuator_user, commentable: investment,
body: "this should be visible")
comment.user.erase
visit valuation_budget_budget_investment_path(budget, investment)
within "#comment_#{comment.id}" do
expect(page).to have_content("User deleted")
expect(page).to have_content("this should be visible")
end
end
describe "Administrators" do
scenario "can create valuation comment as an administrator" do
login_as(admin_user)
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "Leave your comment", with: "I am your Admin!"
check "Comment as admin"
click_button "Publish comment"
within "#comments" do
expect(page).to have_content "I am your Admin!"
expect(page).to have_content "Administrator ##{admin_user.administrator.id}"
expect(page).to have_css "div.is-admin"
expect(page).to have_css "img.admin-avatar"
end
end
scenario "can create valuation reply as an administrator" do
comment = create(:comment, :valuation, author: valuator_user, commentable: investment)
login_as(admin_user)
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in "Leave your comment", with: "Top of the world!"
check "Comment as admin"
click_button "Publish reply"
end
within "#comment_#{comment.id}" do
expect(page).to have_content "Top of the world!"
expect(page).to have_content "Administrator ##{admin_user.administrator.id}"
expect(page).to have_css "div.is-admin"
expect(page).to have_css "img.admin-avatar"
end
expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}")
end
end
scenario "Send email notification" do
ActionMailer::Base.deliveries = []
login_as(admin_user)
expect(ActionMailer::Base.deliveries).to eq([])
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "Leave your comment", with: "I am your Admin!"
check "Comment as admin"
click_button "Publish comment"
within "#comments" do
expect(page).to have_content("I am your Admin!")
end
expect(ActionMailer::Base.deliveries.count).to eq(1)
expect(ActionMailer::Base.deliveries.first.to).to eq([valuator_user.email])
expect(ActionMailer::Base.deliveries.first.subject).to eq("New evaluation comment")
end
end