Merge branch 'danbooru:master' into master
This commit is contained in:
@@ -43,18 +43,20 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if policy(forum_post).destroy? && !forum_post.is_original_post?(original_forum_post_id) %>
|
||||
<% menu.item do %>
|
||||
<% if forum_post.is_deleted? %>
|
||||
<%= link_to undelete_forum_post_path(forum_post.id), method: :post, remote: true do %>
|
||||
<%= undelete_icon %> Undelete
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= link_to forum_post_path(forum_post.id), "data-confirm": "Are you sure you want to delete this forum post?", method: :delete, remote: true do %>
|
||||
<%= delete_icon %> Delete
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if forum_post.is_deleted? && policy(forum_post).undelete? && !forum_post.is_original_post?(original_forum_post_id) %>
|
||||
<% menu.item do %>
|
||||
<%= link_to undelete_forum_post_path(forum_post.id), method: :post, remote: true do %>
|
||||
<%= undelete_icon %> Undelete
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if !forum_post.is_deleted? && policy(forum_post).destroy? && !forum_post.is_original_post?(original_forum_post_id) %>
|
||||
<% menu.item do %>
|
||||
<%= link_to forum_post_path(forum_post.id), "data-confirm": "Are you sure you want to delete this forum post?", method: :delete, remote: true do %>
|
||||
<%= delete_icon %> Delete
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -55,12 +55,16 @@ class ForumPostsController < ApplicationController
|
||||
def destroy
|
||||
@forum_post = authorize ForumPost.find(params[:id])
|
||||
@forum_post.delete!
|
||||
|
||||
flash[:notice] = @forum_post.errors.none? ? "Post deleted" : @forum_post.errors.full_messages.join("; ")
|
||||
respond_with(@forum_post)
|
||||
end
|
||||
|
||||
def undelete
|
||||
@forum_post = authorize ForumPost.find(params[:id])
|
||||
@forum_post.undelete!
|
||||
|
||||
flash[:notice] = @forum_post.errors.none? ? "Post undeleted" : @forum_post.errors.full_messages.join("; ")
|
||||
respond_with(@forum_post)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,15 +30,6 @@ class WikiPagesController < ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
if params[:format].present?
|
||||
request.format = params[:format]
|
||||
elsif params[:id].ends_with?(".html", ".json", ".xml")
|
||||
request.format = params[:id].split(".").last
|
||||
params[:id].delete_suffix!(".#{request.format.symbol}")
|
||||
else
|
||||
request.format = "html"
|
||||
end
|
||||
|
||||
@wiki_page, found_by = WikiPage.find_by_id_or_title(params[:id])
|
||||
|
||||
if request.format.html? && @wiki_page.blank? && found_by == :title
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
html {
|
||||
// Disable font boosting on mobile. By default, when desktop mode is enabled
|
||||
// on mobile, mobile browsers will automagically increase the size of text.
|
||||
// Usually they do so poorly, making things like headers smaller than body
|
||||
// text, which breaks the layout.
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, blockquote, dl, dd, menu {
|
||||
body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, blockquote, dl, dd, menu, input {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ fieldset {
|
||||
img {
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
image-rendering: smooth;
|
||||
}
|
||||
|
||||
input, select, textarea {
|
||||
|
||||
@@ -83,6 +83,11 @@ form.simple_form {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
// Hide "*" in label next to required fields.
|
||||
&.required abbr[title="required"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.radio_buttons {
|
||||
span.radio label {
|
||||
font-weight: normal;
|
||||
|
||||
@@ -15,13 +15,14 @@ class ForumPost < ApplicationRecord
|
||||
has_one :bulk_update_request
|
||||
|
||||
validates :body, presence: true, length: { maximum: 200_000 }, if: :body_changed?
|
||||
validate :validate_deletion_of_original_post
|
||||
validate :validate_undeletion_of_post
|
||||
|
||||
before_create :autoreport_spam
|
||||
before_save :handle_reports_on_deletion
|
||||
after_create :update_topic_updated_at_on_create
|
||||
after_update :update_topic_updated_at_on_update_for_original_posts
|
||||
after_destroy :update_topic_updated_at_on_destroy
|
||||
after_save :delete_topic_if_original_post
|
||||
after_update(:if => ->(rec) {rec.updater_id != rec.creator_id}) do |rec|
|
||||
ModAction.log("#{CurrentUser.user.name} updated forum ##{rec.id}", :forum_post_update)
|
||||
end
|
||||
@@ -83,6 +84,18 @@ class ForumPost < ApplicationRecord
|
||||
votes.exists?(creator_id: user.id, score: score)
|
||||
end
|
||||
|
||||
def validate_deletion_of_original_post
|
||||
if is_original_post? && is_deleted? && !topic.is_deleted?
|
||||
errors.add(:base, "Can't delete original post without deleting the topic first")
|
||||
end
|
||||
end
|
||||
|
||||
def validate_undeletion_of_post
|
||||
if topic.is_deleted? && !is_deleted?
|
||||
errors.add(:base, "Can't undelete post without undeleting the topic first")
|
||||
end
|
||||
end
|
||||
|
||||
def autoreport_spam
|
||||
if SpamDetector.new(self, user_ip: CurrentUser.ip_addr).spam?
|
||||
moderation_reports << ModerationReport.new(creator: User.system, reason: "Spam.")
|
||||
@@ -153,12 +166,6 @@ class ForumPost < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def delete_topic_if_original_post
|
||||
if is_deleted? && is_original_post?
|
||||
topic.update_attribute(:is_deleted, true)
|
||||
end
|
||||
end
|
||||
|
||||
def handle_reports_on_deletion
|
||||
return unless moderation_reports.pending.present? && is_deleted_change == [false, true]
|
||||
|
||||
|
||||
@@ -24,12 +24,13 @@ class ForumTopic < ApplicationRecord
|
||||
has_many :tag_implications
|
||||
|
||||
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?
|
||||
validates_associated :original_post
|
||||
validates :category_id, inclusion: { in: CATEGORIES.keys }
|
||||
validates :min_level, inclusion: { in: MIN_LEVELS.values }
|
||||
|
||||
accepts_nested_attributes_for :original_post
|
||||
after_update :update_orignal_post
|
||||
|
||||
after_update :update_posts_on_deletion_or_undeletion
|
||||
after_update :update_original_post
|
||||
after_save(:if => ->(rec) {rec.is_locked? && rec.saved_change_to_is_locked?}) do |rec|
|
||||
ModAction.log("locked forum topic ##{id} (title: #{title})", :forum_topic_lock)
|
||||
end
|
||||
@@ -179,7 +180,14 @@ class ForumTopic < ApplicationRecord
|
||||
(response_count / Danbooru.config.posts_per_page.to_f).ceil
|
||||
end
|
||||
|
||||
def update_orignal_post
|
||||
# Delete all posts when the topic is deleted. Undelete all posts when the topic is undeleted.
|
||||
def update_posts_on_deletion_or_undeletion
|
||||
if saved_change_to_is_deleted?
|
||||
forum_posts.update!(is_deleted: is_deleted) # XXX depends on current user
|
||||
end
|
||||
end
|
||||
|
||||
def update_original_post
|
||||
original_post&.update_columns(:updater_id => updater.id, :updated_at => Time.now)
|
||||
end
|
||||
|
||||
|
||||
6
app/models/upload_media_asset.rb
Normal file
6
app/models/upload_media_asset.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class UploadMediaAsset < ApplicationRecord
|
||||
belongs_to :upload
|
||||
belongs_to :media_asset
|
||||
end
|
||||
@@ -18,11 +18,11 @@ class ForumPostPolicy < ApplicationPolicy
|
||||
end
|
||||
|
||||
def destroy?
|
||||
unbanned? && show? && user.is_moderator?
|
||||
unbanned? && show? && !record.is_deleted? && user.is_moderator?
|
||||
end
|
||||
|
||||
def undelete?
|
||||
unbanned? && show? && user.is_moderator?
|
||||
unbanned? && show? && record.is_deleted? && !record.topic.is_deleted? && user.is_moderator?
|
||||
end
|
||||
|
||||
def reply?
|
||||
|
||||
@@ -1 +1 @@
|
||||
$("#forum_post_<%= @forum_post.id %>").replaceWith("<%= j render(ForumPostComponent.new(forum_post: @forum_post, current_user: CurrentUser.user)) %>");
|
||||
location.reload();
|
||||
|
||||
@@ -1 +1 @@
|
||||
$("#forum_post_<%= @forum_post.id %>").replaceWith("<%= j render(ForumPostComponent.new(forum_post: @forum_post, current_user: CurrentUser.user)) %>");
|
||||
location.reload();
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
<%= NewRelic::Agent.browser_timing_header rescue "" %>
|
||||
<meta charset="utf-8">
|
||||
<title><%= page_title %></title>
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="/favicon.ico" sizes="16x16" type="image/x-icon">
|
||||
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml">
|
||||
<link rel="top" title="<%= Danbooru.config.app_name %>" href="/">
|
||||
<%= csrf_meta_tag %>
|
||||
<%= raw Danbooru.config.custom_html_header_content %>
|
||||
<%= javascript_pack_tag "application" %>
|
||||
<%= javascript_pack_tag "application", defer: false %>
|
||||
<%= stylesheet_pack_tag "application" %>
|
||||
<%= yield :html_header %>
|
||||
</head>
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<meta charset="utf-8">
|
||||
<title><%= page_title %></title>
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="/favicon.ico" sizes="16x16" type="image/x-icon">
|
||||
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml">
|
||||
<%= render_meta_links @current_item if @current_item.respond_to?(:paginate) %>
|
||||
<%= tag.link rel: "canonical", href: canonical_url %>
|
||||
<%= tag.link rel: "search", type: "application/opensearchdescription+xml", href: opensearch_url(format: :xml, version: 2), title: "Search posts" %>
|
||||
@@ -22,9 +23,9 @@
|
||||
|
||||
<%# XXX hack to only load Ruffle on Flash posts %>
|
||||
<% if controller_name == "posts" && action_name == "show" && @post&.is_flash? %>
|
||||
<%= javascript_pack_tag "application", "flash" %>
|
||||
<%= javascript_pack_tag "application", "flash", defer: false %>
|
||||
<% else %>
|
||||
<%= javascript_pack_tag "application" %>
|
||||
<%= javascript_pack_tag "application", defer: false %>
|
||||
<% end %>
|
||||
|
||||
<%= stylesheet_pack_tag "application" %>
|
||||
|
||||
@@ -72,6 +72,7 @@ Allow: <%= privacy_policy_path %>
|
||||
Allow: <%= not_found_path %>
|
||||
Allow: /sitemap.xml
|
||||
Allow: /favicon.ico
|
||||
Allow: /favicon.svg
|
||||
|
||||
Sitemap: <%= sitemap_url(format: :xml, sitemap: "artists") %>
|
||||
Sitemap: <%= sitemap_url(format: :xml, sitemap: "forum_topics") %>
|
||||
|
||||
@@ -63,6 +63,23 @@ class String
|
||||
include Danbooru::Extensions::String
|
||||
end
|
||||
|
||||
module MimeNegotationExtension
|
||||
# Ignore all file extensions except for .html, .js, .json, and .xml when
|
||||
# parsing the file extension from the URL. Needed for wiki pages (e.g.
|
||||
# /wiki_pages/rnd.jpg).
|
||||
private def format_from_path_extension
|
||||
mime = super
|
||||
|
||||
if mime&.symbol.in?(%i[html js json xml])
|
||||
mime
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionDispatch::Http::MimeNegotiation.prepend(MimeNegotationExtension)
|
||||
|
||||
# Make Symbol#to_s return a frozen string. This reduces allocations, but may be
|
||||
# incompatible with some libraries.
|
||||
#
|
||||
|
||||
@@ -280,7 +280,7 @@ Rails.application.routes.draw do
|
||||
resources :webhooks do
|
||||
post :receive, on: :collection
|
||||
end
|
||||
resources :wiki_pages, id: /.+/, format: false do
|
||||
resources :wiki_pages, id: /.+?(?=\.json|\.xml|\.html)|.+/ do
|
||||
put :revert, on: :member
|
||||
get :search, on: :collection
|
||||
get :show_or_new, on: :collection
|
||||
|
||||
12
db/migrate/20220124195900_add_upload_media_assets.rb
Normal file
12
db/migrate/20220124195900_add_upload_media_assets.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class AddUploadMediaAssets < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :upload_media_assets do |t|
|
||||
t.timestamps null: false
|
||||
t.belongs_to :upload, null: false
|
||||
t.belongs_to :media_asset, null: false
|
||||
end
|
||||
|
||||
add_foreign_key :upload_media_assets, :uploads, deferrable: :deferred
|
||||
add_foreign_key :upload_media_assets, :media_assets, deferrable: :deferred
|
||||
end
|
||||
end
|
||||
@@ -1906,6 +1906,38 @@ CREATE SEQUENCE public.tags_id_seq
|
||||
ALTER SEQUENCE public.tags_id_seq OWNED BY public.tags.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.upload_media_assets (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL,
|
||||
upload_id bigint NOT NULL,
|
||||
media_asset_id bigint NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.upload_media_assets_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.upload_media_assets_id_seq OWNED BY public.upload_media_assets.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: uploads; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -2517,6 +2549,13 @@ ALTER TABLE ONLY public.tag_implications ALTER COLUMN id SET DEFAULT nextval('pu
|
||||
ALTER TABLE ONLY public.tags ALTER COLUMN id SET DEFAULT nextval('public.tags_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.upload_media_assets ALTER COLUMN id SET DEFAULT nextval('public.upload_media_assets_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: uploads id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -2964,6 +3003,14 @@ ALTER TABLE ONLY public.tags
|
||||
ADD CONSTRAINT tags_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets upload_media_assets_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.upload_media_assets
|
||||
ADD CONSTRAINT upload_media_assets_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: uploads uploads_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -4493,6 +4540,20 @@ CREATE INDEX index_tags_on_name_trgm ON public.tags USING gin (name public.gin_t
|
||||
CREATE INDEX index_tags_on_post_count ON public.tags USING btree (post_count);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_upload_media_assets_on_media_asset_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_upload_media_assets_on_media_asset_id ON public.upload_media_assets USING btree (media_asset_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_upload_media_assets_on_upload_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_upload_media_assets_on_upload_id ON public.upload_media_assets USING btree (upload_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_uploads_on_referer_url; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@@ -4806,6 +4867,14 @@ ALTER TABLE ONLY public.uploads
|
||||
ADD CONSTRAINT fk_rails_127111e6ac FOREIGN KEY (post_id) REFERENCES public.posts(id) DEFERRABLE INITIALLY DEFERRED NOT VALID;
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets fk_rails_171271f781; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.upload_media_assets
|
||||
ADD CONSTRAINT fk_rails_171271f781 FOREIGN KEY (upload_id) REFERENCES public.uploads(id) DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
-- Name: bulk_update_requests fk_rails_1773ada54d; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -5414,6 +5483,14 @@ ALTER TABLE ONLY public.post_votes
|
||||
ADD CONSTRAINT fk_rails_f3edc07390 FOREIGN KEY (user_id) REFERENCES public.users(id) DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
-- Name: upload_media_assets fk_rails_f6bce0ea3f; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.upload_media_assets
|
||||
ADD CONSTRAINT fk_rails_f6bce0ea3f FOREIGN KEY (media_asset_id) REFERENCES public.media_assets(id) DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
-- Name: user_upgrades fk_rails_f9349ed07b; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -5697,6 +5774,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20220110171022'),
|
||||
('20220110171023'),
|
||||
('20220110171024'),
|
||||
('20220120233850');
|
||||
('20220120233850'),
|
||||
('20220124195900');
|
||||
|
||||
|
||||
|
||||
14
public/favicon.svg
Normal file
14
public/favicon.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" height="16" width="16" version="1.1">
|
||||
<defs>
|
||||
<linearGradient id="bg" gradientTransform="rotate(85)">
|
||||
<stop offset="49%" stop-color="#ba9570" />
|
||||
<stop offset="67%" stop-color="#a4815f" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<path d="M 1.5,14.5 V 4.25 L 4.25,1.5 H 14.5 v 10.25 l -2.75,2.75 z" fill="url(#bg)" stroke="black" stroke-width="1" />
|
||||
<path d="m 1.5,4.5 h 10 v 10" stroke="black" stroke-width="1" fill="none" />
|
||||
<path d="m 14.5,1.5 -3,3" stroke="black" stroke-width="1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 606 B |
@@ -5,7 +5,8 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="10">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="/favicon.ico" sizes="16x16" type="image/x-icon">
|
||||
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml">
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
|
||||
17
script/fixes/095_delete_forum_posts_in_deleted_topics.rb
Executable file
17
script/fixes/095_delete_forum_posts_in_deleted_topics.rb
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative "base"
|
||||
|
||||
with_confirmation do
|
||||
CurrentUser.scoped(User.system) do
|
||||
# delete all posts in deleted topics
|
||||
ForumPost.undeleted.where(topic: ForumTopic.deleted).update_all(is_deleted: true, updated_at: Time.zone.now, updater_id: User.system.id)
|
||||
|
||||
# undelete all deleted OPs in active topics
|
||||
ForumPost.deleted.where(topic: ForumTopic.undeleted).find_each do |forum_post|
|
||||
if forum_post.is_original_post?
|
||||
forum_post.update_columns(is_deleted: false, updated_at: Time.zone.now, updater_id: User.system.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
14
script/fixes/096_delete_invalid_moderation_reports.rb
Executable file
14
script/fixes/096_delete_invalid_moderation_reports.rb
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative "base"
|
||||
|
||||
with_confirmation do
|
||||
CurrentUser.scoped(User.system) do
|
||||
ModerationReport.find_each do |report|
|
||||
if report.invalid? && report.errors[:model] == ["must exist"]
|
||||
puts "destroying modreport ##{report.id}"
|
||||
report.destroy!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -219,24 +219,36 @@ class ForumPostsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
context "destroy action" do
|
||||
should "allow mods to delete posts" do
|
||||
delete_auth forum_post_path(@forum_post), @mod
|
||||
assert_redirected_to(forum_post_path(@forum_post))
|
||||
assert_equal(true, @forum_post.reload.is_deleted?)
|
||||
@forum_reply = as(@user) { create(:forum_post, topic: @forum_topic, creator: @user) }
|
||||
delete_auth forum_post_path(@forum_reply), @mod
|
||||
|
||||
assert_redirected_to(@forum_reply)
|
||||
assert_equal(true, @forum_reply.reload.is_deleted?)
|
||||
end
|
||||
|
||||
should "not allow users to delete their own posts" do
|
||||
delete_auth forum_post_path(@forum_post), @user
|
||||
@forum_reply = as(@user) { create(:forum_post, topic: @forum_topic, creator: @user) }
|
||||
delete_auth forum_post_path(@forum_reply), @user
|
||||
|
||||
assert_response 403
|
||||
assert_equal(false, @forum_post.reload.is_deleted?)
|
||||
assert_equal(false, @forum_reply.reload.is_deleted?)
|
||||
end
|
||||
|
||||
should "not allow deleting the OP of an active topic" do
|
||||
delete_auth forum_post_path(@forum_topic.original_post), @mod
|
||||
|
||||
assert_redirected_to(@forum_topic.original_post)
|
||||
assert_equal(false, @forum_topic.original_post.is_deleted?)
|
||||
end
|
||||
|
||||
should "mark all pending moderation reports against the post as handled" do
|
||||
report1 = create(:moderation_report, model: @forum_post, status: :pending)
|
||||
report2 = create(:moderation_report, model: @forum_post, status: :rejected)
|
||||
delete_auth forum_post_path(@forum_post), @mod
|
||||
forum_reply = as(@user) { create(:forum_post, topic: @forum_topic, creator: @user) }
|
||||
report1 = create(:moderation_report, model: forum_reply, status: :pending)
|
||||
report2 = create(:moderation_report, model: forum_reply, status: :rejected)
|
||||
delete_auth forum_post_path(forum_reply), @mod
|
||||
|
||||
assert_redirected_to(forum_post_path(@forum_post))
|
||||
assert_equal(true, @forum_post.reload.is_deleted?)
|
||||
assert_redirected_to(forum_post_path(forum_reply))
|
||||
assert_equal(true, forum_reply.reload.is_deleted?)
|
||||
assert_equal(true, report1.reload.handled?)
|
||||
assert_equal(true, report2.reload.rejected?)
|
||||
assert_equal(1, ModAction.moderation_report_handled.where(creator: @mod).count)
|
||||
@@ -245,17 +257,30 @@ class ForumPostsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
context "undelete action" do
|
||||
should "allow mods to undelete posts" do
|
||||
as(@mod) { @forum_post.update!(is_deleted: true) }
|
||||
post_auth undelete_forum_post_path(@forum_post), @mod
|
||||
assert_redirected_to(forum_post_path(@forum_post))
|
||||
assert_equal(false, @forum_post.reload.is_deleted?)
|
||||
@forum_reply = as(@user) { create(:forum_post, topic: @forum_topic, creator: @user, is_deleted: true) }
|
||||
post_auth undelete_forum_post_path(@forum_reply), @mod
|
||||
|
||||
assert_redirected_to(@forum_reply)
|
||||
assert_equal(false, @forum_reply.reload.is_deleted?)
|
||||
end
|
||||
|
||||
should "not allow users to undelete their own posts" do
|
||||
as(@mod) { @forum_post.update!(is_deleted: true) }
|
||||
post_auth undelete_forum_post_path(@forum_post), @user
|
||||
@forum_reply = as(@user) { create(:forum_post, topic: @forum_topic, creator: @user, is_deleted: true) }
|
||||
post_auth undelete_forum_post_path(@forum_reply), @user
|
||||
|
||||
assert_response 403
|
||||
assert_equal(true, @forum_post.reload.is_deleted?)
|
||||
assert_equal(true, @forum_reply.reload.is_deleted?)
|
||||
end
|
||||
|
||||
should "not allow undeleting posts in deleted topics" do
|
||||
@forum_reply = as(@user) { create(:forum_post, topic: @forum_topic, creator: @user) }
|
||||
as(@user) { @forum_topic.update!(is_deleted: true) }
|
||||
assert_equal(true, @forum_reply.reload.is_deleted?)
|
||||
|
||||
post_auth undelete_forum_post_path(@forum_reply), @mod
|
||||
|
||||
assert_response 403
|
||||
assert_equal(true, @forum_reply.reload.is_deleted?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -306,11 +306,13 @@ class ForumTopicsControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
should "destroy the topic and any associated posts" do
|
||||
should "mark the topic and all posts as deleted" do
|
||||
delete_auth forum_topic_path(@forum_topic), @mod
|
||||
assert_redirected_to(forum_topic_path(@forum_topic))
|
||||
@forum_topic.reload
|
||||
assert(@forum_topic.is_deleted?)
|
||||
|
||||
assert_redirected_to(@forum_topic)
|
||||
assert_equal(true, @forum_topic.reload.is_deleted?)
|
||||
assert_equal(true, @forum_topic.original_post.is_deleted?)
|
||||
assert_equal(true, @forum_topic.forum_posts.all?(&:is_deleted?))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -321,11 +323,13 @@ class ForumTopicsControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
should "restore the topic" do
|
||||
should "mark the topic and all posts as undeleted" do
|
||||
post_auth undelete_forum_topic_path(@forum_topic), @mod
|
||||
assert_redirected_to(forum_topic_path(@forum_topic))
|
||||
@forum_topic.reload
|
||||
assert(!@forum_topic.is_deleted?)
|
||||
|
||||
assert_redirected_to(@forum_topic)
|
||||
assert_equal(false, @forum_topic.reload.is_deleted?)
|
||||
assert_equal(false, @forum_topic.original_post.is_deleted?)
|
||||
assert_equal(false, @forum_topic.forum_posts.all?(&:is_deleted?))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,6 +31,13 @@ class WikiPagesControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_equal(WikiPage.count, response.parsed_body.css("urlset url loc").size)
|
||||
end
|
||||
|
||||
should "render for a JSON response" do
|
||||
get wiki_pages_path(format: :json)
|
||||
|
||||
assert_response :success
|
||||
assert_equal("application/json", response.media_type)
|
||||
end
|
||||
|
||||
should "redirect the legacy title param to the show page" do
|
||||
get wiki_pages_path(title: "tagme")
|
||||
assert_redirected_to wiki_pages_path(search: { title_normalize: "tagme" }, redirect: true)
|
||||
|
||||
Reference in New Issue
Block a user