Merge pull request #1833 from rockandror/improve-community

Improve community
This commit is contained in:
Raimond Garcia
2017-09-07 11:11:55 +02:00
committed by GitHub
32 changed files with 770 additions and 124 deletions

View File

@@ -1,7 +1,6 @@
App.EmbedVideo =
initialize: ->
$('#js-embedded-video').each ->
code = $(this).data("video-code")
code = $(this).data("video-code")
$('#js-embedded-video').html(code)

View File

@@ -48,7 +48,7 @@ class Admin::BudgetInvestmentMilestonesController < Admin::BaseController
end
def load_budget_investment_milestone
@milestone = Budget::Investment::Milestone.find params[:id]
@milestone = Budget::Investment::Milestone.find params[:id]
end

View File

@@ -1,8 +1,8 @@
class CommunitiesController < ApplicationController
TOPIC_ORDERS = %w{newest most_commented oldest}.freeze
before_action :set_order, :set_community, :load_topics, :load_participants
before_action :set_order, :set_community, :load_topics, :load_participants, only: :show
has_orders %w{newest most_commented oldest}, only: :show
has_orders TOPIC_ORDERS
skip_authorization_check
@@ -13,7 +13,7 @@ class CommunitiesController < ApplicationController
private
def set_order
@order = params[:order].present? ? params[:order] : "newest"
@order = valid_order? ? params[:order] : "newest"
end
def set_community
@@ -27,4 +27,8 @@ class CommunitiesController < ApplicationController
def load_participants
@participants = @community.participants
end
def valid_order?
params[:order].present? && TOPIC_ORDERS.include?(params[:order])
end
end

View File

@@ -20,7 +20,7 @@ class Management::SessionsController < ActionController::Base
def destroy_session
session[:manager] = nil
session[:document_type] = nil
session[:document_type] = nil
session[:document_number] = nil
end

View File

@@ -1,13 +1,13 @@
class TopicsController < ApplicationController
include CommentableActions
include FlagActions
before_action :load_community
before_action :load_topic, only: [:show, :edit, :update]
before_action :load_topic, only: [:show, :edit, :update, :destroy]
has_orders %w{most_voted newest oldest}, only: :show
skip_authorization_check
skip_authorization_check only: :show
load_and_authorize_resource except: :show
def new
@topic = Topic.new
@@ -39,6 +39,11 @@ class TopicsController < ApplicationController
end
end
def destroy
@topic.destroy
redirect_to community_path(@community), notice: I18n.t('flash.actions.destroy.topic')
end
private
def topic_params

View File

@@ -42,7 +42,7 @@ module CommentsHelper
def commentable_path(comment)
commentable = comment.commentable
case comment.commentable_type
when "Budget::Investment"
budget_investment_path(commentable.budget_id, commentable)
@@ -51,7 +51,7 @@ module CommentsHelper
when "Legislation::Annotation"
legislation_process_draft_version_annotation_path(commentable.draft_version.process, commentable.draft_version, commentable)
when "Topic"
community_topic_path(comment.commentable.community, comment.commentable)
community_topic_path(commentable.community, commentable)
else
commentable
end

View File

@@ -1,12 +1,7 @@
module CommunitiesHelper
def community_title(community)
if community.from_proposal?
community.proposal.title
else
investment = Budget::Investment.where(community_id: community.id).first
investment.title
end
community.from_proposal? ? community.proposal.title : community.investment.title
end
def community_text(community)
@@ -21,8 +16,7 @@ module CommunitiesHelper
if community.from_proposal?
community.proposal.author_id == participant.id
else
investment = Budget::Investment.where(community_id: community.id).first
investment.author_id == participant.id
community.investment.author_id == participant.id
end
end
@@ -30,8 +24,7 @@ module CommunitiesHelper
if community.from_proposal?
proposal_path(community.proposal)
else
investment = Budget::Investment.where(community_id: community.id).first
budget_investment_path(investment.budget_id, investment)
budget_investment_path(community.investment.budget_id, community.investment)
end
end

