From 0e50f88212e8dacdb290dbc3a035063e4978a260 Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Thu, 25 Jan 2024 09:50:59 +1000 Subject: [PATCH] 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 --- config/locales/server.en.yml | 4 +- config/site_settings.yml | 7 + ...owed_groups_based_on_deprecated_setting.rb | 24 ++ lib/site_settings/deprecated_settings.rb | 2 + lib/validators/post_validator.rb | 6 +- .../new_user_narrative.rb | 4 +- .../new_user_narrative_spec.rb | 8 +- spec/jobs/pull_hotlinked_images_spec.rb | 51 ++-- spec/jobs/user_email_spec.rb | 5 +- .../backup_restore/uploads_restorer_spec.rb | 7 +- spec/lib/cooked_post_processor_spec.rb | 264 +++++++++++++----- spec/lib/email/sender_spec.rb | 8 +- spec/lib/search_spec.rb | 16 +- spec/lib/shrink_uploaded_image_spec.rb | 24 +- spec/lib/upload_recovery_spec.rb | 2 +- spec/lib/validators/post_validator_spec.rb | 16 +- spec/models/post_spec.rb | 69 ++--- spec/models/trust_level3_requirements_spec.rb | 6 +- spec/models/upload_spec.rb | 7 +- spec/models/user_search_spec.rb | 4 +- spec/requests/topics_controller_spec.rb | 2 + spec/requests/users_controller_spec.rb | 9 +- 22 files changed, 374 insertions(+), 171 deletions(-) create mode 100644 db/post_migrate/20240112043325_fill_embedded_media_post_allowed_groups_based_on_deprecated_setting.rb diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 6355a9b8b52..bebb3792e1f 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -402,7 +402,7 @@ en: too_many_mentions_newuser: 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." - 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." too_many_embedded_media: 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" 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" + 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_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." @@ -2590,6 +2591,7 @@ en: create_tag_allowed_groups: "min_trust_to_create_tag" send_email_messages_allowed_groups: "min_trust_to_send_email_messages" 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" user_api_key_allowed_groups: "min_trust_level_for_user_api_key" diff --git a/config/site_settings.yml b/config/site_settings.yml index 494a6e74d87..1e31ec5dfff 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -1767,6 +1767,13 @@ trust: min_trust_to_post_embedded_media: default: 0 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: default: 0 client: true diff --git a/db/post_migrate/20240112043325_fill_embedded_media_post_allowed_groups_based_on_deprecated_setting.rb b/db/post_migrate/20240112043325_fill_embedded_media_post_allowed_groups_based_on_deprecated_setting.rb new file mode 100644 index 00000000000..482d0b59e80 --- /dev/null +++ b/db/post_migrate/20240112043325_fill_embedded_media_post_allowed_groups_based_on_deprecated_setting.rb @@ -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 diff --git a/lib/site_settings/deprecated_settings.rb b/lib/site_settings/deprecated_settings.rb index c83e42a0459..664e1c9cfec 100644 --- a/lib/site_settings/deprecated_settings.rb +++ b/lib/site_settings/deprecated_settings.rb @@ -37,6 +37,7 @@ module SiteSettings::DeprecatedSettings ["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"], ["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_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_send_email_messages review_media_unless_trust_level + min_trust_to_post_embedded_media min_trust_to_post_links min_trust_level_for_user_api_key ] diff --git a/lib/validators/post_validator.rb b/lib/validators/post_validator.rb index 766424d13bd..0386a4331ef 100644 --- a/lib/validators/post_validator.rb +++ b/lib/validators/post_validator.rb @@ -96,11 +96,11 @@ class PostValidator < ActiveModel::Validator def max_embedded_media_validator(post) 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( post, - :no_embedded_media_allowed_trust, - :no_embedded_media_allowed_trust, + :no_embedded_media_allowed_group, + :no_embedded_media_allowed_group, post.embedded_media_count, 0, ) diff --git a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb index 7ad317c77e4..d31bd7f2646 100644 --- a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb +++ b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb @@ -80,7 +80,7 @@ module DiscourseNarrativeBot # The prerequisites should ensure only one of them is called. tutorial_images: { 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_instructions: Proc.new { I18n.t("#{I18N_KEY}.likes.instructions", base_uri: Discourse.base_path) }, @@ -93,7 +93,7 @@ module DiscourseNarrativeBot }, tutorial_likes: { 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_instructions: Proc.new do diff --git a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb index cc59a09971a..e38c195de2e 100644 --- a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb +++ b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb @@ -31,6 +31,7 @@ RSpec.describe DiscourseNarrativeBot::NewUserNarrative do stub_image_size Jobs.run_immediately! SiteSetting.discourse_narrative_bot_enabled = true + Group.refresh_automatic_groups! end describe "#notify_timeout" do @@ -828,8 +829,11 @@ RSpec.describe DiscourseNarrativeBot::NewUserNarrative do end end - describe "when min_trust_to_post_embedded_media is too high" do - before { SiteSetting.min_trust_to_post_embedded_media = 4 } + describe "when embedded_media_post_allowed_groups does not include the user" do + 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 post.update!( diff --git a/spec/jobs/pull_hotlinked_images_spec.rb b/spec/jobs/pull_hotlinked_images_spec.rb index 63cc14a24a0..9a9f8fba5a1 100644 --- a/spec/jobs/pull_hotlinked_images_spec.rb +++ b/spec/jobs/pull_hotlinked_images_spec.rb @@ -16,6 +16,7 @@ RSpec.describe Jobs::PullHotlinkedImages do ) end let(:upload_path) { Discourse.store.upload_path } + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } before do Jobs.run_immediately! @@ -54,7 +55,7 @@ RSpec.describe Jobs::PullHotlinkedImages do before { Jobs.run_immediately! } it "does nothing if topic has been deleted" do - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") post.topic.destroy! expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.not_to change { @@ -63,7 +64,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end 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 freeze_time 1.week.from_now @@ -72,7 +73,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "replaces images" do - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size 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 Jobs.run_later! - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size freeze_time @@ -102,7 +103,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "removes downloaded images when they are no longer needed" do - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size post.rebake! post.reload @@ -115,7 +116,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "replaces images again after edit" do - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size expect do post.rebake! end.to change { Upload.count }.by(1) @@ -131,7 +132,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "replaces encoded image urls" do - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change { Upload.count @@ -150,7 +151,7 @@ RSpec.describe Jobs::PullHotlinkedImages do "http://test.localhost/uploads/short-url/z2QSs1KJWoj51uYhDjb6ifCzxH6.gif", ).to_return(status: 200, body: "") - post = Fabricate(:post, raw: <<~MD) + post = Fabricate(:post, user: user, raw: <<~MD)

somelink @@ -173,7 +174,7 @@ RSpec.describe Jobs::PullHotlinkedImages do it "replaces correct image URL" do 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 expect do Jobs::PullHotlinkedImages.new.execute(post_id: post.id) end.to change { @@ -184,7 +185,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end 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}) `![codeblockimage](#{image_url})` RAW @@ -202,7 +203,7 @@ RSpec.describe Jobs::PullHotlinkedImages do it "replaces images without protocol" do url = image_url.sub(/^https?\:/, "") - post = Fabricate(:post, raw: "test") + post = Fabricate(:post, user: user, raw: "test") stub_image_size 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 url = image_url.sub(/\.[a-zA-Z0-9]+$/, "") stub_request(:get, url).to_return(body: png, headers: { "Content-Type" => "image/png" }) - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size 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")) - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") stub_image_size 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 raw = "" - 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 expect do post.rebake! @@ -266,7 +267,7 @@ RSpec.describe Jobs::PullHotlinkedImages do stub_s3(upload) url = Upload.secure_uploads_url_from_upload_url(upload.url) url = Discourse.base_url + url - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") upload.update(access_control_post: post) expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.not_to change { Upload.count @@ -283,7 +284,7 @@ RSpec.describe Jobs::PullHotlinkedImages do Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url) url = Upload.secure_uploads_url_from_upload_url(upload.url) url = Discourse.base_url + url - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") upload.update(access_control_post: post) 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) url = Upload.secure_uploads_url_from_upload_url(upload.url) url = Discourse.base_url + url - post = Fabricate(:post, raw: "") + post = Fabricate(:post, user: user, raw: "") upload.update(access_control_post: Fabricate(:post)) FileStore::S3Store.any_instance.stubs(:store_upload).returns(upload.url) @@ -321,7 +322,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end 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}) ![](#{image_url}) @@ -346,7 +347,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end 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 2]("#{image_url}) MD @@ -358,7 +359,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "replaces bbcode images" do - post = Fabricate(:post, raw: <<~MD) + post = Fabricate(:post, user: user, raw: <<~MD) [img] #{image_url} [/img] @@ -414,7 +415,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "replaces image src" do - post = Fabricate(:post, raw: "#{url}") + post = Fabricate(:post, user: user, raw: "#{url}") stub_image_size post.rebake! @@ -425,7 +426,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "associates uploads correctly" do - post = Fabricate(:post, raw: "#{url}") + post = Fabricate(:post, user: user, raw: "#{url}") stub_image_size post.rebake! post.reload @@ -440,7 +441,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "all combinations" do - post = Fabricate(:post, raw: <<~MD) + post = Fabricate(:post, user: user, raw: <<~MD) #{url} @@ -468,7 +469,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end it "rewrites a lone onebox" do - post = Fabricate(:post, raw: <<~MD) + post = Fabricate(:post, user: user, raw: <<~MD) Onebox here: #{image_url} MD @@ -637,7 +638,7 @@ RSpec.describe Jobs::PullHotlinkedImages do end 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 } before do diff --git a/spec/jobs/user_email_spec.rb b/spec/jobs/user_email_spec.rb index df4e6403704..3d5b681752b 100644 --- a/spec/jobs/user_email_spec.rb +++ b/spec/jobs/user_email_spec.rb @@ -133,7 +133,10 @@ RSpec.describe Jobs::UserEmail do data: { original_post_id: post.id }.to_json, ) 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 Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id) diff --git a/spec/lib/backup_restore/uploads_restorer_spec.rb b/spec/lib/backup_restore/uploads_restorer_spec.rb index 079b5513aba..42e10beb791 100644 --- a/spec/lib/backup_restore/uploads_restorer_spec.rb +++ b/spec/lib/backup_restore/uploads_restorer_spec.rb @@ -153,7 +153,12 @@ RSpec.describe BackupRestore::UploadsRestorer do Fabricate(:optimized_image) 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 FileHelper.stubs(:download).returns(file_from_fixtures("logo.png")) diff --git a/spec/lib/cooked_post_processor_spec.rb b/spec/lib/cooked_post_processor_spec.rb index 40af8e110df..a78e4d1531e 100644 --- a/spec/lib/cooked_post_processor_spec.rb +++ b/spec/lib/cooked_post_processor_spec.rb @@ -6,10 +6,11 @@ require "file_store/s3_store" RSpec.describe CookedPostProcessor do fab!(:upload) fab!(:large_image_upload) + fab!(:user_with_auto_groups) { Fabricate(:user, refresh_auto_groups: true) } let(:upload_path) { Discourse.store.upload_path } describe "#post_process" do - fab!(:post) { Fabricate(:post, raw: <<~RAW) } + fab!(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~RAW) } RAW @@ -34,7 +35,7 @@ RSpec.describe CookedPostProcessor do let(:title) { "some title" } - let(:post) { Fabricate(:post, raw: <<~RAW) } + let(:post) { Fabricate(:post, user: user_with_auto_groups, raw: <<~RAW) } #{url} This is a #{url} with path @@ -126,7 +127,7 @@ RSpec.describe CookedPostProcessor do describe "internal links" do 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 } it "includes the topic title" do @@ -174,7 +175,7 @@ RSpec.describe CookedPostProcessor do let(:title) { "some 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 should not be inline #{url_no_path} oneboxed @@ -259,7 +260,8 @@ RSpec.describe CookedPostProcessor do it "includes responsive images on demand" do upload.update!(width: 2000, height: 1500, filesize: 10_000, dominant_color: "FFFFFF") - post = Fabricate(:post, raw: "hello ") + post = + Fabricate(:post, user: user_with_auto_groups, raw: "hello ") # fake some optimized images OptimizedImage.create!( @@ -316,7 +318,8 @@ RSpec.describe CookedPostProcessor do it "doesn't include response images for cropped images" do upload.update!(width: 200, height: 4000, filesize: 12_345) - post = Fabricate(:post, raw: "hello ") + post = + Fabricate(:post, user: user_with_auto_groups, raw: "hello ") # fake some optimized images OptimizedImage.create!( @@ -346,7 +349,7 @@ RSpec.describe CookedPostProcessor do end 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) } before do @@ -387,7 +390,7 @@ RSpec.describe CookedPostProcessor do context "with unsized images" do 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) } HTML @@ -403,7 +406,7 @@ RSpec.describe CookedPostProcessor do context "with large images" do 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) } HTML @@ -426,7 +429,7 @@ RSpec.describe CookedPostProcessor do context "when image is inside onebox" do 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 Oneboxer @@ -452,6 +455,7 @@ RSpec.describe CookedPostProcessor do fab!(:post) do Fabricate( :post, + user: user_with_auto_groups, raw: "", ) end @@ -470,6 +474,7 @@ RSpec.describe CookedPostProcessor do let(:post) do Fabricate( :post, + user: user_with_auto_groups, raw: "", ) @@ -507,7 +512,11 @@ RSpec.describe CookedPostProcessor do let(:optimized_size) { "600x500" } 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 let(:cooked_html) { <<~HTML } @@ -575,7 +584,10 @@ RSpec.describe CookedPostProcessor do context "when the upload is attached to a different post" do before do 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 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 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) } HTML @@ -612,7 +624,7 @@ RSpec.describe CookedPostProcessor do context "with taller images < default aspect ratio" do 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) } HTML @@ -631,7 +643,7 @@ RSpec.describe CookedPostProcessor do context "with iPhone X screenshots" do 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) } HTML @@ -653,7 +665,7 @@ RSpec.describe CookedPostProcessor do context "with large images when using subfolders" do 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) } HTML @@ -693,7 +705,7 @@ RSpec.describe CookedPostProcessor do context "with title and alt" do 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) } RED HTML @@ -718,7 +730,7 @@ RSpec.describe CookedPostProcessor do context "with title only" do 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) } HTML @@ -743,7 +755,7 @@ RSpec.describe CookedPostProcessor do context "with alt only" do 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) } RED HTML @@ -766,7 +778,7 @@ RSpec.describe CookedPostProcessor do end 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) } 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(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 topic.reload @@ -813,7 +831,7 @@ RSpec.describe CookedPostProcessor do it "prioritizes data-thumbnail images" do upload1 = 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|thumbnail](#{upload2.url}) MD @@ -824,7 +842,9 @@ RSpec.describe CookedPostProcessor do end 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) } 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) } 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.post_process @@ -978,7 +1003,12 @@ RSpec.describe CookedPostProcessor do # skips lightboxing # adds "animated" class to element 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.post_process @@ -1008,6 +1038,7 @@ RSpec.describe CookedPostProcessor do post = Fabricate( :post, + user: user_with_auto_groups, raw: "![tennis-gif|311x280](https://media2.giphy.com/media/7Oifk90VrCdNe/giphy.webp)", ) cpp = CookedPostProcessor.new(post, disable_dominant_color: true) @@ -1021,6 +1052,7 @@ RSpec.describe CookedPostProcessor do post = Fabricate( :post, + user: user_with_auto_groups, raw: "![cat](https://media1.tenor.com/images/20c7ddd5e84c7427954f430439c5209d/tenor.gif)", ) @@ -1033,7 +1065,7 @@ RSpec.describe CookedPostProcessor do end 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] ![image|1024x768, 50%](#{large_image_upload.short_url}) [/quote] @@ -1055,7 +1087,7 @@ RSpec.describe CookedPostProcessor do "", ) - 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.post_process @@ -1101,7 +1133,7 @@ RSpec.describe CookedPostProcessor do .with(url, anything) .returns("") - 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") PostHotlinkedMedia.create!( @@ -1145,7 +1177,7 @@ RSpec.describe CookedPostProcessor do .with(url, anything) .returns("") - 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", @@ -1182,7 +1214,7 @@ RSpec.describe CookedPostProcessor do 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") @@ -1212,7 +1244,7 @@ RSpec.describe CookedPostProcessor do 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/article.jpeg", post: post, status: "too_large") @@ -1242,7 +1274,7 @@ RSpec.describe CookedPostProcessor do .with(url, anything) .returns("") - post = Fabricate(:post, raw: url) + post = Fabricate(:post, user: user_with_auto_groups, raw: url) PostHotlinkedMedia.create!( url: "//image.com/avatar.png", @@ -1274,7 +1306,7 @@ RSpec.describe CookedPostProcessor do HTML - post = Fabricate(:post, raw: url) + post = Fabricate(:post, user: user_with_auto_groups, raw: url) PostHotlinkedMedia.create!( url: "//example.com/favicon.ico", @@ -1537,6 +1569,7 @@ RSpec.describe CookedPostProcessor do the_post = Fabricate( :post, + user: user_with_auto_groups, raw: %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 = Fabricate( :post, + user: user_with_auto_groups, raw: %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(: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) cpp = CookedPostProcessor.new(the_post) @@ -1609,7 +1648,11 @@ RSpec.describe CookedPostProcessor do SiteSetting.prevent_anons_from_downloading_files = true 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.post_process_oneboxes @@ -1631,7 +1674,11 @@ RSpec.describe CookedPostProcessor do video_upload.update_column(:secure, true) 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.post_process_oneboxes @@ -1679,7 +1726,7 @@ RSpec.describe CookedPostProcessor do ![logo.png](upload://#{image_upload.base62_sha1}.#{image_upload.extension}) RAW - the_post = Fabricate(:post, raw: raw) + the_post = Fabricate(:post, user: user_with_auto_groups, raw: raw) cpp = CookedPostProcessor.new(the_post) cpp.post_process_oneboxes @@ -1719,7 +1766,7 @@ RSpec.describe CookedPostProcessor do describe "#remove_user_ids" do 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 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 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 it "doesn't award a badge when the emoji is in a quote" do @@ -1776,7 +1827,9 @@ RSpec.describe CookedPostProcessor do end 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 cpp.grant_badges @@ -1794,7 +1847,12 @@ RSpec.describe CookedPostProcessor do end 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.post_process_oneboxes cpp.grant_badges @@ -1802,7 +1860,8 @@ RSpec.describe CookedPostProcessor do end 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.post_process_oneboxes cpp.grant_badges @@ -1811,7 +1870,12 @@ RSpec.describe CookedPostProcessor do it "does not award the badge when the badge is disabled" do 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.post_process_oneboxes cpp.grant_badges @@ -1821,7 +1885,13 @@ RSpec.describe CookedPostProcessor do context "with reply_by_email" 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 it "awards a badge for replying via email" do @@ -1833,7 +1903,9 @@ RSpec.describe CookedPostProcessor do describe "quote processing" do 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 let(:cp) do @@ -1872,7 +1944,7 @@ RSpec.describe CookedPostProcessor do [/quote] and this is a reply 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 cpp.post_process_quotes @@ -1883,7 +1955,9 @@ RSpec.describe CookedPostProcessor do describe "full quote on direct reply" do 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 } [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 } it "works" do - hidden = Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") - small_action = Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) - reply = Fabricate(:post, topic: topic, raw: raw) + hidden = + Fabricate( + :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 topic.bumped_at = 1.day.ago @@ -1945,14 +2032,14 @@ RSpec.describe CookedPostProcessor do end 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 expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(reply.raw).to eq(raw3) end 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 expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(reply.raw).to eq(raw2) @@ -1961,22 +2048,33 @@ RSpec.describe CookedPostProcessor do it "does nothing when 'remove_full_quote' is disabled" do 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 expect(reply.raw).to eq(raw) end it "does not generate a blank HTML document" do - post = Fabricate(:post, topic: topic, raw: "") + post = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: "") cp = CookedPostProcessor.new(post) cp.post_process expect(cp.html).to eq("

") end it "works only on new posts" do - Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") - Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) + Fabricate( + :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) stub_image_size @@ -1995,8 +2093,8 @@ RSpec.describe CookedPostProcessor do end it "works with nested quotes" do - reply1 = Fabricate(:post, topic: topic, raw: raw) - reply2 = Fabricate(:post, topic: topic, raw: <<~RAW.strip) + reply1 = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: raw) + reply2 = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: <<~RAW.strip) [quote="#{reply1.user.username}, post:#{reply1.post_number}, topic:#{topic.id}"] #{raw} [/quote] @@ -2010,7 +2108,7 @@ RSpec.describe CookedPostProcessor do end 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) let!(:post) { Fabricate(:post, user: user, topic: topic, raw: 'this is the "first" post') } @@ -2055,9 +2153,22 @@ RSpec.describe CookedPostProcessor do end it "removes direct reply with full quotes" do - hidden = Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") - small_action = Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) - reply = Fabricate(:post, topic: topic, raw: raw) + hidden = + Fabricate( + :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 topic.bumped_at = 1.day.ago @@ -2078,14 +2189,14 @@ RSpec.describe CookedPostProcessor do end 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 expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(reply.raw).to eq(raw3) end 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 expect(topic.ordered_posts.pluck(:id)).to eq([post.id, reply.id]) expect(reply.raw).to eq(raw2) @@ -2094,22 +2205,33 @@ RSpec.describe CookedPostProcessor do it "does nothing when 'remove_full_quote' is disabled" do 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 expect(reply.raw).to eq(raw) end it "does not generate a blank HTML document" do - post = Fabricate(:post, topic: topic, raw: "") + post = Fabricate(:post, user: user_with_auto_groups, topic: topic, raw: "") cp = CookedPostProcessor.new(post) cp.post_process expect(cp.html).to eq("

