diff --git a/README.md b/README.md index 0433edc..e07c58b 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,10 @@ By default, SimpleDiscussion will attempt to send email and slack notifications SimpleDiscussion.setup do |config| config.send_email_notifications = false # Default: true config.send_slack_notifications = false # Default: true + + config.markdown_circuit_embed = false # Default: false + config.markdown_user_tagging = false # Default: false + config.markdown_video_embed = false # Default false end ``` diff --git a/app/controllers/simple_discussion/forum_posts_controller.rb b/app/controllers/simple_discussion/forum_posts_controller.rb index 6ed761d..5cc6103 100644 --- a/app/controllers/simple_discussion/forum_posts_controller.rb +++ b/app/controllers/simple_discussion/forum_posts_controller.rb @@ -66,7 +66,7 @@ def unsolved redirect_to simple_discussion.forum_thread_path(@forum_thread, anchor: ActionView::RecordIdentifier.dom_id(@forum_post)) end - def report_spam + def report_post @forum_post = @forum_thread.forum_posts.find(params[:id]) @spam_report = SpamReport.new(forum_post: @forum_post, user: current_user, reason: params[:reason], details: params[:details]) diff --git a/app/models/spam_report.rb b/app/models/spam_report.rb index 58b8acb..bc9b113 100644 --- a/app/models/spam_report.rb +++ b/app/models/spam_report.rb @@ -3,7 +3,7 @@ class SpamReport < ApplicationRecord belongs_to :user validates :forum_post_id, :user_id, :reason, presence: true - validates :details, presence: true, if: -> { reason == "other" } + validates :details, presence: true, if: -> { reason == "others" } enum reason: { sexual_content: 0, diff --git a/app/views/layouts/simple_discussion.html.erb b/app/views/layouts/simple_discussion.html.erb index 57d4e18..64d665a 100644 --- a/app/views/layouts/simple_discussion.html.erb +++ b/app/views/layouts/simple_discussion.html.erb @@ -78,8 +78,8 @@ - + - diff --git a/app/views/simple_discussion/forum_posts/_forum_post.html.erb b/app/views/simple_discussion/forum_posts/_forum_post.html.erb index 3655b67..1e8f496 100644 --- a/app/views/simple_discussion/forum_posts/_forum_post.html.erb +++ b/app/views/simple_discussion/forum_posts/_forum_post.html.erb @@ -1,7 +1,16 @@ <%= content_tag :div, id: forum_post.solved ? 'solution' : dom_id(forum_post), class: "forum-post" do %>
- <% if forum_post.solved? %> + <% unless forum_post == @forum_thread.forum_posts.first %> + <% if is_moderator_or_owner?(@forum_thread) %> + <% if @forum_thread.solved? && forum_post.solved? %> + <%= link_to t('unmark_as_solution'), simple_discussion.unsolved_forum_thread_forum_post_path(@forum_thread, forum_post), method: :put, class: "badge badge-info p-2 mr-2" %> + <% else %> + <%= link_to t('mark_as_solution'), simple_discussion.solved_forum_thread_forum_post_path(@forum_thread, forum_post), method: :put, class: "badge badge-info p-2 mr-2" %> + <% end %> + <% end %> + <% end %> + <% if forum_post.solved? && forum_post != @forum_thread.forum_posts.first && !is_moderator_or_owner?(@forum_thread) %> <%= t('solution') %> <% end %> <% if user_signed_in? %> @@ -21,14 +30,7 @@ data: { toggle: "tooltip", placement: "left", confirm: "Are you sure you want to delete this post?" }, title: t('delete_this_post') %> <% end %> - <% if is_moderator_or_owner?(@forum_thread) %> - <% if @forum_thread.solved? && forum_post.solved? %> - <%= link_to t('unmark_as_solution'), simple_discussion.unsolved_forum_thread_forum_post_path(@forum_thread, forum_post), class: "dropdown-item", method: :put %> - <% else %> - <%= link_to t('mark_as_solution'), simple_discussion.solved_forum_thread_forum_post_path(@forum_thread, forum_post), method: :put, class: "dropdown-item" %> - <% end %> - <% end %> - <%= link_to t('report_post'), "#", class: "dropdown-item", data: { controller: "report-spam", report_spam_target: "reportSpamButton", toggle: "modal", target: "#reportSpamModal", post_id: forum_post.id } %> + <%= link_to t('report_post'), "#", class: "dropdown-item", data: { controller: "report-post", report_post_target: "reportPostButton", toggle: "modal", target: "#reportPostModal", post_id: forum_post.id } %>
<% end %> diff --git a/app/views/simple_discussion/forum_posts/_report_post_modal_form.html.erb b/app/views/simple_discussion/forum_posts/_report_post_modal_form.html.erb new file mode 100644 index 0000000..d35cc7b --- /dev/null +++ b/app/views/simple_discussion/forum_posts/_report_post_modal_form.html.erb @@ -0,0 +1,68 @@ + + + diff --git a/app/views/simple_discussion/forum_posts/_spam_report.html.erb b/app/views/simple_discussion/forum_posts/_spam_report.html.erb index a98c39b..7e75a34 100644 --- a/app/views/simple_discussion/forum_posts/_spam_report.html.erb +++ b/app/views/simple_discussion/forum_posts/_spam_report.html.erb @@ -22,7 +22,7 @@
<% if spam_report.reason == "others" %> - <%= spam_report.details %> + Other:<%= spam_report.details %> <% else %> <%= spam_report.reason.humanize %> <% end %> diff --git a/app/views/simple_discussion/forum_threads/show.html.erb b/app/views/simple_discussion/forum_threads/show.html.erb index 84ec509..3201d9f 100644 --- a/app/views/simple_discussion/forum_threads/show.html.erb +++ b/app/views/simple_discussion/forum_threads/show.html.erb @@ -39,6 +39,6 @@ <%= render partial: "simple_discussion/forum_posts/forum_post", collection: @forum_thread.forum_posts.includes(:user).sorted %> <%= render partial: "simple_discussion/forum_posts/form" if user_signed_in? %> -<%= render partial: "simple_discussion/forum_posts/report_spam_modal_form", locals: { forum_thread: @forum_thread } if user_signed_in? %> +<%= render partial: "simple_discussion/forum_posts/report_post_modal_form", locals: { forum_thread: @forum_thread } if user_signed_in? %> <%= render partial: "login_bar" if !user_signed_in? %> diff --git a/config/routes.rb b/config/routes.rb index 1410ad5..2345640 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,7 +14,7 @@ member do put :solved put :unsolved - post :report_spam + post :report_post end end diff --git a/test/dummy/app/models/user.rb b/test/dummy/app/models/user.rb index 0735bb1..a420c59 100644 --- a/test/dummy/app/models/user.rb +++ b/test/dummy/app/models/user.rb @@ -7,6 +7,6 @@ class User < ApplicationRecord :recoverable, :rememberable, :validatable def moderator? - true + moderator end end diff --git a/test/dummy/db/migrate/20240813072347_add_moderator_to_users.rb b/test/dummy/db/migrate/20240813072347_add_moderator_to_users.rb new file mode 100644 index 0000000..a3cfacd --- /dev/null +++ b/test/dummy/db/migrate/20240813072347_add_moderator_to_users.rb @@ -0,0 +1,5 @@ +class AddModeratorToUsers < ActiveRecord::Migration[7.0] + def change + add_column :users, :moderator, :boolean, default: false + end +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb index 24d545e..af35396 100644 --- a/test/dummy/db/schema.rb +++ b/test/dummy/db/schema.rb @@ -10,13 +10,22 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_07_28_092034) do +ActiveRecord::Schema.define(version: 2024_08_13_072347) do create_table "forum_categories", force: :cascade do |t| t.string "name", null: false t.string "slug", null: false t.string "color", default: "000000" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + end + + create_table "forum_leaderboards", force: :cascade do |t| + t.integer "user_id", null: false + t.integer "points", default: 0, null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["points"], name: "index_forum_leaderboards_on_points" + t.index ["user_id"], name: "index_forum_leaderboards_on_user_id", unique: true end create_table "forum_posts", force: :cascade do |t| @@ -24,16 +33,16 @@ t.integer "user_id" t.text "body" t.boolean "solved", default: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "forum_subscriptions", force: :cascade do |t| t.integer "forum_thread_id" t.integer "user_id" t.string "subscription_type" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "forum_threads", force: :cascade do |t| @@ -44,8 +53,19 @@ t.integer "forum_posts_count", default: 0 t.boolean "pinned", default: false t.boolean "solved", default: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + end + + create_table "spam_reports", force: :cascade do |t| + t.integer "forum_post_id", null: false + t.integer "user_id", null: false + t.integer "reason", null: false + t.text "details" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["forum_post_id"], name: "index_spam_reports_on_forum_post_id" + t.index ["user_id"], name: "index_spam_reports_on_user_id" end create_table "spam_reports", force: :cascade do |t| @@ -63,15 +83,17 @@ t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "reset_password_sent_at", precision: nil + t.datetime "remember_created_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "name" + t.boolean "moderator", default: false t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + add_foreign_key "forum_leaderboards", "users" add_foreign_key "forum_posts", "forum_threads" add_foreign_key "forum_posts", "users" add_foreign_key "forum_subscriptions", "forum_threads" diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 297acdf..4323c34 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -5,3 +5,8 @@ one: two: name: "Second User" email: "second@example.com" + +moderator: + name: "Moderator" + email: "moderator@moderator.com" + moderator: true diff --git a/test/integration/forum_test.rb b/test/integration/forum_test.rb index 882dabf..7ccf989 100644 --- a/test/integration/forum_test.rb +++ b/test/integration/forum_test.rb @@ -6,27 +6,34 @@ class ForumTest < ActionDispatch::IntegrationTest include SimpleDiscussion::Engine.routes.url_helpers setup do - sign_in users(:one) + @regular_user = users(:one) + @moderator_user = users(:moderator) + @forum_thread = forum_threads(:hello) + @forum_post = forum_posts(:hello) @filter = LanguageFilter::Filter.new end test "threads index" do + sign_in @regular_user get "/" assert_response :success assert_match "Community", response.body end test "categories" do + sign_in @regular_user get forum_category_forum_threads_path(forum_categories(:general)) assert_response :success end test "show forum thread" do - get forum_thread_path(forum_threads(:hello)) + sign_in @regular_user + get forum_thread_path(@forum_thread) assert_response :success end test "create a forum thread" do + sign_in @regular_user assert_difference "ForumThread.count" do assert_difference "ForumPost.count" do post forum_threads_path, params: { @@ -45,8 +52,9 @@ class ForumTest < ActionDispatch::IntegrationTest end test "reply to a forum thread" do + sign_in @regular_user assert_difference "ForumPost.count" do - post forum_thread_forum_posts_path(forum_threads(:hello)), params: { + post forum_thread_forum_posts_path(@forum_thread), params: { forum_post: { body: "Reply" } @@ -57,6 +65,7 @@ class ForumTest < ActionDispatch::IntegrationTest end test "cannot create a forum thread with inappropriate language in title" do + sign_in @regular_user inappropriate_word = @filter.matchlist.to_a.sample assert_no_difference "ForumThread.count" do assert_no_difference "ForumPost.count" do @@ -77,6 +86,8 @@ class ForumTest < ActionDispatch::IntegrationTest end test "cannot create a forum thread with inappropriate language in body" do + sign_in @regular_user + inappropriate_word = @filter.matchlist.to_a.sample assert_no_difference "ForumThread.count" do assert_no_difference "ForumPost.count" do @@ -97,9 +108,11 @@ class ForumTest < ActionDispatch::IntegrationTest end test "cannot reply to a forum thread with inappropriate language" do + sign_in @regular_user + inappropriate_word = @filter.matchlist.to_a.sample assert_no_difference "ForumPost.count" do - post forum_thread_forum_posts_path(forum_threads(:hello)), params: { + post forum_thread_forum_posts_path(@forum_thread), params: { forum_post: { body: "contains inappropriate language: #{inappropriate_word}" } @@ -111,6 +124,8 @@ class ForumTest < ActionDispatch::IntegrationTest end test "can create a forum thread with appropriate language in title and body" do + sign_in @regular_user + assert_difference "ForumThread.count" do assert_difference "ForumPost.count" do post forum_threads_path, params: { @@ -127,4 +142,52 @@ class ForumTest < ActionDispatch::IntegrationTest assert_redirected_to forum_thread_path(ForumThread.last) end + + test "can report a post" do + sign_in @regular_user + + assert_difference "SpamReport.count" do + post report_post_forum_thread_forum_post_path(@forum_thread, @forum_post), params: { + reason: "irrelevant_content" + } + end + assert_redirected_to forum_thread_path(@forum_thread, anchor: dom_id(@forum_post)) + + spam_report = SpamReport.last + assert_equal @forum_post, spam_report.forum_post + assert_equal @regular_user, spam_report.user + assert_equal "irrelevant_content", spam_report.reason + end + + test "can report a post with 'other' reason and details" do + sign_in @regular_user + + assert_difference "SpamReport.count" do + post report_post_forum_thread_forum_post_path(@forum_thread, @forum_post), params: { + reason: "others", + details: "This post contains copyrighted material." + } + end + + assert_redirected_to forum_thread_path(@forum_thread, anchor: dom_id(@forum_post)) + + spam_report = SpamReport.last + assert_equal "others", spam_report.reason + assert_equal "This post contains copyrighted material.", spam_report.details + end + + test "modeartor can view spam reports page" do + sign_in @moderator_user + + get spam_reports_forum_threads_path + assert_response :success + end + + test "regular user can't view spam reports page" do + sign_in @regular_user + + get spam_reports_forum_threads_path + assert_response :redirect + assert_redirected_to root_path + end end