Merge remote-tracking branch 'parent/main' into upstream-20240906

This commit is contained in:
KMY 2024-09-06 08:42:24 +09:00
commit f18eabfe75
689 changed files with 4369 additions and 2434 deletions

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AccountAlias do
describe 'Normalizations' do
describe 'acct' do
it { is_expected.to normalize(:acct).from(' @username@domain ').to('username@domain') }
end
end
end

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe AccountFilter do
RSpec.describe AccountFilter do
describe 'with empty params' do
it 'excludes instance actor by default' do
filter = described_class.new({})

View file

@ -3,6 +3,12 @@
require 'rails_helper'
RSpec.describe AccountMigration do
describe 'Normalizations' do
describe 'acct' do
it { is_expected.to normalize(:acct).from(' @username@domain ').to('username@domain') }
end
end
describe 'validations' do
subject { described_class.new(account: source_account, acct: target_acct) }

View file

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe Account do
include_examples 'Reviewable'
context 'with an account record' do
subject { Fabricate(:account) }
@ -944,17 +946,38 @@ RSpec.describe Account do
end
end
describe 'validations' do
it 'is invalid without a username' do
account = Fabricate.build(:account, username: nil)
account.valid?
expect(account).to model_have_error_on_field(:username)
describe '#prepare_contents' do
subject { Fabricate.build :account, domain: domain, note: ' padded note ', display_name: ' padded name ' }
context 'with local account' do
let(:domain) { nil }
it 'strips values' do
expect { subject.valid? }
.to change(subject, :note).to('padded note')
.and(change(subject, :display_name).to('padded name'))
end
end
it 'squishes the username before validation' do
account = Fabricate(:account, domain: nil, username: " \u3000bob \t \u00a0 \n ")
expect(account.username).to eq 'bob'
context 'with remote account' do
let(:domain) { 'host.example' }
it 'preserves values' do
expect { subject.valid? }
.to not_change(subject, :note)
.and(not_change(subject, :display_name))
end
end
end
describe 'Normalizations' do
describe 'username' do
it { is_expected.to normalize(:username).from(" \u3000bob \t \u00a0 \n ").to('bob') }
end
end
describe 'validations' do
it { is_expected.to validate_presence_of(:username) }
context 'when is local' do
it 'is invalid if the username is not unique in case-insensitive comparison among local accounts' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe AccountWarningPreset do
RSpec.describe AccountWarningPreset do
describe 'alphabetical' do
let(:first) { Fabricate(:account_warning_preset, title: 'aaa', text: 'aaa') }
let(:second) { Fabricate(:account_warning_preset, title: 'bbb', text: 'aaa') }

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AccountWarning do
describe 'Normalizations' do
describe 'text' do
it { is_expected.to normalize(:text).from(nil).to('') }
end
end
end

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Admin::AppealFilter do
RSpec.describe Admin::AppealFilter do
describe '#results' do
let(:approved_appeal) { Fabricate(:appeal, approved_at: 10.days.ago) }
let(:not_approved_appeal) { Fabricate(:appeal, approved_at: nil) }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Admin::TagFilter do
RSpec.describe Admin::TagFilter do
describe 'with invalid params' do
it 'raises with key error' do
filter = described_class.new(wrong: true)

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Announcement do
RSpec.describe Announcement do
describe 'Scopes' do
context 'with published and unpublished records' do
let!(:published) { Fabricate(:announcement, published: true) }
@ -64,14 +64,7 @@ describe Announcement do
end
describe 'Validations' do
describe 'text' do
it 'validates presence of attribute' do
record = Fabricate.build(:announcement, text: nil)
expect(record).to_not be_valid
expect(record.errors[:text]).to be_present
end
end
it { is_expected.to validate_presence_of(:text) }
describe 'ends_at' do
it 'validates presence when starts_at is present' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Appeal do
RSpec.describe Appeal do
describe 'Validations' do
it 'validates text length is under limit' do
appeal = Fabricate.build(

View file

@ -4,17 +4,8 @@ require 'rails_helper'
RSpec.describe Block do
describe 'validations' do
it 'is invalid without an account' do
block = Fabricate.build(:block, account: nil)
block.valid?
expect(block).to model_have_error_on_field(:account)
end
it 'is invalid without a target_account' do
block = Fabricate.build(:block, target_account: nil)
block.valid?
expect(block).to model_have_error_on_field(:target_account)
end
it { is_expected.to belong_to(:account).required }
it { is_expected.to belong_to(:target_account).required }
end
it 'removes blocking cache after creation' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Account::Counters do
RSpec.describe Account::Counters do
let!(:account) { Fabricate(:account) }
describe '#increment_count!' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Account::FinderConcern do
RSpec.describe Account::FinderConcern do
describe 'local finders' do
let!(:account) { Fabricate(:account, username: 'Alice') }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Account::Interactions do
RSpec.describe Account::Interactions do
let(:account) { Fabricate(:account, username: 'account') }
let(:account_id) { account.id }
let(:account_ids) { [account_id] }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Account::StatusesSearch do
RSpec.describe Account::StatusesSearch do
let(:account) { Fabricate(:account, indexable: indexable) }
before do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Status::ThreadingConcern do
RSpec.describe Status::ThreadingConcern do
describe '#ancestors' do
let!(:alice) { Fabricate(:account, username: 'alice') }
let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }

