diff --git a/app/models/feedback_message.rb b/app/models/feedback_message.rb index a29efc3bd..cc933f406 100644 --- a/app/models/feedback_message.rb +++ b/app/models/feedback_message.rb @@ -1,8 +1,7 @@ class FeedbackMessage < ApplicationRecord - belongs_to :offender, foreign_key: "offender_id", class_name: "User", optional: true, inverse_of: :feedback_messages - belongs_to :reviewer, foreign_key: "reviewer_id", class_name: "User", optional: true, inverse_of: :feedback_messages - belongs_to :reporter, foreign_key: "reporter_id", class_name: "User", optional: true, inverse_of: :feedback_messages - belongs_to :affected, foreign_key: "affected_id", class_name: "User", optional: true, inverse_of: :feedback_messages + belongs_to :offender, foreign_key: "offender_id", class_name: "User", optional: true, inverse_of: :offender_feedback_messages + belongs_to :reporter, foreign_key: "reporter_id", class_name: "User", optional: true, inverse_of: :reporter_feedback_messages + belongs_to :affected, foreign_key: "affected_id", class_name: "User", optional: true, inverse_of: :affected_feedback_messages has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :destroy validates :feedback_type, :message, presence: true diff --git a/app/models/user.rb b/app/models/user.rb index d31f3cbd3..95fa6dd3c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,34 +21,39 @@ class User < ApplicationRecord has_many :badges, through: :badge_achievements has_many :collections, dependent: :destroy has_many :comments, dependent: :destroy - has_many :email_messages, class_name: "Ahoy::Message" + has_many :email_messages, class_name: "Ahoy::Message", dependent: :destroy has_many :github_repos, dependent: :destroy has_many :identities, dependent: :destroy has_many :mentions, dependent: :destroy has_many :messages, dependent: :destroy has_many :notes, as: :noteable, inverse_of: :noteable - has_many :profile_pins, as: :profile, inverse_of: :profile - has_many :authored_notes, as: :author, inverse_of: :author, class_name: "Note" + has_many :profile_pins, as: :profile, inverse_of: :profile, dependent: :delete_all + has_many :authored_notes, inverse_of: :author, class_name: "Note", foreign_key: :author_id, dependent: :delete_all has_many :notifications, dependent: :destroy has_many :reactions, dependent: :destroy has_many :tweets, dependent: :destroy has_many :chat_channel_memberships, dependent: :destroy has_many :chat_channels, through: :chat_channel_memberships has_many :notification_subscriptions, dependent: :destroy - has_many :feedback_messages - has_many :rating_votes + + has_many :offender_feedback_messages, class_name: "FeedbackMessage", inverse_of: :offender, foreign_key: :offender_id, dependent: :nullify + has_many :reporter_feedback_messages, class_name: "FeedbackMessage", inverse_of: :reporter, foreign_key: :reporter_id, dependent: :nullify + has_many :affected_feedback_messages, class_name: "FeedbackMessage", inverse_of: :affected, foreign_key: :affected_id, dependent: :nullify + + has_many :rating_votes, dependent: :destroy has_many :html_variants, dependent: :destroy - has_many :page_views - has_many :credits + has_many :page_views, dependent: :destroy + has_many :credits, dependent: :destroy has_many :classified_listings - has_many :poll_votes - has_many :poll_skips - has_many :backup_data, foreign_key: "instance_user_id", inverse_of: :instance_user, class_name: "BackupData" - has_many :display_ad_events + has_many :poll_votes, dependent: :destroy + has_many :poll_skips, dependent: :destroy + has_many :backup_data, foreign_key: "instance_user_id", inverse_of: :instance_user, class_name: "BackupData", dependent: :delete_all + has_many :display_ad_events, dependent: :destroy has_many :access_grants, class_name: "Doorkeeper::AccessGrant", foreign_key: :resource_owner_id, inverse_of: :resource_owner, dependent: :delete_all has_many :access_tokens, class_name: "Doorkeeper::AccessToken", foreign_key: :resource_owner_id, inverse_of: :resource_owner, dependent: :delete_all has_many :webhook_endpoints, class_name: "Webhook::Endpoint", foreign_key: :user_id, inverse_of: :user, dependent: :delete_all - has_many :user_blocks + has_many :blocker_blocks, class_name: "UserBlock", foreign_key: :blocker_id, inverse_of: :blocker, dependent: :delete_all + has_many :blocked_blocks, class_name: "UserBlock", foreign_key: :blocked_id, inverse_of: :blocked, dependent: :delete_all has_one :pro_membership, dependent: :destroy has_many :created_podcasts, class_name: "Podcast", foreign_key: :creator_id, inverse_of: :creator, dependent: :nullify diff --git a/app/models/user_block.rb b/app/models/user_block.rb index 7c0ef09f9..b0bafb264 100644 --- a/app/models/user_block.rb +++ b/app/models/user_block.rb @@ -1,6 +1,6 @@ class UserBlock < ApplicationRecord - belongs_to :blocker, foreign_key: "blocker_id", class_name: "User", inverse_of: :user_blocks - belongs_to :blocked, foreign_key: "blocked_id", class_name: "User", inverse_of: :user_blocks + belongs_to :blocker, foreign_key: "blocker_id", class_name: "User", inverse_of: :blocker_blocks + belongs_to :blocked, foreign_key: "blocked_id", class_name: "User", inverse_of: :blocked_blocks validates :blocked_id, :blocker_id, :config, presence: true validates :blocked_id, uniqueness: { scope: %i[blocker_id] } diff --git a/app/services/users/delete_activity.rb b/app/services/users/delete_activity.rb index 070fff596..f8a8fe36a 100644 --- a/app/services/users/delete_activity.rb +++ b/app/services/users/delete_activity.rb @@ -12,6 +12,38 @@ module Users user.mentions.delete_all user.badge_achievements.delete_all user.github_repos.delete_all + + user.access_grants.delete_all + user.access_tokens.delete_all + user.created_podcasts.update_all(creator_id: nil) + + user.blocker_blocks.delete_all + user.blocked_blocks.delete_all + user.webhook_endpoints.delete_all + user.authored_notes.delete_all + user.backup_data.delete_all + user.collections.delete_all + user.credits.delete_all + user.display_ad_events.delete_all + user.email_messages.delete_all + user.html_variants.delete_all + user.organization_memberships.delete_all + user.page_views.delete_all + user.poll_skips.delete_all + user.poll_votes.delete_all + user.pro_membership.delete if user.pro_membership.present? + user.profile_pins.delete_all + user.rating_votes.delete_all + user.tweets.delete_all + + handle_feedback_messages(user) + end + + # delete_all will nullify the corresponding foreign_key field bacause of the dependent: :nullify strategy + def handle_feedback_messages(user) + user.offender_feedback_messages.delete_all + user.reporter_feedback_messages.delete_all + user.affected_feedback_messages.delete_all end end end diff --git a/spec/factories/ahoy_message.rb b/spec/factories/ahoy_message.rb new file mode 100644 index 000000000..dc1d54652 --- /dev/null +++ b/spec/factories/ahoy_message.rb @@ -0,0 +1,5 @@ +FactoryBot.define do + factory :ahoy_message, class: "Ahoy::Message" do + user + end +end diff --git a/spec/factories/backup_data.rb b/spec/factories/backup_data.rb new file mode 100644 index 000000000..9bad23b54 --- /dev/null +++ b/spec/factories/backup_data.rb @@ -0,0 +1,9 @@ +FactoryBot.define do + factory :backup_data do + association :instance_user, factory: :user + after(:build) do |backup_data| + backup_data.instance = backup_data.instance_user.identities.first || create(:identity, user: backup_data.instance_user) + backup_data.json_data = backup_data.instance.attributes + end + end +end diff --git a/spec/factories/chat_channel_memberships.rb b/spec/factories/chat_channel_memberships.rb index 5537885f1..1d3874266 100644 --- a/spec/factories/chat_channel_memberships.rb +++ b/spec/factories/chat_channel_memberships.rb @@ -1,4 +1,6 @@ FactoryBot.define do factory :chat_channel_membership do + user + association :chat_channel, channel_type: "open" end end diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb index 3a9e3ca14..63afe803f 100644 --- a/spec/factories/comments.rb +++ b/spec/factories/comments.rb @@ -1,11 +1,7 @@ FactoryBot.define do - factory :comment do + factory :comment, aliases: [:article_comment] do user - body_markdown { Faker::Hipster.paragraph(sentence_count: 1) } - commentable_id { rand(1000) } - commentable_type { "Article" } - factory :article_comment do - association :commentable, factory: :article - end + body_markdown { Faker::Hipster.paragraph(sentence_count: 1) } + association :commentable, factory: :article end end diff --git a/spec/factories/display_ad_events.rb b/spec/factories/display_ad_events.rb index a4c9a9e38..719a49add 100644 --- a/spec/factories/display_ad_events.rb +++ b/spec/factories/display_ad_events.rb @@ -2,5 +2,6 @@ FactoryBot.define do factory :display_ad_event do category { "impression" } context_type { "home" } + display_ad end end diff --git a/spec/factories/display_ads.rb b/spec/factories/display_ads.rb index cb0ccbd15..6a8d6d521 100644 --- a/spec/factories/display_ads.rb +++ b/spec/factories/display_ads.rb @@ -2,5 +2,6 @@ FactoryBot.define do factory :display_ad do placement_area { "sidebar_left" } body_markdown { "Hello _hey_ Hey hey" } + organization end end diff --git a/spec/factories/doorkeeper_access_grants.rb b/spec/factories/doorkeeper_access_grants.rb new file mode 100644 index 000000000..02139d9cd --- /dev/null +++ b/spec/factories/doorkeeper_access_grants.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :doorkeeper_access_grant, class: "Doorkeeper::AccessGrant" do + application + expires_in { 600 } + redirect_uri { "urn:ietf:wg:oauth:2.0:oob" } + end +end diff --git a/spec/factories/feedback_messages.rb b/spec/factories/feedback_messages.rb index 87cb837cb..5737cd44d 100644 --- a/spec/factories/feedback_messages.rb +++ b/spec/factories/feedback_messages.rb @@ -1,8 +1,9 @@ FactoryBot.define do factory :feedback_message do - transient do - reporter_id { 1 } - end + feedback_type { "abuse-reports" } + message { Faker::Hipster.paragraph(sentence_count: 1) } + category { "rude or vulgar" } + reported_url { "/" } after(:create) do |feedback_message, evaluator| feedback_message.update(reporter_id: evaluator.reporter_id) diff --git a/spec/factories/note.rb b/spec/factories/note.rb new file mode 100644 index 000000000..fd3826712 --- /dev/null +++ b/spec/factories/note.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :note do + association :noteable, factory: :user + content { Faker::Book.title } + reason { "misc_note" } + end +end diff --git a/spec/factories/notification_subscriptions.rb b/spec/factories/notification_subscriptions.rb index da0fd2fe2..52f57def2 100644 --- a/spec/factories/notification_subscriptions.rb +++ b/spec/factories/notification_subscriptions.rb @@ -1,4 +1,6 @@ FactoryBot.define do factory :notification_subscription do + user + association :notifiable, factory: :article end end diff --git a/spec/factories/organization_memberships.rb b/spec/factories/organization_memberships.rb index 45ac8e2ae..c2dce017b 100644 --- a/spec/factories/organization_memberships.rb +++ b/spec/factories/organization_memberships.rb @@ -1,8 +1,7 @@ FactoryBot.define do factory :organization_membership do - # TODO: replace with `user` and `organization` since this currently doesn't have a belongs_to relationship - user_id { rand(6) } - organization_id { rand(6) } + user + organization type_of_user { "member" } end end diff --git a/spec/factories/poll_options.rb b/spec/factories/poll_options.rb index d50be7800..3e6c56087 100644 --- a/spec/factories/poll_options.rb +++ b/spec/factories/poll_options.rb @@ -1,5 +1,6 @@ FactoryBot.define do factory :poll_option do + poll markdown { Faker::Hipster.words(number: 3) } end end diff --git a/spec/factories/poll_skips.rb b/spec/factories/poll_skips.rb index 48d359ba2..8317313e1 100644 --- a/spec/factories/poll_skips.rb +++ b/spec/factories/poll_skips.rb @@ -1,4 +1,6 @@ FactoryBot.define do factory :poll_skip do + poll + user end end diff --git a/spec/factories/poll_votes.rb b/spec/factories/poll_votes.rb index b636322e3..a8cf29a8b 100644 --- a/spec/factories/poll_votes.rb +++ b/spec/factories/poll_votes.rb @@ -1,4 +1,7 @@ FactoryBot.define do factory :poll_vote do + user + poll + poll_option end end diff --git a/spec/factories/polls.rb b/spec/factories/polls.rb index 247349149..c75640c36 100644 --- a/spec/factories/polls.rb +++ b/spec/factories/polls.rb @@ -1,5 +1,6 @@ FactoryBot.define do factory :poll do + article prompt_markdown { Faker::Hipster.words(number: 5) } poll_options_input_array { [rand(5).to_s, rand(5).to_s, rand(5).to_s, rand(5).to_s] } end diff --git a/spec/factories/profile_pins.rb b/spec/factories/profile_pins.rb index caf7eab03..07976bab4 100644 --- a/spec/factories/profile_pins.rb +++ b/spec/factories/profile_pins.rb @@ -1,6 +1,8 @@ FactoryBot.define do factory :profile_pin do - pinnable_type { "Article" } - profile_type { "User" } + association :profile, factory: :user + after(:build) do |profile_pin| + profile_pin.pinnable ||= create(:article, user: profile_pin.profile) + end end end diff --git a/spec/factories/rating_votes.rb b/spec/factories/rating_votes.rb index 71fadd5a2..ac4201020 100644 --- a/spec/factories/rating_votes.rb +++ b/spec/factories/rating_votes.rb @@ -1,6 +1,10 @@ FactoryBot.define do factory :rating_vote do + user group { "experience_level" } rating { rand(1.0..8.0) } + after(:build) do |vote| + vote.article ||= create(:article, user: vote.user) + end end end diff --git a/spec/factories/reactions.rb b/spec/factories/reactions.rb index d13ed3b71..bbf2799de 100644 --- a/spec/factories/reactions.rb +++ b/spec/factories/reactions.rb @@ -1,14 +1,13 @@ FactoryBot.define do factory :reaction do - reactable_id { rand(10_000) } user - reactable_type { "Article" } + association :reactable, factory: :article category { "like" } end factory :reading_reaction, class: "Reaction" do user - reactable { create(:article) } + association :reactable, factory: :article category { "readinglist" } end end diff --git a/spec/factories/tweets.rb b/spec/factories/tweets.rb new file mode 100644 index 000000000..fdae99e4c --- /dev/null +++ b/spec/factories/tweets.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :tweet do + twitter_id_code { rand(10_000) } + full_fetched_object_serialized { Faker::Book.title } + end +end diff --git a/spec/factories/user_blocks.rb b/spec/factories/user_blocks.rb index 99b772bd9..6a70b95ed 100644 --- a/spec/factories/user_blocks.rb +++ b/spec/factories/user_blocks.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :user_block do - blocker { user } - blocked { user } + association :blocker, factory: :user + association :blocked, factory: :user config { "default" } end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 4f55c0625..72d91abab 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -94,7 +94,7 @@ FactoryBot.define do after(:create) do |user| other_user = create(:user) article = create(:article, user_id: other_user.id) - create(:comment, user_id: user.id, commentable_id: article.id) + create(:comment, user_id: user.id, commentable: article) user.update(comments_count: 1) end end @@ -102,7 +102,7 @@ FactoryBot.define do trait :with_article_and_comment do after(:create) do |user| article = create(:article, user_id: user.id) - create(:comment, user_id: user.id, commentable_id: article.id) + create(:comment, user_id: user.id, commentable: article) user.update(articles_count: 1, comments_count: 1) end end diff --git a/spec/labor/cache_buster_spec.rb b/spec/labor/cache_buster_spec.rb index b4ef10ef3..d225aae97 100644 --- a/spec/labor/cache_buster_spec.rb +++ b/spec/labor/cache_buster_spec.rb @@ -4,7 +4,7 @@ RSpec.describe CacheBuster, type: :labor do let(:cache_buster) { described_class } let(:user) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } let(:organization) { create(:organization) } let(:listing) { create(:classified_listing, user_id: user.id, category: "cfp") } let(:podcast) { create(:podcast) } diff --git a/spec/labor/rate_limit_checker_spec.rb b/spec/labor/rate_limit_checker_spec.rb index aabbb068a..d8d1db0d9 100644 --- a/spec/labor/rate_limit_checker_spec.rb +++ b/spec/labor/rate_limit_checker_spec.rb @@ -17,13 +17,13 @@ RSpec.describe RateLimitChecker, type: :labor do end it "returns true if too many comments at once" do - create_list(:comment, 2, user_id: user.id, commentable_id: article.id) + create_list(:comment, 2, user_id: user.id, commentable: article) expect(rate_limit_checker.limit_by_action("comment_creation")).to eq(true) end it "triggers ping admin when too many comments" do allow(RateLimitCheckerWorker).to receive(:perform_async) - create_list(:comment, 2, user_id: user.id, commentable_id: article.id) + create_list(:comment, 2, user_id: user.id, commentable: article) rate_limit_checker.limit_by_action("comment_creation") expect(RateLimitCheckerWorker).to have_received(:perform_async).with(user.id, "comment_creation") end diff --git a/spec/mailers/notify_mailer_spec.rb b/spec/mailers/notify_mailer_spec.rb index e82c53d58..1280feb22 100644 --- a/spec/mailers/notify_mailer_spec.rb +++ b/spec/mailers/notify_mailer_spec.rb @@ -4,7 +4,7 @@ RSpec.describe NotifyMailer, type: :mailer do let(:user) { create(:user) } let(:user2) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } describe "#new_reply_email" do let(:email) { described_class.new_reply_email(comment) } diff --git a/spec/models/profile_pin_spec.rb b/spec/models/profile_pin_spec.rb index c3504c87d..96fd8f672 100644 --- a/spec/models/profile_pin_spec.rb +++ b/spec/models/profile_pin_spec.rb @@ -7,21 +7,22 @@ RSpec.describe ProfilePin, type: :model do describe "number of pins" do let_it_be(:articles) { create_list(:article, 4, user: user) } let_it_be(:pins) do - articles.each { |article| create(:profile_pin, pinnable_id: article.id, profile_id: user.id) } + articles.each { |article| create(:profile_pin, pinnable: article, profile: user) } end let(:fifth_article) { create(:article, user: user) } let(:sixth_article) { create(:article, user: user) } it "allows up to five pins per user" do - pin = build(:profile_pin, pinnable_id: fifth_article.id, profile_id: user.id) + pin = build(:profile_pin, pinnable: fifth_article, profile: user) expect(pin).to be_valid end it "disallows the sixth pin" do - create(:profile_pin, pinnable_id: fifth_article.id, profile_id: user.id) + create(:profile_pin, pinnable: fifth_article, profile: user) + user.reload expect do - create(:profile_pin, pinnable_id: sixth_article.id, profile_id: user.id) + create(:profile_pin, pinnable: sixth_article, profile: user) end.to raise_error(ActiveRecord::RecordInvalid) end end @@ -30,13 +31,13 @@ RSpec.describe ProfilePin, type: :model do let_it_be(:article) { create(:article, user: user) } it "ensures pinnable belongs to the same profile" do - pin = build(:profile_pin, pinnable_id: article.id, profile_id: create(:user).id) + pin = build(:profile_pin, pinnable: article, profile: create(:user)) expect(pin).not_to be_valid end it "ensures one pin per pinnable per profile" do - create(:profile_pin, pinnable_id: article.id, profile_id: user.id) - other_pin = build(:profile_pin, pinnable_id: article.id, profile_id: user.id) + create(:profile_pin, pinnable: article, profile: user) + other_pin = build(:profile_pin, pinnable: article, profile: user) expect(other_pin).not_to be_valid end end diff --git a/spec/requests/buffer_updates_spec.rb b/spec/requests/buffer_updates_spec.rb index 8f275b5f8..d041855fd 100644 --- a/spec/requests/buffer_updates_spec.rb +++ b/spec/requests/buffer_updates_spec.rb @@ -5,7 +5,7 @@ RSpec.describe "BufferUpdates", type: :request do let(:mod_user) { create(:user) } let(:article) { create(:article, user_id: user.id) } let(:mod_article) { create(:article, user_id: mod_user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } context "when trusted user is logged in" do before do diff --git a/spec/requests/comments_destroy_spec.rb b/spec/requests/comments_destroy_spec.rb index a2eb00761..4b4d029e0 100644 --- a/spec/requests/comments_destroy_spec.rb +++ b/spec/requests/comments_destroy_spec.rb @@ -10,7 +10,7 @@ RSpec.describe "CommentsDestroy", type: :request do describe "GET /:username/comment/:id_code/delete_confirm" do it "renders the confirmation message" do - comment = create(:comment, user_id: user.id, commentable_id: article.id) + comment = create(:comment, user_id: user.id, commentable: article) get comment.path + "/delete_confirm" expect(response.body).to include("Are you sure you want to delete this comment") end @@ -19,19 +19,19 @@ RSpec.describe "CommentsDestroy", type: :request do describe "DELETE /comments/:id" do context "when comment has no children" do it "destroys the comment" do - comment = create(:comment, user_id: user.id, commentable_id: article.id) + comment = create(:comment, user_id: user.id, commentable: article) delete "/comments/#{comment.id}" expect(Comment.all.size).to eq(0) end end context "when comment has children" do - let(:parent_comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:parent_comment) { create(:comment, user_id: user.id, commentable: article) } let(:child_comment) do create( :comment, user_id: user.id, - commentable_id: article.id, + commentable: article, parent_id: parent_comment.id, ) end diff --git a/spec/requests/comments_update_spec.rb b/spec/requests/comments_update_spec.rb index 99cdf3c33..01ecc55e7 100644 --- a/spec/requests/comments_update_spec.rb +++ b/spec/requests/comments_update_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe "CommentsUpdate", type: :request do let(:user) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } before do sign_in user diff --git a/spec/requests/internal/buffer_updates_spec.rb b/spec/requests/internal/buffer_updates_spec.rb index b2ad95f31..1ce2aeba7 100644 --- a/spec/requests/internal/buffer_updates_spec.rb +++ b/spec/requests/internal/buffer_updates_spec.rb @@ -4,7 +4,7 @@ require "requests/shared_examples/internal_policy_dependant_request" RSpec.describe "/internal/buffer_updates", type: :request do let(:user) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } it_behaves_like "an InternalPolicy dependant request", BufferUpdate do let(:request) { post "/internal/buffer_updates" } diff --git a/spec/requests/internal/reactions_spec.rb b/spec/requests/internal/reactions_spec.rb index 98ecc33d3..547cf3ed4 100644 --- a/spec/requests/internal/reactions_spec.rb +++ b/spec/requests/internal/reactions_spec.rb @@ -11,7 +11,7 @@ RSpec.describe "/internal/reactions", type: :request do sign_in admin end - let(:reaction) { create(:reaction, category: "vomit", user_id: user.id, reactable_id: article.id) } + let(:reaction) { create(:reaction, category: "vomit", user_id: user.id, reactable: article) } it "updates reaction to be confirmed" do put "/internal/reactions/#{reaction.id}", params: { @@ -34,7 +34,7 @@ RSpec.describe "/internal/reactions", type: :request do sign_in user end - let(:reaction) { create(:reaction, category: "vomit", user_id: user.id, reactable_id: article.id) } + let(:reaction) { create(:reaction, category: "vomit", user_id: user.id, reactable: article) } it "updates reaction to be confirmed" do invalid_request = lambda do diff --git a/spec/requests/internal/users_banish_spec.rb b/spec/requests/internal/users_banish_spec.rb index 2da4f963a..4dfd27c25 100644 --- a/spec/requests/internal/users_banish_spec.rb +++ b/spec/requests/internal/users_banish_spec.rb @@ -170,7 +170,7 @@ RSpec.describe "Internal::Users", type: :request do :comment, body_markdown: "Hello @#{user.username}, you are cool.", user_id: user2.id, - commentable_id: article2.id, + commentable: article2, ) perform_enqueued_jobs do Mention.create_all(comment) diff --git a/spec/requests/organizations_update_spec.rb b/spec/requests/organizations_update_spec.rb index a2b613a8a..393c0575f 100644 --- a/spec/requests/organizations_update_spec.rb +++ b/spec/requests/organizations_update_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "OrganizationsUpdate", type: :request do let(:user) { create(:user, :org_admin) } let(:org_id) { user.organizations.first.id } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } before do sign_in user diff --git a/spec/requests/profile_pins_spec.rb b/spec/requests/profile_pins_spec.rb index 5aa30f23e..6438e932c 100644 --- a/spec/requests/profile_pins_spec.rb +++ b/spec/requests/profile_pins_spec.rb @@ -33,7 +33,7 @@ RSpec.describe "ProfilePins", type: :request do describe "PUT /profile_pins/:id" do # delete it "adds pin on behalf of current user" do - profile_pin = create(:profile_pin, pinnable_id: article.id, profile_id: user.id) + profile_pin = create(:profile_pin, pinnable: article, profile: user) put "/profile_pins/#{profile_pin.id}" expect(ProfilePin.all.size).to eq(0) end diff --git a/spec/requests/reactions_spec.rb b/spec/requests/reactions_spec.rb index 2c51ad808..186798287 100644 --- a/spec/requests/reactions_spec.rb +++ b/spec/requests/reactions_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe "Reactions", type: :request do let(:user) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, commentable_id: article.id) } + let(:comment) { create(:comment, commentable: article) } let(:max_age) { FastlyRails.configuration.max_age } let(:stale_if_error) { FastlyRails.configuration.stale_if_error } diff --git a/spec/requests/reading_list_items_spec.rb b/spec/requests/reading_list_items_spec.rb index e94aa5762..ed2648928 100644 --- a/spec/requests/reading_list_items_spec.rb +++ b/spec/requests/reading_list_items_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe "ReadingListItems", type: :request do let(:user) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:reaction) { create(:reaction, reactable_id: article.id, user_id: user.id) } + let(:reaction) { create(:reaction, reactable: article, user_id: user.id) } before do sign_in user diff --git a/spec/requests/social_previews_spec.rb b/spec/requests/social_previews_spec.rb index b7164e94b..97d7c2101 100644 --- a/spec/requests/social_previews_spec.rb +++ b/spec/requests/social_previews_spec.rb @@ -5,7 +5,7 @@ RSpec.describe "SocialPreviews", type: :request do let(:tag) { create(:tag, badge: create(:badge)) } let(:organization) { create(:organization) } let(:article) { create(:article, user_id: user.id, tags: tag.name) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } let(:image_url) { "https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1" } let(:listing) { create(:classified_listing, user_id: user.id, category: "cfp") } diff --git a/spec/requests/user/user_profile_spec.rb b/spec/requests/user/user_profile_spec.rb index 5084f2e8f..b15cf93d9 100644 --- a/spec/requests/user/user_profile_spec.rb +++ b/spec/requests/user/user_profile_spec.rb @@ -14,7 +14,7 @@ RSpec.describe "UserProfiles", type: :request do create(:article, user_id: user.id) create(:article, user_id: user.id) last_article = create(:article, user_id: user.id) - create(:profile_pin, pinnable_id: last_article.id, profile_id: user.id) + create(:profile_pin, pinnable: last_article, profile: user) get "/#{user.username}" expect(response.body).to include "Pinned" end diff --git a/spec/services/mentions/create_all_spec.rb b/spec/services/mentions/create_all_spec.rb index a26b5b990..a46d092c5 100644 --- a/spec/services/mentions/create_all_spec.rb +++ b/spec/services/mentions/create_all_spec.rb @@ -4,13 +4,13 @@ RSpec.describe Mentions::CreateAll, type: :service do let(:user) { create(:user) } let(:user2) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user2.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user2.id, commentable: article) } let(:comment2) do create( :comment, body_markdown: "Hello @#{user.username}, you are cool.", user_id: user2.id, - commentable_id: article.id, + commentable: article, ) end diff --git a/spec/services/notifications/remove_all_spec.rb b/spec/services/notifications/remove_all_spec.rb index 33110f069..1d3b32804 100644 --- a/spec/services/notifications/remove_all_spec.rb +++ b/spec/services/notifications/remove_all_spec.rb @@ -4,8 +4,8 @@ RSpec.describe Notifications::RemoveAll, type: :service do let(:user) { create(:user) } let(:user2) { create(:user) } let(:article) { create(:article, user_id: user.id) } - let(:comment) { create(:comment, user_id: user.id, commentable_id: article.id) } - let(:comment2) { create(:comment, user_id: user2.id, commentable_id: article.id) } + let(:comment) { create(:comment, user_id: user.id, commentable: article) } + let(:comment2) { create(:comment, user_id: user2.id, commentable: article) } let(:mention) { create(:mention, user_id: user.id, mentionable_id: comment.id, mentionable_type: "Comment") } let(:mention2) { create(:mention, user_id: user2.id, mentionable_id: comment2.id, mentionable_type: "Comment") } let(:notifiable_collection_ids) { [mention.id, mention2.id] } diff --git a/spec/services/suggester/articles/boosted_spec.rb b/spec/services/suggester/articles/boosted_spec.rb index 488524460..b4750cad5 100644 --- a/spec/services/suggester/articles/boosted_spec.rb +++ b/spec/services/suggester/articles/boosted_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Suggester::Articles::Boosted, type: :service do let(:organization) { create(:organization) } let(:tag) { create(:tag, supported: true) } let(:article) { create(:article, tags: [tag.name], featured: true) } - let(:reaction) { create(:reaction, user_id: user.id, reactable_id: article.id) } + let(:reaction) { create(:reaction, user_id: user.id, reactable: article) } it "returns an article" do user.follow(tag) diff --git a/spec/services/suggester/articles/classic_spec.rb b/spec/services/suggester/articles/classic_spec.rb index 376850d1e..3a3f74cfb 100644 --- a/spec/services/suggester/articles/classic_spec.rb +++ b/spec/services/suggester/articles/classic_spec.rb @@ -4,12 +4,12 @@ RSpec.describe Suggester::Articles::Classic, type: :service do let(:user) { create(:user) } let(:tag) { create(:tag, supported: true) } let(:article) { create(:article, tags: [tag.name], featured: true) } - let(:reaction) { create(:reaction, user_id: user.id, reactable_id: article.id) } + let(:reaction) { create(:reaction, user_id: user.id, reactable: article) } it "returns an article" do - create(:reaction, user_id: user.id, reactable_id: article.id) - create(:reaction, user_id: user.id, reactable_id: article.id, category: "thinking") - create(:reaction, user_id: user.id, reactable_id: article.id, category: "unicorn") + create(:reaction, user_id: user.id, reactable: article) + create(:reaction, user_id: user.id, reactable: article, category: "thinking") + create(:reaction, user_id: user.id, reactable: article, category: "unicorn") expect(described_class.new(article).get.first.id).to eq article.id end @@ -20,14 +20,14 @@ RSpec.describe Suggester::Articles::Classic, type: :service do it "returns single article if multiple qualify" do user.follow(tag) - create(:reaction, user_id: user.id, reactable_id: article.id) - create(:reaction, user_id: user.id, reactable_id: article.id, category: "thinking") - create(:reaction, user_id: user.id, reactable_id: article.id, category: "unicorn") + create(:reaction, user_id: user.id, reactable: article) + create(:reaction, user_id: user.id, reactable: article, category: "thinking") + create(:reaction, user_id: user.id, reactable: article, category: "unicorn") user2 = create(:user) article2 = create(:article, user_id: user2.id) - create(:reaction, user_id: user2.id, reactable_id: article2.id) - create(:reaction, user_id: user2.id, reactable_id: article2.id, category: "thinking") - create(:reaction, user_id: user2.id, reactable_id: article2.id, category: "unicorn") + create(:reaction, user_id: user2.id, reactable: article2) + create(:reaction, user_id: user2.id, reactable: article2, category: "thinking") + create(:reaction, user_id: user2.id, reactable: article2, category: "unicorn") expect(described_class.new(article).get.first&.id).to eq article.id end end diff --git a/spec/services/users/delete_articles_spec.rb b/spec/services/users/delete_articles_spec.rb index bffb6276c..86d43b5d5 100644 --- a/spec/services/users/delete_articles_spec.rb +++ b/spec/services/users/delete_articles_spec.rb @@ -27,7 +27,7 @@ RSpec.describe Users::DeleteArticles, type: :service do it "deletes articles' comments" do described_class.call(user) - expect(Comment.where(commentable_id: article, commentable_type: "Article").any?).to be false + expect(Comment.where(commentable_id: article.id, commentable_type: "Article").any?).to be false end it "busts cache" do diff --git a/spec/services/users/delete_spec.rb b/spec/services/users/delete_spec.rb index 2859673be..35223858a 100644 --- a/spec/services/users/delete_spec.rb +++ b/spec/services/users/delete_spec.rb @@ -34,4 +34,56 @@ RSpec.describe Users::Delete, type: :service do described_class.call(user) expect(Rails.cache).to have_received(:delete).with("user-destroy-token-#{user.id}") end + + # check that all the associated records are being destroyed, except for those that are kept explicitly (kept_associations) + describe "deleting associations" do + let(:kept_association_names) { %i[created_podcasts notes offender_feedback_messages reporter_feedback_messages affected_feedback_messages] } + let(:direct_associations) { User.reflect_on_all_associations.reject { |a| a.options.key?(:join_table) || a.options.key?(:through) } } + let!(:user_associations) do + create_associations(direct_associations.reject { |a| kept_association_names.include?(a.name) }) + end + let!(:kept_associations) do + create_associations(direct_associations.select { |a| kept_association_names.include?(a.name) }) + end + + def create_associations(names) + associations = [] + names.each do |association| + if user.public_send(association.name).present? + associations.push(*user.public_send(association.name)) + else + singular_name = ActiveSupport::Inflector.singularize(association.name) + class_name = association.options[:class_name] || singular_name + possible_factory_name = class_name.underscore.tr("/", "_") + inverse_of = association.options[:inverse_of] || association.options[:as] || :user + record = create(possible_factory_name, inverse_of => user) + associations.push record + end + end + associations + end + + it "keeps the kept associations" do + expect(kept_associations).not_to be_empty + user.reload + described_class.call(user) + aggregate_failures "associations should exist" do + kept_associations.each do |kept_association| + expect { kept_association.reload }.not_to raise_error + end + end + end + + it "deletes all the associations" do + # making sure that the association records were actually created + expect(user_associations).not_to be_empty + user.reload + described_class.call(user) + aggregate_failures "associations should not exist" do + user_associations.each do |user_association| + expect { user_association.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end + end end diff --git a/spec/system/comments/user_fills_out_comment_spec.rb b/spec/system/comments/user_fills_out_comment_spec.rb index ac0a060d2..cfab6c183 100644 --- a/spec/system/comments/user_fills_out_comment_spec.rb +++ b/spec/system/comments/user_fills_out_comment_spec.rb @@ -36,7 +36,7 @@ RSpec.describe "Creating Comment", type: :system, js: true do end it "User replies to a comment" do - create(:comment, commentable_id: article.id, user_id: user.id) + create(:comment, commentable: article, user_id: user.id) visit article.path.to_s wait_for_javascript