Refactor and tests.
This commit is contained in:
@@ -22,4 +22,8 @@ class CommunitiesController < ApplicationController
|
|||||||
def load_topics
|
def load_topics
|
||||||
@topics = @community.topics.send("sort_by_#{@order}").page(params[:page])
|
@topics = @community.topics.send("sort_by_#{@order}").page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_participants
|
||||||
|
@participants = @community.participants
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
class TopicsController < ApplicationController
|
class TopicsController < ApplicationController
|
||||||
include CommentableActions
|
include CommentableActions
|
||||||
|
include FlagActions
|
||||||
|
|
||||||
before_action :set_community
|
before_action :load_community
|
||||||
|
before_action :load_topic, only: [:show, :edit, :update]
|
||||||
|
|
||||||
has_orders %w{most_voted newest oldest}, only: :show
|
has_orders %w{most_voted newest oldest}, only: :show
|
||||||
|
|
||||||
@@ -13,7 +15,6 @@ class TopicsController < ApplicationController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
@topic = Topic.new(topic_params.merge(author: current_user, community_id: params[:community_id]))
|
@topic = Topic.new(topic_params.merge(author: current_user, community_id: params[:community_id]))
|
||||||
|
|
||||||
if @topic.save
|
if @topic.save
|
||||||
redirect_to community_path(@community), notice: I18n.t('flash.actions.create.topic')
|
redirect_to community_path(@community), notice: I18n.t('flash.actions.create.topic')
|
||||||
else
|
else
|
||||||
@@ -22,20 +23,17 @@ class TopicsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
@commentable = @topic
|
@commentable = @topic
|
||||||
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
||||||
set_comment_flags(@comment_tree.comments)
|
set_comment_flags(@comment_tree.comments)
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
if @topic.update(topic_params)
|
if @topic.update(topic_params)
|
||||||
redirect_to community_path(@community), notice: t('topic.update.notice')
|
redirect_to community_path(@community), notice: t('flash.actions.update.topic')
|
||||||
else
|
else
|
||||||
render :edit
|
render :edit
|
||||||
end
|
end
|
||||||
@@ -44,10 +42,14 @@ class TopicsController < ApplicationController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def topic_params
|
def topic_params
|
||||||
params.require(:topic).permit(:title, :community_id, :description_as_comment)
|
params.require(:topic).permit(:title, :description)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_community
|
def load_community
|
||||||
@community = Community.find(params[:community_id])
|
@community = Community.find(params[:community_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_topic
|
||||||
|
@topic = Topic.find(params[:id])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ module CommentsHelper
|
|||||||
legislation_process_question_path(commentable.process, commentable)
|
legislation_process_question_path(commentable.process, commentable)
|
||||||
when "Legislation::Annotation"
|
when "Legislation::Annotation"
|
||||||
legislation_process_draft_version_annotation_path(commentable.draft_version.process, commentable.draft_version, commentable)
|
legislation_process_draft_version_annotation_path(commentable.draft_version.process, commentable.draft_version, commentable)
|
||||||
|
when "Topic"
|
||||||
|
community_topic_path(comment.commentable.community, comment.commentable)
|
||||||
else
|
else
|
||||||
commentable
|
commentable
|
||||||
end
|
end
|
||||||
|
|||||||
11
app/helpers/topics_helper.rb
Normal file
11
app/helpers/topics_helper.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
module TopicsHelper
|
||||||
|
|
||||||
|
def disabled_create_topic
|
||||||
|
"disabled" unless current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
def disabled_info_title
|
||||||
|
t("community.show.sidebar.disabled_info_title") unless current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -33,7 +33,7 @@ module Abilities
|
|||||||
can :unmark_featured, Debate
|
can :unmark_featured, Debate
|
||||||
|
|
||||||
can :comment_as_administrator, [Debate, Comment, Proposal, Poll::Question, Budget::Investment,
|
can :comment_as_administrator, [Debate, Comment, Proposal, Poll::Question, Budget::Investment,
|
||||||
Legislation::Question, Legislation::Annotation]
|
Legislation::Question, Legislation::Annotation, Topic]
|
||||||
|
|
||||||
can [:search, :create, :index, :destroy], ::Administrator
|
can [:search, :create, :index, :destroy], ::Administrator
|
||||||
can [:search, :create, :index, :destroy], ::Moderator
|
can [:search, :create, :index, :destroy], ::Moderator
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ module Abilities
|
|||||||
merge Abilities::Moderation.new(user)
|
merge Abilities::Moderation.new(user)
|
||||||
|
|
||||||
can :comment_as_moderator, [Debate, Comment, Proposal, Budget::Investment, Poll::Question,
|
can :comment_as_moderator, [Debate, Comment, Proposal, Budget::Investment, Poll::Question,
|
||||||
Legislation::Question, Legislation::Annotation]
|
Legislation::Question, Legislation::Annotation, Topic]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,4 +3,7 @@ class Community < ActiveRecord::Base
|
|||||||
has_one :investment
|
has_one :investment
|
||||||
has_many :topics
|
has_many :topics
|
||||||
|
|
||||||
|
def participants
|
||||||
|
User.community_participants(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
class Topic < ActiveRecord::Base
|
class Topic < ActiveRecord::Base
|
||||||
|
include Flaggable
|
||||||
|
|
||||||
acts_as_paranoid column: :hidden_at
|
acts_as_paranoid column: :hidden_at
|
||||||
include ActsAsParanoidAliases
|
include ActsAsParanoidAliases
|
||||||
|
|
||||||
@@ -7,15 +9,12 @@ class Topic < ActiveRecord::Base
|
|||||||
|
|
||||||
has_many :comments, as: :commentable
|
has_many :comments, as: :commentable
|
||||||
|
|
||||||
after_create :associate_comment
|
validates :title, presence: true
|
||||||
|
validates :description, presence: true
|
||||||
|
validates :author, presence: true
|
||||||
|
|
||||||
scope :sort_by_newest, -> { order(created_at: :desc) }
|
scope :sort_by_newest, -> { order(created_at: :desc) }
|
||||||
scope :sort_by_oldest, -> { order(created_at: :asc) }
|
scope :sort_by_oldest, -> { order(created_at: :asc) }
|
||||||
scope :sort_by_most_commented, -> { reorder(comments_count: :desc) }
|
scope :sort_by_most_commented, -> { reorder(comments_count: :desc) }
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def associate_comment
|
|
||||||
Comment.create(commentable: self, user: self.author, body: self.description_as_comment)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -315,7 +315,13 @@ class User < ActiveRecord::Base
|
|||||||
|
|
||||||
def self.community_participants(community)
|
def self.community_participants(community)
|
||||||
topics_ids = community.topics.pluck(:id)
|
topics_ids = community.topics.pluck(:id)
|
||||||
User.joins(:comments).where("comments.commentable_id IN (?) and comments.commentable_type = 'Topic'", topics_ids)
|
users_who_commented = User.joins(:comments).where("comments.commentable_id IN (?) and comments.commentable_type = 'Topic'", topics_ids).uniq
|
||||||
|
|
||||||
|
author_ids = community.topics.pluck(:author_id)
|
||||||
|
users_who_authors = User.where("users.id IN (?)", author_ids)
|
||||||
|
|
||||||
|
users_participants = users_who_commented + users_who_authors
|
||||||
|
users_participants.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
<aside class="show-for-small-only small-12 column">
|
<aside class="show-for-small-only small-12 column">
|
||||||
<div class="sidebar-divider"></div>
|
<div class="sidebar-divider"></div>
|
||||||
<h2><%= t("community.sidebar.topic.title") %></h2>
|
<h2><%= t("community.show.sidebar.participate") %></h2>
|
||||||
<%= link_to t("community.sidebar.topic.new_topic"), new_community_topic_path(@community.id), class: 'button expanded' %>
|
<%= link_to t("community.show.sidebar.new_topic"), new_community_topic_path(@community.id), class: "button expanded #{disabled_create_topic}" %>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<div class="small-12 medium-9 column">
|
<div class="small-12 medium-9 column">
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
<aside class="small-12 medium-3 hide-for-small-only column">
|
<aside class="small-12 medium-3 hide-for-small-only column">
|
||||||
<div class="sidebar-divider"></div>
|
<div class="sidebar-divider"></div>
|
||||||
<h2><%= t("community.sidebar.topic.title") %></h2>
|
<h2><%= t("community.show.sidebar.participate") %></h2>
|
||||||
<%= link_to t("community.sidebar.topic.new_topic"), new_community_topic_path(@community.id), class: 'button expanded' %>
|
<%= link_to t("community.show.sidebar.new_topic"), new_community_topic_path(@community.id), class: "button expanded #{disabled_create_topic}", title: "#{disabled_info_title}" %>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,9 +35,9 @@
|
|||||||
<div class="row column communities-participant">
|
<div class="row column communities-participant">
|
||||||
<ul class="tabs" data-tabs id="communities-show-tabs">
|
<ul class="tabs" data-tabs id="communities-show-tabs">
|
||||||
<li class="tabs-title is-active">
|
<li class="tabs-title is-active">
|
||||||
<%= link_to "#tab-participantes" do %>
|
<%= link_to "#tab-participants" do %>
|
||||||
<h3>
|
<h3>
|
||||||
<%= t("community.tab.participant") %>
|
<%= t("community.show.tab.participants") %>
|
||||||
<span class="js-comments-count">(<%= @participants.count %>)</span>
|
<span class="js-comments-count">(<%= @participants.count %>)</span>
|
||||||
</h3>
|
</h3>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
|
|
||||||
<div id="comments" class="small-12 column">
|
<div id="comments" class="small-12 column">
|
||||||
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
|
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
|
||||||
<!-- <p class="first-comment"><%= @topic.description_as_comment %></p> -->
|
|
||||||
<% @comment_tree.root_comments.each do |comment| %>
|
|
||||||
|
|
||||||
|
<% @comment_tree.root_comments.each do |comment| %>
|
||||||
<%= render 'comments/comment', comment: comment %>
|
<%= render 'comments/comment', comment: comment %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
<%= form_for([@community, @topic]) do |f| %>
|
<%= form_for([@community, @topic]) do |f| %>
|
||||||
|
|
||||||
|
<%= render 'shared/errors', resource: @topic %>
|
||||||
|
|
||||||
<%= render 'shared/errors', resource: @topic %>
|
<%= render 'shared/errors', resource: @topic %>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="small-12 column">
|
<div class="small-12 column">
|
||||||
<%= f.label :title, t("community.topic.form.topic_title") %>
|
<%= f.label :title, t("community.topic.form.topic_title") %>
|
||||||
<%= f.text_field :title, label: false %>
|
<%= f.text_field :title, label: false %>
|
||||||
|
<%= f.label :description, t("community.topic.form.topic_description") %>
|
||||||
|
<%= f.text_area :description, label: false %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions small-12 column">
|
<div class="actions small-12 column">
|
||||||
|
|||||||
9
app/views/topics/_recommendations.html.erb
Normal file
9
app/views/topics/_recommendations.html.erb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<div class="small-12 medium-3 column">
|
||||||
|
<span class="icon-proposals float-right"></span>
|
||||||
|
<h2><%= t("community.topic.sidebar.recommendations_title") %></h2>
|
||||||
|
<ul class="recommendations">
|
||||||
|
<li><%= t("community.topic.sidebar.recommendation_one") %></li>
|
||||||
|
<li><%= t("community.topic.sidebar.recommendation_two") %></li>
|
||||||
|
<li><%= t("community.topic.sidebar.recommendation_three") %></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<h3><%= link_to topic.title, community_topic_path(@community, topic) %></h3>
|
<h3><%= link_to topic.title, community_topic_path(@community, topic) %></h3>
|
||||||
<p class="topic-info">
|
<p class="topic-info">
|
||||||
<span class="icon-comments"></span>
|
<span class="icon-comments"></span>
|
||||||
<%= link_to t("proposals.proposal.comments", count: topic.comments_count), community_topic_path(@community, topic, anchor: "comments") %>
|
<%= link_to t("community.show.topic.comments", count: topic.comments_count), community_topic_path(@community, topic, anchor: "comments") %>
|
||||||
<span class="bullet"> • </span>
|
<span class="bullet"> • </span>
|
||||||
<%= I18n.l topic.created_at.to_date %>
|
<%= I18n.l topic.created_at.to_date %>
|
||||||
<span class="bullet"> • </span>
|
<span class="bullet"> • </span>
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="small-2 column text-right">
|
<div class="small-2 column text-right">
|
||||||
<% if topic.author == current_user %>
|
<% if topic.author == current_user %>
|
||||||
<%= link_to t("community.topic.edit_button"), edit_community_topic_path(@community.id, topic), class: 'button small hollow' %>
|
<%= link_to t("community.show.topic.edit_button"), edit_community_topic_path(@community.id, topic), class: 'button small hollow' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<h4><%= t("community.create_first_community_theme") %></h4>
|
<h4><%= t("community.show.create_first_community_topic") %></h4>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -2,17 +2,9 @@
|
|||||||
|
|
||||||
<div class="small-12 medium-9 column">
|
<div class="small-12 medium-9 column">
|
||||||
<%= render "shared/back_link" %>
|
<%= render "shared/back_link" %>
|
||||||
<h1><%= t("topic.edit.editing") %></h1>
|
<h1><%= t("community.topic.edit") %></h1>
|
||||||
<%= render "form" %>
|
<%= render "form" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-12 medium-3 column">
|
<%= render "recommendations" %>
|
||||||
<span class="icon-proposals float-right"></span>
|
|
||||||
<h2><%= t("community.sidebar.topic.recommendations_title") %></h2>
|
|
||||||
<ul class="recommendations">
|
|
||||||
<li><%= t("community.sidebar.topic.recommendation_one") %></li>
|
|
||||||
<li><%= t("community.sidebar.topic.recommendation_two") %></li>
|
|
||||||
<li><%= t("community.sidebar.topic..recommendation_three") %></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,19 +2,9 @@
|
|||||||
<div class="small-12 medium-9 column">
|
<div class="small-12 medium-9 column">
|
||||||
<%= render "shared/back_link" %>
|
<%= render "shared/back_link" %>
|
||||||
<h1><%= t("community.topic.create") %></h1>
|
<h1><%= t("community.topic.create") %></h1>
|
||||||
|
<%= render 'form' %>
|
||||||
<%= render '/topics/form' %>
|
|
||||||
<%#= render '/topics/form', form_url: budget_investments_path(@budget) %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-12 medium-3 column">
|
<%= render "recommendations" %>
|
||||||
<span class="icon-proposals float-right"></span>
|
|
||||||
<h2><%= t("community.sidebar.topic.recommendations_title") %></h2>
|
|
||||||
<ul class="recommendations">
|
|
||||||
<li><%= t("community.sidebar.topic.recommendation_one") %></li>
|
|
||||||
<li><%= t("community.sidebar.topic.recommendation_two") %></li>
|
|
||||||
<li><%= t("community.sidebar.topic..recommendation_three") %></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<p><%= t("community.topic.show.community_of_the_proposal") %> <strong><%= @community.proposal.title %></strong></p>
|
<p><%= t("community.topic.show.community_of_the_proposal") %> <strong><%= @community.proposal.title %></strong></p>
|
||||||
<h1><%= @topic.title %></h1>
|
<h1><%= @topic.title %></h1>
|
||||||
<div class="topic-info">
|
<div class="topic-info">
|
||||||
|
<p><%= @topic.description %></p>
|
||||||
<%= render '/shared/author_info', resource: @topic %>
|
<%= render '/shared/author_info', resource: @topic %>
|
||||||
|
|
||||||
<span class="bullet"> • </span>
|
<span class="bullet"> • </span>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ data:
|
|||||||
- config/locales/%{locale}/officing.yml
|
- config/locales/%{locale}/officing.yml
|
||||||
- config/locales/%{locale}/budgets.yml
|
- config/locales/%{locale}/budgets.yml
|
||||||
- config/locales/%{locale}/legislation.yml
|
- config/locales/%{locale}/legislation.yml
|
||||||
|
- config/locales/%{locale}/community.yml
|
||||||
- config/locales/%{locale}/documents.yml
|
- config/locales/%{locale}/documents.yml
|
||||||
|
|
||||||
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
|
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
|
||||||
|
|||||||
@@ -1,41 +1,48 @@
|
|||||||
en:
|
en:
|
||||||
community:
|
community:
|
||||||
create_first_community_theme: Create the first community theme
|
|
||||||
join_the_community_of_users: Join the community of users, give your opinion.
|
|
||||||
tab:
|
|
||||||
participant: Participants
|
|
||||||
|
|
||||||
sidebar:
|
sidebar:
|
||||||
title: Community
|
title: Comunidad
|
||||||
description: Join the community of users, give your opinion.
|
description: Partecipa a la comunidad de usuarios, da tu opinión.
|
||||||
button_to_access: Access the community
|
button_to_access: Access the community
|
||||||
|
|
||||||
topic:
|
|
||||||
title: Participants
|
|
||||||
new_topic: Create topic
|
|
||||||
edit_topic: Edit theme
|
|
||||||
recommendations_title: Recommendations to create a theme
|
|
||||||
recommendation_one: Do not write the topic title or whole sentences in capital letters. On the internet that is considered shouting. And no one likes to be yelled at.
|
|
||||||
recommendation_two: Any topic or comment that implies an illegal action will be eliminated, also those that intend to sabotage the spaces of the subject, everything else is allowed.
|
|
||||||
recommendation_three: Enjoy this space, the voices that fill it, it's yours too
|
|
||||||
without_topics: Create the first community topic
|
|
||||||
|
|
||||||
show:
|
show:
|
||||||
title: User community
|
title: Proposal community
|
||||||
description: Participate in the community of this proposal
|
description: Participate in the community of this proposal
|
||||||
|
create_first_community_topic: Create the first community topic
|
||||||
|
tab:
|
||||||
participants: Participants
|
participants: Participants
|
||||||
|
sidebar:
|
||||||
|
participate: Participate
|
||||||
|
new_topic: Create topic
|
||||||
|
disabled_info_title: You need to be logged to create a new topic
|
||||||
topic:
|
topic:
|
||||||
create: Create a theme
|
|
||||||
edit_button: Edit
|
edit_button: Edit
|
||||||
|
comments:
|
||||||
|
one: 1 comment
|
||||||
|
other: "%{count} comments"
|
||||||
|
zero: No comments
|
||||||
|
topic:
|
||||||
|
create: Create a topic
|
||||||
|
edit: Edit Topic
|
||||||
form:
|
form:
|
||||||
topic_title: Topic Title
|
topic_title: Topic Title
|
||||||
topic_description_as_comment: Initial comment
|
topic_description: Description
|
||||||
new:
|
new:
|
||||||
submit_button: Create theme
|
submit_button: Create topic
|
||||||
edit:
|
edit:
|
||||||
submit_button: Edit theme
|
submit_button: Edit topic
|
||||||
|
create:
|
||||||
|
submit_button: Create topic
|
||||||
|
update:
|
||||||
|
submit_button: Update topic
|
||||||
show:
|
show:
|
||||||
community_of_the_proposal: Community of the proposal
|
community_of_the_proposal: Community of the proposal
|
||||||
tab:
|
tab:
|
||||||
comments_tab: Comments
|
comments_tab: Comments
|
||||||
|
sidebar:
|
||||||
|
recommendations_title: Recommendations to create a topic
|
||||||
|
recommendation_one: Do not write the topic title or whole sentences in capital letters. On the internet that is considered shouting. And no one likes to be yelled at.
|
||||||
|
recommendation_two: Any topic or comment that implies an illegal action will be eliminated, also those that intend to sabotage the spaces of the subject, everything else is allowed.
|
||||||
|
recommendation_three: Enjoy this space, the voices that fill it, it's yours too.
|
||||||
|
topics:
|
||||||
|
show:
|
||||||
|
login_to_comment: You must %{signin} or %{signup} to leave a comment.
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ en:
|
|||||||
verification/sms: phone
|
verification/sms: phone
|
||||||
signature_sheet: Signature sheet
|
signature_sheet: Signature sheet
|
||||||
document: Document
|
document: Document
|
||||||
|
topic: Topic
|
||||||
geozones:
|
geozones:
|
||||||
none: All city
|
none: All city
|
||||||
all: All scopes
|
all: All scopes
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ en:
|
|||||||
spending_proposal: "Spending proposal created successfully. You can access it from %{activity}"
|
spending_proposal: "Spending proposal created successfully. You can access it from %{activity}"
|
||||||
budget_investment: "Budget Investment created successfully."
|
budget_investment: "Budget Investment created successfully."
|
||||||
signature_sheet: "Signature sheet created successfully"
|
signature_sheet: "Signature sheet created successfully"
|
||||||
|
topic: "Topic created successfully."
|
||||||
save_changes:
|
save_changes:
|
||||||
notice: Changes saved
|
notice: Changes saved
|
||||||
update:
|
update:
|
||||||
@@ -23,6 +24,7 @@ en:
|
|||||||
proposal: "Proposal updated successfully."
|
proposal: "Proposal updated successfully."
|
||||||
spending_proposal: "Investment project updated succesfully."
|
spending_proposal: "Investment project updated succesfully."
|
||||||
budget_investment: "Investment project updated succesfully."
|
budget_investment: "Investment project updated succesfully."
|
||||||
|
topic: "Topic updated successfully."
|
||||||
destroy:
|
destroy:
|
||||||
spending_proposal: "Spending proposal deleted succesfully."
|
spending_proposal: "Spending proposal deleted succesfully."
|
||||||
budget_investment: "Investment project deleted succesfully."
|
budget_investment: "Investment project deleted succesfully."
|
||||||
|
|||||||
@@ -1,39 +1,48 @@
|
|||||||
es:
|
es:
|
||||||
community:
|
community:
|
||||||
create_first_community_theme: Crea el primer tema de la comunidad
|
|
||||||
join_the_community_of_users: Partecipa a la comunidad de usuarios, da tu opinión.
|
|
||||||
tab:
|
|
||||||
participant: Participantes
|
|
||||||
|
|
||||||
sidebar:
|
sidebar:
|
||||||
title: Comunidad
|
title: Comunidad
|
||||||
description: Partecipa a la comunidad de usuarios, da tu opinión.
|
description: Partecipa a la comunidad de usuarios, da tu opinión.
|
||||||
button_to_access: Acceder a la comunidad
|
button_to_access: Acceder a la comunidad
|
||||||
topic:
|
|
||||||
title: Participa
|
|
||||||
new_topic: Crea un tema
|
|
||||||
recommendations_title: Recomendaciones para crear un tema
|
|
||||||
recommendation_one: No escribas el título del tema o frases enteras en mayúsculas. En internet eso se considera gritar. Y a nadie le gusta que le griten.
|
|
||||||
recommendation_two: Cualquier tema o comentario que implique una acción ilegal será eliminada, también las que tengan la intención de sabotear los espacios del tema, todo lo demás está permitido.
|
|
||||||
recommendation_three: Disfruta de este espacio, de las voces que lo llenan, también es tuyo
|
|
||||||
without_topics: Crea el primer tema de la comunidad
|
|
||||||
|
|
||||||
show:
|
show:
|
||||||
title: Comunidad de usuarios
|
title: Comunidad de la propuesta
|
||||||
description: Participa en la comunidad de esta propuesta
|
description: Participa en la comunidad de esta propuesta
|
||||||
|
create_first_community_topic: Crea el primer tema de la comunidad
|
||||||
|
tab:
|
||||||
paricipants: Participantes
|
paricipants: Participantes
|
||||||
|
sidebar:
|
||||||
|
participate: Participa
|
||||||
|
new_topic: Crea un tema
|
||||||
|
disabled_info_title: Necesitas estar logueado para crear un nuevo tema
|
||||||
|
topic:
|
||||||
|
edit_button: Editar
|
||||||
|
comments:
|
||||||
|
one: 1 Comentario
|
||||||
|
other: "%{count} Comentarios"
|
||||||
|
zero: Sin comentarios
|
||||||
topic:
|
topic:
|
||||||
create: Crear un tema
|
create: Crear un tema
|
||||||
edit_button: Editar
|
edit: Editar tema
|
||||||
form:
|
form:
|
||||||
topic_title: Titulo del tema
|
topic_title: Titulo del tema
|
||||||
topic_description_as_comment: Comentario inicial
|
topic_description: Descripción
|
||||||
new:
|
new:
|
||||||
submit_button: Crear tema
|
submit_button: Crear tema
|
||||||
edit:
|
edit:
|
||||||
submit_button: Guardar cambios
|
submit_button: Guardar cambios
|
||||||
|
create:
|
||||||
|
submit_button: Crear tema
|
||||||
|
update:
|
||||||
|
submit_button: Actualizar tema
|
||||||
show:
|
show:
|
||||||
community_of_the_proposal: Comunidad de la propuesta
|
community_of_the_proposal: Comunidad de la propuesta
|
||||||
tab:
|
tab:
|
||||||
comments_tab: Comentarios
|
comments_tab: Comentarios
|
||||||
|
sidebar:
|
||||||
|
recommendations_title: Recomendaciones para crear un tema
|
||||||
|
recommendation_one: No escribas el título del tema o frases enteras en mayúsculas. En internet eso se considera gritar. Y a nadie le gusta que le griten.
|
||||||
|
recommendation_two: Cualquier tema o comentario que implique una acción ilegal será eliminada, también las que tengan la intención de sabotear los espacios del tema, todo lo demás está permitido.
|
||||||
|
recommendation_three: Disfruta de este espacio, de las voces que lo llenan, también es tuyo
|
||||||
|
topics:
|
||||||
|
show:
|
||||||
|
login_to_comment: Necesitas %{signin} o %{signup} para comentar.
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ es:
|
|||||||
verification/sms: el teléfono
|
verification/sms: el teléfono
|
||||||
signature_sheet: la hoja de firmas
|
signature_sheet: la hoja de firmas
|
||||||
document: el documento
|
document: el documento
|
||||||
|
topic: Tema
|
||||||
geozones:
|
geozones:
|
||||||
none: Toda la ciudad
|
none: Toda la ciudad
|
||||||
all: Todos los ámbitos de actuación
|
all: Todos los ámbitos de actuación
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ es:
|
|||||||
spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}"
|
spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}"
|
||||||
budget_investment: "Propuesta de inversión creada correctamente."
|
budget_investment: "Propuesta de inversión creada correctamente."
|
||||||
signature_sheet: "Hoja de firmas creada correctamente"
|
signature_sheet: "Hoja de firmas creada correctamente"
|
||||||
|
topic: "Tema creado correctamente."
|
||||||
save_changes:
|
save_changes:
|
||||||
notice: Cambios guardados
|
notice: Cambios guardados
|
||||||
update:
|
update:
|
||||||
@@ -23,6 +24,7 @@ es:
|
|||||||
poll_booth: "Urna actualizada correctamente."
|
poll_booth: "Urna actualizada correctamente."
|
||||||
spending_proposal: "Propuesta de inversión actualizada correctamente."
|
spending_proposal: "Propuesta de inversión actualizada correctamente."
|
||||||
budget_investment: "Propuesta de inversión actualizada correctamente"
|
budget_investment: "Propuesta de inversión actualizada correctamente"
|
||||||
|
topic: "Tema actualizado correctamente."
|
||||||
destroy:
|
destroy:
|
||||||
spending_proposal: "Propuesta de inversión eliminada."
|
spending_proposal: "Propuesta de inversión eliminada."
|
||||||
budget_investment: "Propuesta de inversión eliminada."
|
budget_investment: "Propuesta de inversión eliminada."
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class CreateTopics < ActiveRecord::Migration
|
|||||||
def change
|
def change
|
||||||
create_table :topics do |t|
|
create_table :topics do |t|
|
||||||
t.string :title, null: false
|
t.string :title, null: false
|
||||||
t.text :description_as_comment
|
t.text :description
|
||||||
t.integer :author_id
|
t.integer :author_id
|
||||||
t.integer "comments_count", default: 0
|
t.integer "comments_count", default: 0
|
||||||
t.references :community, index: true
|
t.references :community, index: true
|
||||||
|
|||||||
@@ -892,7 +892,7 @@ ActiveRecord::Schema.define(version: 20170807082243) do
|
|||||||
|
|
||||||
create_table "topics", force: :cascade do |t|
|
create_table "topics", force: :cascade do |t|
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
t.text "description_as_comment"
|
t.text "description"
|
||||||
t.integer "author_id"
|
t.integer "author_id"
|
||||||
t.integer "comments_count", default: 0
|
t.integer "comments_count", default: 0
|
||||||
t.integer "community_id"
|
t.integer "community_id"
|
||||||
|
|||||||
@@ -784,4 +784,11 @@ LOREM_IPSUM
|
|||||||
locale "en"
|
locale "en"
|
||||||
body "Some top links content"
|
body "Some top links content"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :topic do
|
||||||
|
sequence(:title) { |n| "Topic title #{n}" }
|
||||||
|
sequence(:description) { |n| "Description as comment #{n}" }
|
||||||
|
association :author, factory: :user
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ feature 'Commenting proposals' do
|
|||||||
expect(page).to have_content parent_comment.body
|
expect(page).to have_content parent_comment.body
|
||||||
expect(page).to have_content first_child.body
|
expect(page).to have_content first_child.body
|
||||||
expect(page).to have_content second_child.body
|
expect(page).to have_content second_child.body
|
||||||
|
debugger
|
||||||
expect(page).to have_link "Go back to #{proposal.title}", href: proposal_path(proposal)
|
expect(page).to have_link "Go back to #{proposal.title}", href: proposal_path(proposal)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
548
spec/features/comments/topics_spec.rb
Normal file
548
spec/features/comments/topics_spec.rb
Normal file
@@ -0,0 +1,548 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
include ActionView::Helpers::DateHelper
|
||||||
|
|
||||||
|
feature 'Commenting topics' do
|
||||||
|
let(:user) { create :user }
|
||||||
|
let(:proposal) { create :proposal }
|
||||||
|
|
||||||
|
scenario 'Index', :js do
|
||||||
|
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
3.times { create(:comment, commentable: topic) }
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
expect(page).to have_css('.comment', count: 3)
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Show', :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
parent_comment = create(:comment, commentable: topic)
|
||||||
|
first_child = create(:comment, commentable: topic, parent: parent_comment)
|
||||||
|
second_child = create(:comment, commentable: topic, parent: parent_comment)
|
||||||
|
|
||||||
|
visit comment_path(parent_comment)
|
||||||
|
|
||||||
|
expect(page).to have_css(".comment", count: 3)
|
||||||
|
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).to have_link "Go back to #{topic.title}", href: community_topic_path(community, topic)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Collapsable comments', :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
parent_comment = create(:comment, body: "Main comment", commentable: topic)
|
||||||
|
child_comment = create(:comment, body: "First subcomment", commentable: topic, parent: parent_comment)
|
||||||
|
grandchild_comment = create(:comment, body: "Last subcomment", commentable: topic, parent: child_comment)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
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).to_not 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).to_not have_content child_comment.body
|
||||||
|
expect(page).to_not have_content grandchild_comment.body
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Comment order' do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
c1 = create(:comment, :with_confidence_score, commentable: topic, cached_votes_up: 100,
|
||||||
|
cached_votes_total: 120, created_at: Time.current - 2)
|
||||||
|
c2 = create(:comment, :with_confidence_score, commentable: topic, cached_votes_up: 10,
|
||||||
|
cached_votes_total: 12, created_at: Time.current - 1)
|
||||||
|
c3 = create(:comment, :with_confidence_score, commentable: topic, cached_votes_up: 1,
|
||||||
|
cached_votes_total: 2, created_at: Time.current)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic, order: :most_voted)
|
||||||
|
|
||||||
|
expect(c1.body).to appear_before(c2.body)
|
||||||
|
expect(c2.body).to appear_before(c3.body)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic, order: :newest)
|
||||||
|
|
||||||
|
expect(c3.body).to appear_before(c2.body)
|
||||||
|
expect(c2.body).to appear_before(c1.body)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic, order: :oldest)
|
||||||
|
|
||||||
|
expect(c1.body).to appear_before(c2.body)
|
||||||
|
expect(c2.body).to appear_before(c3.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Creation date works differently in roots and in child comments, when sorting by confidence_score' do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
old_root = create(:comment, commentable: topic, created_at: Time.current - 10)
|
||||||
|
new_root = create(:comment, commentable: topic, created_at: Time.current)
|
||||||
|
old_child = create(:comment, commentable: topic, parent_id: new_root.id, created_at: Time.current - 10)
|
||||||
|
new_child = create(:comment, commentable: topic, parent_id: new_root.id, created_at: Time.current)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic, order: :most_voted)
|
||||||
|
|
||||||
|
expect(new_root.body).to appear_before(old_root.body)
|
||||||
|
expect(old_child.body).to appear_before(new_child.body)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic, order: :newest)
|
||||||
|
|
||||||
|
expect(new_root.body).to appear_before(old_root.body)
|
||||||
|
expect(new_child.body).to appear_before(old_child.body)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic, order: :oldest)
|
||||||
|
|
||||||
|
expect(old_root.body).to appear_before(new_root.body)
|
||||||
|
expect(old_child.body).to appear_before(new_child.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Turns links into html links' do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
create :comment, commentable: topic, body: 'Built with http://rubyonrails.org/'
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
within first('.comment') do
|
||||||
|
expect(page).to have_content 'Built with 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
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
create :comment, commentable: topic,
|
||||||
|
body: "<script>alert('hola')</script> <a href=\"javascript:alert('sorpresa!')\">click me<a/> http://www.url.com"
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
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
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
per_page = 10
|
||||||
|
(per_page + 2).times { create(:comment, commentable: topic)}
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
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).to_not have_content("3")
|
||||||
|
click_link "Next", exact: false
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_css('.comment', count: 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature 'Not logged user' do
|
||||||
|
scenario 'can not see comments forms' do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
create(:comment, commentable: topic)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
expect(page).to have_content 'You must Sign in or Sign up to leave a comment'
|
||||||
|
within('#comments') do
|
||||||
|
expect(page).to_not have_content 'Write a comment'
|
||||||
|
expect(page).to_not have_content 'Reply'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Create', :js do
|
||||||
|
login_as(user)
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
fill_in "comment-body-topic_#{topic.id}", with: 'Have you thought about...?'
|
||||||
|
click_button 'Publish comment'
|
||||||
|
|
||||||
|
within "#comments" do
|
||||||
|
expect(page).to have_content 'Have you thought about...?'
|
||||||
|
end
|
||||||
|
|
||||||
|
within "#tab-comments-label" do
|
||||||
|
expect(page).to have_content 'Comments (1)'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Errors on create', :js do
|
||||||
|
login_as(user)
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
click_button 'Publish comment'
|
||||||
|
|
||||||
|
expect(page).to have_content "Can't be blank"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Reply', :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
citizen = create(:user, username: 'Ana')
|
||||||
|
manuela = create(:user, username: 'Manuela')
|
||||||
|
comment = create(:comment, commentable: topic, user: citizen)
|
||||||
|
|
||||||
|
login_as(manuela)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
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).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Errors on reply', :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
comment = create(:comment, commentable: topic, user: user)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
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 "N replies", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
parent = create(:comment, commentable: topic)
|
||||||
|
|
||||||
|
7.times do
|
||||||
|
create(:comment, commentable: topic, parent: parent)
|
||||||
|
parent = parent.children.first
|
||||||
|
end
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Flagging as inappropriate", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
comment = create(:comment, commentable: topic)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
within "#comment_#{comment.id}" do
|
||||||
|
page.find("#flag-expand-comment-#{comment.id}").click
|
||||||
|
page.find("#flag-comment-#{comment.id}").click
|
||||||
|
|
||||||
|
expect(page).to have_css("#unflag-expand-comment-#{comment.id}")
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(Flag.flagged?(user, comment)).to be
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Undoing flagging as inappropriate", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
comment = create(:comment, commentable: topic)
|
||||||
|
Flag.flag(user, comment)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
within "#comment_#{comment.id}" do
|
||||||
|
page.find("#unflag-expand-comment-#{comment.id}").click
|
||||||
|
page.find("#unflag-comment-#{comment.id}").click
|
||||||
|
|
||||||
|
expect(page).to have_css("#flag-expand-comment-#{comment.id}")
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(Flag.flagged?(user, comment)).to_not be
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Flagging turbolinks sanity check", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community, title: "Should we change the world?")
|
||||||
|
comment = create(:comment, commentable: topic)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit community_path(community)
|
||||||
|
click_link "Should we change the world?"
|
||||||
|
|
||||||
|
within "#comment_#{comment.id}" do
|
||||||
|
page.find("#flag-expand-comment-#{comment.id}").click
|
||||||
|
expect(page).to have_selector("#flag-comment-#{comment.id}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Erasing a comment's author" do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
comment = create(:comment, commentable: topic, body: "this should be visible")
|
||||||
|
comment.user.erase
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
within "#comment_#{comment.id}" do
|
||||||
|
expect(page).to have_content('User deleted')
|
||||||
|
expect(page).to have_content('this should be visible')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature "Moderators" do
|
||||||
|
scenario "can create comment as a moderator", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
moderator = create(:moderator)
|
||||||
|
|
||||||
|
login_as(moderator.user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
fill_in "comment-body-topic_#{topic.id}", with: "I am moderating!"
|
||||||
|
check "comment-as-moderator-topic_#{topic.id}"
|
||||||
|
click_button "Publish comment"
|
||||||
|
|
||||||
|
within "#comments" do
|
||||||
|
expect(page).to have_content "I am moderating!"
|
||||||
|
expect(page).to have_content "Moderator ##{moderator.id}"
|
||||||
|
expect(page).to have_css "div.is-moderator"
|
||||||
|
expect(page).to have_css "img.moderator-avatar"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can create reply as a moderator", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
citizen = create(:user, username: "Ana")
|
||||||
|
manuela = create(:user, username: "Manuela")
|
||||||
|
moderator = create(:moderator, user: manuela)
|
||||||
|
comment = create(:comment, commentable: topic, user: citizen)
|
||||||
|
|
||||||
|
login_as(manuela)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
click_link "Reply"
|
||||||
|
|
||||||
|
within "#js-comment-form-comment_#{comment.id}" do
|
||||||
|
fill_in "comment-body-comment_#{comment.id}", with: "I am moderating!"
|
||||||
|
check "comment-as-moderator-comment_#{comment.id}"
|
||||||
|
click_button 'Publish reply'
|
||||||
|
end
|
||||||
|
|
||||||
|
within "#comment_#{comment.id}" do
|
||||||
|
expect(page).to have_content "I am moderating!"
|
||||||
|
expect(page).to have_content "Moderator ##{moderator.id}"
|
||||||
|
expect(page).to have_css "div.is-moderator"
|
||||||
|
expect(page).to have_css "img.moderator-avatar"
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can not comment as an administrator" do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
moderator = create(:moderator)
|
||||||
|
|
||||||
|
login_as(moderator.user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
expect(page).to_not have_content "Comment as administrator"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature "Administrators" do
|
||||||
|
scenario "can create comment as an administrator", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
admin = create(:administrator)
|
||||||
|
|
||||||
|
login_as(admin.user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
fill_in "comment-body-topic_#{topic.id}", with: "I am your Admin!"
|
||||||
|
check "comment-as-administrator-topic_#{topic.id}"
|
||||||
|
click_button "Publish comment"
|
||||||
|
|
||||||
|
within "#comments" do
|
||||||
|
expect(page).to have_content "I am your Admin!"
|
||||||
|
expect(page).to have_content "Administrator ##{admin.id}"
|
||||||
|
expect(page).to have_css "div.is-admin"
|
||||||
|
expect(page).to have_css "img.admin-avatar"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can create reply as an administrator", :js do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
citizen = create(:user, username: "Ana")
|
||||||
|
manuela = create(:user, username: "Manuela")
|
||||||
|
admin = create(:administrator, user: manuela)
|
||||||
|
comment = create(:comment, commentable: topic, user: citizen)
|
||||||
|
|
||||||
|
login_as(manuela)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
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.id}"
|
||||||
|
expect(page).to have_css "div.is-admin"
|
||||||
|
expect(page).to have_css "img.admin-avatar"
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can not comment as a moderator" do
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
admin = create(:administrator)
|
||||||
|
|
||||||
|
login_as(admin.user)
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
expect(page).to_not have_content "Comment as moderator"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature 'Voting comments' do
|
||||||
|
|
||||||
|
background do
|
||||||
|
@manuela = create(:user, verified_at: Time.current)
|
||||||
|
@pablo = create(:user)
|
||||||
|
@proposal = create(:proposal)
|
||||||
|
@topic = create(:topic, community: @proposal.community)
|
||||||
|
@comment = create(:comment, commentable: @topic)
|
||||||
|
|
||||||
|
login_as(@manuela)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Show' do
|
||||||
|
create(:vote, voter: @manuela, votable: @comment, vote_flag: true)
|
||||||
|
create(:vote, voter: @pablo, votable: @comment, vote_flag: false)
|
||||||
|
|
||||||
|
visit community_topic_path(@proposal.community, @topic)
|
||||||
|
|
||||||
|
within("#comment_#{@comment.id}_votes") do
|
||||||
|
within(".in_favor") do
|
||||||
|
expect(page).to have_content "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
within(".against") do
|
||||||
|
expect(page).to have_content "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content "2 votes"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Create', :js do
|
||||||
|
visit community_topic_path(@proposal.community, @topic)
|
||||||
|
|
||||||
|
within("#comment_#{@comment.id}_votes") do
|
||||||
|
find(".in_favor a").click
|
||||||
|
|
||||||
|
within(".in_favor") do
|
||||||
|
expect(page).to have_content "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
within(".against") do
|
||||||
|
expect(page).to have_content "0"
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content "1 vote"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Update', :js do
|
||||||
|
visit community_topic_path(@proposal.community, @topic)
|
||||||
|
|
||||||
|
within("#comment_#{@comment.id}_votes") do
|
||||||
|
find('.in_favor a').click
|
||||||
|
find('.against a').click
|
||||||
|
|
||||||
|
within('.in_favor') do
|
||||||
|
expect(page).to have_content "0"
|
||||||
|
end
|
||||||
|
|
||||||
|
within('.against') do
|
||||||
|
expect(page).to have_content "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content "1 vote"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Trying to vote multiple times', :js do
|
||||||
|
visit community_topic_path(@proposal.community, @topic)
|
||||||
|
|
||||||
|
within("#comment_#{@comment.id}_votes") do
|
||||||
|
find('.in_favor a').click
|
||||||
|
find('.in_favor a').click
|
||||||
|
|
||||||
|
within('.in_favor') do
|
||||||
|
expect(page).to have_content "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
within('.against') do
|
||||||
|
expect(page).to have_content "0"
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content "1 vote"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
107
spec/features/communities_spec.rb
Normal file
107
spec/features/communities_spec.rb
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature 'Communities' do
|
||||||
|
|
||||||
|
context 'Show' do
|
||||||
|
|
||||||
|
scenario 'Should display default content' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user = create(:user)
|
||||||
|
login_as(user)
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
expect(page).to have_content "Proposal community"
|
||||||
|
expect(page).to have_content proposal.title
|
||||||
|
expect(page).to have_content "Participate in the community of this proposal"
|
||||||
|
expect(page).to have_link("Create topic", href: new_community_topic_path(community))
|
||||||
|
expect(page).not_to have_selector(".button.disabled", text: "Create topic")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should display disabled create topic button when user is not logged' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
expect(page).to have_selector(".button.disabled", text: "Create topic")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should display without_topics_text and empty participants when there are not topics' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
expect(page).to have_content "Create the first community topic"
|
||||||
|
expect(page).to have_content "Participants (0)"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should display order selector and topic content when there are topics' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
create(:comment, commentable: topic)
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
expect(page).to have_selector ".wide-order-selector"
|
||||||
|
within "#topic_#{topic.id}" do
|
||||||
|
expect(page).to have_content topic.title
|
||||||
|
expect(page).to have_content "#{topic.comments_count} comment"
|
||||||
|
expect(page).to have_content I18n.l(topic.created_at.to_date)
|
||||||
|
expect(page).to have_content topic.author.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should display topic edit button when author is logged' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user = create(:user)
|
||||||
|
topic1 = create(:topic, community: community, author: user)
|
||||||
|
topic2 = create(:topic, community: community)
|
||||||
|
login_as(user)
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
within "#topic_#{topic1.id}" do
|
||||||
|
expect(page).to have_link("Edit", href: edit_community_topic_path(community, topic1))
|
||||||
|
end
|
||||||
|
|
||||||
|
within "#topic_#{topic2.id}" do
|
||||||
|
expect(page).not_to have_link("Edit", href: edit_community_topic_path(community, topic2))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should display participant when there is topics' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
within ".communities-participant" do
|
||||||
|
expect(page).to have_content "Participants (1)"
|
||||||
|
expect(page).to have_content topic.author.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should display participants when there are topics and comments' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
comment = create(:comment, commentable: topic)
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
within ".communities-participant" do
|
||||||
|
expect(page).to have_content "Participants (2)"
|
||||||
|
expect(page).to have_content topic.author.name
|
||||||
|
expect(page).to have_content comment.author.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -63,6 +63,7 @@ feature 'Proposals' do
|
|||||||
expect(page.html).to include "<title>#{proposal.title}</title>"
|
expect(page.html).to include "<title>#{proposal.title}</title>"
|
||||||
expect(page).not_to have_selector ".js-flag-actions"
|
expect(page).not_to have_selector ".js-flag-actions"
|
||||||
expect(page).not_to have_selector ".js-follow"
|
expect(page).not_to have_selector ".js-follow"
|
||||||
|
expect(page).to have_content "Access the community"
|
||||||
|
|
||||||
within('.social-share-button') do
|
within('.social-share-button') do
|
||||||
expect(page.all('a').count).to be(4) # Twitter, Facebook, Google+, Telegram
|
expect(page.all('a').count).to be(4) # Twitter, Facebook, Google+, Telegram
|
||||||
|
|||||||
102
spec/features/topics_specs.rb
Normal file
102
spec/features/topics_specs.rb
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature 'Topics' do
|
||||||
|
|
||||||
|
context 'New' do
|
||||||
|
|
||||||
|
scenario 'Should display disabled button to new topic page without user logged', :js do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
expect(page).to have_selector(".button.expanded.disabled")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should can access to new topic page with user logged', :js do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user = create(:user)
|
||||||
|
login_as(user)
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
click_link "Create topic"
|
||||||
|
|
||||||
|
expect(page).to have_content "Create a topic"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Should have content on new topic page', :js do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user = create(:user)
|
||||||
|
login_as(user)
|
||||||
|
visit community_path(community)
|
||||||
|
|
||||||
|
click_link "Create topic"
|
||||||
|
|
||||||
|
expect(page).to have_content "Topic Title"
|
||||||
|
expect(page).to have_content "Description"
|
||||||
|
expect(page).to have_content "Recommendations to create a topic"
|
||||||
|
expect(page).to have_content "Do not write the topic title or whole sentences in capital letters. On the internet that is considered shouting. And no one likes to be yelled at."
|
||||||
|
expect(page).to have_content "Any topic or comment that implies an illegal action will be eliminated, also those that intend to sabotage the spaces of the subject, everything else is allowed."
|
||||||
|
expect(page).to have_content "Enjoy this space, the voices that fill it, it's yours too."
|
||||||
|
expect(page).to have_button("Create topic")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Create' do
|
||||||
|
|
||||||
|
scenario 'Should can create a new topic', :js do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user = create(:user)
|
||||||
|
login_as(user)
|
||||||
|
|
||||||
|
visit new_community_topic_path(community)
|
||||||
|
fill_in "topic_title", with: "New topic title"
|
||||||
|
fill_in "topic_description", with: "Topic description"
|
||||||
|
click_button "Create topic"
|
||||||
|
|
||||||
|
expect(page).to have_content "New topic title"
|
||||||
|
expect(current_path).to eq(community_path(community))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Edit' do
|
||||||
|
|
||||||
|
scenario 'Should can edit a topic' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user = create(:user)
|
||||||
|
topic = create(:topic, community: community, author: user)
|
||||||
|
login_as(user)
|
||||||
|
visit edit_community_topic_path(community, topic)
|
||||||
|
|
||||||
|
fill_in "topic_title", with: "Edit topic title"
|
||||||
|
fill_in "topic_description", with: "Edit topic description"
|
||||||
|
click_button "Edit topic"
|
||||||
|
|
||||||
|
expect(page).to have_content "Edit topic title"
|
||||||
|
expect(current_path).to eq(community_path(community))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Show' do
|
||||||
|
|
||||||
|
scenario 'Should can show topic' do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic = create(:topic, community: community)
|
||||||
|
|
||||||
|
visit community_topic_path(community, topic)
|
||||||
|
|
||||||
|
expect(page).to have_content community.proposal.title
|
||||||
|
expect(page).to have_content topic.title
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
10
spec/models/community_spec.rb
Normal file
10
spec/models/community_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Community, type: :model do
|
||||||
|
|
||||||
|
it "should be valid when create proposal" do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
|
||||||
|
expect(proposal.community).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
75
spec/models/topic_spec.rb
Normal file
75
spec/models/topic_spec.rb
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Topic do
|
||||||
|
let(:topic) { build(:topic) }
|
||||||
|
|
||||||
|
it "should be valid" do
|
||||||
|
expect(topic).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not be valid without an author" do
|
||||||
|
topic.author = nil
|
||||||
|
expect(topic).to_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not be valid without a title" do
|
||||||
|
topic.title = nil
|
||||||
|
expect(topic).to_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not be valid without a description" do
|
||||||
|
topic.description = nil
|
||||||
|
expect(topic).to_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
context "order" do
|
||||||
|
|
||||||
|
it "orders by newest" do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic1 = create(:topic, community: community)
|
||||||
|
topic2 = create(:topic, community: community)
|
||||||
|
topic3 = create(:topic, community: community)
|
||||||
|
|
||||||
|
results = community.topics.sort_by_newest
|
||||||
|
|
||||||
|
expect(results.first).to eq(topic3)
|
||||||
|
expect(results.second).to eq(topic2)
|
||||||
|
expect(results.third).to eq(topic1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "orders by oldest" do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic1 = create(:topic, community: community)
|
||||||
|
topic2 = create(:topic, community: community)
|
||||||
|
topic3 = create(:topic, community: community)
|
||||||
|
|
||||||
|
results = community.topics.sort_by_oldest
|
||||||
|
|
||||||
|
expect(results.first).to eq(topic1)
|
||||||
|
expect(results.second).to eq(topic2)
|
||||||
|
expect(results.third).to eq(topic3)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "orders by most_commented" do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
topic1 = create(:topic, community: community)
|
||||||
|
create(:comment, commentable: topic1)
|
||||||
|
create(:comment, commentable: topic1)
|
||||||
|
topic2 = create(:topic, community: community)
|
||||||
|
create(:comment, commentable: topic2)
|
||||||
|
topic3 = create(:topic, community: community)
|
||||||
|
|
||||||
|
results = community.topics.sort_by_most_commented
|
||||||
|
|
||||||
|
expect(results.first).to eq(topic1)
|
||||||
|
expect(results.second).to eq(topic2)
|
||||||
|
expect(results.third).to eq(topic3)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -680,4 +680,22 @@ describe User do
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#community_participants" do
|
||||||
|
|
||||||
|
it "should return participants without duplicates" do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
community = proposal.community
|
||||||
|
user1 = create(:user)
|
||||||
|
user2 = create(:user)
|
||||||
|
|
||||||
|
topic1 = create(:topic, community: community, author: user1)
|
||||||
|
create(:comment, commentable: topic1, author: user1)
|
||||||
|
create(:comment, commentable: topic1, author: user2)
|
||||||
|
topic2 = create(:topic, community: community, author: user2)
|
||||||
|
|
||||||
|
expect(User.community_participants(community)).to eq [user1, user2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user