Merge pull request #2403 from consul/valuation_comments

Valuation comments
This commit is contained in:
BertoCQ
2018-01-31 13:46:22 +01:00
committed by GitHub
23 changed files with 471 additions and 35 deletions

View File

@@ -45,12 +45,13 @@ class CommentsController < ApplicationController
def comment_params
params.require(:comment).permit(:commentable_type, :commentable_id, :parent_id,
:body, :as_moderator, :as_administrator)
:body, :as_moderator, :as_administrator, :valuation)
end
def build_comment
@comment = Comment.build(@commentable, current_user, comment_params[:body],
comment_params[:parent_id].presence)
comment_params[:parent_id].presence,
comment_params[:valuation])
check_for_special_comments
end

View File

@@ -1,11 +1,14 @@
class Valuation::BudgetInvestmentsController < Valuation::BaseController
include FeatureFlags
include CommentableActions
feature_flag :budgets
before_action :restrict_access_to_assigned_items, only: [:show, :edit, :valuate]
before_action :load_budget
before_action :load_investment, only: [:show, :edit, :valuate]
has_orders %w{oldest}, only: [:show, :edit]
has_filters %w{valuating valuation_finished}, only: :index
load_and_authorize_resource :investment, class: "Budget::Investment"
@@ -36,8 +39,30 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController
end
end
def show
load_comments
end
def edit
load_comments
end
private
def load_comments
@commentable = @investment
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order, valuations: true)
set_comment_flags(@comment_tree.comments)
end
def resource_model
Budget::Investment
end
def resource_name
resource_model.parameterize('_')
end
def load_budget
@budget = Budget.find(params[:budget_id])
end

View File

@@ -55,7 +55,7 @@ module Abilities
can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :update, :toggle_selection], Budget::Investment
can :valuate, Budget::Investment
can [:valuate, :comment_valuation], Budget::Investment
can :create, Budget::ValuatorAssignment
can [:search, :edit, :update, :create, :index, :destroy], Banner

View File

@@ -5,8 +5,8 @@ module Abilities
def initialize(user)
valuator = user.valuator
can [:read, :update, :valuate], SpendingProposal
can [:read, :update, :valuate], Budget::Investment, id: valuator.investment_ids
cannot [:update, :valuate], Budget::Investment, budget: { phase: 'finished' }
can [:read, :update, :valuate, :comment_valuation], Budget::Investment, id: valuator.investment_ids
cannot [:update, :valuate, :comment_valuation], Budget::Investment, budget: { phase: 'finished' }
end
end
end

View File

@@ -34,7 +34,10 @@ class Budget
has_many :valuator_assignments, dependent: :destroy
has_many :valuators, through: :valuator_assignments
has_many :comments, as: :commentable
has_many :comments, -> {where(valuation: false)}, as: :commentable, class_name: 'Comment'
has_many :valuations, -> {where(valuation: true)}, as: :commentable, class_name: 'Comment'
has_many :milestones
validates :title, presence: true
@@ -86,6 +89,10 @@ class Budget
before_validation :set_responsible_name
before_validation :set_denormalized_ids
def comments_count
comments.count
end
def url
budget_investment_path(budget, self)
end

View File

