1
0
Fork 0
mirror of https://github.com/mastodon/mastodon.git synced 2024-08-20 21:08:15 -07:00

Compare commits

...

7 commits

Author SHA1 Message Date
Matt Jankowski
46928808ef
Merge b33aa09787 into a50c8e951f 2024-07-31 14:05:07 +00:00
Claire
a50c8e951f
Fix issue with grouped notifications UI due to recent API change (#31224) 2024-07-31 13:23:08 +00:00
Claire
2c1e75727d
Change filtered notification banner design to take up less space (#31222) 2024-07-31 12:36:08 +00:00
Matt Jankowski
b33aa09787 Add required to belongs to check 2024-07-18 13:44:46 -04:00
Matt Jankowski
6b51f4c10b Use shoulda matchers validation presence matchers 2024-07-18 13:44:46 -04:00
Matt Jankowski
0194ecbc80 Configure shoulda matchers to integrate with rspec 2024-07-18 13:44:45 -04:00
Matt Jankowski
30eeb5dd5d Add shoulda-matchers gem 2024-07-18 13:44:45 -04:00
25 changed files with 52 additions and 197 deletions

View file

@ -155,6 +155,8 @@ group :test do
# Test harness fo rack components
gem 'rack-test', '~> 2.1'
gem 'shoulda-matchers'
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
gem 'simplecov', '~> 0.22', require: false
gem 'simplecov-lcov', '~> 0.8', require: false

View file

@ -790,6 +790,8 @@ GEM
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
semantic_range (3.0.0)
shoulda-matchers (6.2.0)
activesupport (>= 5.2.0)
sidekiq (6.5.12)
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
@ -1038,6 +1040,7 @@ DEPENDENCIES
sanitize (~> 6.0)
scenic (~> 1.7)
selenium-webdriver
shoulda-matchers
sidekiq (~> 6.5)
sidekiq-bulk (~> 0.2.0)
sidekiq-scheduler (~> 5.0)

View file

@ -60,7 +60,7 @@ export interface BaseNotificationGroupJSON {
interface NotificationGroupWithStatusJSON extends BaseNotificationGroupJSON {
type: NotificationWithStatusType;
status: ApiStatusJSON;
status_id: string;
}
interface NotificationWithStatusJSON extends BaseNotificationJSON {

View file

@ -49,21 +49,14 @@ export const FilteredNotificationsBanner: React.FC = () => {
<span>
<FormattedMessage
id='filtered_notifications_banner.pending_requests'
defaultMessage='Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know'
defaultMessage='From {count, plural, =0 {no one} one {one person} other {# people}} you may know'
values={{ count: policy.summary.pending_requests_count }}
/>
</span>
</div>
<div className='filtered-notifications-banner__badge'>
<div className='filtered-notifications-banner__badge__badge'>
{toCappedNumber(policy.summary.pending_notifications_count)}
</div>
<FormattedMessage
id='filtered_notifications_banner.mentions'
defaultMessage='{count, plural, one {mention} other {mentions}}'
values={{ count: policy.summary.pending_notifications_count }}
/>
{toCappedNumber(policy.summary.pending_notifications_count)}
</div>
</Link>
);

View file

@ -300,8 +300,7 @@
"filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
"filter_modal.select_filter.title": "Filter this post",
"filter_modal.title.status": "Filter a post",
"filtered_notifications_banner.mentions": "{count, plural, one {mention} other {mentions}}",
"filtered_notifications_banner.pending_requests": "Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know",
"filtered_notifications_banner.pending_requests": "From {count, plural, =0 {no one} one {one person} other {# people}} you may know",
"filtered_notifications_banner.title": "Filtered notifications",
"firehose.all": "All",
"firehose.local": "This server",

View file

@ -124,9 +124,9 @@ export function createNotificationGroupFromJSON(
case 'mention':
case 'poll':
case 'update': {
const { status, ...groupWithoutStatus } = group;
const { status_id: statusId, ...groupWithoutStatus } = group;
return {
statusId: status.id,
statusId,
sampleAccountIds,
...groupWithoutStatus,
};

View file

@ -10171,25 +10171,10 @@ noscript {
}
&__badge {
display: flex;
align-items: center;
border-radius: 999px;
background: var(--background-border-color);
color: $darker-text-color;
padding: 4px;
padding-inline-end: 8px;
gap: 6px;
font-weight: 500;
font-size: 11px;
line-height: 16px;
word-break: keep-all;
&__badge {
background: $ui-button-background-color;
color: $white;
border-radius: 100px;
padding: 2px 8px;
}
background: $ui-button-background-color;
color: $white;
border-radius: 100px;
padding: 2px 8px;
}
}

View file

@ -722,11 +722,7 @@ RSpec.describe Account do
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)
end
it { is_expected.to validate_presence_of(:username) }
it 'squishes the username before validation' do
account = Fabricate(:account, domain: nil, username: " \u3000bob \t \u00a0 \n ")

View file

@ -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

@ -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

@ -4,11 +4,6 @@ require 'rails_helper'
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

@ -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: [])

View file

@ -4,11 +4,7 @@ require 'rails_helper'
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

@ -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

@ -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

@ -4,19 +4,8 @@ require 'rails_helper'
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

@ -3,14 +3,7 @@
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
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

@ -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

@ -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@')

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: [])

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end