DEV: Move min_trust_to_post_embedded_media to group setting (#25238)

c.f. https://meta.discourse.org/t/we-are-changing-giving-access-to-features/283408
This commit is contained in:
Martin Brennan 2024-01-25 09:50:59 +10:00 committed by GitHub
parent cf25fab9b0
commit 0e50f88212
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 374 additions and 171 deletions

View File

@ -402,7 +402,7 @@ en:
too_many_mentions_newuser: too_many_mentions_newuser:
one: "Sorry, new users can only mention one other user in a post." one: "Sorry, new users can only mention one other user in a post."
other: "Sorry, new users can only mention %{count} users in a post." other: "Sorry, new users can only mention %{count} users in a post."
no_embedded_media_allowed_trust: "Sorry, you can't embed media items in a post." no_embedded_media_allowed_group: "Sorry, you can't embed media items in a post."
no_embedded_media_allowed: "Sorry, new users can't embed media items in posts." no_embedded_media_allowed: "Sorry, new users can't embed media items in posts."
too_many_embedded_media: too_many_embedded_media:
one: "Sorry, new users can only put one embedded media item in a post." one: "Sorry, new users can only put one embedded media item in a post."
@ -1986,6 +1986,7 @@ en:
min_trust_to_post_links: "The minimum trust level required to include links in posts" min_trust_to_post_links: "The minimum trust level required to include links in posts"
post_links_allowed_groups: "Groups that are allowed to include links in posts." post_links_allowed_groups: "Groups that are allowed to include links in posts."
min_trust_to_post_embedded_media: "The minimum trust level required to embed media items in a post" min_trust_to_post_embedded_media: "The minimum trust level required to embed media items in a post"
embedded_media_post_allowed_groups: "The users in these groups are allowed to embed media items in a post"
min_trust_level_to_allow_profile_background: "The minimum trust level required to upload a profile background" min_trust_level_to_allow_profile_background: "The minimum trust level required to upload a profile background"
min_trust_level_to_allow_user_card_background: "The minimum trust level required to upload a user card background" min_trust_level_to_allow_user_card_background: "The minimum trust level required to upload a user card background"
user_card_background_allowed_groups: "Groups that are allowed to upload a user card background." user_card_background_allowed_groups: "Groups that are allowed to upload a user card background."
@ -2590,6 +2591,7 @@ en:
create_tag_allowed_groups: "min_trust_to_create_tag" create_tag_allowed_groups: "min_trust_to_create_tag"
send_email_messages_allowed_groups: "min_trust_to_send_email_messages" send_email_messages_allowed_groups: "min_trust_to_send_email_messages"
skip_review_media_groups: "review_media_unless_trust_level" skip_review_media_groups: "review_media_unless_trust_level"
embedded_media_allowed_groups: "min_trust_to_post_embedded_media"
post_links_allowed_groups: "min_trust_to_post_links" post_links_allowed_groups: "min_trust_to_post_links"
user_api_key_allowed_groups: "min_trust_level_for_user_api_key" user_api_key_allowed_groups: "min_trust_level_for_user_api_key"

View File

@ -1767,6 +1767,13 @@ trust:
min_trust_to_post_embedded_media: min_trust_to_post_embedded_media:
default: 0 default: 0
enum: "TrustLevelSetting" enum: "TrustLevelSetting"
hidden: true
embedded_media_post_allowed_groups:
default: "10"
type: group_list
allow_any: false
refresh: true
validator: "AtLeastOneGroupValidator"
min_trust_level_to_allow_profile_background: min_trust_level_to_allow_profile_background:
default: 0 default: 0
client: true client: true

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
class FillEmbeddedMediaPostAllowedGroupsBasedOnDeprecatedSetting < ActiveRecord::Migration[7.0]
def up
old_setting_trust_level =
DB.query_single(
"SELECT value FROM site_settings WHERE name = 'min_trust_to_post_embedded_media' LIMIT 1",
).first
if old_setting_trust_level.present?
allowed_groups = "1#{old_setting_trust_level}"
DB.exec(
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
VALUES('embedded_media_post_allowed_groups', :setting, '20', NOW(), NOW())",
setting: allowed_groups,
)
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -37,6 +37,7 @@ module SiteSettings::DeprecatedSettings
["min_trust_to_create_tag", "create_tag_allowed_groups", false, "3.3"], ["min_trust_to_create_tag", "create_tag_allowed_groups", false, "3.3"],
["min_trust_to_send_email_messages", "send_email_messages_allowed_groups", false, "3.3"], ["min_trust_to_send_email_messages", "send_email_messages_allowed_groups", false, "3.3"],
["review_media_unless_trust_level", "skip_review_media_groups", false, "3.3"], ["review_media_unless_trust_level", "skip_review_media_groups", false, "3.3"],
["min_trust_to_post_embedded_media", "embedded_media_post_allowed_groups", false, "3.3"],
["min_trust_to_post_links", "post_links_allowed_groups", false, "3.3"], ["min_trust_to_post_links", "post_links_allowed_groups", false, "3.3"],
["min_trust_level_for_user_api_key", "user_api_key_allowed_groups", false, "3.3"], ["min_trust_level_for_user_api_key", "user_api_key_allowed_groups", false, "3.3"],
] ]
@ -60,6 +61,7 @@ module SiteSettings::DeprecatedSettings
min_trust_to_create_tag min_trust_to_create_tag
min_trust_to_send_email_messages min_trust_to_send_email_messages
review_media_unless_trust_level review_media_unless_trust_level
min_trust_to_post_embedded_media
min_trust_to_post_links min_trust_to_post_links
min_trust_level_for_user_api_key min_trust_level_for_user_api_key
] ]

View File

@ -96,11 +96,11 @@ class PostValidator < ActiveModel::Validator
def max_embedded_media_validator(post) def max_embedded_media_validator(post)
return if post.acting_user.blank? || post.acting_user&.staff? return if post.acting_user.blank? || post.acting_user&.staff?
if post.acting_user.trust_level < TrustLevel[SiteSetting.min_trust_to_post_embedded_media] if !post.acting_user.in_any_groups?(SiteSetting.embedded_media_post_allowed_groups_map)
add_error_if_count_exceeded( add_error_if_count_exceeded(
post, post,
:no_embedded_media_allowed_trust, :no_embedded_media_allowed_group,
:no_embedded_media_allowed_trust, :no_embedded_media_allowed_group,
post.embedded_media_count, post.embedded_media_count,
0, 0,
) )

View File

