diff --git a/app/assets/stylesheets/simple_discussion.scss b/app/assets/stylesheets/simple_discussion.scss index 606f3ff..c63f794 100644 --- a/app/assets/stylesheets/simple_discussion.scss +++ b/app/assets/stylesheets/simple_discussion.scss @@ -4,11 +4,8 @@ @import "simple_discussion_variables"; .community-heading { - margin-top: 10px; - width: 95%; color: #212529; - margin-left: 4rem; - margin-bottom: 24px; + padding-block: 12px; } // Primary button for Forum @@ -236,32 +233,30 @@ border: 1px solid #80808029; border-radius: 3px; padding: 20px; + + &:hover { + text-decoration: none; + background-color: $forum-thread-filter-btn-link-hover-background; + + } } // Formatting forum post .simple_discussion .forum-post { - padding: 10px; border-radius: $post-body-border-radius; margin-bottom: 10px; border: 1px solid #80808029; - &:hover { - background-color: #f4f3f3; - } - .card-body { - padding: 10px; - - p { - font-size: 14px; - } + margin-top: 16px; } } // Formatting the listtile for user details .simple_discussion .forum-post .forum-post-header, .form-user-details { - padding: 0 10px; + padding: 10px; + background-color: $forum-thread-filter-btn-link-hover-background; p { padding: 0; @@ -295,10 +290,9 @@ .sidebar-sticky { position: sticky; - top: 120px; + top: 60px; } .thread-page-container { - border: 1px solid #80808029; - padding: 15px; + padding: 24px; } diff --git a/app/controllers/simple_discussion/forum_posts_controller.rb b/app/controllers/simple_discussion/forum_posts_controller.rb index 4303e97..23e59e9 100644 --- a/app/controllers/simple_discussion/forum_posts_controller.rb +++ b/app/controllers/simple_discussion/forum_posts_controller.rb @@ -13,7 +13,7 @@ def create SimpleDiscussion::ForumPostNotificationJob.perform_later(@forum_post) redirect_to simple_discussion.forum_thread_path(@forum_thread, anchor: "forum_post_#{@forum_post.id}") else - render template: "simple_discussion/forum_threads/show" + render template: "simple_discussion/forum_threads/show", status: :unprocessable_entity end end @@ -24,7 +24,7 @@ def update if @forum_post.update(forum_post_params) redirect_to simple_discussion.forum_thread_path(@forum_thread) else - render action: :edit + render action: :edit, status: :unprocessable_entity end end diff --git a/app/controllers/simple_discussion/forum_threads_controller.rb b/app/controllers/simple_discussion/forum_threads_controller.rb index d7e5bf0..6edc92d 100644 --- a/app/controllers/simple_discussion/forum_threads_controller.rb +++ b/app/controllers/simple_discussion/forum_threads_controller.rb @@ -45,7 +45,7 @@ def create SimpleDiscussion::ForumThreadNotificationJob.perform_later(@forum_thread) redirect_to simple_discussion.forum_thread_path(@forum_thread) else - render action: :new + render action: :new, status: :unprocessable_entity end end @@ -56,7 +56,7 @@ def update if @forum_thread.update(forum_thread_params) redirect_to simple_discussion.forum_thread_path(@forum_thread), notice: I18n.t("your_changes_were_saved") else - render action: :edit + render action: :edit, status: :unprocessable_entity end end diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 267d5e5..dfd9202 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -1,13 +1,29 @@ +require "language_filter" class ForumPost < ApplicationRecord belongs_to :forum_thread, counter_cache: true, touch: true belongs_to :user validates :user_id, :body, presence: true + validate :clean_body, if: -> { SimpleDiscussion.profanity_filter } scope :sorted, -> { order(:created_at) } after_update :solve_forum_thread, if: :solved? + def clean_body + filters = [:profanity, :sex, :violence, :hate] + detected_words = Set.new + + filters.each do |matchlist| + filter = LanguageFilter::Filter.new(matchlist: matchlist) + detected_words.merge(filter.matched(body)) if filter.match?(body) + end + + if detected_words.any? + errors.add(:body, I18n.t(".inappropriate_language_error_message", words: detected_words.to_a.join(", "))) + end + end + def solve_forum_thread forum_thread.update(solved: true) end diff --git a/app/models/forum_thread.rb b/app/models/forum_thread.rb index ec0d044..18ad3c7 100644 --- a/app/models/forum_thread.rb +++ b/app/models/forum_thread.rb @@ -1,3 +1,4 @@ +require "language_filter" class ForumThread < ApplicationRecord extend FriendlyId friendly_id :title, use: :slugged @@ -16,12 +17,29 @@ class ForumThread < ApplicationRecord validates :user_id, :title, presence: true validates_associated :forum_posts + validate :clean_title, if: -> { SimpleDiscussion.profanity_filter } + scope :pinned_first, -> { order(pinned: :desc) } scope :solved, -> { where(solved: true) } scope :sorted, -> { order(updated_at: :desc) } scope :unpinned, -> { where.not(pinned: true) } scope :unsolved, -> { where.not(solved: true) } + def clean_title + filters = [:profanity, :sex, :violence, :hate] + + detected_words = Set.new + + filters.each do |matchlist| + filter = LanguageFilter::Filter.new(matchlist: matchlist) + detected_words.merge(filter.matched(title)) if filter.match?(title) + end + + if detected_words.any? + errors.add(:title, I18n.t(".inappropriate_language_error_message", words: detected_words.to_a.join(", "))) + end + end + def subscribed_users (users + optin_subscribers).uniq - optout_subscribers end diff --git a/app/views/layouts/simple_discussion.html.erb b/app/views/layouts/simple_discussion.html.erb index ed9dedb..80f1e73 100644 --- a/app/views/layouts/simple_discussion.html.erb +++ b/app/views/layouts/simple_discussion.html.erb @@ -1,8 +1,8 @@
-

<%= t('community') %>

-
+
-
+
<%= formatted_content forum_post.body %>
diff --git a/app/views/simple_discussion/forum_threads/_form.html.erb b/app/views/simple_discussion/forum_threads/_form.html.erb index 2582d56..64f2d18 100644 --- a/app/views/simple_discussion/forum_threads/_form.html.erb +++ b/app/views/simple_discussion/forum_threads/_form.html.erb @@ -3,14 +3,10 @@ html: { data: {behavior: "comment-form"} } do |f| %> <% if @forum_thread.errors.any? %> -
-

<%= pluralize(@forum_thread.errors.count, "error") %> <%= t("forum_thread_error_explanation") %>

- -
    +
<% end %> diff --git a/app/views/simple_discussion/forum_threads/_forum_thread.html.erb b/app/views/simple_discussion/forum_threads/_forum_thread.html.erb index bbd64e9..bc62b3b 100644 --- a/app/views/simple_discussion/forum_threads/_forum_thread.html.erb +++ b/app/views/simple_discussion/forum_threads/_forum_thread.html.erb @@ -1,13 +1,13 @@ <%= cache forum_thread do %> -
+ <%= link_to simple_discussion.forum_thread_path(forum_thread), class: "forum-thread d-flex flex-row mb-4" do %>
user avatar
- <%= link_to simple_discussion.forum_thread_path(forum_thread), class: "thread-header-title" do %> +
<%= icon "fas", "thumb-tack", class: "text-muted" if forum_thread.pinned? %> <%= forum_thread.title %> - <% end %> +
<%= icon "fas", "comments" %> @@ -39,5 +39,5 @@
-
+ <% end %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index aeeedeb..de519dd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -55,4 +55,5 @@ en: open: "Open" create_account: "Create account" login: "Log in" - commented: "commented:" \ No newline at end of file + commented: "commented:" + inappropriate_language_error_message: "contains inappropriate language: %{words}" diff --git a/config/locales/es.yml b/config/locales/es.yml index f4a98e9..851831c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -39,3 +39,20 @@ es: ask_your_question: Haz tu pregunta update_comment: Actualiza tu comentario your_changes_were_saved: Tus cambios fueron guardados + search_not_found: No se encontraron resultados para tu búsqueda + check_out: Echa un vistazo + latest_questions: las preguntas más recientes + instead: ¿en su lugar? + forum_thread_error_explanation: "prohibió que este hilo del foro se guardara:" + ago: "hace" + on: "el" + mark_as_solved: "Marcar como resuelto" + undo: "Deshacer" + back_to_thread: "Volver al hilo" + created_by: "Creado por" + solved: "Resuelto" + open: "Abrir" + create_account: "Crear cuenta" + login: "Iniciar sesión" + commented: "comentó:" + inappropriate_language_error_message: "contiene lenguaje inapropiado: %{words}" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index e2021ca..c137054 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -45,3 +45,16 @@ fr: check_out: Voir latest_questions: les dernières questions instead: à la place + forum_thread_error_explanation: "a interdit l'enregistrement de ce fil de discussion:" + ago: "il y a" + on: "le" + mark_as_solved: "Marquer comme résolu" + undo: "Annuler" + back_to_thread: "Retour au fil de discussion" + created_by: "Créé par" + solved: "Résolu" + open: "Ouvrir" + create_account: "Créer un compte" + login: "Se connecter" + commented: "a commenté:" + inappropriate_language_error_message: "contient un langage inapproprié : %{words}" diff --git a/gemfiles/rails_6_1.gemfile.lock b/gemfiles/rails_6_1.gemfile.lock index a2726ce..cffead0 100644 --- a/gemfiles/rails_6_1.gemfile.lock +++ b/gemfiles/rails_6_1.gemfile.lock @@ -4,66 +4,67 @@ PATH simple_discussion (1.3.0) font-awesome-sass (>= 5.13.0) friendly_id (>= 5.2.0) + language_filter (>= 0.3.01) rails (>= 4.2) will_paginate (>= 3.1.0) GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.7) - actionpack (= 6.1.7.7) - activesupport (= 6.1.7.7) + actioncable (6.1.7.8) + actionpack (= 6.1.7.8) + activesupport (= 6.1.7.8) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.7) - actionpack (= 6.1.7.7) - activejob (= 6.1.7.7) - activerecord (= 6.1.7.7) - activestorage (= 6.1.7.7) - activesupport (= 6.1.7.7) + actionmailbox (6.1.7.8) + actionpack (= 6.1.7.8) + activejob (= 6.1.7.8) + activerecord (= 6.1.7.8) + activestorage (= 6.1.7.8) + activesupport (= 6.1.7.8) mail (>= 2.7.1) - actionmailer (6.1.7.7) - actionpack (= 6.1.7.7) - actionview (= 6.1.7.7) - activejob (= 6.1.7.7) - activesupport (= 6.1.7.7) + actionmailer (6.1.7.8) + actionpack (= 6.1.7.8) + actionview (= 6.1.7.8) + activejob (= 6.1.7.8) + activesupport (= 6.1.7.8) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.7.7) - actionview (= 6.1.7.7) - activesupport (= 6.1.7.7) + actionpack (6.1.7.8) + actionview (= 6.1.7.8) + activesupport (= 6.1.7.8) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.7) - actionpack (= 6.1.7.7) - activerecord (= 6.1.7.7) - activestorage (= 6.1.7.7) - activesupport (= 6.1.7.7) + actiontext (6.1.7.8) + actionpack (= 6.1.7.8) + activerecord (= 6.1.7.8) + activestorage (= 6.1.7.8) + activesupport (= 6.1.7.8) nokogiri (>= 1.8.5) - actionview (6.1.7.7) - activesupport (= 6.1.7.7) + actionview (6.1.7.8) + activesupport (= 6.1.7.8) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.7.7) - activesupport (= 6.1.7.7) + activejob (6.1.7.8) + activesupport (= 6.1.7.8) globalid (>= 0.3.6) - activemodel (6.1.7.7) - activesupport (= 6.1.7.7) - activerecord (6.1.7.7) - activemodel (= 6.1.7.7) - activesupport (= 6.1.7.7) - activestorage (6.1.7.7) - actionpack (= 6.1.7.7) - activejob (= 6.1.7.7) - activerecord (= 6.1.7.7) - activesupport (= 6.1.7.7) + activemodel (6.1.7.8) + activesupport (= 6.1.7.8) + activerecord (6.1.7.8) + activemodel (= 6.1.7.8) + activesupport (= 6.1.7.8) + activestorage (6.1.7.8) + actionpack (= 6.1.7.8) + activejob (= 6.1.7.8) + activerecord (= 6.1.7.8) + activesupport (= 6.1.7.8) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.7) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -75,8 +76,8 @@ GEM thor (>= 0.14.0) ast (2.4.2) bcrypt (3.1.20) - builder (3.2.4) - concurrent-ruby (1.3.1) + builder (3.3.0) + concurrent-ruby (1.3.3) crass (1.0.6) date (3.3.4) devise (4.9.4) @@ -85,7 +86,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - erubi (1.12.0) + erubi (1.13.0) ffi (1.17.0-x86_64-linux-gnu) font-awesome-sass (5.13.1) sassc (>= 1.11) @@ -96,6 +97,7 @@ GEM i18n (1.14.5) concurrent-ruby (~> 1.0) json (2.7.2) + language_filter (0.3.01) language_server-protocol (3.17.0.3) lint_roller (1.1.0) loofah (2.22.0) @@ -109,8 +111,8 @@ GEM marcel (1.0.4) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.23.1) - net-imap (0.4.12) + minitest (5.24.1) + net-imap (0.4.14) date net-protocol net-pop (0.1.2) @@ -120,11 +122,11 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.5-x86_64-linux) + nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.24.0) - parser (3.3.2.0) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc puma (6.4.2) @@ -133,20 +135,20 @@ GEM rack (2.2.9) rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.7) - actioncable (= 6.1.7.7) - actionmailbox (= 6.1.7.7) - actionmailer (= 6.1.7.7) - actionpack (= 6.1.7.7) - actiontext (= 6.1.7.7) - actionview (= 6.1.7.7) - activejob (= 6.1.7.7) - activemodel (= 6.1.7.7) - activerecord (= 6.1.7.7) - activestorage (= 6.1.7.7) - activesupport (= 6.1.7.7) + rails (6.1.7.8) + actioncable (= 6.1.7.8) + actionmailbox (= 6.1.7.8) + actionmailer (= 6.1.7.8) + actionpack (= 6.1.7.8) + actiontext (= 6.1.7.8) + actionview (= 6.1.7.8) + activejob (= 6.1.7.8) + activemodel (= 6.1.7.8) + activerecord (= 6.1.7.8) + activestorage (= 6.1.7.8) + activesupport (= 6.1.7.8) bundler (>= 1.15.0) - railties (= 6.1.7.7) + railties (= 6.1.7.8) sprockets-rails (>= 2.0.0) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) @@ -155,9 +157,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (6.1.7.7) - actionpack (= 6.1.7.7) - activesupport (= 6.1.7.7) + railties (6.1.7.8) + actionpack (= 6.1.7.8) + activesupport (= 6.1.7.8) method_source rake (>= 12.2) thor (~> 1.0) @@ -167,9 +169,9 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rubocop (1.63.5) + rexml (3.3.2) + strscan + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -182,7 +184,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) - rubocop-performance (1.21.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) @@ -191,15 +193,15 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.1) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) sqlite3 (1.7.3-x86_64-linux) - standard (1.36.0) + standard (1.39.2) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.63.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) standard-performance (~> 1.4) standard-custom (1.0.2) @@ -221,8 +223,8 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - will_paginate (4.0.0) - zeitwerk (2.6.15) + will_paginate (4.0.1) + zeitwerk (2.6.16) PLATFORMS x86_64-linux-gnu diff --git a/gemfiles/rails_7.gemfile.lock b/gemfiles/rails_7.gemfile.lock index dd9e779..2ded953 100644 --- a/gemfiles/rails_7.gemfile.lock +++ b/gemfiles/rails_7.gemfile.lock @@ -4,73 +4,74 @@ PATH simple_discussion (1.3.0) font-awesome-sass (>= 5.13.0) friendly_id (>= 5.2.0) + language_filter (>= 0.3.01) rails (>= 4.2) will_paginate (>= 3.1.0) GEM remote: https://rubygems.org/ specs: - actioncable (7.0.8.3) - actionpack (= 7.0.8.3) - activesupport (= 7.0.8.3) + actioncable (7.0.8.4) + actionpack (= 7.0.8.4) + activesupport (= 7.0.8.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.8.3) - actionpack (= 7.0.8.3) - activejob (= 7.0.8.3) - activerecord (= 7.0.8.3) - activestorage (= 7.0.8.3) - activesupport (= 7.0.8.3) + actionmailbox (7.0.8.4) + actionpack (= 7.0.8.4) + activejob (= 7.0.8.4) + activerecord (= 7.0.8.4) + activestorage (= 7.0.8.4) + activesupport (= 7.0.8.4) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.8.3) - actionpack (= 7.0.8.3) - actionview (= 7.0.8.3) - activejob (= 7.0.8.3) - activesupport (= 7.0.8.3) + actionmailer (7.0.8.4) + actionpack (= 7.0.8.4) + actionview (= 7.0.8.4) + activejob (= 7.0.8.4) + activesupport (= 7.0.8.4) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.8.3) - actionview (= 7.0.8.3) - activesupport (= 7.0.8.3) + actionpack (7.0.8.4) + actionview (= 7.0.8.4) + activesupport (= 7.0.8.4) rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.8.3) - actionpack (= 7.0.8.3) - activerecord (= 7.0.8.3) - activestorage (= 7.0.8.3) - activesupport (= 7.0.8.3) + actiontext (7.0.8.4) + actionpack (= 7.0.8.4) + activerecord (= 7.0.8.4) + activestorage (= 7.0.8.4) + activesupport (= 7.0.8.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.8.3) - activesupport (= 7.0.8.3) + actionview (7.0.8.4) + activesupport (= 7.0.8.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.8.3) - activesupport (= 7.0.8.3) + activejob (7.0.8.4) + activesupport (= 7.0.8.4) globalid (>= 0.3.6) - activemodel (7.0.8.3) - activesupport (= 7.0.8.3) - activerecord (7.0.8.3) - activemodel (= 7.0.8.3) - activesupport (= 7.0.8.3) - activestorage (7.0.8.3) - actionpack (= 7.0.8.3) - activejob (= 7.0.8.3) - activerecord (= 7.0.8.3) - activesupport (= 7.0.8.3) + activemodel (7.0.8.4) + activesupport (= 7.0.8.4) + activerecord (7.0.8.4) + activemodel (= 7.0.8.4) + activesupport (= 7.0.8.4) + activestorage (7.0.8.4) + actionpack (= 7.0.8.4) + activejob (= 7.0.8.4) + activerecord (= 7.0.8.4) + activesupport (= 7.0.8.4) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.8.3) + activesupport (7.0.8.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -81,8 +82,8 @@ GEM thor (>= 0.14.0) ast (2.4.2) bcrypt (3.1.20) - builder (3.2.4) - concurrent-ruby (1.3.1) + builder (3.3.0) + concurrent-ruby (1.3.3) crass (1.0.6) date (3.3.4) devise (4.9.4) @@ -91,7 +92,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - erubi (1.12.0) + erubi (1.13.0) ffi (1.17.0-x86_64-linux-gnu) font-awesome-sass (5.13.1) sassc (>= 1.11) @@ -102,6 +103,7 @@ GEM i18n (1.14.5) concurrent-ruby (~> 1.0) json (2.7.2) + language_filter (0.3.01) language_server-protocol (3.17.0.3) lint_roller (1.1.0) loofah (2.22.0) @@ -115,8 +117,8 @@ GEM marcel (1.0.4) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.23.1) - net-imap (0.4.12) + minitest (5.24.1) + net-imap (0.4.14) date net-protocol net-pop (0.1.2) @@ -126,11 +128,11 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.5-x86_64-linux) + nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.24.0) - parser (3.3.2.0) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc puma (6.4.2) @@ -139,20 +141,20 @@ GEM rack (2.2.9) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.8.3) - actioncable (= 7.0.8.3) - actionmailbox (= 7.0.8.3) - actionmailer (= 7.0.8.3) - actionpack (= 7.0.8.3) - actiontext (= 7.0.8.3) - actionview (= 7.0.8.3) - activejob (= 7.0.8.3) - activemodel (= 7.0.8.3) - activerecord (= 7.0.8.3) - activestorage (= 7.0.8.3) - activesupport (= 7.0.8.3) + rails (7.0.8.4) + actioncable (= 7.0.8.4) + actionmailbox (= 7.0.8.4) + actionmailer (= 7.0.8.4) + actionpack (= 7.0.8.4) + actiontext (= 7.0.8.4) + actionview (= 7.0.8.4) + activejob (= 7.0.8.4) + activemodel (= 7.0.8.4) + activerecord (= 7.0.8.4) + activestorage (= 7.0.8.4) + activesupport (= 7.0.8.4) bundler (>= 1.15.0) - railties (= 7.0.8.3) + railties (= 7.0.8.4) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -160,9 +162,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.0.8.3) - actionpack (= 7.0.8.3) - activesupport (= 7.0.8.3) + railties (7.0.8.4) + actionpack (= 7.0.8.4) + activesupport (= 7.0.8.4) method_source rake (>= 12.2) thor (~> 1.0) @@ -173,9 +175,9 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rubocop (1.63.5) + rexml (3.3.2) + strscan + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -188,7 +190,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) - rubocop-performance (1.21.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) @@ -197,15 +199,15 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.1) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) sqlite3 (1.7.3-x86_64-linux) - standard (1.36.0) + standard (1.39.2) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.63.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) standard-performance (~> 1.4) standard-custom (1.0.2) @@ -227,8 +229,8 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - will_paginate (4.0.0) - zeitwerk (2.6.15) + will_paginate (4.0.1) + zeitwerk (2.6.16) PLATFORMS x86_64-linux-gnu diff --git a/gemfiles/rails_7_1.gemfile.lock b/gemfiles/rails_7_1.gemfile.lock index 7fad461..d2ea195 100644 --- a/gemfiles/rails_7_1.gemfile.lock +++ b/gemfiles/rails_7_1.gemfile.lock @@ -4,41 +4,42 @@ PATH simple_discussion (1.3.0) font-awesome-sass (>= 5.13.0) friendly_id (>= 5.2.0) + language_filter (>= 0.3.01) rails (>= 4.2) will_paginate (>= 3.1.0) GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3.3) - actionpack (= 7.1.3.3) - activesupport (= 7.1.3.3) + actioncable (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.3) - actionpack (= 7.1.3.3) - activejob (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionmailbox (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.3.3) - actionpack (= 7.1.3.3) - actionview (= 7.1.3.3) - activejob (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionmailer (7.1.3.4) + actionpack (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.3.3) - actionview (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionpack (7.1.3.4) + actionview (= 7.1.3.4) + activesupport (= 7.1.3.4) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -46,35 +47,35 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.3) - actionpack (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + actiontext (7.1.3.4) + actionpack (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.3) - activesupport (= 7.1.3.3) + actionview (7.1.3.4) + activesupport (= 7.1.3.4) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3.3) - activesupport (= 7.1.3.3) + activejob (7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.3.6) - activemodel (7.1.3.3) - activesupport (= 7.1.3.3) - activerecord (7.1.3.3) - activemodel (= 7.1.3.3) - activesupport (= 7.1.3.3) + activemodel (7.1.3.4) + activesupport (= 7.1.3.4) + activerecord (7.1.3.4) + activemodel (= 7.1.3.4) + activesupport (= 7.1.3.4) timeout (>= 0.4.0) - activestorage (7.1.3.3) - actionpack (= 7.1.3.3) - activejob (= 7.1.3.3) - activerecord (= 7.1.3.3) - activesupport (= 7.1.3.3) + activestorage (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activesupport (= 7.1.3.4) marcel (~> 1.0) - activesupport (7.1.3.3) + activesupport (7.1.3.4) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -92,8 +93,8 @@ GEM base64 (0.2.0) bcrypt (3.1.20) bigdecimal (3.1.8) - builder (3.2.4) - concurrent-ruby (1.3.1) + builder (3.3.0) + concurrent-ruby (1.3.3) connection_pool (2.4.1) crass (1.0.6) date (3.3.4) @@ -104,7 +105,7 @@ GEM responders warden (~> 1.2.3) drb (2.2.1) - erubi (1.12.0) + erubi (1.13.0) ffi (1.17.0-x86_64-linux-gnu) font-awesome-sass (5.13.1) sassc (>= 1.11) @@ -115,10 +116,11 @@ GEM i18n (1.14.5) concurrent-ruby (~> 1.0) io-console (0.7.2) - irb (1.13.1) + irb (1.14.0) rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.7.2) + language_filter (0.3.01) language_server-protocol (3.17.0.3) lint_roller (1.1.0) loofah (2.22.0) @@ -131,9 +133,9 @@ GEM net-smtp marcel (1.0.4) mini_mime (1.1.5) - minitest (5.23.1) + minitest (5.24.1) mutex_m (0.2.0) - net-imap (0.4.12) + net-imap (0.4.14) date net-protocol net-pop (0.1.2) @@ -143,11 +145,11 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.5-x86_64-linux) + nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.24.0) - parser (3.3.2.0) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc psych (5.1.2) @@ -155,7 +157,7 @@ GEM puma (6.4.2) nio4r (~> 2.0) racc (1.8.0) - rack (3.0.11) + rack (3.1.7) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -163,20 +165,20 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.1.3.3) - actioncable (= 7.1.3.3) - actionmailbox (= 7.1.3.3) - actionmailer (= 7.1.3.3) - actionpack (= 7.1.3.3) - actiontext (= 7.1.3.3) - actionview (= 7.1.3.3) - activejob (= 7.1.3.3) - activemodel (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + rails (7.1.3.4) + actioncable (= 7.1.3.4) + actionmailbox (= 7.1.3.4) + actionmailer (= 7.1.3.4) + actionpack (= 7.1.3.4) + actiontext (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activemodel (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) bundler (>= 1.15.0) - railties (= 7.1.3.3) + railties (= 7.1.3.4) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -184,9 +186,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.1.3.3) - actionpack (= 7.1.3.3) - activesupport (= 7.1.3.3) + railties (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -197,14 +199,14 @@ GEM rdoc (6.7.0) psych (>= 4.0.0) regexp_parser (2.9.2) - reline (0.5.8) + reline (0.5.9) io-console (~> 0.5) responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rubocop (1.63.5) + rexml (3.3.2) + strscan + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -217,7 +219,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) - rubocop-performance (1.21.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) @@ -226,15 +228,15 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.1) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) sqlite3 (1.7.3-x86_64-linux) - standard (1.36.0) + standard (1.39.2) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.63.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) standard-performance (~> 1.4) standard-custom (1.0.2) @@ -245,7 +247,7 @@ GEM rubocop-performance (~> 1.21.0) standardrb (1.0.1) standard - stringio (3.1.0) + stringio (3.1.1) strscan (3.1.0) thor (1.3.1) timeout (0.4.1) @@ -258,8 +260,8 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - will_paginate (4.0.0) - zeitwerk (2.6.15) + will_paginate (4.0.1) + zeitwerk (2.6.16) PLATFORMS x86_64-linux-gnu diff --git a/gemfiles/rails_main.gemfile.lock b/gemfiles/rails_main.gemfile.lock index 1eeb031..25885b2 100644 --- a/gemfiles/rails_main.gemfile.lock +++ b/gemfiles/rails_main.gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/rails/rails - revision: 3769f1eee6a1ec4f6438155d67477db6d192577f + revision: 0db535f88d856bcac66faee901df51aa493b639b branch: main specs: actioncable (8.0.0.alpha) @@ -69,6 +69,7 @@ GIT connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) tzinfo (~> 2.0, >= 2.0.5) rails (8.0.0.alpha) @@ -100,6 +101,7 @@ PATH simple_discussion (1.3.0) font-awesome-sass (>= 5.13.0) friendly_id (>= 5.2.0) + language_filter (>= 0.3.01) rails (>= 4.2) will_paginate (>= 3.1.0) @@ -114,8 +116,8 @@ GEM base64 (0.2.0) bcrypt (3.1.20) bigdecimal (3.1.8) - builder (3.2.4) - concurrent-ruby (1.3.1) + builder (3.3.0) + concurrent-ruby (1.3.3) connection_pool (2.4.1) crass (1.0.6) date (3.3.4) @@ -126,9 +128,17 @@ GEM responders warden (~> 1.2.3) drb (2.2.1) - erubi (1.12.0) - ffi (1.17.0) + erubi (1.13.0) + ffi (1.17.0-aarch64-linux-gnu) + ffi (1.17.0-aarch64-linux-musl) + ffi (1.17.0-arm-linux-gnu) + ffi (1.17.0-arm-linux-musl) + ffi (1.17.0-arm64-darwin) + ffi (1.17.0-x86-linux-gnu) + ffi (1.17.0-x86-linux-musl) + ffi (1.17.0-x86_64-darwin) ffi (1.17.0-x86_64-linux-gnu) + ffi (1.17.0-x86_64-linux-musl) font-awesome-sass (5.13.1) sassc (>= 1.11) friendly_id (5.5.1) @@ -138,12 +148,14 @@ GEM i18n (1.14.5) concurrent-ruby (~> 1.0) io-console (0.7.2) - irb (1.13.1) + irb (1.14.0) rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.7.2) + language_filter (0.3.01) language_server-protocol (3.17.0.3) lint_roller (1.1.0) + logger (1.6.0) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -154,8 +166,8 @@ GEM net-smtp marcel (1.0.4) mini_mime (1.1.5) - minitest (5.23.1) - net-imap (0.4.12) + minitest (5.24.1) + net-imap (0.4.14) date net-protocol net-pop (0.1.2) @@ -165,21 +177,21 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.5-aarch64-linux) + nokogiri (1.16.6-aarch64-linux) racc (~> 1.4) - nokogiri (1.16.5-arm-linux) + nokogiri (1.16.6-arm-linux) racc (~> 1.4) - nokogiri (1.16.5-arm64-darwin) + nokogiri (1.16.6-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.5-x86-linux) + nokogiri (1.16.6-x86-linux) racc (~> 1.4) - nokogiri (1.16.5-x86_64-darwin) + nokogiri (1.16.6-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.5-x86_64-linux) + nokogiri (1.16.6-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.24.0) - parser (3.3.2.0) + parallel (1.25.1) + parser (3.3.4.0) ast (~> 2.4.1) racc psych (5.1.2) @@ -187,7 +199,7 @@ GEM puma (6.4.2) nio4r (~> 2.0) racc (1.8.0) - rack (3.0.11) + rack (3.1.7) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -207,14 +219,14 @@ GEM rdoc (6.7.0) psych (>= 4.0.0) regexp_parser (2.9.2) - reline (0.5.8) + reline (0.5.9) io-console (~> 0.5) responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rubocop (1.63.5) + rexml (3.3.2) + strscan + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -227,7 +239,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) - rubocop-performance (1.21.0) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) @@ -236,9 +248,9 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.1) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) sqlite3 (2.0.2-aarch64-linux-gnu) sqlite3 (2.0.2-aarch64-linux-musl) @@ -250,10 +262,10 @@ GEM sqlite3 (2.0.2-x86_64-darwin) sqlite3 (2.0.2-x86_64-linux-gnu) sqlite3 (2.0.2-x86_64-linux-musl) - standard (1.36.0) + standard (1.39.2) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.63.0) + rubocop (~> 1.64.0) standard-custom (~> 1.0.0) standard-performance (~> 1.4) standard-custom (1.0.2) @@ -264,7 +276,7 @@ GEM rubocop-performance (~> 1.21.0) standardrb (1.0.1) standard - stringio (3.1.0) + stringio (3.1.1) strscan (3.1.0) thor (1.3.1) timeout (0.4.1) @@ -278,8 +290,8 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - will_paginate (4.0.0) - zeitwerk (2.6.15) + will_paginate (4.0.1) + zeitwerk (2.6.16) PLATFORMS aarch64-linux diff --git a/lib/simple_discussion.rb b/lib/simple_discussion.rb index 444154b..974718d 100644 --- a/lib/simple_discussion.rb +++ b/lib/simple_discussion.rb @@ -12,8 +12,10 @@ module SimpleDiscussion # Define who owns the subscription mattr_accessor :send_email_notifications mattr_accessor :send_slack_notifications + mattr_accessor :profanity_filter @@send_email_notifications = true @@send_slack_notifications = true + @@profanity_filter = true def self.setup yield self diff --git a/simple_discussion.gemspec b/simple_discussion.gemspec index c243509..d7da08a 100644 --- a/simple_discussion.gemspec +++ b/simple_discussion.gemspec @@ -26,5 +26,6 @@ Gem::Specification.new do |spec| spec.add_dependency "friendly_id", ">= 5.2.0" spec.add_dependency "rails", ">= 4.2" spec.add_dependency "will_paginate", ">= 3.1.0" + spec.add_dependency "language_filter", ">= 0.3.01" spec.metadata["rubygems_mfa_required"] = "true" end diff --git a/test/integration/forum_test.rb b/test/integration/forum_test.rb index 56965c0..882dabf 100644 --- a/test/integration/forum_test.rb +++ b/test/integration/forum_test.rb @@ -1,4 +1,5 @@ require "test_helper" +require "language_filter" class ForumTest < ActionDispatch::IntegrationTest include ActionView::RecordIdentifier @@ -6,6 +7,7 @@ class ForumTest < ActionDispatch::IntegrationTest setup do sign_in users(:one) + @filter = LanguageFilter::Filter.new end test "threads index" do @@ -53,4 +55,76 @@ class ForumTest < ActionDispatch::IntegrationTest assert_redirected_to forum_thread_path(forum_threads(:hello), anchor: dom_id(ForumPost.last)) end + + test "cannot create a forum thread with inappropriate language in title" do + inappropriate_word = @filter.matchlist.to_a.sample + assert_no_difference "ForumThread.count" do + assert_no_difference "ForumPost.count" do + post forum_threads_path, params: { + forum_thread: { + forum_category_id: forum_categories(:general).id, + title: "This title contains inappropriate language: #{inappropriate_word}", + forum_posts_attributes: [{ + body: "Clean body" + }] + } + } + end + end + + assert_response :unprocessable_entity + assert_includes response.body, "contains inappropriate language: #{inappropriate_word}" + end + + test "cannot create a forum thread with inappropriate language in body" do + inappropriate_word = @filter.matchlist.to_a.sample + assert_no_difference "ForumThread.count" do + assert_no_difference "ForumPost.count" do + post forum_threads_path, params: { + forum_thread: { + forum_category_id: forum_categories(:general).id, + title: "Clean Title", + forum_posts_attributes: [{ + body: "contains inappropriate language: #{inappropriate_word}" + }] + } + } + end + end + + assert_response :unprocessable_entity + assert_includes response.body, "contains inappropriate language: #{inappropriate_word}" + end + + test "cannot reply to a forum thread with inappropriate language" do + inappropriate_word = @filter.matchlist.to_a.sample + assert_no_difference "ForumPost.count" do + post forum_thread_forum_posts_path(forum_threads(:hello)), params: { + forum_post: { + body: "contains inappropriate language: #{inappropriate_word}" + } + } + end + + assert_response :unprocessable_entity + assert_includes response.body, "contains inappropriate language: #{inappropriate_word}" + end + + test "can create a forum thread with appropriate language in title and body" do + assert_difference "ForumThread.count" do + assert_difference "ForumPost.count" do + post forum_threads_path, params: { + forum_thread: { + forum_category_id: forum_categories(:general).id, + title: "Clean Thread Title", + forum_posts_attributes: [{ + body: "This is a clean and appropriate post." + }] + } + } + end + end + + assert_redirected_to forum_thread_path(ForumThread.last) + end end