View file

@ -2,13 +2,8 @@
require 'rails_helper'
describe CustomEmojiCategory do
RSpec.describe CustomEmojiCategory do
describe 'validations' do
it 'validates name presence' do
record = described_class.new(name: nil)
expect(record).to_not be_valid
expect(record).to model_have_error_on_field(:name)
end
it { is_expected.to validate_presence_of(:name) }
end
end

View file

@ -125,22 +125,9 @@ RSpec.describe CustomEmoji, :attachment_processing do
end
describe 'Normalizations' do
describe 'downcase domain value' do
context 'with a mixed case domain value' do
it 'normalizes the value to downcased' do
custom_emoji = Fabricate.build(:custom_emoji, domain: 'wWw.MaStOdOn.CoM')
expect(custom_emoji.domain).to eq('www.mastodon.com')
end
end
context 'with a nil domain value' do
it 'leaves the value as nil' do
custom_emoji = Fabricate.build(:custom_emoji, domain: nil)
expect(custom_emoji.domain).to be_nil
end
end
describe 'domain' do
it { is_expected.to normalize(:domain).from('wWw.MaStOdOn.CoM').to('www.mastodon.com') }
it { is_expected.to normalize(:domain).from(nil).to(nil) }
end
end
end

View file

@ -4,19 +4,8 @@ require 'rails_helper'
RSpec.describe CustomFilter do
describe 'Validations' do
it 'requires presence of title' do
record = described_class.new(title: '')
record.valid?
expect(record).to model_have_error_on_field(:title)
end
it 'requires presence of context' do
record = described_class.new(context: nil)
record.valid?
expect(record).to model_have_error_on_field(:context)
end
it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_presence_of(:context) }
it 'requires non-empty of context' do
record = described_class.new(context: [])
@ -34,10 +23,8 @@ RSpec.describe CustomFilter do
end
describe 'Normalizations' do
it 'cleans up context values' do
record = described_class.new(context: ['home', 'notifications', 'public ', ''])
expect(record.context).to eq(%w(home notifications public))
describe 'context' do
it { is_expected.to normalize(:context).from(['home', 'notifications', 'public ', '']).to(%w(home notifications public)) }
end
end
end

View file

@ -2,13 +2,9 @@
require 'rails_helper'
describe DomainAllow do
RSpec.describe DomainAllow do
describe 'Validations' do
it 'is invalid without a domain' do
domain_allow = Fabricate.build(:domain_allow, domain: nil)
domain_allow.valid?
expect(domain_allow).to model_have_error_on_field(:domain)
end
it { is_expected.to validate_presence_of(:domain) }
it 'is invalid if the same normalized domain already exists' do
_domain_allow = Fabricate(:domain_allow, domain: 'にゃん')

View file

