mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 03:00:33 +02:00
Add email subscriptions (#38163)
This commit is contained in:
7
spec/fabricators/email_subscription_fabricator.rb
Normal file
7
spec/fabricators/email_subscription_fabricator.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:email_subscription) do
|
||||
account
|
||||
email { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } }
|
||||
locale 'en'
|
||||
end
|
||||
51
spec/mailers/email_subscription_mailer_spec.rb
Normal file
51
spec/mailers/email_subscription_mailer_spec.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe EmailSubscriptionMailer do
|
||||
describe '.confirmation' do
|
||||
let(:email_subscription) { Fabricate(:email_subscription) }
|
||||
let(:mail) { described_class.with(subscription: email_subscription).confirmation }
|
||||
|
||||
it 'renders the email' do
|
||||
expect { mail.deliver }
|
||||
.to send_email(
|
||||
to: email_subscription.email,
|
||||
from: 'notifications@localhost',
|
||||
subject: I18n.t('email_subscription_mailer.confirmation.subject')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.notification' do
|
||||
let(:email_subscription) { Fabricate(:email_subscription, confirmed_at: Time.now.utc) }
|
||||
let(:statuses) { Fabricate.times(num_of_statuses, :status) }
|
||||
let(:mail) { described_class.with(subscription: email_subscription).notification(statuses) }
|
||||
|
||||
context 'with a single status' do
|
||||
let(:num_of_statuses) { 1 }
|
||||
|
||||
it 'renders the email' do
|
||||
expect { mail.deliver }
|
||||
.to send_email(
|
||||
to: email_subscription.email,
|
||||
from: 'notifications@localhost',
|
||||
subject: I18n.t('email_subscription_mailer.notification.subject', count: statuses.size, name: email_subscription.account.display_name, excerpt: statuses.first.text.truncate(17))
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple statuses' do
|
||||
let(:num_of_statuses) { 2 }
|
||||
|
||||
it 'renders the email' do
|
||||
expect { mail.deliver }
|
||||
.to send_email(
|
||||
to: email_subscription.email,
|
||||
from: 'notifications@localhost',
|
||||
subject: I18n.t('email_subscription_mailer.notification.subject', count: statuses.size, name: email_subscription.account.display_name, excerpt: ActionController::Base.helpers.truncate(statuses.first.text, length: 17))
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
15
spec/mailers/previews/email_subscription_mailer_preview.rb
Normal file
15
spec/mailers/previews/email_subscription_mailer_preview.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Preview all emails at http://localhost:3000/rails/mailers/admin_mailer
|
||||
|
||||
class EmailSubscriptionMailerPreview < ActionMailer::Preview
|
||||
# Preview this email at http://localhost:3000/rails/mailers/email_subscription_mailer/confirmation
|
||||
def confirmation
|
||||
EmailSubscriptionMailer.with(subscription: EmailSubscription.last!).confirmation
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/email_subscription_mailer/notification
|
||||
def notification
|
||||
EmailSubscriptionMailer.with(subscription: EmailSubscription.last!).notification(Status.where(visibility: :public).without_replies.without_reblogs.limit(5))
|
||||
end
|
||||
end
|
||||
43
spec/models/email_subscription_spec.rb
Normal file
43
spec/models/email_subscription_spec.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe EmailSubscription do
|
||||
describe '#confirmed?' do
|
||||
it 'returns true when confirmed' do
|
||||
subject.confirmed_at = Time.now.utc
|
||||
expect(subject.confirmed?).to be true
|
||||
end
|
||||
|
||||
it 'returns false when not confirmed' do
|
||||
subject.confirmed_at = nil
|
||||
expect(subject.confirmed?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirm!' do
|
||||
subject { Fabricate(:email_subscription) }
|
||||
|
||||
it 'records confirmation time' do
|
||||
subject.confirm!
|
||||
expect(subject.confirmed_at).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Callbacks' do
|
||||
subject { Fabricate(:email_subscription) }
|
||||
|
||||
it 'generates token and delivers confirmation email', :inline_jobs do
|
||||
emails = capture_emails { subject }
|
||||
|
||||
expect(subject.confirmed_at).to be_nil
|
||||
expect(subject.confirmation_token).to_not be_nil
|
||||
expect(emails.size).to eq(1)
|
||||
expect(emails.first)
|
||||
.to have_attributes(
|
||||
to: contain_exactly(subject.email),
|
||||
subject: eq(I18n.t('email_subscription_mailer.confirmation.subject', name: subject.account.username, domain: Rails.configuration.x.local_domain))
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
48
spec/requests/api/v1/accounts/email_subscriptions_spec.rb
Normal file
48
spec/requests/api/v1/accounts/email_subscriptions_spec.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Accounts Email Subscriptions API', feature: :email_subscriptions do
|
||||
let(:account) { Fabricate(:user).account }
|
||||
|
||||
describe 'POST /api/v1/accounts/:id/email_subscriptions' do
|
||||
context 'when the account has the permission' do
|
||||
let(:role) { Fabricate(:user_role, permissions: UserRole::FLAGS[:manage_email_subscriptions]) }
|
||||
|
||||
before do
|
||||
account.user.update!(role: role)
|
||||
end
|
||||
|
||||
context 'when user has enabled the setting' do
|
||||
before do
|
||||
account.user.settings['email_subscriptions'] = true
|
||||
account.user.save!
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
post "/api/v1/accounts/#{account.id}/email_subscriptions", params: { email: 'test@example.com' }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user has not enabled the setting' do
|
||||
it 'returns http not found' do
|
||||
post "/api/v1/accounts/#{account.id}/email_subscriptions", params: { email: 'test@example.com' }
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the account does not have the permission' do
|
||||
it 'returns http not found' do
|
||||
post "/api/v1/accounts/#{account.id}/email_subscriptions", params: { email: 'test@example.com' }
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
33
spec/requests/email_subscriptions/confirmations_spec.rb
Normal file
33
spec/requests/email_subscriptions/confirmations_spec.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Email Subscriptions Confirmation' do
|
||||
describe 'GET /email_subscriptions/confirmation' do
|
||||
context 'when email subscription is unconfirmed' do
|
||||
let!(:email_subscription) { Fabricate(:email_subscription, confirmed_at: nil) }
|
||||
|
||||
it 'renders success page and updates subscription as confirmed' do
|
||||
get email_subscriptions_confirmation_path(confirmation_token: email_subscription.confirmation_token)
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(email_subscription.reload.confirmed?)
|
||||
.to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when email subscription is already confirmed' do
|
||||
let!(:email_subscription) { Fabricate(:email_subscription, confirmed_at: Time.now.utc) }
|
||||
|
||||
it 'renders success page' do
|
||||
get email_subscriptions_confirmation_path(confirmation_token: email_subscription.confirmation_token)
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
expect(email_subscription.reload.confirmed?)
|
||||
.to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'MailSubscriptionsController' do
|
||||
RSpec.describe 'UnsubscriptionsController' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { user.to_sgid(for: 'unsubscribe').to_s }
|
||||
let(:type) { 'follow' }
|
||||
@@ -39,9 +39,8 @@ RSpec.describe 'MailSubscriptionsController' do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
expect(response.body).to include(
|
||||
I18n.t('mail_subscriptions.unsubscribe.action')
|
||||
I18n.t('unsubscriptions.show.action')
|
||||
)
|
||||
expect(response.body).to include(user.email)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,9 +59,8 @@ RSpec.describe 'MailSubscriptionsController' do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
expect(response.body).to include(
|
||||
I18n.t('mail_subscriptions.unsubscribe.complete')
|
||||
I18n.t('unsubscriptions.create.title')
|
||||
)
|
||||
expect(response.body).to include(user.email)
|
||||
end
|
||||
|
||||
it 'updates notification settings' do
|
||||
@@ -3,35 +3,31 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe BootstrapTimelineService do
|
||||
subject { described_class.new }
|
||||
subject { described_class.new.call(new_user.account) }
|
||||
|
||||
let(:invite) { nil }
|
||||
let(:new_user) { Fabricate(:user, invite_code: invite&.code) }
|
||||
|
||||
context 'when the new user has registered from an invite' do
|
||||
let(:service) { instance_double(FollowService) }
|
||||
let(:autofollow) { false }
|
||||
let(:inviter) { Fabricate(:user, confirmed_at: 2.days.ago) }
|
||||
let(:invite) { Fabricate(:invite, user: inviter, max_uses: nil, expires_at: 1.hour.from_now, autofollow: autofollow) }
|
||||
let(:new_user) { Fabricate(:user, invite_code: invite.code) }
|
||||
|
||||
before do
|
||||
allow(FollowService).to receive(:new).and_return(service)
|
||||
allow(service).to receive(:call)
|
||||
end
|
||||
|
||||
context 'when the invite has auto-follow enabled' do
|
||||
let(:autofollow) { true }
|
||||
|
||||
it 'calls FollowService to follow the inviter' do
|
||||
subject.call(new_user.account)
|
||||
expect(service).to have_received(:call).with(new_user.account, inviter.account)
|
||||
it 'follows the inviter' do
|
||||
subject
|
||||
expect(new_user.account.following?(inviter.account)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the invite does not have auto-follow enable' do
|
||||
let(:autofollow) { false }
|
||||
|
||||
it 'calls FollowService to follow the inviter' do
|
||||
subject.call(new_user.account)
|
||||
expect(service).to_not have_received(:call)
|
||||
it 'does not follow the inviter' do
|
||||
subject
|
||||
expect(new_user.account.following?(inviter.account)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user