View File

@@ -71,6 +71,9 @@ module Abilities
can :create, Annotation
can [:update, :destroy], Annotation, user_id: user.id
can [:create], Topic
can [:update, :destroy], Topic, author_id: user.id
end
end
end

View File

@@ -1,11 +1,11 @@
class Community < ActiveRecord::Base
has_one :proposal
has_one :investment
has_one :investment, class_name: Budget::Investment
has_many :topics
def participants
users_participants = users_who_commented_by +
users_who_topics_author_by +
users_participants = users_who_commented +
users_who_topics_author +
author_from_community
users_participants.uniq
end
@@ -16,24 +16,19 @@ class Community < ActiveRecord::Base
private
def users_who_commented_by
def users_who_commented
topics_ids = topics.pluck(:id)
query = "comments.commentable_id IN (?)and comments.commentable_type = 'Topic'"
User.by_comments(query, topics_ids)
end
def users_who_topics_author_by
def users_who_topics_author
author_ids = topics.pluck(:author_id)
User.by_authors(author_ids)
end
def author_from_community
if from_proposal?
User.where(id: proposal.author_id)
else
investment = Budget::Investment.where(community_id: id).first
User.where(id: investment.author_id)
end
from_proposal? ? User.where(id: proposal.author_id) : User.where(id: investment.author_id)
end
end

View File

@@ -7,8 +7,8 @@ module Communitable
end
def associate_community
community = Community.create
self.community_id = community.id
community = Community.create
self.community_id = community.id
end
end

View File

@@ -1,6 +1,4 @@
class Topic < ActiveRecord::Base
include Flaggable
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases

View File

@@ -34,7 +34,7 @@
<% if page.status == "published" %>
<%= link_to t("admin.site_customization.pages.index.see_page"), page.url, target: "_blank" %>
<% else %>
<%= t("admin.site_customization.pages.index.see_page") %>
<%= t("admin.site_customization.pages.index.see_page") %>
<% end %>
</td>
<td class="small delete">

View File

@@ -0,0 +1,22 @@
<div class="comment-body">
<div class="comment-info">
<%= avatar_image( participant, seed: participant.id, size: 32, class: 'author-photo') %>
<div class="comment-info">
<span class="user-name">
<%= link_to participant.name, user_path(participant)%>
</span>
<% if is_author?(@community, participant) %>
&nbsp;&bull;&nbsp;
<span class="label round is-author">
<%= t("comments.comment.author") %>
</span>
<% end %>
</div>
</div>
</div>

View File

@@ -14,28 +14,7 @@
</ul>
<% @participants.each do |participant| %>
<div class="comment-body">
<div class="comment-info">
<%= avatar_image( participant, seed: participant.id, size: 32, class: 'author-photo') %>
<div class="comment-info">
<span class="user-name">
<%= link_to participant.name, user_path(participant)%>
</span>
<% if is_author?(@community, participant) %>
&nbsp;&bull;&nbsp;
<span class="label round is-author">
<%= t("comments.comment.author") %>
</span>
<% end %>
</div>
</div>
</div>
<%= render 'participant', participant: participant %>
<% end %>
</div>

View File

@@ -64,7 +64,7 @@
<% if poll.expired? %>
<%= t("polls.index.participate_button_expired") %>
<% elsif poll.incoming? %>
<%= t("polls.index.participate_button_incoming") %>
<%= t("polls.index.participate_button_incoming") %>
<% else %>
<%= t("polls.index.participate_button") %>
<% end %>

View File