@ -4,11 +4,7 @@ require 'rails_helper'
RSpec.describe DomainBlock do
describe 'validations' do
it 'is invalid without a domain' do
domain_block = Fabricate.build(:domain_block, domain: nil)
domain_block.valid?
expect(domain_block).to model_have_error_on_field(:domain)
end
it { is_expected.to validate_presence_of(:domain) }
it 'is invalid if the same normalized domain already exists' do
_domain_block = Fabricate(:domain_block, domain: 'にゃん')

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Export do
RSpec.describe Export do
let(:account) { Fabricate(:account) }
let(:target_accounts) do
[{}, { username: 'one', domain: 'local.host' }].map(&method(:Fabricate).curry(2).call(:account))

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe ExtendedDescription do
RSpec.describe ExtendedDescription do
describe '.current' do
context 'with the default values' do
it 'makes a new instance' do

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe FeaturedTag do
describe 'Normalizations' do
describe 'name' do
it { is_expected.to normalize(:name).from(' #hashtag ').to('hashtag') }
end
end
end

View file

@ -9,17 +9,8 @@ RSpec.describe Follow do
describe 'validations' do
subject { described_class.new(account: alice, target_account: bob, rate_limit: true) }
it 'is invalid without an account' do
follow = Fabricate.build(:follow, account: nil)
follow.valid?
expect(follow).to model_have_error_on_field(:account)
end
it 'is invalid without a target_account' do
follow = Fabricate.build(:follow, target_account: nil)
follow.valid?
expect(follow).to model_have_error_on_field(:target_account)
end
it { is_expected.to belong_to(:account).required }
it { is_expected.to belong_to(:target_account).required }
it 'is invalid if account already follows too many people' do
alice.update(following_count: FollowLimitValidator::LIMIT)

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Form::AdminSettings do
RSpec.describe Form::AdminSettings do
describe 'validations' do
describe 'site_contact_username' do
context 'with no accounts' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Form::CustomEmojiBatch do
RSpec.describe Form::CustomEmojiBatch do
describe '#save' do
subject { described_class.new({ current_account: account }.merge(options)) }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Form::StatusFilterBatchAction do
RSpec.describe Form::StatusFilterBatchAction do
describe '#save!' do
it 'does nothing if status_filter_ids is empty' do
batch_action = described_class.new(status_filter_ids: [])

View file

@ -3,19 +3,8 @@
require 'rails_helper'
RSpec.describe Import do
let(:account) { Fabricate(:account) }
let(:type) { 'following' }
let(:data) { attachment_fixture('imports.txt') }
describe 'validations' do
it 'is invalid without an type' do
import = described_class.create(account: account, data: data)
expect(import).to model_have_error_on_field(:type)
end
it 'is invalid without a data' do
import = described_class.create(account: account, type: type)
expect(import).to model_have_error_on_field(:data)
end
describe 'Validations' do
it { is_expected.to validate_presence_of(:type) }
it { is_expected.to validate_presence_of(:data) }
end
end

View file

@ -2,21 +2,10 @@
require 'rails_helper'
describe IpBlock do
RSpec.describe IpBlock do
describe 'validations' do
it 'validates ip presence', :aggregate_failures do
ip_block = described_class.new(ip: nil, severity: :no_access)
expect(ip_block).to_not be_valid
expect(ip_block).to model_have_error_on_field(:ip)
end
it 'validates severity presence', :aggregate_failures do
ip_block = described_class.new(ip: '127.0.0.1', severity: nil)
expect(ip_block).to_not be_valid
expect(ip_block).to model_have_error_on_field(:severity)
end
it { is_expected.to validate_presence_of(:ip) }
it { is_expected.to validate_presence_of(:severity) }
it 'validates ip uniqueness', :aggregate_failures do
described_class.create!(ip: '127.0.0.1', severity: :no_access)

View file

@ -2,15 +2,8 @@
require 'rails_helper'
describe Marker do
describe 'validations' do
describe 'timeline' do
it 'must be included in valid list' do
record = described_class.new(timeline: 'not real timeline')
expect(record).to_not be_valid
expect(record).to model_have_error_on_field(:timeline)
end
end
RSpec.describe Marker do
describe 'Validations' do
it { is_expected.to validate_inclusion_of(:timeline).in_array(described_class::TIMELINES) }
end
end