") end it "works only on new posts" do - Fabricate(:post, topic: topic, hidden: true, raw: "this is the second post after") - Fabricate(:post, topic: topic, post_type: Post.types[:small_action]) + Fabricate( + :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) stub_image_size @@ -2129,7 +2251,7 @@ RSpec.describe CookedPostProcessor do it "works with nested quotes" do 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}"] #{raw} [/quote] @@ -2143,7 +2265,7 @@ RSpec.describe CookedPostProcessor do end 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) 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 it "escapes html entities in attributes per html5" do - post = Fabricate(:post, raw: '&<something>') + post = Fabricate(:post, user: user_with_auto_groups, raw: '&<something>') expect(post.cook(post.raw)).to eq('

&<something>

') expect(CookedPostProcessor.new(post).html).to eq('

&<something>

') end diff --git a/spec/lib/email/sender_spec.rb b/spec/lib/email/sender_spec.rb index 1b785588ade..91299ca43b1 100644 --- a/spec/lib/email/sender_spec.rb +++ b/spec/lib/email/sender_spec.rb @@ -541,7 +541,13 @@ RSpec.describe Email::Sender do #{UploadMarkdown.new(image).image_markdown} #{UploadMarkdown.new(csv_file).attachment_markdown} 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 end diff --git a/spec/lib/search_spec.rb b/spec/lib/search_spec.rb index c56d05f0f15..08d20d09d8d 100644 --- a/spec/lib/search_spec.rb +++ b/spec/lib/search_spec.rb @@ -290,10 +290,17 @@ RSpec.describe Search do describe "post indexing" do fab!(:category) { Fabricate(:category_with_definition, name: "america") } fab!(:topic) { Fabricate(:topic, title: "sam saffron test topic", category: category) } + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + let!(:post) do - Fabricate(:post, topic: topic, raw: 'this fun test ') + Fabricate( + :post, + topic: topic, + raw: 'this fun test ', + user: user, + ) end - let!(:post2) { Fabricate(:post, topic: topic) } + let!(:post2) { Fabricate(:post, topic: topic, user: user) } it "should index correctly" do search_data = post.post_search_data.search_data @@ -1995,8 +2002,9 @@ RSpec.describe Search do end it "can find posts with images" do - post_uploaded = Fabricate(:post_with_uploaded_image) - Fabricate(:post) + user = Fabricate(:user, refresh_auto_groups: true) + post_uploaded = Fabricate(:post_with_uploaded_image, user: user) + Fabricate(:post, user: user) CookedPostProcessor.new(post_uploaded).update_post_image diff --git a/spec/lib/shrink_uploaded_image_spec.rb b/spec/lib/shrink_uploaded_image_spec.rb index 06f0076a0ce..cec4ea60688 100644 --- a/spec/lib/shrink_uploaded_image_spec.rb +++ b/spec/lib/shrink_uploaded_image_spec.rb @@ -1,13 +1,20 @@ # frozen_string_literal: true RSpec.describe ShrinkUploadedImage do + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + + def create_post_with_upload + post = Fabricate(:post, raw: "", user: user) + post.link_post_uploads + post + end + context "when local uploads are enabled" do let(:upload) { Fabricate(:image_upload, width: 200, height: 200) } it "resizes the image" do + create_post_with_upload filesize_before = upload.filesize - post = Fabricate(:post, raw: "") - post.link_post_uploads result = ShrinkUploadedImage.new( @@ -32,8 +39,7 @@ RSpec.describe ShrinkUploadedImage do smaller_sha1 = Upload.generate_digest("/tmp/smaller.png") smaller_upload = Fabricate(:image_upload, sha1: smaller_sha1) - post = Fabricate(:post, raw: "") - post.link_post_uploads + post = create_post_with_upload post_hotlinked_media = PostHotlinkedMedia.create!( post: post, @@ -63,8 +69,8 @@ RSpec.describe ShrinkUploadedImage do end it "returns false if the image cannot be shrunk more" do - post = Fabricate(:post, raw: "") - post.link_post_uploads + create_post_with_upload + ShrinkUploadedImage.new( upload: upload, path: Discourse.store.path_for(upload), @@ -84,8 +90,7 @@ RSpec.describe ShrinkUploadedImage do end it "returns false when the upload is above the size limit" do - post = Fabricate(:post, raw: "") - post.link_post_uploads + create_post_with_upload SiteSetting.max_image_size_kb = 0 result = @@ -137,8 +142,7 @@ RSpec.describe ShrinkUploadedImage do it "resizes the image" do filesize_before = upload.filesize - post = Fabricate(:post, raw: "") - post.link_post_uploads + create_post_with_upload result = ShrinkUploadedImage.new( diff --git a/spec/lib/upload_recovery_spec.rb b/spec/lib/upload_recovery_spec.rb index 253386d0ff0..ead6eea7dae 100644 --- a/spec/lib/upload_recovery_spec.rb +++ b/spec/lib/upload_recovery_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe UploadRecovery do - fab!(:user) + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } let(:upload) do UploadCreator.new(file_from_fixtures("smallest.png"), "logo.png").create_for(user.id) diff --git a/spec/lib/validators/post_validator_spec.rb b/spec/lib/validators/post_validator_spec.rb index a13411ac65b..75962203d7a 100644 --- a/spec/lib/validators/post_validator_spec.rb +++ b/spec/lib/validators/post_validator_spec.rb @@ -184,42 +184,44 @@ RSpec.describe PostValidator do end describe "too_many_embedded_media" do + fab!(:new_user) { Fabricate(:newuser, refresh_auto_groups: true) } + 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 end 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) validator.max_embedded_media_validator(post) expect(post.errors.count).to be > 0 end 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) validator.max_embedded_media_validator(post) expect(post.errors.count).to be(0) end it "should be invalid when user trust level is not sufficient" do - SiteSetting.min_trust_to_post_embedded_media = 4 - post.acting_user = build(:leader) + SiteSetting.embedded_media_post_allowed_groups = Group::AUTO_GROUPS[:trust_level_4] + post.acting_user = Fabricate(:leader, groups: []) post.expects(:embedded_media_count).returns(2) validator.max_embedded_media_validator(post) expect(post.errors.count).to be > 0 end 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 validator.max_embedded_media_validator(post) expect(post.errors.count).to be(0) end 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 validator.max_embedded_media_validator(post) expect(post.errors.count).to be(0) diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 05fd815cb89..105e3aee57c 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -70,7 +70,8 @@ RSpec.describe Post do 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 } } describe "scopes" do @@ -336,36 +337,6 @@ RSpec.describe Post do expect(post_one_image).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 = 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 PrettyText.stubs(:cook).returns(post_with_favicon.raw) 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) 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 before { SiteSetting.newuser_max_embedded_media = 1 } @@ -1760,7 +1765,7 @@ RSpec.describe Post do end 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 } Link diff --git a/spec/models/trust_level3_requirements_spec.rb b/spec/models/trust_level3_requirements_spec.rb index 3de1711a260..9fab75617ef 100644 --- a/spec/models/trust_level3_requirements_spec.rb +++ b/spec/models/trust_level3_requirements_spec.rb @@ -454,14 +454,16 @@ RSpec.describe TrustLevel3Requirements do end 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(: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_post2) { create_post(topic: topic, user: user, created_at: 10.days.ago) } let(:private_post) do - Group.refresh_automatic_groups! create_post( user: user, archetype: Archetype.private_message, diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb index e644146753a..b955571fa0a 100644 --- a/spec/models/upload_spec.rb +++ b/spec/models/upload_spec.rb @@ -19,7 +19,12 @@ RSpec.describe Upload do describe ".with_no_non_post_relations" do it "does not find non-post related uploads" do post_upload = Fabricate(:upload) - post = Fabricate(:post, raw: "") + post = + Fabricate( + :post, + raw: "", + user: Fabricate(:user, refresh_auto_groups: true), + ) post.link_post_uploads badge_upload = Fabricate(:upload) diff --git a/spec/models/user_search_spec.rb b/spec/models/user_search_spec.rb index e7e5b3e4271..eda5e5e5211 100644 --- a/spec/models/user_search_spec.rb +++ b/spec/models/user_search_spec.rb @@ -191,7 +191,8 @@ RSpec.describe UserSearch do end 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 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, ) - Group.refresh_automatic_groups! pm_topic.invite(pm_topic.user, mr_b.username) results = search_for("", topic_id: pm_topic.id, searching_user: mr_b) diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index a9912613182..8d6e4ef32cf 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -3194,6 +3194,8 @@ RSpec.describe TopicsController do end describe "image only topic" do + before { Group.refresh_automatic_groups! } + it "uses image alt tag for meta description" do post = Fabricate( diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 8247ce3fca3..d9d260a9b0c 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -3,9 +3,9 @@ require "rotp" RSpec.describe UsersController do - fab!(:user) - fab!(:user1) { Fabricate(:user, username: "someusername") } - fab!(:another_user) { Fabricate(:user) } + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + fab!(:user1) { Fabricate(:user, username: "someusername", refresh_auto_groups: true) } + fab!(:another_user) { Fabricate(:user, refresh_auto_groups: true) } fab!(:invitee) { Fabricate(:user) } fab!(:inviter) { Fabricate(:user) } @@ -6786,10 +6786,9 @@ RSpec.describe UsersController do end 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 - Group.refresh_automatic_groups! create_post( user: user1, target_usernames: [user_2.username],