@@ -0,0 +1,11 @@
<h3><%= t("community.show.create_first_community_topic.first_theme") %></h3>
<% if user_signed_in? %>
<%= t("community.show.create_first_community_topic.first_theme_not_logged_in") %>
<% else %>
<div class="callout primary">
<%= t("community.show.create_first_community_topic.sub_first_theme",
link: link_to(t("community.show.create_first_community_topic.sign_link",
org_name: setting['org_name']), new_user_session_path)).html_safe %>
</div>
<% end %>

View File

@@ -0,0 +1,25 @@
<div id="<%= dom_id(topic) %>" class="panel column">
<div class="small-8 column">
<h3><%= link_to topic.title, community_topic_path(@community, topic) %></h3>
<p class="topic-info">
<span class="icon-comments"></span>&nbsp;
<%= link_to t("community.show.topic.comments", count: topic.comments_count), community_topic_path(@community, topic, anchor: "comments") %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= I18n.l topic.created_at.to_date %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= topic.author.name %>
</p>
</div>
<div class="small-4 column text-right">
<% if topic.author == current_user %>
<%= link_to t("community.show.topic.edit_button"), edit_community_topic_path(@community.id, topic), class: 'button small hollow' %>
<%= link_to t("community.show.topic.destroy_button"), community_topic_path(@community.id, topic), method: :delete, class: 'button hollow alert small' %>
<% end %>
</div>
</div>

View File

@@ -1,48 +1,13 @@
<% if topics.any? %>
<div class="row column">
<div class="order">
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
</div>
</div>
<% topics.each do |topic| %>
<div id="<%= dom_id(topic) %>" class="panel column">
<div class="small-10 column">
<h3><%= link_to topic.title, community_topic_path(@community, topic) %></h3>
<p class="topic-info">
<span class="icon-comments"></span>&nbsp;
<%= link_to t("community.show.topic.comments", count: topic.comments_count), community_topic_path(@community, topic, anchor: "comments") %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= I18n.l topic.created_at.to_date %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= topic.author.name %>
</p>
</div>
<div class="small-2 column text-right">
<% if topic.author == current_user %>
<%= link_to t("community.show.topic.edit_button"), edit_community_topic_path(@community.id, topic), class: 'button small hollow' %>
<% end %>
</div>
</div>
<% end %>
<% else %>
<h3><%= t("community.show.create_first_community_topic.first_theme") %></h3>
<% if user_signed_in? %>
<%= t("community.show.create_first_community_topic.first_theme_not_logged_in") %>
<% else %>
<div class="callout primary">
<%= t("community.show.create_first_community_topic.sub_first_theme",
link: link_to(t("community.show.create_first_community_topic.sign_link",
org_name: setting['org_name']), new_user_session_path)).html_safe %>
</div>
<% end %>
<%= render 'topics/informative_text', topics: topics %>
<% end %>
<% topics.each do |topic| %>
<%= render 'topics/topic', topic: topic %>
<% end %>

View File

@@ -26,6 +26,7 @@ en:
disabled_info_title: You need to be logged to create a new topic
topic:
edit_button: Edit
destroy_button: Destroy
comments:
one: 1 comment
other: "%{count} comments"

View File

@@ -29,3 +29,4 @@ en:
spending_proposal: "Spending proposal deleted succesfully."
budget_investment: "Investment project deleted succesfully."
error: "Could not delete"
topic: "Topic deleted successfully."

View File

@@ -26,6 +26,7 @@ es:
disabled_info_title: Necesitas estar logueado para crear un nuevo tema
topic:
edit_button: Editar
destroy_button: Eliminar
comments:
one: 1 Comentario
other: "%{count} Comentarios"

View File

@@ -29,3 +29,4 @@ es:
spending_proposal: "Propuesta de inversión eliminada."
budget_investment: "Propuesta de inversión eliminada."
error: "No se pudo borrar"
topic: "Tema eliminado."

View File