@ -80,7 +80,7 @@ module DiscourseNarrativeBot
# The prerequisites should ensure only one of them is called. # The prerequisites should ensure only one of them is called.
tutorial_images: { tutorial_images: {
prerequisite: prerequisite:
Proc.new { @user.has_trust_level?(SiteSetting.min_trust_to_post_embedded_media) }, Proc.new { @user.in_any_groups?(SiteSetting.embedded_media_post_allowed_groups_map) },
next_state: :tutorial_likes, next_state: :tutorial_likes,
next_instructions: next_instructions:
Proc.new { I18n.t("#{I18N_KEY}.likes.instructions", base_uri: Discourse.base_path) }, Proc.new { I18n.t("#{I18N_KEY}.likes.instructions", base_uri: Discourse.base_path) },
@ -93,7 +93,7 @@ module DiscourseNarrativeBot
}, },
tutorial_likes: { tutorial_likes: {
prerequisite: prerequisite:
Proc.new { !@user.has_trust_level?(SiteSetting.min_trust_to_post_embedded_media) }, Proc.new { !@user.in_any_groups?(SiteSetting.embedded_media_post_allowed_groups_map) },
next_state: :tutorial_flag, next_state: :tutorial_flag,
next_instructions: next_instructions:
Proc.new do Proc.new do

View File

@ -31,6 +31,7 @@ RSpec.describe DiscourseNarrativeBot::NewUserNarrative do
stub_image_size stub_image_size
Jobs.run_immediately! Jobs.run_immediately!
SiteSetting.discourse_narrative_bot_enabled = true SiteSetting.discourse_narrative_bot_enabled = true
Group.refresh_automatic_groups!
end end
describe "#notify_timeout" do describe "#notify_timeout" do
@ -828,8 +829,11 @@ RSpec.describe DiscourseNarrativeBot::NewUserNarrative do
end end
end end
describe "when min_trust_to_post_embedded_media is too high" do describe "when embedded_media_post_allowed_groups does not include the user" do
before { SiteSetting.min_trust_to_post_embedded_media = 4 } before do
SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
Group.refresh_automatic_groups!
end
it "should skip the images tutorial step" do it "should skip the images tutorial step" do
post.update!( post.update!(

View File

@ -16,6 +16,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
) )
end end
let(:upload_path) { Discourse.store.upload_path } let(:upload_path) { Discourse.store.upload_path }
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
before do before do
Jobs.run_immediately! Jobs.run_immediately!
@ -54,7 +55,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
before { Jobs.run_immediately! } before { Jobs.run_immediately! }
it "does nothing if topic has been deleted" do it "does nothing if topic has been deleted" do
post = Fabricate(:post, raw: "<img src='#{image_url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{image_url}'>")
post.topic.destroy! post.topic.destroy!
expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.not_to change { expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.not_to change {
@ -63,7 +64,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "does nothing if there are no large images to pull" do it "does nothing if there are no large images to pull" do
post = Fabricate(:post, raw: "bob bob") post = Fabricate(:post, user: user, raw: "bob bob")
orig = post.updated_at orig = post.updated_at
freeze_time 1.week.from_now freeze_time 1.week.from_now
@ -72,7 +73,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "replaces images" do it "replaces images" do
post = Fabricate(:post, raw: "<img src='#{image_url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{image_url}'>")
stub_image_size stub_image_size
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.to change { expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.to change {
@ -85,7 +86,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
it "enqueues raw replacement job with a delay" do it "enqueues raw replacement job with a delay" do
Jobs.run_later! Jobs.run_later!
post = Fabricate(:post, raw: "<img src='#{image_url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{image_url}'>")
stub_image_size stub_image_size
freeze_time freeze_time
@ -102,7 +103,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "removes downloaded images when they are no longer needed" do it "removes downloaded images when they are no longer needed" do
post = Fabricate(:post, raw: "<img src='#{image_url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{image_url}'>")
stub_image_size stub_image_size
post.rebake! post.rebake!
post.reload post.reload
@ -115,7 +116,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "replaces images again after edit" do it "replaces images again after edit" do
post = Fabricate(:post, raw: "<img src='#{image_url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{image_url}'>")
stub_image_size stub_image_size
expect do post.rebake! end.to change { Upload.count }.by(1) expect do post.rebake! end.to change { Upload.count }.by(1)
@ -131,7 +132,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "replaces encoded image urls" do it "replaces encoded image urls" do
post = Fabricate(:post, raw: "<img src='#{encoded_image_url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{encoded_image_url}'>")
stub_image_size stub_image_size
expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change { expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change {
Upload.count Upload.count
@ -150,7 +151,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
"http://test.localhost/uploads/short-url/z2QSs1KJWoj51uYhDjb6ifCzxH6.gif", "http://test.localhost/uploads/short-url/z2QSs1KJWoj51uYhDjb6ifCzxH6.gif",
).to_return(status: 200, body: "") ).to_return(status: 200, body: "")
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user, raw: <<~MD)
<h1></h1> <h1></h1>
<a href="https://somelink.com"> <a href="https://somelink.com">
<img alt="somelink" src="#{image_url}"> <img alt="somelink" src="#{image_url}">
@ -173,7 +174,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
it "replaces correct image URL" do it "replaces correct image URL" do
url = image_url.sub("/2e/Longcat1.png", "") url = image_url.sub("/2e/Longcat1.png", "")
post = Fabricate(:post, raw: "[Images](#{url})\n![](#{image_url})") post = Fabricate(:post, user: user, raw: "[Images](#{url})\n![](#{image_url})")
stub_image_size stub_image_size
expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change { expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change {
@ -184,7 +185,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "does not replace images in code blocks", skip: "Known issue" do it "does not replace images in code blocks", skip: "Known issue" do
post = Fabricate(:post, raw: <<~RAW) post = Fabricate(:post, user: user, raw: <<~RAW)
![realimage](#{image_url}) ![realimage](#{image_url})
`![codeblockimage](#{image_url})` `![codeblockimage](#{image_url})`
RAW RAW
@ -202,7 +203,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
it "replaces images without protocol" do it "replaces images without protocol" do
url = image_url.sub(/^https?\:/, "") url = image_url.sub(/^https?\:/, "")
post = Fabricate(:post, raw: "<img alt='test' src='#{url}'>") post = Fabricate(:post, user: user, raw: "<img alt='test' src='#{url}'>")
stub_image_size stub_image_size
expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change { expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change {
@ -215,7 +216,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
it "replaces images without extension" do it "replaces images without extension" do
url = image_url.sub(/\.[a-zA-Z0-9]+$/, "") url = image_url.sub(/\.[a-zA-Z0-9]+$/, "")
stub_request(:get, url).to_return(body: png, headers: { "Content-Type" => "image/png" }) stub_request(:get, url).to_return(body: png, headers: { "Content-Type" => "image/png" })
post = Fabricate(:post, raw: "<img src='#{url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{url}'>")
stub_image_size stub_image_size
expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change { expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change {
@ -231,7 +232,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
stub_request(:get, url).to_return(status: 200, body: file_from_fixtures("smallest.png")) stub_request(:get, url).to_return(status: 200, body: file_from_fixtures("smallest.png"))
post = Fabricate(:post, raw: "<img src='#{url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{url}'>")
stub_image_size stub_image_size
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.to change { expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.to change {
@ -247,7 +248,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
it "skips editing raw for raw_html posts" do it "skips editing raw for raw_html posts" do
raw = "<img src=\"#{image_url}\">" raw = "<img src=\"#{image_url}\">"
post = Fabricate(:post, raw: raw, cook_method: Post.cook_methods[:raw_html]) post = Fabricate(:post, user: user, raw: raw, cook_method: Post.cook_methods[:raw_html])
stub_image_size stub_image_size
expect do expect do
post.rebake! post.rebake!
@ -266,7 +267,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
stub_s3(upload) stub_s3(upload)
url = Upload.secure_uploads_url_from_upload_url(upload.url) url = Upload.secure_uploads_url_from_upload_url(upload.url)
url = Discourse.base_url + url url = Discourse.base_url + url
post = Fabricate(:post, raw: "<img src='#{url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{url}'>")
upload.update(access_control_post: post) upload.update(access_control_post: post)
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.not_to change { expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.not_to change {
Upload.count Upload.count
@ -283,7 +284,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url) Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url)
url = Upload.secure_uploads_url_from_upload_url(upload.url) url = Upload.secure_uploads_url_from_upload_url(upload.url)
url = Discourse.base_url + url url = Discourse.base_url + url
post = Fabricate(:post, raw: "<img src='#{url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{url}'>")
upload.update(access_control_post: post) upload.update(access_control_post: post)
FileStore::S3Store.any_instance.stubs(:store_upload).returns(upload.url) FileStore::S3Store.any_instance.stubs(:store_upload).returns(upload.url)
@ -305,7 +306,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url) Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url)
url = Upload.secure_uploads_url_from_upload_url(upload.url) url = Upload.secure_uploads_url_from_upload_url(upload.url)
url = Discourse.base_url + url url = Discourse.base_url + url
post = Fabricate(:post, raw: "<img src='#{url}'>") post = Fabricate(:post, user: user, raw: "<img src='#{url}'>")
upload.update(access_control_post: Fabricate(:post)) upload.update(access_control_post: Fabricate(:post))
FileStore::S3Store.any_instance.stubs(:store_upload).returns(upload.url) FileStore::S3Store.any_instance.stubs(:store_upload).returns(upload.url)
@ -321,7 +322,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "replaces markdown image" do it "replaces markdown image" do
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user, raw: <<~MD)
[![some test](#{image_url})](https://somelink.com) [![some test](#{image_url})](https://somelink.com)
![some test](#{image_url}) ![some test](#{image_url})
![](#{image_url}) ![](#{image_url})
@ -346,7 +347,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "works when invalid url in post" do it "works when invalid url in post" do
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user, raw: <<~MD)
![some test](#{image_url}) ![some test](#{image_url})
![some test 2]("#{image_url}) ![some test 2]("#{image_url})
MD MD
@ -358,7 +359,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "replaces bbcode images" do it "replaces bbcode images" do
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user, raw: <<~MD)
[img] [img]
#{image_url} #{image_url}
[/img] [/img]
@ -414,7 +415,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "replaces image src" do it "replaces image src" do
post = Fabricate(:post, raw: "#{url}") post = Fabricate(:post, user: user, raw: "#{url}")
stub_image_size stub_image_size
post.rebake! post.rebake!
@ -425,7 +426,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "associates uploads correctly" do it "associates uploads correctly" do
post = Fabricate(:post, raw: "#{url}") post = Fabricate(:post, user: user, raw: "#{url}")
stub_image_size stub_image_size
post.rebake! post.rebake!
post.reload post.reload
@ -440,7 +441,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "all combinations" do it "all combinations" do
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user, raw: <<~MD)
<img src='#{image_url}'> <img src='#{image_url}'>
#{url} #{url}
<img src='#{broken_image_url}'> <img src='#{broken_image_url}'>
@ -468,7 +469,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
it "rewrites a lone onebox" do it "rewrites a lone onebox" do
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user, raw: <<~MD)
Onebox here: Onebox here:
#{image_url} #{image_url}
MD MD
@ -637,7 +638,7 @@ RSpec.describe Jobs::PullHotlinkedImages do
end end
describe "#disable_if_low_on_disk_space" do describe "#disable_if_low_on_disk_space" do
fab!(:post) { Fabricate(:post, created_at: 20.days.ago) } fab!(:post) { Fabricate(:post, user: user, created_at: 20.days.ago) }
let(:job) { Jobs::PullHotlinkedImages.new } let(:job) { Jobs::PullHotlinkedImages.new }
before do before do

View File

@ -133,7 +133,10 @@ RSpec.describe Jobs::UserEmail do
data: { original_post_id: post.id }.to_json, data: { original_post_id: post.id }.to_json,
) )
end end
before { user.update_column(:last_seen_at, 9.minutes.ago) } before do
user.update_column(:last_seen_at, 9.minutes.ago)
Group.refresh_automatic_groups!
end
it "doesn't send an email to a user that's been recently seen" do it "doesn't send an email to a user that's been recently seen" do
Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id) Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id)

View File

@ -153,7 +153,12 @@ RSpec.describe BackupRestore::UploadsRestorer do
Fabricate(:optimized_image) Fabricate(:optimized_image)
upload = Fabricate(:upload_s3) upload = Fabricate(:upload_s3)
post = Fabricate(:post, raw: "![#{upload.original_filename}](#{upload.short_url})") post =
Fabricate(
:post,
raw: "![#{upload.original_filename}](#{upload.short_url})",
user: Fabricate(:user, refresh_auto_groups: true),
)
post.link_post_uploads post.link_post_uploads
FileHelper.stubs(:download).returns(file_from_fixtures("logo.png")) FileHelper.stubs(:download).returns(file_from_fixtures("logo.png"))

View File

@ -6,10 +6,11 @@ require "file_store/s3_store"
RSpec.describe CookedPostProcessor do RSpec.describe CookedPostProcessor do
fab!(:upload) fab!(:upload)
fab!(:large_image_upload) fab!(:large_image_upload)
fab!(:user_with_auto_groups) { Fabricate(:user, refresh_auto_groups: true) }
let(:upload_path) { Discourse.store.upload_path } let(:upload_path) { Discourse.store.upload_path }
describe "#post_process" do describe "#post_process" do
fab!(:post) { Fabricate(:post, raw: <<~RAW) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~RAW) }
<img src="#{upload.url}"> <img src="#{upload.url}">
RAW RAW
@ -34,7 +35,7 @@ RSpec.describe CookedPostProcessor do
let(:title) { "some title" } let(:title) { "some title" }
let(:post) { Fabricate(:post, raw: <<~RAW) } let(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~RAW) }
#{url} #{url}
This is a #{url} with path This is a #{url} with path
@ -126,7 +127,7 @@ RSpec.describe CookedPostProcessor do
describe "internal links" do describe "internal links" do
fab!(:topic) fab!(:topic)
fab!(:post) { Fabricate(:post, raw: "Hello #{topic.url}") } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: "Hello #{topic.url}") }
let(:url) { topic.url } let(:url) { topic.url }
it "includes the topic title" do it "includes the topic title" do
@ -174,7 +175,7 @@ RSpec.describe CookedPostProcessor do
let(:title) { "<b>some title</b>" } let(:title) { "<b>some title</b>" }
let(:escaped_title) { CGI.escapeHTML(title) } let(:escaped_title) { CGI.escapeHTML(title) }
let(:post) { Fabricate(:post, raw: <<~RAW) } let(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~RAW) }
This is a #{url_with_path} topic This is a #{url_with_path} topic
This should not be inline #{url_no_path} oneboxed This should not be inline #{url_no_path} oneboxed
@ -259,7 +260,8 @@ RSpec.describe CookedPostProcessor do
it "includes responsive images on demand" do it "includes responsive images on demand" do
upload.update!(width: 2000, height: 1500, filesize: 10_000, dominant_color: "FFFFFF") upload.update!(width: 2000, height: 1500, filesize: 10_000, dominant_color: "FFFFFF")
post = Fabricate(:post, raw: "hello <img src='#{upload.url}'>") post =
Fabricate(:post, user: user_with_auto_groups, raw: "hello <img src='#{upload.url}'>")
# fake some optimized images # fake some optimized images
OptimizedImage.create!( OptimizedImage.create!(
@ -316,7 +318,8 @@ RSpec.describe CookedPostProcessor do
it "doesn't include response images for cropped images" do it "doesn't include response images for cropped images" do
upload.update!(width: 200, height: 4000, filesize: 12_345) upload.update!(width: 200, height: 4000, filesize: 12_345)
post = Fabricate(:post, raw: "hello <img src='#{upload.url}'>") post =
Fabricate(:post, user: user_with_auto_groups, raw: "hello <img src='#{upload.url}'>")
# fake some optimized images # fake some optimized images
OptimizedImage.create!( OptimizedImage.create!(
@ -346,7 +349,7 @@ RSpec.describe CookedPostProcessor do
end end
context "with image_sizes" do context "with image_sizes" do
fab!(:post) { Fabricate(:post_with_image_urls) } fab!(:post) { Fabricate(:post_with_image_urls, user: user_with_auto_groups) }
let(:cpp) { CookedPostProcessor.new(post, image_sizes: image_sizes) } let(:cpp) { CookedPostProcessor.new(post, image_sizes: image_sizes) }
before do before do
@ -387,7 +390,7 @@ RSpec.describe CookedPostProcessor do
context "with unsized images" do context "with unsized images" do
fab!(:upload) { Fabricate(:image_upload, width: 123, height: 456) } fab!(:upload) { Fabricate(:image_upload, width: 123, height: 456) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}"> <img src="#{upload.url}">
HTML HTML
@ -403,7 +406,7 @@ RSpec.describe CookedPostProcessor do
context "with large images" do context "with large images" do
fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) } fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}"> <img src="#{upload.url}">
HTML HTML
@ -426,7 +429,7 @@ RSpec.describe CookedPostProcessor do
context "when image is inside onebox" do context "when image is inside onebox" do
let(:url) { "https://image.com/my-avatar" } let(:url) { "https://image.com/my-avatar" }
let(:post) { Fabricate(:post, raw: url) } let(:post) { Fabricate(:post, user: user_with_auto_groups, raw: url) }
before do before do
Oneboxer Oneboxer
@ -452,6 +455,7 @@ RSpec.describe CookedPostProcessor do
fab!(:post) do fab!(:post) do
Fabricate( Fabricate(
:post, :post,
user: user_with_auto_groups,
raw: "<img src=\"/#{Discourse.store.upload_path}/original/1X/1234567890123456.svg\">", raw: "<img src=\"/#{Discourse.store.upload_path}/original/1X/1234567890123456.svg\">",
) )
end end
@ -470,6 +474,7 @@ RSpec.describe CookedPostProcessor do
let(:post) do let(:post) do
Fabricate( Fabricate(
:post, :post,
user: user_with_auto_groups,
raw: raw:
"<img src=\"http://test.discourse/#{upload_path}/original/1X/1234567890123456.svg?somepamas\">", "<img src=\"http://test.discourse/#{upload_path}/original/1X/1234567890123456.svg?somepamas\">",
) )
@ -507,7 +512,11 @@ RSpec.describe CookedPostProcessor do
let(:optimized_size) { "600x500" } let(:optimized_size) { "600x500" }
let(:post) do let(:post) do
Fabricate(:post, raw: "![large.png|#{optimized_size}](#{upload.short_url})") Fabricate(
:post,
user: user_with_auto_groups,
raw: "![large.png|#{optimized_size}](#{upload.short_url})",
)
end end
let(:cooked_html) { <<~HTML } let(:cooked_html) { <<~HTML }
@ -575,7 +584,10 @@ RSpec.describe CookedPostProcessor do
context "when the upload is attached to a different post" do context "when the upload is attached to a different post" do
before do before do
FastImage.size(upload.url) FastImage.size(upload.url)
upload.update(secure: true, access_control_post: Fabricate(:post)) upload.update(
secure: true,
access_control_post: Fabricate(:post, user: user_with_auto_groups),
)
end end
it "does not create thumbnails or optimize images" do it "does not create thumbnails or optimize images" do
@ -593,7 +605,7 @@ RSpec.describe CookedPostProcessor do
context "with tall images > default aspect ratio" do context "with tall images > default aspect ratio" do
fab!(:upload) { Fabricate(:image_upload, width: 500, height: 2200) } fab!(:upload) { Fabricate(:image_upload, width: 500, height: 2200) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}"> <img src="#{upload.url}">
HTML HTML
@ -612,7 +624,7 @@ RSpec.describe CookedPostProcessor do
context "with taller images < default aspect ratio" do context "with taller images < default aspect ratio" do
fab!(:upload) { Fabricate(:image_upload, width: 500, height: 2300) } fab!(:upload) { Fabricate(:image_upload, width: 500, height: 2300) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}"> <img src="#{upload.url}">
HTML HTML
@ -631,7 +643,7 @@ RSpec.describe CookedPostProcessor do
context "with iPhone X screenshots" do context "with iPhone X screenshots" do
fab!(:upload) { Fabricate(:image_upload, width: 1125, height: 2436) } fab!(:upload) { Fabricate(:image_upload, width: 1125, height: 2436) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}"> <img src="#{upload.url}">
HTML HTML
@ -653,7 +665,7 @@ RSpec.describe CookedPostProcessor do
context "with large images when using subfolders" do context "with large images when using subfolders" do
fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) } fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="/subfolder#{upload.url}"> <img src="/subfolder#{upload.url}">
HTML HTML
@ -693,7 +705,7 @@ RSpec.describe CookedPostProcessor do
context "with title and alt" do context "with title and alt" do
fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) } fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}" title="WAT" alt="RED"> <img src="#{upload.url}" title="WAT" alt="RED">
HTML HTML
@ -718,7 +730,7 @@ RSpec.describe CookedPostProcessor do
context "with title only" do context "with title only" do
fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) } fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}" title="WAT"> <img src="#{upload.url}" title="WAT">
HTML HTML
@ -743,7 +755,7 @@ RSpec.describe CookedPostProcessor do
context "with alt only" do context "with alt only" do
fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) } fab!(:upload) { Fabricate(:image_upload, width: 1750, height: 2000) }
fab!(:post) { Fabricate(:post, raw: <<~HTML) } fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~HTML) }
<img src="#{upload.url}" alt="RED"> <img src="#{upload.url}" alt="RED">
HTML HTML
@ -766,7 +778,7 @@ RSpec.describe CookedPostProcessor do
end end
context "with topic image" do context "with topic image" do
fab!(:post) { Fabricate(:post_with_uploaded_image) } fab!(:post) { Fabricate(:post_with_uploaded_image, user: user_with_auto_groups) }
let(:cpp) { CookedPostProcessor.new(post) } let(:cpp) { CookedPostProcessor.new(post) }
it "adds a topic image if there's one in the first post" do it "adds a topic image if there's one in the first post" do
@ -801,7 +813,13 @@ RSpec.describe CookedPostProcessor do
expect(topic.image_upload_id).to be_present expect(topic.image_upload_id).to be_present
expect(post.image_upload_id).to be_present expect(post.image_upload_id).to be_present
post = Fabricate(:post, topic: topic, raw: "this post doesn't have an image") post =
Fabricate(
:post,
user: user_with_auto_groups,
topic: topic,
raw: "this post doesn't have an image",
)
CookedPostProcessor.new(post).post_process CookedPostProcessor.new(post).post_process
topic.reload topic.reload
@ -813,7 +831,7 @@ RSpec.describe CookedPostProcessor do
it "prioritizes data-thumbnail images" do it "prioritizes data-thumbnail images" do
upload1 = Fabricate(:image_upload, width: 1750, height: 2000) upload1 = Fabricate(:image_upload, width: 1750, height: 2000)
upload2 = Fabricate(:image_upload, width: 1750, height: 2000) upload2 = Fabricate(:image_upload, width: 1750, height: 2000)
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user_with_auto_groups, raw: <<~MD)
![alttext|1750x2000](#{upload1.url}) ![alttext|1750x2000](#{upload1.url})
![alttext|1750x2000|thumbnail](#{upload2.url}) ![alttext|1750x2000|thumbnail](#{upload2.url})
MD MD
@ -824,7 +842,9 @@ RSpec.describe CookedPostProcessor do
end end
context "with post image" do context "with post image" do
let(:reply) { Fabricate(:post_with_uploaded_image, post_number: 2) } let(:reply) do
Fabricate(:post_with_uploaded_image, user: user_with_auto_groups, post_number: 2)
end
let(:cpp) { CookedPostProcessor.new(reply) } let(:cpp) { CookedPostProcessor.new(reply) }
it "adds a post image if there's one in the post" do it "adds a post image if there's one in the post" do
@ -963,7 +983,12 @@ RSpec.describe CookedPostProcessor do
fab!(:thumbnail) { Fabricate(:optimized_image, upload: upload, width: 512, height: 384) } fab!(:thumbnail) { Fabricate(:optimized_image, upload: upload, width: 512, height: 384) }
it "adds lightbox and optimizes images" do it "adds lightbox and optimizes images" do
post = Fabricate(:post, raw: "![image|1024x768, 50%](#{large_image_upload.short_url})") post =
Fabricate(
:post,
user: user_with_auto_groups,
raw: "![image|1024x768, 50%](#{large_image_upload.short_url})",
)
cpp = CookedPostProcessor.new(post, disable_dominant_color: true) cpp = CookedPostProcessor.new(post, disable_dominant_color: true)
cpp.post_process cpp.post_process
@ -978,7 +1003,12 @@ RSpec.describe CookedPostProcessor do
# skips lightboxing # skips lightboxing
# adds "animated" class to element # adds "animated" class to element
upload.update!(animated: true) upload.update!(animated: true)
post = Fabricate(:post, raw: "![image|1024x768, 50%](#{upload.short_url})") post =
Fabricate(
:post,
user: user_with_auto_groups,
raw: "![image|1024x768, 50%](#{upload.short_url})",
)
cpp = CookedPostProcessor.new(post, disable_dominant_color: true) cpp = CookedPostProcessor.new(post, disable_dominant_color: true)
cpp.post_process cpp.post_process
@ -1008,6 +1038,7 @@ RSpec.describe CookedPostProcessor do
post = post =
Fabricate( Fabricate(
:post, :post,
user: user_with_auto_groups,
raw: "![tennis-gif|311x280](https://media2.giphy.com/media/7Oifk90VrCdNe/giphy.webp)", raw: "![tennis-gif|311x280](https://media2.giphy.com/media/7Oifk90VrCdNe/giphy.webp)",
) )
cpp = CookedPostProcessor.new(post, disable_dominant_color: true) cpp = CookedPostProcessor.new(post, disable_dominant_color: true)
@ -1021,6 +1052,7 @@ RSpec.describe CookedPostProcessor do
post = post =
Fabricate( Fabricate(
:post, :post,
user: user_with_auto_groups,
raw: raw:
"![cat](https://media1.tenor.com/images/20c7ddd5e84c7427954f430439c5209d/tenor.gif)", "![cat](https://media1.tenor.com/images/20c7ddd5e84c7427954f430439c5209d/tenor.gif)",
) )
@ -1033,7 +1065,7 @@ RSpec.describe CookedPostProcessor do
end end
it "optimizes and wraps images in quotes with lightbox wrapper" do it "optimizes and wraps images in quotes with lightbox wrapper" do
post = Fabricate(:post, raw: <<~MD) post = Fabricate(:post, user: user_with_auto_groups, raw: <<~MD)
[quote] [quote]
![image|1024x768, 50%](#{large_image_upload.short_url}) ![image|1024x768, 50%](#{large_image_upload.short_url})
[/quote] [/quote]
@ -1055,7 +1087,7 @@ RSpec.describe CookedPostProcessor do
"<aside class='onebox'><img src='#{large_image_upload.url}' width='512' height='384'></aside>", "<aside class='onebox'><img src='#{large_image_upload.url}' width='512' height='384'></aside>",
) )
post = Fabricate(:post, raw: "https://discourse.org") post = Fabricate(:post, user: user_with_auto_groups, raw: "https://discourse.org")
cpp = CookedPostProcessor.new(post, disable_dominant_color: true) cpp = CookedPostProcessor.new(post, disable_dominant_color: true)
cpp.post_process cpp.post_process
@ -1101,7 +1133,7 @@ RSpec.describe CookedPostProcessor do
.with(url, anything) .with(url, anything)
.returns("<img class='onebox' src='#{image_url}' />") .returns("<img class='onebox' src='#{image_url}' />")
post = Fabricate(:post, raw: url) post = Fabricate(:post, user: user_with_auto_groups, raw: url)
upload.update!(url: "https://test.s3.amazonaws.com/something.png", dominant_color: "00ffff") upload.update!(url: "https://test.s3.amazonaws.com/something.png", dominant_color: "00ffff")
PostHotlinkedMedia.create!( PostHotlinkedMedia.create!(
@ -1145,7 +1177,7 @@ RSpec.describe CookedPostProcessor do
.with(url, anything) .with(url, anything)
.returns("<img class='onebox' src='#{image_url}' />") .returns("<img class='onebox' src='#{image_url}' />")
post = Fabricate(:post, raw: url) post = Fabricate(:post, user: user_with_auto_groups, raw: url)
upload.update!( upload.update!(
url: "https://test.s3.amazonaws.com/something.png", url: "https://test.s3.amazonaws.com/something.png",
dominant_color: "00ffff", dominant_color: "00ffff",
@ -1182,7 +1214,7 @@ RSpec.describe CookedPostProcessor do
</a> </a>
HTML HTML
post = Fabricate(:post, raw: url) post = Fabricate(:post, user: user_with_auto_groups, raw: url)
PostHotlinkedMedia.create!(url: "//image.com/avatar.png", post: post, status: "too_large") PostHotlinkedMedia.create!(url: "//image.com/avatar.png", post: post, status: "too_large")
@ -1212,7 +1244,7 @@ RSpec.describe CookedPostProcessor do
</aside> </aside>
HTML HTML
post = Fabricate(:post, raw: url) post = Fabricate(:post, user: user_with_auto_groups, raw: url)
PostHotlinkedMedia.create!(url: "//example.com/favicon.ico", post: post, status: "too_large") PostHotlinkedMedia.create!(url: "//example.com/favicon.ico", post: post, status: "too_large")
PostHotlinkedMedia.create!(url: "//example.com/article.jpeg", post: post, status: "too_large") PostHotlinkedMedia.create!(url: "//example.com/article.jpeg", post: post, status: "too_large")
@ -1242,7 +1274,7 @@ RSpec.describe CookedPostProcessor do
.with(url, anything) .with(url, anything)
.returns("<img class='onebox' src='#{image_url}' />") .returns("<img class='onebox' src='#{image_url}' />")
post = Fabricate(:post, raw: url) post = Fabricate(:post, user: user_with_auto_groups, raw: url)
PostHotlinkedMedia.create!( PostHotlinkedMedia.create!(
url: "//image.com/avatar.png", url: "//image.com/avatar.png",
@ -1274,7 +1306,7 @@ RSpec.describe CookedPostProcessor do
</aside> </aside>
HTML HTML
post = Fabricate(:post, raw: url) post = Fabricate(:post, user: user_with_auto_groups, raw: url)
PostHotlinkedMedia.create!( PostHotlinkedMedia.create!(
url: "//example.com/favicon.ico", url: "//example.com/favicon.ico",
@ -1537,6 +1569,7 @@ RSpec.describe CookedPostProcessor do
the_post = the_post =
Fabricate( Fabricate(
:post, :post,
user: user_with_auto_groups,
raw: raw:
%Q{This post has a local emoji :+1: and an external upload\n\n![smallest.png|10x20](#{upload.short_url})}, %Q{This post has a local emoji :+1: and an external upload\n\n![smallest.png|10x20](#{upload.short_url})},
) )
@ -1560,6 +1593,7 @@ RSpec.describe CookedPostProcessor do
the_post = the_post =
Fabricate( Fabricate(
:post, :post,
user: user_with_auto_groups,
raw: raw:
%Q{This post has a local emoji :+1: and an external upload\n\n![smallest.png|10x20](#{upload.short_url})}, %Q{This post has a local emoji :+1: and an external upload\n\n![smallest.png|10x20](#{upload.short_url})},
) )
@ -1581,7 +1615,12 @@ RSpec.describe CookedPostProcessor do
upload.update_column(:url, "#{SiteSetting.Upload.absolute_base_url}/#{stored_path}") upload.update_column(:url, "#{SiteSetting.Upload.absolute_base_url}/#{stored_path}")
upload.update_column(:secure, true) upload.update_column(:secure, true)
the_post = Fabricate(:post, raw: "This post has a custom emoji :trout:") the_post =
Fabricate(
:post,
user: user_with_auto_groups,
raw: "This post has a custom emoji :trout:",
)
the_post.cook(the_post.raw) the_post.cook(the_post.raw)
cpp = CookedPostProcessor.new(the_post) cpp = CookedPostProcessor.new(the_post)
@ -1609,7 +1648,11 @@ RSpec.describe CookedPostProcessor do
SiteSetting.prevent_anons_from_downloading_files = true SiteSetting.prevent_anons_from_downloading_files = true
the_post = the_post =
Fabricate(:post, raw: "This post has an S3 video onebox:\n#{video_upload.url}") Fabricate(
:post,
user: user_with_auto_groups,
raw: "This post has an S3 video onebox:\n#{video_upload.url}",
)
cpp = CookedPostProcessor.new(the_post.reload) cpp = CookedPostProcessor.new(the_post.reload)
cpp.post_process_oneboxes cpp.post_process_oneboxes
@ -1631,7 +1674,11 @@ RSpec.describe CookedPostProcessor do
video_upload.update_column(:secure, true) video_upload.update_column(:secure, true)
the_post = the_post =
Fabricate(:post, raw: "This post has an S3 video onebox:\n#{video_upload.url}") Fabricate(
:post,
user: user_with_auto_groups,
raw: "This post has an S3 video onebox:\n#{video_upload.url}",
)
cpp = CookedPostProcessor.new(the_post) cpp = CookedPostProcessor.new(the_post)
cpp.post_process_oneboxes cpp.post_process_oneboxes
@ -1679,7 +1726,7 @@ RSpec.describe CookedPostProcessor do
![logo.png](upload://#{image_upload.base62_sha1}.#{image_upload.extension}) ![logo.png](upload://#{image_upload.base62_sha1}.#{image_upload.extension})
RAW RAW
the_post = Fabricate(:post, raw: raw) the_post = Fabricate(:post, user: user_with_auto_groups, raw: raw)
cpp = CookedPostProcessor.new(the_post) cpp = CookedPostProcessor.new(the_post)
cpp.post_process_oneboxes cpp.post_process_oneboxes
@ -1719,7 +1766,7 @@ RSpec.describe CookedPostProcessor do
describe "#remove_user_ids" do describe "#remove_user_ids" do
let(:topic) { Fabricate(:topic) } let(:topic) { Fabricate(:topic) }
let(:post) { Fabricate(:post, raw: <<~RAW) } let(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~RAW) }
link to a topic: #{topic.url}?u=foo link to a topic: #{topic.url}?u=foo
a tricky link to a topic: #{topic.url}?bob=bob;u=sam&jane=jane a tricky link to a topic: #{topic.url}?bob=bob;u=sam&jane=jane
@ -1766,7 +1813,11 @@ RSpec.describe CookedPostProcessor do
context "with emoji inside a quote" do context "with emoji inside a quote" do
let(:post) do let(:post) do
Fabricate(:post, raw: "time to eat some sweet \n[quote]\n:candy:\n[/quote]\n mmmm") Fabricate(
:post,
user: user_with_auto_groups,
raw: "time to eat some sweet \n[quote]\n:candy:\n[/quote]\n mmmm",
)
end end
it "doesn't award a badge when the emoji is in a quote" do it "doesn't award a badge when the emoji is in a quote" do
@ -1776,7 +1827,9 @@ RSpec.describe CookedPostProcessor do
end end
context "with emoji in the text" do context "with emoji in the text" do
let(:post) { Fabricate(:post, raw: "time to eat some sweet :candy: mmmm") } let(:post) do
Fabricate(:post, user: user_with_auto_groups, raw: "time to eat some sweet :candy: mmmm")
end
it "awards a badge for using an emoji" do it "awards a badge for using an emoji" do
cpp.grant_badges cpp.grant_badges
@ -1794,7 +1847,12 @@ RSpec.describe CookedPostProcessor do
end end
it "awards the badge for using an onebox" do it "awards the badge for using an onebox" do
post = Fabricate(:post, raw: "onebox me:\n\nhttps://discourse.org\n") post =
Fabricate(
:post,
user: user_with_auto_groups,
raw: "onebox me:\n\nhttps://discourse.org\n",
)
cpp = CookedPostProcessor.new(post) cpp = CookedPostProcessor.new(post)
cpp.post_process_oneboxes cpp.post_process_oneboxes
cpp.grant_badges cpp.grant_badges
@ -1802,7 +1860,8 @@ RSpec.describe CookedPostProcessor do
end end
it "does not award the badge when link is not oneboxed" do it "does not award the badge when link is not oneboxed" do
post = Fabricate(:post, raw: "onebox me:\n\nhttp://example.com\n") post =
Fabricate(:post, user: user_with_auto_groups, raw: "onebox me:\n\nhttp://example.com\n")
cpp = CookedPostProcessor.new(post) cpp = CookedPostProcessor.new(post)
cpp.post_process_oneboxes cpp.post_process_oneboxes
cpp.grant_badges cpp.grant_badges
@ -1811,7 +1870,12 @@ RSpec.describe CookedPostProcessor do
it "does not award the badge when the badge is disabled" do it "does not award the badge when the badge is disabled" do
Badge.where(id: Badge::FirstOnebox).update_all(enabled: false) Badge.where(id: Badge::FirstOnebox).update_all(enabled: false)
post = Fabricate(:post, raw: "onebox me:\n\nhttps://discourse.org\n") post =
Fabricate(
:post,
user: user_with_auto_groups,
raw: "onebox me:\n\nhttps://discourse.org\n",
)
cpp = CookedPostProcessor.new(post) cpp = CookedPostProcessor.new(post)
cpp.post_process_oneboxes cpp.post_process_oneboxes
cpp.grant_badges cpp.grant_badges
@ -1821,7 +1885,13 @@ RSpec.describe CookedPostProcessor do
context "with reply_by_email" do context "with reply_by_email" do
let(:post) do let(:post) do
Fabricate(:post, raw: "This is a **reply** via email ;)", via_email: true, post_number: 2) Fabricate(
:post,
user: user_with_auto_groups,
raw: "This is a **reply** via email ;)",
via_email: true,
post_number: 2,
)
end end
it "awards a badge for replying via email" do it "awards a badge for replying via email" do
@ -1833,7 +1903,9 @@ RSpec.describe CookedPostProcessor do
describe "quote processing" do describe "quote processing" do
let(:cpp) { CookedPostProcessor.new(cp) } let(:cpp) { CookedPostProcessor.new(cp) }
let(:pp) { Fabricate(:post, raw: "This post is ripe for quoting!") } let(:pp) do
Fabricate(:post, user: user_with_auto_groups, raw: "This post is ripe for quoting!")
end
context "with an unmodified quote" do context "with an unmodified quote" do
let(:cp) do let(:cp) do
@ -1872,7 +1944,7 @@ RSpec.describe CookedPostProcessor do
[/quote] [/quote]
and this is a reply and this is a reply
RAW RAW
let(:cp) { Fabricate(:post, raw: external_raw) } let(:cp) { Fabricate(:post, user: user_with_auto_groups, raw: external_raw) }
it "it should be marked as missing" do it "it should be marked as missing" do
cpp.post_process_quotes cpp.post_process_quotes
@ -1883,7 +1955,9 @@ RSpec.describe CookedPostProcessor do
describe "full quote on direct reply" do describe "full quote on direct reply" do
fab!(:topic) fab!(:topic)
let!(:post) { Fabricate(:post, topic: topic, raw: 'this is the "first" post') } let!(:post) do
Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: 'this is the "first" post')
end
let(:raw) { <<~RAW.strip } let(:raw) { <<~RAW.strip }
[quote="#{post.user.username}, post:#{post.post_number}, topic:#{topic.id}"] [quote="#{post.user.username}, post:#{post.post_number}, topic:#{topic.id}"]
@ -1922,9 +1996,22 @@ RSpec.describe CookedPostProcessor do
before { SiteSetting.remove_full_quote = true } before { SiteSetting.remove_full_quote = true }
it "works" do it "works" do
hidden = Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") hidden =
small_action = Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) Fabricate(
reply = Fabricate(:post, topic: topic, raw: raw) :post,
user: user_with_auto_groups,
topic: topic,
hidden: true,
raw: "this is the second post after",
)
small_action =
Fabricate(
:post,
user: user_with_auto_groups,
topic: topic,
post_type: Post.types[:small_action],
)
reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw)
freeze_time do freeze_time do
topic.bumped_at = 1.day.ago topic.bumped_at = 1.day.ago
@ -1945,14 +2032,14 @@ RSpec.describe CookedPostProcessor do
end end
it "does nothing if there are multiple quotes" do it "does nothing if there are multiple quotes" do
reply = Fabricate(:post, topic: topic, raw: raw3) reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw3)
CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply
expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id])
expect(reply.raw).to eq(raw3) expect(reply.raw).to eq(raw3)
end end
it "does not delete quote if not first paragraph" do it "does not delete quote if not first paragraph" do
reply = Fabricate(:post, topic: topic, raw: raw2) reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw2)
CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply
expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id])
expect(reply.raw).to eq(raw2) expect(reply.raw).to eq(raw2)
@ -1961,22 +2048,33 @@ RSpec.describe CookedPostProcessor do
it "does nothing when 'remove_full_quote' is disabled" do it "does nothing when 'remove_full_quote' is disabled" do
SiteSetting.remove_full_quote = false SiteSetting.remove_full_quote = false
reply = Fabricate(:post, topic: topic, raw: raw) reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw)
CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply
expect(reply.raw).to eq(raw) expect(reply.raw).to eq(raw)
end end
it "does not generate a blank HTML document" do it "does not generate a blank HTML document" do
post = Fabricate(:post, topic: topic, raw: "<sunday><monday>") post = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: "<sunday><monday>")
cp = CookedPostProcessor.new(post) cp = CookedPostProcessor.new(post)
cp.post_process cp.post_process
expect(cp.html).to eq("<p></p>") expect(cp.html).to eq("<p></p>")
end end
it "works only on new posts" do it "works only on new posts" do
Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") Fabricate(
Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) :post,
user: user_with_auto_groups,
topic: topic,
hidden: true,
raw: "this is the second post after",
)
Fabricate(
:post,
user: user_with_auto_groups,
topic: topic,
post_type: Post.types[:small_action],
)
reply = PostCreator.create!(topic.user, topic_id: topic.id, raw: raw) reply = PostCreator.create!(topic.user, topic_id: topic.id, raw: raw)
stub_image_size stub_image_size
@ -1995,8 +2093,8 @@ RSpec.describe CookedPostProcessor do
end end
it "works with nested quotes" do it "works with nested quotes" do
reply1 = Fabricate(:post, topic: topic, raw: raw) reply1 = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw)
reply2 = Fabricate(:post, topic: topic, raw: <<~RAW.strip) reply2 = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: <<~RAW.strip)
[quote="#{reply1.user.username}, post:#{reply1.post_number}, topic:#{topic.id}"] [quote="#{reply1.user.username}, post:#{reply1.post_number}, topic:#{topic.id}"]
#{raw} #{raw}
[/quote] [/quote]
@ -2010,7 +2108,7 @@ RSpec.describe CookedPostProcessor do
end end
describe "full quote on direct reply with full name prioritization" do describe "full quote on direct reply with full name prioritization" do
fab!(:user) { Fabricate(:user, name: "james, john, the third") } fab!(:user) { Fabricate(:user, name: "james, john, the third", refresh_auto_groups: true) }
fab!(:topic) fab!(:topic)
let!(:post) { Fabricate(:post, user: user, topic: topic, raw: 'this is the "first" post') } let!(:post) { Fabricate(:post, user: user, topic: topic, raw: 'this is the "first" post') }
@ -2055,9 +2153,22 @@ RSpec.describe CookedPostProcessor do
end end
it "removes direct reply with full quotes" do it "removes direct reply with full quotes" do
hidden = Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") hidden =
small_action = Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) Fabricate(
reply = Fabricate(:post, topic: topic, raw: raw) :post,
user: user_with_auto_groups,
topic: topic,
hidden: true,
raw: "this is the second post after",
)
small_action =
Fabricate(
:post,
user: user_with_auto_groups,
topic: topic,
post_type: Post.types[:small_action],
)
reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw)
freeze_time do freeze_time do
topic.bumped_at = 1.day.ago topic.bumped_at = 1.day.ago
@ -2078,14 +2189,14 @@ RSpec.describe CookedPostProcessor do
end end
it "does nothing if there are multiple quotes" do it "does nothing if there are multiple quotes" do
reply = Fabricate(:post, topic: topic, raw: raw3) reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw3)
CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply
expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id])
expect(reply.raw).to eq(raw3) expect(reply.raw).to eq(raw3)
end end
it "does not delete quote if not first paragraph" do it "does not delete quote if not first paragraph" do
reply = Fabricate(:post, topic: topic, raw: raw2) reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw2)
CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply
expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id])
expect(reply.raw).to eq(raw2) expect(reply.raw).to eq(raw2)
@ -2094,22 +2205,33 @@ RSpec.describe CookedPostProcessor do
it "does nothing when 'remove_full_quote' is disabled" do it "does nothing when 'remove_full_quote' is disabled" do
SiteSetting.remove_full_quote = false SiteSetting.remove_full_quote = false
reply = Fabricate(:post, topic: topic, raw: raw) reply = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw)
CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply CookedPostProcessor.new(reply).remove_full_quote_on_direct_reply
expect(reply.raw).to eq(raw) expect(reply.raw).to eq(raw)
end end
it "does not generate a blank HTML document" do it "does not generate a blank HTML document" do
post = Fabricate(:post, topic: topic, raw: "<sunday><monday>") post = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: "<sunday><monday>")
cp = CookedPostProcessor.new(post) cp = CookedPostProcessor.new(post)
cp.post_process cp.post_process
expect(cp.html).to eq("<p></p>") expect(cp.html).to eq("<p></p>")
end end
it "works only on new posts" do it "works only on new posts" do
Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") Fabricate(
Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) :post,
user: user_with_auto_groups,
topic: topic,
hidden: true,
raw: "this is the second post after",
)
Fabricate(
:post,
user: user_with_auto_groups,
topic: topic,
post_type: Post.types[:small_action],
)
reply = PostCreator.create!(topic.user, topic_id: topic.id, raw: raw) reply = PostCreator.create!(topic.user, topic_id: topic.id, raw: raw)
stub_image_size stub_image_size
@ -2129,7 +2251,7 @@ RSpec.describe CookedPostProcessor do
it "works with nested quotes" do it "works with nested quotes" do
reply1 = Fabricate(:post, user: user, topic: topic, raw: raw) reply1 = Fabricate(:post, user: user, topic: topic, raw: raw)
reply2 = Fabricate(:post, topic: topic, raw: <<~RAW.strip) reply2 = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: <<~RAW.strip)
[quote="#{reply1.user.name}, post:#{reply1.post_number}, topic:#{topic.id}, username:#{reply1.user.username}"] [quote="#{reply1.user.name}, post:#{reply1.post_number}, topic:#{topic.id}, username:#{reply1.user.username}"]
#{raw} #{raw}
[/quote] [/quote]
@ -2143,7 +2265,7 @@ RSpec.describe CookedPostProcessor do
end end
describe "prioritizes full name in quotes" do describe "prioritizes full name in quotes" do
fab!(:user) { Fabricate(:user, name: "james, john, the third") } fab!(:user) { Fabricate(:user, name: "james, john, the third", refresh_auto_groups: true) }
fab!(:topic) fab!(:topic)
let!(:post) { Fabricate(:post, user: user, topic: topic, raw: 'this is the "first" post') } let!(:post) { Fabricate(:post, user: user, topic: topic, raw: 'this is the "first" post') }
@ -2167,7 +2289,7 @@ RSpec.describe CookedPostProcessor do
describe "#html" do describe "#html" do
it "escapes html entities in attributes per html5" do it "escapes html entities in attributes per html5" do
post = Fabricate(:post, raw: '<img alt="&<something>">') post = Fabricate(:post, user: user_with_auto_groups, raw: '<img alt="&<something>">')
expect(post.cook(post.raw)).to eq('<p><img alt="&amp;<something>"></p>') expect(post.cook(post.raw)).to eq('<p><img alt="&amp;<something>"></p>')
expect(CookedPostProcessor.new(post).html).to eq('<p><img alt="&amp;<something>"></p>') expect(CookedPostProcessor.new(post).html).to eq('<p><img alt="&amp;<something>"></p>')
end end