@@ -20,6 +20,7 @@ class Comment < ActiveRecord::Base
validates :commentable_type, inclusion: { in: COMMENTABLE_TYPES }
validate :validate_body_length
validate :comment_valuation, if: -> { valuation }
belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true
belongs_to :user, -> { with_hidden }
@@ -33,7 +34,8 @@ class Comment < ActiveRecord::Base
end
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :public_for_api, -> do
where(%{(comments.commentable_type = 'Debate' and comments.commentable_id in (?)) or
not_valuations
.where(%{(comments.commentable_type = 'Debate' and comments.commentable_id in (?)) or
(comments.commentable_type = 'Proposal' and comments.commentable_id in (?)) or
(comments.commentable_type = 'Poll' and comments.commentable_id in (?))},
Debate.public_for_api.pluck(:id),
@@ -50,13 +52,16 @@ class Comment < ActiveRecord::Base
scope :sort_by_oldest, -> { order(created_at: :asc) }
scope :sort_descendants_by_oldest, -> { order(created_at: :asc) }
scope :not_valuations, -> { where(valuation: false) }
after_create :call_after_commented
def self.build(commentable, user, body, p_id = nil)
new commentable: commentable,
def self.build(commentable, user, body, p_id = nil, valuation = false)
new(commentable: commentable,
user_id: user.id,
body: body,
parent_id: p_id
parent_id: p_id,
valuation: valuation)
end
def self.find_commentable(c_type, c_id)
@@ -129,4 +134,9 @@ class Comment < ActiveRecord::Base
validator.validate(self)
end
def comment_valuation
unless author.can?(:comment_valuation, commentable)
errors.add(:valuation, :cannot_comment_valuation)
end
end
end

View File

@@ -1,6 +1,8 @@
<span id="flag-actions-<%= dom_id(comment) %>" class="js-flag-actions">
<%= render 'comments/flag_actions', comment: comment %>
</span>
<% if local_assigns.fetch(:allow_flagging, true) %>
<span id="flag-actions-<%= dom_id(comment) %>" class="js-flag-actions">
<%= render 'comments/flag_actions', comment: comment %>
</span>
<% end %>
<span class='js-moderation-actions'>
<% if can? :hide, comment %>

View File

@@ -1,4 +1,7 @@
<% comment_flags ||= @comment_flags %>
<% valuation = local_assigns.fetch(:valuation, false) %>
<% allow_votes = local_assigns.fetch(:allow_votes, true) %>
<% allow_flagging = local_assigns.fetch(:allow_flagging, true) %>
<% cache [locale_and_user_status(comment), comment, commentable_cache_key(comment.commentable), comment.author, (comment_flags[comment.id] if comment_flags)] do %>
<ul id="<%= dom_id(comment) %>" class="comment no-bullet small-12">
<li class="comment-body">
@@ -67,9 +70,11 @@
</div>
<div id="<%= dom_id(comment) %>_reply" class="reply">
<div id="<%= dom_id(comment) %>_votes" class="comment-votes float-right">
<%= render 'comments/votes', comment: comment %>
</div>
<% if allow_votes %>
<div id="<%= dom_id(comment) %>_votes" class="comment-votes float-right">
<%= render 'comments/votes', comment: comment %>
</div>
<% end %>
<% if comment.children.size > 0 %>
<%= link_to "", class: "js-toggle-children relative", data: {'id': "#{dom_id(comment)}"} do %>
@@ -86,9 +91,13 @@
<%= link_to(comment_link_text(comment), "",
class: "js-add-comment-link", data: {'id': dom_id(comment)}) %>
<%= render 'comments/actions', comment: comment %>
<%= render 'comments/actions', { comment: comment,
allow_flagging: allow_flagging } %>
<%= render 'comments/form', {commentable: comment.commentable, parent_id: comment.id, toggeable: true} %>
<%= render 'comments/form', {commentable: comment.commentable,
parent_id: comment.id,
toggeable: true,
valuation: valuation } %>
<% end %>
</div>
<% end %>
@@ -98,7 +107,10 @@
<ul id="<%= dom_id(comment) %>_children" class="no-bullet comment-children">
<% child_comments_of(comment).each do |child| %>
<li>
<%= render 'comments/comment', comment: child %>
<%= render 'comments/comment', { comment: child,
valuation: valuation,
allow_votes: allow_votes,
allow_flagging: allow_flagging } %>
</li>
<% end %>
</ul>

View File

@@ -1,5 +1,5 @@
<% commentable = comment_tree.commentable %>
<% valuation = local_assigns.fetch(:valuation, false) %>
<% cache [locale_and_user_status, comment_tree.order, commentable_cache_key(commentable), comment_tree.comments, comment_tree.comment_authors, commentable.comments_count, comment_flags] do %>
<section class="expanded comments">
<div class="row">
@@ -27,7 +27,8 @@
<% else %>
<%= render 'comments/form', { commentable: commentable,
parent_id: nil,
toggeable: false } %>
toggeable: false,
valuation: valuation } %>
<% end %>
<% else %>
<br>
@@ -39,7 +40,11 @@
<% end %>
<% comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', {comment: comment, comment_flags: comment_flags} %>
<%= render 'comments/comment', { comment: comment,
comment_flags: comment_flags,
valuation: valuation,
allow_votes: !valuation,
allow_flagging: !valuation } %>
<% end %>
<%= paginate comment_tree.root_comments %>
</div>

View File

@@ -10,7 +10,10 @@
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @investment, parent_id: nil, toggeable: false} %>
<%= render 'comments/form', { commentable: @investment,
parent_id: nil,
toggeable: false,
valuation: local_assigns.fetch(:valuation, false) } %>
<% else %>
<br>
@@ -22,7 +25,8 @@
<% end %>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<%= render 'comments/comment', { comment: comment,
valuation: local_assigns.fetch(:valuation, false) } %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>

View File

@@ -7,6 +7,7 @@
<%= f.hidden_field :commentable_type, value: commentable.class.name %>
<%= f.hidden_field :commentable_id, value: commentable.id %>
<%= f.hidden_field :parent_id, value: parent_id %>
<%= f.hidden_field :valuation, value: local_assigns.fetch(:valuation, false) %>
<%= f.submit comment_button_text(parent_id, commentable), class: "button", id: "publish_comment" %>

View File

@@ -51,3 +51,12 @@
<h2><%= t("valuation.budget_investments.show.internal_comments") %></h2>
<%= explanation_field @investment.internal_comments %>
<% end %>
<div class="tabs-panel is-active" id="tab-comments">
<% unless @comment_tree.nil? %>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: false,
valuation: true } %>
<% end %>
</div>

