mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-05 17:31:12 +00:00
Extract User::Confirmation
concern (#35582)
This commit is contained in:
parent
15b72591d4
commit
6dc55a2f4e
22
app/models/concerns/user/confirmation.rb
Normal file
22
app/models/concerns/user/confirmation.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module User::Confirmation
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :confirmed, -> { where.not(confirmed_at: nil) }
|
||||
scope :unconfirmed, -> { where(confirmed_at: nil) }
|
||||
|
||||
def confirm
|
||||
wrap_email_confirmation { super }
|
||||
end
|
||||
end
|
||||
|
||||
def confirmed?
|
||||
confirmed_at.present?
|
||||
end
|
||||
|
||||
def unconfirmed?
|
||||
!confirmed?
|
||||
end
|
||||
end
|
|
@ -58,6 +58,7 @@ class User < ApplicationRecord
|
|||
|
||||
include LanguagesHelper
|
||||
include Redisable
|
||||
include User::Confirmation
|
||||
include User::HasSettings
|
||||
include User::LdapAuthenticable
|
||||
include User::Omniauthable
|
||||
|
@ -118,8 +119,6 @@ class User < ApplicationRecord
|
|||
scope :recent, -> { order(id: :desc) }
|
||||
scope :pending, -> { where(approved: false) }
|
||||
scope :approved, -> { where(approved: true) }
|
||||
scope :confirmed, -> { where.not(confirmed_at: nil) }
|
||||
scope :unconfirmed, -> { where(confirmed_at: nil) }
|
||||
scope :enabled, -> { where(disabled: false) }
|
||||
scope :disabled, -> { where(disabled: true) }
|
||||
scope :active, -> { confirmed.signed_in_recently.account_not_suspended }
|
||||
|
@ -184,10 +183,6 @@ class User < ApplicationRecord
|
|||
current_sign_in_at.present? && current_sign_in_at >= ACTIVE_DURATION.ago
|
||||
end
|
||||
|
||||
def confirmed?
|
||||
confirmed_at.present?
|
||||
end
|
||||
|
||||
def invited?
|
||||
invite_id.present?
|
||||
end
|
||||
|
@ -212,12 +207,6 @@ class User < ApplicationRecord
|
|||
account_id
|
||||
end
|
||||
|
||||
def confirm
|
||||
wrap_email_confirmation do
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Mark current email as confirmed, bypassing Devise
|
||||
def mark_email_as_confirmed!
|
||||
wrap_email_confirmation do
|
||||
|
@ -264,10 +253,6 @@ class User < ApplicationRecord
|
|||
confirmed? && approved? && !disabled? && !account.unavailable? && !account.memorial?
|
||||
end
|
||||
|
||||
def unconfirmed?
|
||||
!confirmed?
|
||||
end
|
||||
|
||||
def unconfirmed_or_pending?
|
||||
unconfirmed? || pending?
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ RSpec.describe User do
|
|||
let(:account) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it_behaves_like 'two_factor_backupable'
|
||||
it_behaves_like 'User::Confirmation'
|
||||
|
||||
describe 'otp_secret' do
|
||||
it 'encrypts the saved value' do
|
||||
|
@ -65,14 +66,6 @@ RSpec.describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'confirmed' do
|
||||
it 'returns an array of users who are confirmed' do
|
||||
Fabricate(:user, confirmed_at: nil)
|
||||
confirmed_user = Fabricate(:user, confirmed_at: Time.zone.now)
|
||||
expect(described_class.confirmed).to contain_exactly(confirmed_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'signed_in_recently' do
|
||||
it 'returns a relation of users who have signed in during the recent period' do
|
||||
recent_sign_in_user = Fabricate(:user, current_sign_in_at: within_duration_window_days.ago)
|
||||
|
@ -228,79 +221,6 @@ RSpec.describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#confirmed?' do
|
||||
it 'returns true when a confirmed_at is set' do
|
||||
user = Fabricate.build(:user, confirmed_at: Time.now.utc)
|
||||
expect(user.confirmed?).to be true
|
||||
end
|
||||
|
||||
it 'returns false if a confirmed_at is nil' do
|
||||
user = Fabricate.build(:user, confirmed_at: nil)
|
||||
expect(user.confirmed?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirm' do
|
||||
subject { user.confirm }
|
||||
|
||||
let(:new_email) { 'new-email@example.com' }
|
||||
|
||||
before do
|
||||
allow(TriggerWebhookWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
context 'when the user is already confirmed' do
|
||||
let!(:user) { Fabricate(:user, confirmed_at: Time.now.utc, approved: true, unconfirmed_email: new_email) }
|
||||
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is a new user' do
|
||||
let(:user) { Fabricate(:user, confirmed_at: nil, unconfirmed_email: new_email) }
|
||||
|
||||
context 'when the user is already approved' do
|
||||
before do
|
||||
Setting.registrations_mode = 'approved'
|
||||
user.approve!
|
||||
end
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user does not require explicit approval' do
|
||||
before do
|
||||
Setting.registrations_mode = 'open'
|
||||
end
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user requires explicit approval but is not approved' do
|
||||
before do
|
||||
Setting.registrations_mode = 'approved'
|
||||
end
|
||||
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#approve!' do
|
||||
subject { user.approve! }
|
||||
|
||||
|
|
114
spec/support/examples/models/concerns/user/confirmation.rb
Normal file
114
spec/support/examples/models/concerns/user/confirmation.rb
Normal file
|
@ -0,0 +1,114 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.shared_examples 'User::Confirmation' do
|
||||
describe 'Scopes' do
|
||||
let!(:unconfirmed_user) { Fabricate :user, confirmed_at: nil }
|
||||
let!(:confirmed_user) { Fabricate :user, confirmed_at: Time.now.utc }
|
||||
|
||||
describe '.confirmed' do
|
||||
it 'returns users who are confirmed' do
|
||||
expect(described_class.confirmed)
|
||||
.to contain_exactly(confirmed_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.unconfirmed' do
|
||||
it 'returns users who are not confirmed' do
|
||||
expect(described_class.unconfirmed)
|
||||
.to contain_exactly(unconfirmed_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirmed?' do
|
||||
subject { Fabricate.build(:user, confirmed_at:) }
|
||||
|
||||
context 'when confirmed_at is set' do
|
||||
let(:confirmed_at) { Time.now.utc }
|
||||
|
||||
it { is_expected.to be_confirmed }
|
||||
end
|
||||
|
||||
context 'when confirmed_at is not set' do
|
||||
let(:confirmed_at) { nil }
|
||||
|
||||
it { is_expected.to_not be_confirmed }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#unconfirmed?' do
|
||||
subject { Fabricate.build(:user, confirmed_at:) }
|
||||
|
||||
context 'when confirmed_at is set' do
|
||||
let(:confirmed_at) { Time.now.utc }
|
||||
|
||||
it { is_expected.to_not be_unconfirmed }
|
||||
end
|
||||
|
||||
context 'when confirmed_at is not set' do
|
||||
let(:confirmed_at) { nil }
|
||||
|
||||
it { is_expected.to be_unconfirmed }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirm' do
|
||||
subject { user.confirm }
|
||||
|
||||
let(:new_email) { 'new-email@host.example' }
|
||||
|
||||
before { allow(TriggerWebhookWorker).to receive(:perform_async) }
|
||||
|
||||
context 'when the user is already confirmed' do
|
||||
let!(:user) { Fabricate(:user, confirmed_at: Time.now.utc, approved: true, unconfirmed_email: new_email) }
|
||||
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is a new user' do
|
||||
let(:user) { Fabricate(:user, confirmed_at: nil, unconfirmed_email: new_email) }
|
||||
|
||||
context 'when the user does not require explicit approval' do
|
||||
before { Setting.registrations_mode = 'open' }
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when registrations mode is approved' do
|
||||
before { Setting.registrations_mode = 'approved' }
|
||||
|
||||
context 'when the user is already approved' do
|
||||
before { user.approve! }
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is not approved' do
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user