Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fix characters limits when editing comments #646

Merged
merged 2 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Application < Rails::Application
require "extends/controllers/decidim/admin/scopes_controller_extends"
require "extends/controllers/decidim/scopes_controller_extends"
require "extends/controllers/decidim/initiatives/committee_requests_controller_extends"
require "extends/controllers/decidim/comments/comments_controller"
# Models
require "extends/models/decidim/budgets/project_extends"
require "extends/models/decidim/authorization_extends"
Expand All @@ -67,6 +68,7 @@ class Application < Rails::Application
# Forms
require "extends/forms/decidim/initiatives/initiative_form_extends"
require "extends/forms/decidim/initiatives/admin/initiative_form_extends"
require "extends/forms/decidim/comments/comment_form_extends"
# Commands
require "extends/commands/decidim/initiatives/admin/update_initiative_answer_extends"
require "extends/commands/decidim/budgets/admin/import_proposals_to_budgets_extends"
Expand Down
4 changes: 4 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ en:
projects_count:
one: 1 project
other: "%{count} projects"
comments:
comments:
create:
error: There was a problem creating the comment.
devise:
sessions:
new:
Expand Down
4 changes: 4 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ fr:
projects_count:
one: 1 projet
other: "%{count} projets"
comments:
comments:
create:
error: Une erreur s'est produite lors du vote sur le commentaire.
devise:
sessions:
new:
Expand Down
61 changes: 61 additions & 0 deletions lib/extends/controllers/decidim/comments/comments_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# frozen_string_literal: true

require "active_support/concern"
module CommentsControllerExtends
extend ActiveSupport::Concern
included do
def update
set_comment
@commentable = comment.commentable
enforce_permission_to :update, :comment, comment: comment

form = Decidim::Comments::CommentForm.from_params(
params.merge(commentable: comment.commentable, current_component: current_component)
).with_context(
current_organization: current_organization
)

Decidim::Comments::UpdateComment.call(comment, current_user, form) do
on(:ok) do
respond_to do |format|
format.js { render :update }
end
end

on(:invalid) do
respond_to do |format|
format.js { render :update_error }
end
end
end
end

def create
enforce_permission_to :create, :comment, commentable: commentable

form = Decidim::Comments::CommentForm.from_params(
params.merge(commentable: commentable, current_component: current_component)
).with_context(
current_organization: current_organization,
current_component: current_component
)
Decidim::Comments::CreateComment.call(form, current_user) do
on(:ok) do |comment|
handle_success(comment)
respond_to do |format|
format.js { render :create }
end
end

on(:invalid) do
@error = t("create.error", scope: "decidim.comments.comments")
respond_to do |format|
format.js { render :error }
end
end
end
end
end
end

Decidim::Comments::CommentsController.include(CommentsControllerExtends)
15 changes: 15 additions & 0 deletions lib/extends/forms/decidim/comments/comment_form_extends.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require "active_support/concern"

module CommentFormExtends
extend ActiveSupport::Concern

included do
attribute :current_component, Decidim::Component

validates :current_component, presence: true
end
end

Decidim::Comments::CommentForm.include(CommentFormExtends)
237 changes: 237 additions & 0 deletions spec/controllers/decidim/comments/comments_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
module Comments
describe CommentsController, type: :controller do
routes { Decidim::Comments::Engine.routes }

let(:organization) { create(:organization) }
let(:participatory_process) { create :participatory_process, organization: organization }
let(:component) { create(:component, participatory_space: participatory_process) }
let(:commentable) { create(:dummy_resource, component: component) }

before do
request.env["decidim.current_organization"] = organization
end

describe "GET index" do
it "renders the index template" do
get :index, xhr: true, params: { commentable_gid: commentable.to_signed_global_id.to_s }
expect(subject).to render_template(:index)
end

it "tells devise not to reset timeout counter" do
expect(request.env["devise.skip_timeoutable"]).to be_nil
get :index, xhr: true, params: { commentable_gid: commentable.to_signed_global_id.to_s }
expect(request.env["devise.skip_timeoutable"]).to be(true)
end

context "when requested without an XHR request" do
it "redirects to the commentable" do
get :index, params: { commentable_gid: commentable.to_signed_global_id.to_s }
expect(subject).to redirect_to(
Decidim::ResourceLocatorPresenter.new(commentable).path
)
end
end

context "when the reload parameter is given" do
it "renders the reload template" do
get :index, xhr: true, params: { commentable_gid: commentable.to_signed_global_id.to_s, reload: 1 }
expect(subject).to render_template(:reload)
end
end

context "when comments are disabled for the component" do
let(:component) { create(:component, :with_comments_disabled, participatory_space: participatory_process) }