View File

@@ -103,6 +103,15 @@
</div>
<% end %>
<div class="tabs-panel is-active" id="tab-comments">
<% unless @comment_tree.nil? %>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: false,
valuation: true } %>
<% end %>
</div>
<h1><%= @investment.title %></h1>
<%= safe_html_with_links @investment.description %>

View File

@@ -296,6 +296,10 @@ en:
image:
image_width: "Width must be %{required_width}px"
image_height: "Height must be %{required_height}px"
comment:
attributes:
valuation:
cannot_comment_valuation: 'You cannot comment a valuation'
messages:
record_invalid: "Validation failed: %{errors}"
restrict_dependent_destroy:

View File

@@ -292,6 +292,10 @@ es:
image:
image_width: "Debe tener %{required_width}px de ancho"
image_height: "Debe tener %{required_height}px de alto"
comment:
attributes:
valuation:
cannot_comment_valuation: 'No puedes comentar una evaluación'
messages:
record_invalid: 'Error de validación: %{errors}'
restrict_dependent_destroy:

View File

@@ -0,0 +1,5 @@
class AddValuationFlagToComments < ActiveRecord::Migration
def change
add_column :comments, :valuation, :boolean, default: false
end
end

View File

@@ -0,0 +1,7 @@
class AddIndexToValuationComments < ActiveRecord::Migration
disable_ddl_transaction!
def change
add_index :comments, :valuation, algorithm: :concurrently
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180119073228) do
ActiveRecord::Schema.define(version: 20180129190950) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -234,7 +234,7 @@ ActiveRecord::Schema.define(version: 20180119073228) do
t.string "commentable_type"
t.text "body"
t.string "subject"
t.integer "user_id", null: false
t.integer "user_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "hidden_at"
@@ -247,7 +247,8 @@ ActiveRecord::Schema.define(version: 20180119073228) do
t.integer "cached_votes_down", default: 0
t.datetime "confirmed_hide_at"
t.string "ancestry"
t.integer "confidence_score", default: 0, null: false
t.integer "confidence_score", default: 0, null: false
t.boolean "valuation", default: false
end
add_index "comments", ["ancestry"], name: "index_comments_on_ancestry", using: :btree
@@ -257,6 +258,7 @@ ActiveRecord::Schema.define(version: 20180119073228) do
add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree
add_index "comments", ["hidden_at"], name: "index_comments_on_hidden_at", using: :btree
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
add_index "comments", ["valuation"], name: "index_comments_on_valuation", using: :btree
create_table "communities", force: :cascade do |t|
t.datetime "created_at", null: false

View File

@@ -4,16 +4,24 @@ class CommentTree
attr_accessor :root_comments, :comments, :commentable, :page, :order
def initialize(commentable, page, order = 'confidence_score')
def initialize(commentable, page, order = 'confidence_score', valuations: false)
@commentable = commentable
@page = page
@order = order
@valuations = valuations
@comments = root_comments + root_descendants
end
def root_comments
commentable.comments.roots.send("sort_by_#{order}").page(page).per(ROOT_COMMENTS_PER_PAGE).for_render
base_comments.roots.send("sort_by_#{order}").page(page).per(ROOT_COMMENTS_PER_PAGE).for_render
end
def base_comments
if @valuations && commentable.respond_to?('valuations')
commentable.valuations
else
commentable.comments
end
end
def root_descendants

View File

@@ -465,6 +465,16 @@ FactoryBot.define do
trait :with_confidence_score do
before(:save) { |d| d.calculate_confidence_score }
end
trait :valuation do
valuation true
association :commentable, factory: :budget_investment
before :create do |valuation|
valuator = create(:valuator)
valuation.author = valuator.user
valuation.commentable.valuators << valuator
end
end
end
factory :legacy_legislation do