View file

@ -257,12 +257,7 @@ RSpec.describe MediaAttachment, :attachment_processing do
end
end
it 'is invalid without file' do
media = described_class.new
expect(media.valid?).to be false
expect(media).to model_have_error_on_field(:file)
end
it { is_expected.to validate_presence_of(:file) }
describe 'size limit validation' do
it 'rejects video files that are too large' do

View file

@ -4,16 +4,7 @@ require 'rails_helper'
RSpec.describe Mention do
describe 'validations' do
it 'is invalid without an account' do
mention = Fabricate.build(:mention, account: nil)
mention.valid?
expect(mention).to model_have_error_on_field(:account)
end
it 'is invalid without a status' do
mention = Fabricate.build(:mention, status: nil)
mention.valid?
expect(mention).to model_have_error_on_field(:status)
end
it { is_expected.to belong_to(:account).required }
it { is_expected.to belong_to(:status).required }
end
end

View file

@ -3,7 +3,34 @@
require 'rails_helper'
RSpec.describe NotificationGroup do
subject { described_class.from_notification(notification) }
subject { described_class.from_notifications([notification]) }
context 'when favourite notifications' do
let(:target_status) { Fabricate(:status) }
let(:alice) { Fabricate(:account) }
let(:bob) { Fabricate(:account) }
let(:favourite) { Fabricate(:favourite, account: alice, status: target_status) }
let(:notification) { Fabricate(:notification, account: target_status.account, activity: favourite, group_key: group_key) }
let(:group_key) { 5 }
it 'a simple case' do
group = subject.first
expect(group).to_not be_nil
expect(group.notification.id).to eq notification.id
expect(group.sample_accounts.pluck(:id)).to eq [alice.id]
end
it 'multiple reactors' do
second = Fabricate(:favourite, account: bob, status: target_status)
Fabricate(:notification, account: target_status.account, activity: second, group_key: group_key)
group = subject.first
expect(group).to_not be_nil
expect(group.sample_accounts.pluck(:id)).to contain_exactly(alice.id, bob.id)
end
end
context 'when emoji reaction notifications' do
let(:target_status) { Fabricate(:status) }
@ -16,18 +43,30 @@ RSpec.describe NotificationGroup do
let(:group_key) { 5 }
it 'with single emoji_reaction' do
group = subject.emoji_reaction_groups.first
group = subject.first&.emoji_reaction_groups&.first
expect(group).to_not be_nil
expect(group.emoji_reaction.id).to eq emoji_reaction.id
expect(group.sample_accounts.map(&:id)).to contain_exactly(alice.id)
end
context 'when group_key is not defined' do
let(:group_key) { nil }
it 'with single emoji_reaction' do
group = subject.first&.emoji_reaction_groups&.first
expect(group).to_not be_nil
expect(group.emoji_reaction.id).to eq emoji_reaction.id
expect(group.sample_accounts.map(&:id)).to contain_exactly(alice.id)
end
end
it 'with multiple reactions' do
second = Fabricate(:emoji_reaction, account: bob, status: target_status, name: custom_emoji.shortcode, custom_emoji: custom_emoji)
Fabricate(:notification, account: target_status.account, activity: second, group_key: group_key)
group = subject.emoji_reaction_groups.first
group = subject.first&.emoji_reaction_groups&.first
expect(group).to_not be_nil
expect([emoji_reaction.id, second.id]).to include group.emoji_reaction.id
@ -40,8 +79,8 @@ RSpec.describe NotificationGroup do
third = Fabricate(:emoji_reaction, account: ohagi, status: target_status, name: '😀')
Fabricate(:notification, account: target_status.account, activity: third, group_key: group_key)
group = subject.emoji_reaction_groups.find { |g| g.emoji_reaction.name == custom_emoji.shortcode }
second_group = subject.emoji_reaction_groups.find { |g| g.emoji_reaction.name == '😀' }
group = subject.first.emoji_reaction_groups.find { |g| g.emoji_reaction.name == custom_emoji.shortcode }
second_group = subject.first.emoji_reaction_groups.find { |g| g.emoji_reaction.name == '😀' }
expect(group).to_not be_nil
expect([emoji_reaction.id, second.id]).to include group.emoji_reaction.id

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe OneTimeKey do
RSpec.describe OneTimeKey do
describe 'validations' do
context 'with an invalid signature' do
let(:one_time_key) { Fabricate.build(:one_time_key, signature: 'wrong!') }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Poll do
RSpec.describe Poll do
describe 'scopes' do
let(:status) { Fabricate(:status) }
let(:attached_poll) { Fabricate(:poll, status: status) }
@ -32,12 +32,9 @@ describe Poll do
describe 'validations' do
context 'when not valid' do
let(:poll) { Fabricate.build(:poll, expires_at: nil) }
subject { Fabricate.build(:poll) }
it 'is invalid without an expire date' do
poll.valid?
expect(poll).to model_have_error_on_field(:expires_at)
end
it { is_expected.to validate_presence_of(:expires_at) }
end
end
end

