Skip to content

Commit

Permalink
Destroy talk media upon user deletion (#651)
Browse files Browse the repository at this point in the history
  • Loading branch information
Splines authored Aug 13, 2024
1 parent 8e44e6f commit 013cca2
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
17 changes: 17 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ class User < ApplicationRecord
after_create :set_consented_at
before_destroy :destroy_single_submissions, prepend: true

attr_accessor :skip_destroy_talk_media

before_destroy :destroy_talk_media_upon_user_deletion, prepend: true,
unless: :skip_destroy_talk_media

# users can comment stuff
acts_as_commontator

Expand Down Expand Up @@ -704,6 +709,7 @@ def archive_and_destroy(archive_name)
success = transfer_contributions_to(archive_user(archive_name))
return false unless success
end
self.skip_destroy_talk_media = true
destroy
end

Expand Down Expand Up @@ -839,6 +845,17 @@ def destroy_single_submissions
.map(&:id)).destroy_all
end

# Destroys all talk media of the user.
# If the user is an editor of media other than talk-related media,
# nothing will happen.
def destroy_talk_media_upon_user_deletion
return if edited_media.where.not(teachable_type: "Talk").any?

# Only delete media where the user is the sole editor.
sole_editor_media = edited_media.select { |m| m.editors.count == 1 }
Medium.where(id: sole_editor_media.pluck(:id)).destroy_all
end

def archive_email
splitting = DefaultSetting::PROJECT_EMAIL.split("@")
"#{splitting.first}-archive-#{id}@#{splitting.second}"
Expand Down
65 changes: 65 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,69 @@
# end
# end
# end

describe("#destroy_talk_media") do
let(:medium) do
medium = FactoryBot.build(:medium)
medium.teachable_type = "Lecture"
medium.save(validate: false)
medium
end

let(:medium_talk) do
medium = FactoryBot.build(:medium)
medium.teachable_type = "Talk"
medium.save(validate: false)
medium
end

context("when user is destroyed") do
it("method is called") do
user = FactoryBot.create(:confirmed_user)
expect(user).to receive(:destroy_talk_media_upon_user_deletion)
user.destroy
end

context("when user self-deletes (archive & destroy)") do
it("method is not called") do
user = FactoryBot.create(:confirmed_user)
expect(user).not_to receive(:destroy_talk_media_upon_user_deletion)
user.archive_and_destroy("dummy archive user name")
end
end
end

context("when user has media other than talk media") do
it("does not destroy any media") do
user = FactoryBot.create(:confirmed_user)
medium
medium_talk

# use .send(:...) to access private method
expect { user.send(:destroy_talk_media_upon_user_deletion) }
.not_to(change { Medium.count })
end
end

context("when user has only talk media") do
it("does not destroy talk media that has multiple editors") do
user = FactoryBot.create(:confirmed_user)
user2 = FactoryBot.create(:confirmed_user)
medium_talk.editors << user
medium_talk.editors << user2

expect { user.send(:destroy_talk_media_upon_user_deletion) }
.not_to(change { Medium.count })
end

it("destroys talk media that has only one editor") do
user = FactoryBot.create(:confirmed_user)
medium_talk.editors << user

expect { user.send(:destroy_talk_media_upon_user_deletion) }
.to(change { Medium.count }.by(-1)
.and(change { Medium.exists?(medium_talk.id) }.from(true).to(false)))
end
end
end
end

0 comments on commit 013cca2

Please sign in to comment.