View File

@@ -7,16 +7,19 @@ feature 'Commenting Budget::Investments' do
scenario 'Index' do
3.times { create(:comment, commentable: investment) }
valuation_comment = create(:comment, :valuation, commentable: investment, subject: 'Not viable')
visit budget_investment_path(investment.budget, investment)
expect(page).to have_css('.comment', count: 3)
expect(page).not_to have_content('Not viable')
comment = Comment.last
within first('.comment') do
expect(page).to have_content comment.user.name
expect(page).to have_content I18n.l(comment.created_at, format: :datetime)
expect(page).to have_content comment.body
within("#comments") do
Comment.not_valuations.last(3).each do |comment|
expect(page).to have_content comment.user.name
expect(page).to have_content I18n.l(comment.created_at, format: :datetime)
expect(page).to have_content comment.body
end
end
end
@@ -24,6 +27,7 @@ feature 'Commenting Budget::Investments' do
parent_comment = create(:comment, commentable: investment)
first_child = create(:comment, commentable: investment, parent: parent_comment)
second_child = create(:comment, commentable: investment, parent: parent_comment)
valuation_comment = create(:comment, :valuation, commentable: investment, subject: 'Not viable')
visit comment_path(parent_comment)
@@ -31,6 +35,7 @@ feature 'Commenting Budget::Investments' do
expect(page).to have_content parent_comment.body
expect(page).to have_content first_child.body
expect(page).to have_content second_child.body
expect(page).not_to have_content('Not viable')
expect(page).to have_link "Go back to #{investment.title}", href: budget_investment_path(investment.budget, investment)

View File

@@ -0,0 +1,300 @@
require 'rails_helper'
feature '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) }
background do
Setting['feature.budgets'] = true
investment.valuators << valuator_user.valuator
login_as(valuator_user)
end
after do
Setting['feature.budgets'] = nil
end
context 'Show valuation comments' do
context 'Show valuation comments without public comments' do
background 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', :js do
parent_comment = create(:comment, :valuation, author: valuator_user, body: "Main comment",
commentable: investment)
child_comment = create(:comment, :valuation, author: valuator_user, body: "First child",
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)
find("#comment_#{child_comment.id}_children_arrow").trigger('click')
expect(page).to have_css('.comment', count: 2)
expect(page).not_to have_content grandchild_comment.body
find("#comment_#{child_comment.id}_children_arrow").trigger('click')
expect(page).to have_css('.comment', count: 3)
expect(page).to have_content grandchild_comment.body
find("#comment_#{parent_comment.id}_children_arrow").trigger('click')
expect(page).to have_css('.comment', count: 1)
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)
end
end
context 'Valuation comment creation' do
scenario 'Normal users cannot create valuation comments altering public comments form', :js do
logout
login_as(user)
visit budget_investment_path(investment.budget, investment)
fill_in "comment-body-budget_investment_#{investment.id}", with: 'HACKERMAN IS HERE'
find(:xpath, "//input[@id='comment_valuation']", visible: false).set('true')
click_button 'Publish comment'
visit budget_investment_path(investment.budget, investment)
expect(page).not_to have_content('HACKERMAN IS HERE')
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content('HACKERMAN IS HERE')
end
scenario 'Create comment', :js do
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "comment-body-budget_investment_#{investment.id}", with: 'Have you thought about...?'
click_button 'Publish comment'
within "#comments" do
expect(page).to have_content 'Have you thought about...?'
end
end
scenario 'Errors on create without comment text', :js 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 comment', :js 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 "comment-body-comment_#{comment.id}", 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}", visible: true)
end
scenario 'Errors on reply without comment text', :js 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", :js 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')
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
feature "Administrators" do
scenario "can create valuation comment as an administrator", :js do
login_as(admin_user)
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "comment-body-budget_investment_#{investment.id}", with: "I am your Admin!"
check "comment-as-administrator-budget_investment_#{investment.id}"
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", :js 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 "comment-body-comment_#{comment.id}", with: "Top of the world!"
check "comment-as-administrator-comment_#{comment.id}"
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}", visible: true)
end
end
end

View File

@@ -187,5 +187,11 @@ describe Comment do
expect(described_class.public_for_api).not_to include(comment)
end
it "does not return internal valuation comments" do
valuation_comment = create(:comment, :valuation)
expect(described_class.public_for_api).not_to include(valuation_comment)
end
end
end