@@ -39,10 +39,10 @@ Setting["months_to_archive_proposals"] = 12
Setting["email_domain_for_officials"] = ''
# Code to be included at the top (inside <head>) of every page (useful for tracking)
Setting['per_page_code_head'] = ''
Setting['per_page_code_head'] = ''
# Code to be included at the top (inside <body>) of every page
Setting['per_page_code_body'] = ''
Setting['per_page_code_body'] = ''
# Social settings
Setting["twitter_handle"] = nil
@@ -79,7 +79,7 @@ Setting['feature.public_stats'] = true
Setting['feature.budgets'] = true
Setting['feature.signature_sheets'] = true
Setting['feature.legislation'] = true
Setting['feature.community'] = nil
Setting['feature.community'] = true
# Spending proposals feature flags
Setting['feature.spending_proposal_features.voting_allowed'] = nil

View File

@@ -5,14 +5,14 @@ namespace :communities do
Proposal.all.each do |proposal|
if proposal.community.blank?
community = Community.create
community = Community.create
proposal.update(community_id: community.id)
end
end
Budget::Investment.all.each do |investment|
if investment.community.blank?
community = Community.create
community = Community.create
investment.update(community_id: community.id)
end
end

View File

@@ -340,6 +340,8 @@ feature 'Budget Investments' do
end
scenario 'Can not access the community' do
Setting['feature.community'] = false
investment = create(:budget_investment, heading: heading)
visit budget_investment_path(budget_id: budget.id, id: investment.id)
expect(page).not_to have_content "Access the community"

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
include ActionView::Helpers::DateHelper
feature 'Commenting topics' do
feature 'Commenting topics from proposals' do
let(:user) { create :user }
let(:proposal) { create :proposal }
@@ -319,7 +319,7 @@ feature 'Commenting topics' do
page.find("#flag-expand-comment-#{comment.id}").click
expect(page).to have_selector("#flag-comment-#{comment.id}")
end
Setting['feature.community'] = nil
end
@@ -550,3 +550,553 @@ feature 'Commenting topics' do
end
end
feature 'Commenting topics from budget investments' do
let(:user) { create :user }
let(:investment) { create :budget_investment }
scenario 'Index', :js do
community = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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
Setting['feature.community'] = true
community = investment.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
Setting['feature.community'] = nil
end
scenario "Erasing a comment's author" do
community = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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 = investment.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)
@investment = create(:budget_investment)
@topic = create(:topic, community: @investment.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(@investment.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(@investment.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(@investment.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(@investment.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

View File

@@ -15,7 +15,7 @@ feature 'Communities' do
scenario 'Should display default content' do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
user = create(:user)
login_as(user)
visit community_path(community)
@@ -63,10 +63,47 @@ feature 'Communities' do
end
end
scenario "Topic order" do
proposal = create(:proposal)
community = proposal.community
topic1 = create(:topic, community: community)
topic2 = create(:topic, community: community)
topic2_comment = create(:comment, :with_confidence_score, commentable: topic2)
topic3 = create(:topic, community: community)
topic3_comment = create(:comment, :with_confidence_score, commentable: topic3)
topic3_comment = create(:comment, :with_confidence_score, commentable: topic3)
visit community_path(community, order: :most_commented)
expect(topic3.title).to appear_before(topic2.title)
expect(topic2.title).to appear_before(topic1.title)
visit community_path(community, order: :oldest)
expect(topic1.title).to appear_before(topic2.title)
expect(topic2.title).to appear_before(topic3.title)
visit community_path(community, order: :newest)
expect(topic3.title).to appear_before(topic2.title)
expect(topic2.title).to appear_before(topic1.title)
end
scenario "Should order by newest when order param is invalid" do
proposal = create(:proposal)
community = proposal.community
topic1 = create(:topic, community: community)
topic2 = create(:topic, community: community)
visit community_path(community, order: "invalid_param")
expect(topic2.title).to appear_before(topic1.title)
end
scenario 'Should display topic edit button when author is logged' do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
user = create(:user)
topic1 = create(:topic, community: community, author: user)
topic2 = create(:topic, community: community)
login_as(user)

View File

@@ -101,6 +101,8 @@ feature 'Proposals' do
end
scenario 'Can not access the community' do
Setting['feature.community'] = false
proposal = create(:proposal)
visit proposal_path(proposal)
expect(page).not_to have_content "Access the community"

View File

@@ -13,10 +13,10 @@ feature 'Topics' do
expect(page).to have_selector(".button.expanded.disabled")
end
scenario 'Should can access to new topic page with user logged', :js do
scenario 'Can access to new topic page with user logged', :js do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
user = create(:user)
login_as(user)
visit community_path(community)
@@ -28,7 +28,7 @@ feature 'Topics' do
scenario 'Should have content on new topic page', :js do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
user = create(:user)
login_as(user)
visit community_path(community)
@@ -47,10 +47,10 @@ feature 'Topics' do
context 'Create' do
scenario 'Should can create a new topic', :js do
scenario 'Can create a new topic', :js do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
user = create(:user)
login_as(user)
visit new_community_topic_path(community)
@@ -62,14 +62,23 @@ feature 'Topics' do
expect(current_path).to eq(community_path(community))
end
scenario 'Can not create a new topic when user not logged', :js do
proposal = create(:proposal)
community = proposal.community
visit new_community_topic_path(community)
expect(page).to have_content "You do not have permission to carry out the action 'new' on topic."
end
end
context 'Edit' do
scenario 'Should can edit a topic' do
scenario 'Can edit a topic' do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
user = create(:user)
topic = create(:topic, community: community, author: user)
login_as(user)
visit edit_community_topic_path(community, topic)
@@ -82,11 +91,23 @@ feature 'Topics' do
expect(current_path).to eq(community_path(community))
end
scenario 'Can not edit a topic when user logged is not an author' do
proposal = create(:proposal)
community = proposal.community
topic = create(:topic, community: community)
user = create(:user)
login_as(user)
visit edit_community_topic_path(community, topic)
expect(page).to have_content "You do not have permission to carry out the action 'edit' on topic."
end
end
context 'Show' do
scenario 'Should can show topic' do
scenario 'Can show topic' do
proposal = create(:proposal)
community = proposal.community
topic = create(:topic, community: community)
@@ -99,4 +120,35 @@ feature 'Topics' do
end
context 'Destroy' do
scenario 'Can destroy a topic' do
proposal = create(:proposal)
community = proposal.community
user = create(:user)
topic = create(:topic, community: community, author: user)
login_as(user)
visit community_path(community)
click_link "Destroy"
expect(page).to have_content "Topic deleted successfully."
expect(page).not_to have_content topic.title
expect(current_path).to eq(community_path(community))
end
scenario 'Can not destroy a topic when user logged is not an author' do
proposal = create(:proposal)
community = proposal.community
topic = create(:topic, community: community)
user = create(:user)
login_as(user)
visit community_path(community)
expect(page).not_to have_link "Destroy"
end
end
end

View File

@@ -235,7 +235,7 @@ feature 'Users' do
end
scenario 'Not display interests when proposal has been destroyed' do
proposal = create(:proposal, tag_list: "Sport")
proposal = create(:proposal, tag_list: "Sport")
create(:follow, :followed_proposal, followable: proposal, user: @user)
proposal.destroy

View File

@@ -668,8 +668,8 @@ describe User do
end
it "should discard followed objects duplicated tags" do
proposal1 = create(:proposal, tag_list: "Sport")
proposal2 = create(:proposal, tag_list: "Sport")
proposal1 = create(:proposal, tag_list: "Sport")
proposal2 = create(:proposal, tag_list: "Sport")
budget_investment = create(:budget_investment, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)

View File

@@ -2054,7 +2054,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// getElementById is not reliable as a find shortcut
delete Expr.find["ID"];
Expr.filter["ID"] = function( id ) {
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");