it "redirects with a flash alert" do
get :index, xhr: true, params: { commentable_gid: commentable.to_signed_global_id.to_s }
expect(flash[:alert]).to be_present
expect(response).to have_http_status(:redirect)
end
end
end

describe "POST create" do
let(:comment_alignment) { 0 }
let(:comment_params) do
{
commentable_gid: commentable.to_signed_global_id.to_s,
body: "This is a new comment",
alignment: comment_alignment
}
end

it "responds with unauthorized status" do
post :create, xhr: true, params: { comment: comment_params }
expect(response).to have_http_status(:unauthorized)
end

context "when the user is signed in" do
let(:user) { create(:user, :confirmed, locale: "en", organization: organization) }
let(:comment) { Decidim::Comments::Comment.last }

before do
sign_in user, scope: :user
end

it "creates the comment" do
expect do
post :create, xhr: true, params: { comment: comment_params }
end.to change(Decidim::Comments::Comment, :count).by(1)

expect(comment.body.values.first).to eq("This is a new comment")
expect(comment.alignment).to eq(comment_alignment)
expect(subject).to render_template(:create)
end

context "when requested without an XHR request" do
it "throws an unknown format exception" do
expect do
post :create, params: { comment: comment_params }
end.to raise_error(ActionController::UnknownFormat)
end
end

context "when comments are disabled for the component" do
let(:component) { create(:component, :with_comments_disabled, participatory_space: participatory_process) }

it "redirects with a flash alert" do
post :create, xhr: true, params: { comment: comment_params }
expect(flash[:alert]).to be_present
expect(response).to have_http_status(:redirect)
end
end

context "when trying to comment on a private space where the user is not assigned to" do
let(:participatory_process) { create :participatory_process, :private, organization: organization }

it "redirects with a flash alert" do
post :create, xhr: true, params: { comment: comment_params }
expect(flash[:alert]).to be_present
expect(response).to have_http_status(:redirect)
end
end

context "when comment alignment is positive" do
let(:comment_alignment) { 1 }

it "creates the comment with the alignment defined as 1" do
expect do
post :create, xhr: true, params: { comment: comment_params }
end.to change(Decidim::Comments::Comment, :count).by(1)

expect(comment.alignment).to eq(comment_alignment)
expect(subject).to render_template(:create)
end
end

context "when comment alignment is negative" do
let(:comment_alignment) { -1 }

it "creates the comment with the alignment defined as -1" do
expect do
post :create, xhr: true, params: { comment: comment_params }
end.to change(Decidim::Comments::Comment, :count).by(1)

expect(comment.alignment).to eq(comment_alignment)
expect(subject).to render_template(:create)
end
end

context "when comment body is missing" do
let(:comment_params) do
{
commentable_gid: commentable.to_signed_global_id.to_s,
alignment: comment_alignment
}
end

it "renders the error template" do
post :create, xhr: true, params: { comment: comment_params }
expect(subject).to render_template(:error)
end

context "when requested without an XHR request" do
it "throws an unknown format exception" do
expect do
post :create, params: { comment: comment_params }
end.to raise_error(ActionController::UnknownFormat)
end
end
end

context "when comment alignment is invalid" do
let(:comment_alignment) { 2 }

it "renders the error template" do
post :create, xhr: true, params: { comment: comment_params }
expect(subject).to render_template(:error)
end
end

context "when the comment does not exist" do
let(:comment_params) do
{
commentable_gid: "unexisting",
body: "This is a new comment",
alignment: 0
}
end

it "raises a routing error" do
expect do
post :create, xhr: true, params: { comment: comment_params }
end.to raise_error(ActionController::RoutingError)
end
end
end
end

describe "DELETE destroy" do
let(:user) { create(:user, :confirmed, locale: "en", organization: organization) }
let(:comment_author) { create(:user, :confirmed, locale: "en", organization: organization) }
let!(:comment) { create(:comment, commentable: commentable, author: comment_author) }

it "redirects to sign in path" do
expect do
delete :destroy, xhr: true, params: { id: comment.id }
end.not_to(change { Decidim::Comments::Comment.not_deleted.count })

expect(response).to redirect_to("/users/sign_in")
end

context "when a user different of the author is signed in" do
before do
sign_in user, scope: :user
end

it "doesn't delete the comment" do
expect do
delete :destroy, xhr: true, params: { id: comment.id }
end.not_to(change { Decidim::Comments::Comment.not_deleted.count })

expect(response).not_to have_http_status(:success)
end
end

context "when the author is signed in" do
before do
sign_in comment_author, scope: :user
end

it "deletes the comment" do
expect do
delete :destroy, xhr: true, params: { id: comment.id }
end.to change { Decidim::Comments::Comment.not_deleted.count }.by(-1)

expect(response).to have_http_status(:success)
end
end
end
end
end
end
Loading
Loading