View File

@ -541,7 +541,13 @@ RSpec.describe Email::Sender do
#{UploadMarkdown.new(image).image_markdown} #{UploadMarkdown.new(image).image_markdown}
#{UploadMarkdown.new(csv_file).attachment_markdown} #{UploadMarkdown.new(csv_file).attachment_markdown}
RAW RAW
reply = Fabricate(:post, raw: raw, topic: post.topic, user: Fabricate(:user)) reply =
Fabricate(
:post,
raw: raw,
topic: post.topic,
user: Fabricate(:user, refresh_auto_groups: true),
)
reply.link_post_uploads reply.link_post_uploads
reply reply
end end

View File

@ -290,10 +290,17 @@ RSpec.describe Search do
describe "post indexing" do describe "post indexing" do
fab!(:category) { Fabricate(:category_with_definition, name: "america") } fab!(:category) { Fabricate(:category_with_definition, name: "america") }
fab!(:topic) { Fabricate(:topic, title: "sam saffron test topic", category: category) } fab!(:topic) { Fabricate(:topic, title: "sam saffron test topic", category: category) }
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
let!(:post) do let!(:post) do
Fabricate(:post, topic: topic, raw: 'this <b>fun test</b> <img src="bla" title="my image">') Fabricate(
:post,
topic: topic,
raw: 'this <b>fun test</b> <img src="bla" title="my image">',
user: user,
)
end end
let!(:post2) { Fabricate(:post, topic: topic) } let!(:post2) { Fabricate(:post, topic: topic, user: user) }
it "should index correctly" do it "should index correctly" do
search_data = post.post_search_data.search_data search_data = post.post_search_data.search_data
@ -1995,8 +2002,9 @@ RSpec.describe Search do
end end
it "can find posts with images" do it "can find posts with images" do
post_uploaded = Fabricate(:post_with_uploaded_image) user = Fabricate(:user, refresh_auto_groups: true)
Fabricate(:post) post_uploaded = Fabricate(:post_with_uploaded_image, user: user)
Fabricate(:post, user: user)
CookedPostProcessor.new(post_uploaded).update_post_image CookedPostProcessor.new(post_uploaded).update_post_image