View file

@ -2,7 +2,9 @@
require 'rails_helper'
describe PreviewCardProvider do
RSpec.describe PreviewCardProvider do
include_examples 'Reviewable'
describe 'scopes' do
let(:trendable_and_reviewed) { Fabricate(:preview_card_provider, trendable: true, reviewed_at: 5.days.ago) }
let(:not_trendable_and_not_reviewed) { Fabricate(:preview_card_provider, trendable: false, reviewed_at: nil) }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe PreviewCard do
RSpec.describe PreviewCard do
describe 'validations' do
describe 'urls' do
it 'allows http schemes' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe PrivacyPolicy do
RSpec.describe PrivacyPolicy do
describe '.current' do
context 'with the default values' do
it 'has the privacy text' do

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe RelationshipFilter do
RSpec.describe RelationshipFilter do
let(:account) { Fabricate(:account) }
describe '#results' do

11
spec/models/relay_spec.rb Normal file
View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Relay do
describe 'Normalizations' do
describe 'inbox_url' do
it { is_expected.to normalize(:inbox_url).from(' http://host.example ').to('http://host.example') }
end
end
end

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe ReportFilter do
RSpec.describe ReportFilter do
describe 'with empty params' do
it 'defaults to unresolved reports list' do
filter = described_class.new({})

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Report do
RSpec.describe Report do
describe 'statuses' do
it 'returns the statuses for the report' do
status = Fabricate(:status)

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe Rule do
RSpec.describe Rule do
describe 'scopes' do
describe 'ordered' do
let(:deleted_rule) { Fabricate(:rule, deleted_at: 10.days.ago) }

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe StatusEdit do
RSpec.describe StatusEdit do
describe '#reblog?' do
it 'returns false' do
record = described_class.new

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe TagFeed do
RSpec.describe TagFeed do
describe '#get' do
let(:account) { Fabricate(:account) }
let(:tag_cats) { Fabricate(:tag, name: 'cats') }

View file

@ -3,6 +3,8 @@
require 'rails_helper'
RSpec.describe Tag do
include_examples 'Reviewable'
describe 'validations' do
it 'invalid with #' do
expect(described_class.new(name: '#hello_world')).to_not be_valid

View file

@ -32,11 +32,7 @@ RSpec.describe User do
end
describe 'validations' do
it 'is invalid without an account' do
user = Fabricate.build(:user, account: nil)
user.valid?
expect(user).to model_have_error_on_field(:account)
end
it { is_expected.to belong_to(:account).required }
it 'is invalid without a valid email' do
user = Fabricate.build(:user, email: 'john@')
@ -59,45 +55,18 @@ RSpec.describe User do
describe 'Normalizations' do
describe 'locale' do
it 'preserves valid locale' do
user = Fabricate.build(:user, locale: 'en')
expect(user.locale).to eq('en')
end
it 'cleans out invalid locale' do
user = Fabricate.build(:user, locale: 'toto')
expect(user.locale).to be_nil
end
it { is_expected.to_not normalize(:locale).from('en') }
it { is_expected.to normalize(:locale).from('toto').to(nil) }
end
describe 'time_zone' do
it 'preserves valid timezone' do
user = Fabricate.build(:user, time_zone: 'UTC')
expect(user.time_zone).to eq('UTC')
end
it 'cleans out invalid timezone' do
user = Fabricate.build(:user, time_zone: 'toto')
expect(user.time_zone).to be_nil
end
it { is_expected.to_not normalize(:time_zone).from('UTC') }
it { is_expected.to normalize(:time_zone).from('toto').to(nil) }
end
describe 'languages' do
it 'preserves valid options for languages' do
user = Fabricate.build(:user, chosen_languages: ['en', 'fr', ''])
expect(user.chosen_languages).to eq(['en', 'fr'])
end
it 'cleans out empty string from languages' do
user = Fabricate.build(:user, chosen_languages: [''])
expect(user.chosen_languages).to be_nil
end
describe 'chosen_languages' do
it { is_expected.to normalize(:chosen_languages).from(['en', 'fr', '']).to(%w(en fr)) }
it { is_expected.to normalize(:chosen_languages).from(['']).to(nil) }
end
end

View file

@ -4,37 +4,10 @@ require 'rails_helper'
RSpec.describe WebauthnCredential do
describe 'validations' do
it 'is invalid without an external id' do
webauthn_credential = Fabricate.build(:webauthn_credential, external_id: nil)
webauthn_credential.valid?
expect(webauthn_credential).to model_have_error_on_field(:external_id)
end
it 'is invalid without a public key' do
webauthn_credential = Fabricate.build(:webauthn_credential, public_key: nil)
webauthn_credential.valid?
expect(webauthn_credential).to model_have_error_on_field(:public_key)
end
it 'is invalid without a nickname' do
webauthn_credential = Fabricate.build(:webauthn_credential, nickname: nil)
webauthn_credential.valid?
expect(webauthn_credential).to model_have_error_on_field(:nickname)
end
it 'is invalid without a sign_count' do
webauthn_credential = Fabricate.build(:webauthn_credential, sign_count: nil)
webauthn_credential.valid?
expect(webauthn_credential).to model_have_error_on_field(:sign_count)
end
it { is_expected.to validate_presence_of(:external_id) }
it { is_expected.to validate_presence_of(:public_key) }
it { is_expected.to validate_presence_of(:nickname) }
it { is_expected.to validate_presence_of(:sign_count) }
it 'is invalid if already exist a webauthn credential with the same external id' do
Fabricate(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw')

View file

@ -6,12 +6,7 @@ RSpec.describe Webhook do
let(:webhook) { Fabricate(:webhook) }
describe 'Validations' do
it 'requires presence of events' do
record = described_class.new(events: nil)
record.valid?
expect(record).to model_have_error_on_field(:events)
end
it { is_expected.to validate_presence_of(:events) }
it 'requires non-empty events value' do
record = described_class.new(events: [])
@ -29,37 +24,35 @@ RSpec.describe Webhook do
end
describe 'Normalizations' do
it 'cleans up events values' do
record = described_class.new(events: ['account.approved', 'account.created ', ''])
expect(record.events).to eq(%w(account.approved account.created))
describe 'events' do
it { is_expected.to normalize(:events).from(['account.approved', 'account.created ', '']).to(%w(account.approved account.created)) }
end
end
describe '#rotate_secret!' do
it 'changes the secret' do
previous_value = webhook.secret
webhook.rotate_secret!
expect(webhook.secret).to_not be_blank
expect(webhook.secret).to_not eq previous_value
expect { webhook.rotate_secret! }
.to change(webhook, :secret)
expect(webhook.secret)
.to_not be_blank
end
end
describe '#enable!' do
before do
webhook.disable!
end
let(:webhook) { Fabricate(:webhook, enabled: false) }
it 'enables the webhook' do
webhook.enable!
expect(webhook.enabled?).to be true
expect { webhook.enable! }
.to change(webhook, :enabled?).to(true)
end
end
describe '#disable!' do
let(:webhook) { Fabricate(:webhook, enabled: true) }
it 'disables the webhook' do
webhook.disable!
expect(webhook.enabled?).to be false
expect { webhook.disable! }
.to change(webhook, :enabled?).to(false)
end
end
end