View File

@ -1,13 +1,20 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe ShrinkUploadedImage do RSpec.describe ShrinkUploadedImage do
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
def create_post_with_upload
post = Fabricate(:post, raw: "<img src='#{upload.url}'>", user: user)
post.link_post_uploads
post
end
context "when local uploads are enabled" do context "when local uploads are enabled" do
let(:upload) { Fabricate(:image_upload, width: 200, height: 200) } let(:upload) { Fabricate(:image_upload, width: 200, height: 200) }
it "resizes the image" do it "resizes the image" do
create_post_with_upload
filesize_before = upload.filesize filesize_before = upload.filesize
post = Fabricate(:post, raw: "<img src='#{upload.url}'>")
post.link_post_uploads
result = result =
ShrinkUploadedImage.new( ShrinkUploadedImage.new(
@ -32,8 +39,7 @@ RSpec.describe ShrinkUploadedImage do
smaller_sha1 = Upload.generate_digest("/tmp/smaller.png") smaller_sha1 = Upload.generate_digest("/tmp/smaller.png")
smaller_upload = Fabricate(:image_upload, sha1: smaller_sha1) smaller_upload = Fabricate(:image_upload, sha1: smaller_sha1)
post = Fabricate(:post, raw: "<img src='#{upload.url}'>") post = create_post_with_upload
post.link_post_uploads
post_hotlinked_media = post_hotlinked_media =
PostHotlinkedMedia.create!( PostHotlinkedMedia.create!(
post: post, post: post,
@ -63,8 +69,8 @@ RSpec.describe ShrinkUploadedImage do
end end
it "returns false if the image cannot be shrunk more" do it "returns false if the image cannot be shrunk more" do
post = Fabricate(:post, raw: "<img src='#{upload.url}'>") create_post_with_upload
post.link_post_uploads
ShrinkUploadedImage.new( ShrinkUploadedImage.new(
upload: upload, upload: upload,
path: Discourse.store.path_for(upload), path: Discourse.store.path_for(upload),
@ -84,8 +90,7 @@ RSpec.describe ShrinkUploadedImage do
end end
it "returns false when the upload is above the size limit" do it "returns false when the upload is above the size limit" do
post = Fabricate(:post, raw: "<img src='#{upload.url}'>") create_post_with_upload
post.link_post_uploads
SiteSetting.max_image_size_kb = 0 SiteSetting.max_image_size_kb = 0
result = result =
@ -137,8 +142,7 @@ RSpec.describe ShrinkUploadedImage do
it "resizes the image" do it "resizes the image" do
filesize_before = upload.filesize filesize_before = upload.filesize
post = Fabricate(:post, raw: "<img src='#{upload.url}'>") create_post_with_upload
post.link_post_uploads
result = result =
ShrinkUploadedImage.new( ShrinkUploadedImage.new(

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe UploadRecovery do RSpec.describe UploadRecovery do
fab!(:user) fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
let(:upload) do let(:upload) do
UploadCreator.new(file_from_fixtures("smallest.png"), "logo.png").create_for(user.id) UploadCreator.new(file_from_fixtures("smallest.png"), "logo.png").create_for(user.id)

View File

@ -184,42 +184,44 @@ RSpec.describe PostValidator do
end end
describe "too_many_embedded_media" do describe "too_many_embedded_media" do
fab!(:new_user) { Fabricate(:newuser, refresh_auto_groups: true) }
before do before do
SiteSetting.min_trust_to_post_embedded_media = 0 SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
SiteSetting.newuser_max_embedded_media = 2 SiteSetting.newuser_max_embedded_media = 2
end end
it "should be invalid when new user exceeds max mentions limit" do it "should be invalid when new user exceeds max mentions limit" do
post.acting_user = build(:newuser) post.acting_user = new_user
post.expects(:embedded_media_count).returns(3) post.expects(:embedded_media_count).returns(3)
validator.max_embedded_media_validator(post) validator.max_embedded_media_validator(post)
expect(post.errors.count).to be > 0 expect(post.errors.count).to be > 0
end end
it "should be valid when new user does not exceed max mentions limit" do it "should be valid when new user does not exceed max mentions limit" do
post.acting_user = build(:newuser) post.acting_user = new_user
post.expects(:embedded_media_count).returns(2) post.expects(:embedded_media_count).returns(2)
validator.max_embedded_media_validator(post) validator.max_embedded_media_validator(post)
expect(post.errors.count).to be(0) expect(post.errors.count).to be(0)
end end
it "should be invalid when user trust level is not sufficient" do it "should be invalid when user trust level is not sufficient" do
SiteSetting.min_trust_to_post_embedded_media = 4 SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
post.acting_user = build(:leader) post.acting_user = Fabricate(:leader, groups: [])
post.expects(:embedded_media_count).returns(2) post.expects(:embedded_media_count).returns(2)
validator.max_embedded_media_validator(post) validator.max_embedded_media_validator(post)
expect(post.errors.count).to be > 0 expect(post.errors.count).to be > 0
end end
it "should be valid for moderator in all cases" do it "should be valid for moderator in all cases" do
post.acting_user = build(:moderator) post.acting_user = Fabricate(:moderator)
post.expects(:embedded_media_count).never post.expects(:embedded_media_count).never
validator.max_embedded_media_validator(post) validator.max_embedded_media_validator(post)
expect(post.errors.count).to be(0) expect(post.errors.count).to be(0)
end end
it "should be valid for admin in all cases" do it "should be valid for admin in all cases" do
post.acting_user = build(:admin) post.acting_user = Fabricate(:admin)
post.expects(:embedded_media_count).never post.expects(:embedded_media_count).never
validator.max_embedded_media_validator(post) validator.max_embedded_media_validator(post)
expect(post.errors.count).to be(0) expect(post.errors.count).to be(0)

View File

@ -70,7 +70,8 @@ RSpec.describe Post do
it { is_expected.to rate_limit } it { is_expected.to rate_limit }
let(:topic) { Fabricate(:topic) } fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
let(:topic) { Fabricate(:topic, user: user) }
let(:post_args) { { user: topic.user, topic: topic } } let(:post_args) { { user: topic.user, topic: topic } }
describe "scopes" do describe "scopes" do
@ -336,36 +337,6 @@ RSpec.describe Post do
expect(post_one_image).to be_valid expect(post_one_image).to be_valid
end end
it "doesn't allow more than `min_trust_to_post_embedded_media`" do
SiteSetting.min_trust_to_post_embedded_media = 4
post_one_image.user.trust_level = 3
expect(post_one_image).not_to be_valid
end
it "doesn't allow more than `min_trust_to_post_embedded_media` in a quote" do
SiteSetting.min_trust_to_post_embedded_media = 4
post_one_image.user.trust_level = 3
expect(post_image_within_quote).not_to be_valid
end
it "doesn't allow more than `min_trust_to_post_embedded_media` in code" do
SiteSetting.min_trust_to_post_embedded_media = 4
post_one_image.user.trust_level = 3
expect(post_image_within_code).not_to be_valid
end
it "doesn't allow more than `min_trust_to_post_embedded_media` in pre" do
SiteSetting.min_trust_to_post_embedded_media = 4
post_one_image.user.trust_level = 3
expect(post_image_within_pre).not_to be_valid
end
it "doesn't allow more than `min_trust_to_post_embedded_media`" do
SiteSetting.min_trust_to_post_embedded_media = 4
post_one_image.user.trust_level = 4
expect(post_one_image).to be_valid
end
it "doesn't count favicons as images" do it "doesn't count favicons as images" do
PrettyText.stubs(:cook).returns(post_with_favicon.raw) PrettyText.stubs(:cook).returns(post_with_favicon.raw)
expect(post_with_favicon.embedded_media_count).to eq(0) expect(post_with_favicon.embedded_media_count).to eq(0)
@ -387,6 +358,40 @@ RSpec.describe Post do
expect(post_with_two_embedded_media.embedded_media_count).to eq(2) expect(post_with_two_embedded_media.embedded_media_count).to eq(2)
end end
describe "embedded_media_allowed_groups" do
before { Group.refresh_automatic_groups! }
it "doesn't allow users outside of `embedded_media_post_allowed_groups`" do
SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
post_one_image.user.change_trust_level!(3)
expect(post_one_image).not_to be_valid
end
it "doesn't allow users outside of `embedded_media_post_allowed_groups` in a quote" do
SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
post_one_image.user.change_trust_level!(3)
expect(post_image_within_quote).not_to be_valid
end
it "doesn't allow users outside of `embedded_media_post_allowed_groups` in code" do
SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
post_one_image.user.change_trust_level!(3)
expect(post_image_within_code).not_to be_valid
end
it "doesn't allow users outside of `embedded_media_post_allowed_groups` in pre" do
SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
post_one_image.user.change_trust_level!(3)
expect(post_image_within_pre).not_to be_valid
end
it "allows users who are in a group in `embedded_media_post_allowed_groups`" do
SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
post_one_image.user.change_trust_level!(4)
expect(post_one_image).to be_valid
end
end
context "with validation" do context "with validation" do
before { SiteSetting.newuser_max_embedded_media = 1 } before { SiteSetting.newuser_max_embedded_media = 1 }
@ -1760,7 +1765,7 @@ RSpec.describe Post do
end end
describe "#update_uploads_secure_status" do describe "#update_uploads_secure_status" do
fab!(:user) { Fabricate(:user, trust_level: 0) } fab!(:user) { Fabricate(:user, trust_level: 0, refresh_auto_groups: true) }
let(:raw) { <<~RAW } let(:raw) { <<~RAW }
<a href="#{attachment_upload.url}">Link</a> <a href="#{attachment_upload.url}">Link</a>

View File

@ -454,14 +454,16 @@ RSpec.describe TrustLevel3Requirements do
end end
describe "num_likes_received" do describe "num_likes_received" do
before { UserActionManager.enable } before do
UserActionManager.enable
Group.refresh_automatic_groups!
end
let(:topic) { Fabricate(:topic, user: user, created_at: 102.days.ago) } let(:topic) { Fabricate(:topic, user: user, created_at: 102.days.ago) }
let(:old_post) { create_post(topic: topic, user: user, created_at: 102.days.ago) } let(:old_post) { create_post(topic: topic, user: user, created_at: 102.days.ago) }
let(:recent_post1) { create_post(topic: topic, user: user, created_at: 1.hour.ago) } let(:recent_post1) { create_post(topic: topic, user: user, created_at: 1.hour.ago) }
let(:recent_post2) { create_post(topic: topic, user: user, created_at: 10.days.ago) } let(:recent_post2) { create_post(topic: topic, user: user, created_at: 10.days.ago) }
let(:private_post) do let(:private_post) do
Group.refresh_automatic_groups!
create_post( create_post(
user: user, user: user,
archetype: Archetype.private_message, archetype: Archetype.private_message,

View File

@ -19,7 +19,12 @@ RSpec.describe Upload do
describe ".with_no_non_post_relations" do describe ".with_no_non_post_relations" do
it "does not find non-post related uploads" do it "does not find non-post related uploads" do
post_upload = Fabricate(:upload) post_upload = Fabricate(:upload)
post = Fabricate(:post, raw: "<img src='#{post_upload.url}'>") post =
Fabricate(
:post,
raw: "<img src='#{post_upload.url}'>",
user: Fabricate(:user, refresh_auto_groups: true),
)
post.link_post_uploads post.link_post_uploads
badge_upload = Fabricate(:upload) badge_upload = Fabricate(:upload)

View File

@ -191,7 +191,8 @@ RSpec.describe UserSearch do
end end
it "only reveals topic participants to people with permission" do it "only reveals topic participants to people with permission" do
pm_topic = Fabricate(:private_message_post).topic pm_topic =
Fabricate(:private_message_post, user: Fabricate(:user, refresh_auto_groups: true)).topic
# Anonymous, does not have access # Anonymous, does not have access
expect do search_for("", topic_id: pm_topic.id) end.to raise_error(Discourse::InvalidAccess) expect do search_for("", topic_id: pm_topic.id) end.to raise_error(Discourse::InvalidAccess)
@ -201,7 +202,6 @@ RSpec.describe UserSearch do
Discourse::InvalidAccess, Discourse::InvalidAccess,
) )
Group.refresh_automatic_groups!
pm_topic.invite(pm_topic.user, mr_b.username) pm_topic.invite(pm_topic.user, mr_b.username)
results = search_for("", topic_id: pm_topic.id, searching_user: mr_b) results = search_for("", topic_id: pm_topic.id, searching_user: mr_b)

View File

@ -3194,6 +3194,8 @@ RSpec.describe TopicsController do
end end
describe "image only topic" do describe "image only topic" do
before { Group.refresh_automatic_groups! }
it "uses image alt tag for meta description" do it "uses image alt tag for meta description" do
post = post =
Fabricate( Fabricate(

View File

@ -3,9 +3,9 @@
require "rotp" require "rotp"
RSpec.describe UsersController do RSpec.describe UsersController do
fab!(:user) fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:user1) { Fabricate(:user, username: "someusername") } fab!(:user1) { Fabricate(:user, username: "someusername", refresh_auto_groups: true) }
fab!(:another_user) { Fabricate(:user) } fab!(:another_user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:invitee) { Fabricate(:user) } fab!(:invitee) { Fabricate(:user) }
fab!(:inviter) { Fabricate(:user) } fab!(:inviter) { Fabricate(:user) }
@ -6786,10 +6786,9 @@ RSpec.describe UsersController do
end end
describe "#private_message_topic_tracking_state" do describe "#private_message_topic_tracking_state" do
fab!(:user_2) { Fabricate(:user) } fab!(:user_2) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:private_message) do fab!(:private_message) do
Group.refresh_automatic_groups!
create_post( create_post(
user: user1, user: user1,
target_usernames: [user_2.username], target_usernames: [user_2.username],