From 62c996b52d4dc50e5713b8e7657fc5eaa52f39c8 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Sat, 10 Jun 2023 12:38:22 -0400 Subject: [PATCH] Reduce `RSpec/MultipleExpectations` cop max to 8 (#25313) --- .rubocop_todo.yml | 2 +- .../accounts/relationships_controller_spec.rb | 41 +++--- .../confirmations_controller_spec.rb | 31 +++-- spec/models/form/import_spec.rb | 49 +++++-- spec/models/notification_spec.rb | 120 ++++++++++-------- .../services/translate_status_service_spec.rb | 35 +++-- 6 files changed, 172 insertions(+), 106 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d1996ca74..45593104d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -394,7 +394,7 @@ RSpec/MessageSpies: - 'spec/validators/status_length_validator_spec.rb' RSpec/MultipleExpectations: - Max: 19 + Max: 8 # Configuration parameters: AllowSubject. RSpec/MultipleMemoizedHelpers: diff --git a/spec/controllers/api/v1/accounts/relationships_controller_spec.rb b/spec/controllers/api/v1/accounts/relationships_controller_spec.rb index 6bc07fa9e..993ead636 100644 --- a/spec/controllers/api/v1/accounts/relationships_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/relationships_controller_spec.rb @@ -48,25 +48,32 @@ describe Api::V1::Accounts::RelationshipsController do expect(response).to have_http_status(200) end - it 'returns JSON with correct data' do - json = body_as_json + context 'when there is returned JSON data' do + let(:json) { body_as_json } - expect(json).to be_a Enumerable - expect(json.first[:id]).to eq simon.id.to_s - expect(json.first[:following]).to be true - expect(json.first[:showing_reblogs]).to be true - expect(json.first[:followed_by]).to be false - expect(json.first[:muting]).to be false - expect(json.first[:requested]).to be false - expect(json.first[:domain_blocking]).to be false + it 'returns an enumerable json' do + expect(json).to be_a Enumerable + end - expect(json.second[:id]).to eq lewis.id.to_s - expect(json.second[:following]).to be false - expect(json.second[:showing_reblogs]).to be false - expect(json.second[:followed_by]).to be true - expect(json.second[:muting]).to be false - expect(json.second[:requested]).to be false - expect(json.second[:domain_blocking]).to be false + it 'returns a correct first element' do + expect(json.first[:id]).to eq simon.id.to_s + expect(json.first[:following]).to be true + expect(json.first[:showing_reblogs]).to be true + expect(json.first[:followed_by]).to be false + expect(json.first[:muting]).to be false + expect(json.first[:requested]).to be false + expect(json.first[:domain_blocking]).to be false + end + + it 'returns a correct second element' do + expect(json.second[:id]).to eq lewis.id.to_s + expect(json.second[:following]).to be false + expect(json.second[:showing_reblogs]).to be false + expect(json.second[:followed_by]).to be true + expect(json.second[:muting]).to be false + expect(json.second[:requested]).to be false + expect(json.second[:domain_blocking]).to be false + end end it 'returns JSON with correct data on cached requests too' do diff --git a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb index 0b807b280..84dfd60b3 100644 --- a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb @@ -56,18 +56,11 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do end describe 'when creation succeeds' do + let!(:otp_backup_codes) { user.generate_otp_backup_codes! } + it 'renders page with success' do - otp_backup_codes = user.generate_otp_backup_codes! - expect_any_instance_of(User).to receive(:generate_otp_backup_codes!) do |value| - expect(value).to eq user - otp_backup_codes - end - expect_any_instance_of(User).to receive(:validate_and_consume_otp!) do |value, code, options| - expect(value).to eq user - expect(code).to eq '123456' - expect(options).to eq({ otp_secret: 'thisisasecretforthespecofnewview' }) - true - end + prepare_user_otp_generation + prepare_user_otp_consumption expect do post :create, @@ -80,6 +73,22 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do expect(response).to have_http_status(200) expect(response).to render_template('settings/two_factor_authentication/recovery_codes/index') end + + def prepare_user_otp_generation + expect_any_instance_of(User).to receive(:generate_otp_backup_codes!) do |value| + expect(value).to eq user + otp_backup_codes + end + end + + def prepare_user_otp_consumption + expect_any_instance_of(User).to receive(:validate_and_consume_otp!) do |value, code, options| + expect(value).to eq user + expect(code).to eq '123456' + expect(options).to eq({ otp_secret: 'thisisasecretforthespecofnewview' }) + true + end + end end describe 'when creation fails' do diff --git a/spec/models/form/import_spec.rb b/spec/models/form/import_spec.rb index 52cf1c96e..2b70e396b 100644 --- a/spec/models/form/import_spec.rb +++ b/spec/models/form/import_spec.rb @@ -245,17 +245,44 @@ RSpec.describe Form::Import do expect(account.bulk_imports.first.rows.pluck(:data)).to match_array(expected_rows) end - it 'creates a BulkImport with expected attributes' do - bulk_import = account.bulk_imports.first - expect(bulk_import).to_not be_nil - expect(bulk_import.type.to_sym).to eq subject.type.to_sym - expect(bulk_import.original_filename).to eq subject.data.original_filename - expect(bulk_import.likely_mismatched?).to eq subject.likely_mismatched? - expect(bulk_import.overwrite?).to eq !!subject.overwrite # rubocop:disable Style/DoubleNegation - expect(bulk_import.processed_items).to eq 0 - expect(bulk_import.imported_items).to eq 0 - expect(bulk_import.total_items).to eq bulk_import.rows.count - expect(bulk_import.unconfirmed?).to be true + context 'with a BulkImport' do + let(:bulk_import) { account.bulk_imports.first } + + it 'creates a non-nil bulk import' do + expect(bulk_import).to_not be_nil + end + + it 'matches the subjects type' do + expect(bulk_import.type.to_sym).to eq subject.type.to_sym + end + + it 'matches the subjects original filename' do + expect(bulk_import.original_filename).to eq subject.data.original_filename + end + + it 'matches the subjects likely_mismatched? value' do + expect(bulk_import.likely_mismatched?).to eq subject.likely_mismatched? + end + + it 'matches the subject overwrite value' do + expect(bulk_import.overwrite?).to eq !!subject.overwrite # rubocop:disable Style/DoubleNegation + end + + it 'has zero processed items' do + expect(bulk_import.processed_items).to eq 0 + end + + it 'has zero imported items' do + expect(bulk_import.imported_items).to eq 0 + end + + it 'has a correct total_items value' do + expect(bulk_import.total_items).to eq bulk_import.rows.count + end + + it 'defaults to unconfirmed true' do + expect(bulk_import.unconfirmed?).to be true + end end end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index 0dd9264e0..d6e228202 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -99,73 +99,87 @@ RSpec.describe Notification do ] end - it 'preloads target status' do - # mention - expect(subject[0].type).to eq :mention - expect(subject[0].association(:mention)).to be_loaded - expect(subject[0].mention.association(:status)).to be_loaded + context 'with a preloaded target status' do + it 'preloads mention' do + expect(subject[0].type).to eq :mention + expect(subject[0].association(:mention)).to be_loaded + expect(subject[0].mention.association(:status)).to be_loaded + end - # status - expect(subject[1].type).to eq :status - expect(subject[1].association(:status)).to be_loaded + it 'preloads status' do + expect(subject[1].type).to eq :status + expect(subject[1].association(:status)).to be_loaded + end - # reblog - expect(subject[2].type).to eq :reblog - expect(subject[2].association(:status)).to be_loaded - expect(subject[2].status.association(:reblog)).to be_loaded + it 'preloads reblog' do + expect(subject[2].type).to eq :reblog + expect(subject[2].association(:status)).to be_loaded + expect(subject[2].status.association(:reblog)).to be_loaded + end - # follow: nothing - expect(subject[3].type).to eq :follow - expect(subject[3].target_status).to be_nil + it 'preloads follow as nil' do + expect(subject[3].type).to eq :follow + expect(subject[3].target_status).to be_nil + end - # follow_request: nothing - expect(subject[4].type).to eq :follow_request - expect(subject[4].target_status).to be_nil + it 'preloads follow_request as nill' do + expect(subject[4].type).to eq :follow_request + expect(subject[4].target_status).to be_nil + end - # favourite - expect(subject[5].type).to eq :favourite - expect(subject[5].association(:favourite)).to be_loaded - expect(subject[5].favourite.association(:status)).to be_loaded + it 'preloads favourite' do + expect(subject[5].type).to eq :favourite + expect(subject[5].association(:favourite)).to be_loaded + expect(subject[5].favourite.association(:status)).to be_loaded + end - # poll - expect(subject[6].type).to eq :poll - expect(subject[6].association(:poll)).to be_loaded - expect(subject[6].poll.association(:status)).to be_loaded + it 'preloads poll' do + expect(subject[6].type).to eq :poll + expect(subject[6].association(:poll)).to be_loaded + expect(subject[6].poll.association(:status)).to be_loaded + end end - it 'replaces to cached status' do - # mention - expect(subject[0].type).to eq :mention - expect(subject[0].target_status.association(:account)).to be_loaded - expect(subject[0].target_status).to eq mention.status + context 'with a cached status' do + it 'replaces mention' do + expect(subject[0].type).to eq :mention + expect(subject[0].target_status.association(:account)).to be_loaded + expect(subject[0].target_status).to eq mention.status + end - # status - expect(subject[1].type).to eq :status - expect(subject[1].target_status.association(:account)).to be_loaded - expect(subject[1].target_status).to eq status + it 'replaces status' do + expect(subject[1].type).to eq :status + expect(subject[1].target_status.association(:account)).to be_loaded + expect(subject[1].target_status).to eq status + end - # reblog - expect(subject[2].type).to eq :reblog - expect(subject[2].target_status.association(:account)).to be_loaded - expect(subject[2].target_status).to eq reblog.reblog + it 'replaces reblog' do + expect(subject[2].type).to eq :reblog + expect(subject[2].target_status.association(:account)).to be_loaded + expect(subject[2].target_status).to eq reblog.reblog + end - # follow: nothing - expect(subject[3].type).to eq :follow - expect(subject[3].target_status).to be_nil + it 'replaces follow' do + expect(subject[3].type).to eq :follow + expect(subject[3].target_status).to be_nil + end - # follow_request: nothing - expect(subject[4].type).to eq :follow_request - expect(subject[4].target_status).to be_nil + it 'replaces follow_request' do + expect(subject[4].type).to eq :follow_request + expect(subject[4].target_status).to be_nil + end - # favourite - expect(subject[5].type).to eq :favourite - expect(subject[5].target_status.association(:account)).to be_loaded - expect(subject[5].target_status).to eq favourite.status + it 'replaces favourite' do + expect(subject[5].type).to eq :favourite + expect(subject[5].target_status.association(:account)).to be_loaded + expect(subject[5].target_status).to eq favourite.status + end - # poll - expect(subject[6].type).to eq :poll - expect(subject[6].target_status.association(:account)).to be_loaded - expect(subject[6].target_status).to eq poll.status + it 'replaces poll' do + expect(subject[6].type).to eq :poll + expect(subject[6].target_status.association(:account)).to be_loaded + expect(subject[6].target_status).to eq poll.status + end end end end diff --git a/spec/services/translate_status_service_spec.rb b/spec/services/translate_status_service_spec.rb index 074f55544..515dd1a99 100644 --- a/spec/services/translate_status_service_spec.rb +++ b/spec/services/translate_status_service_spec.rb @@ -152,22 +152,31 @@ RSpec.describe TranslateStatusService, type: :service do describe 'status has poll' do let(:poll) { Fabricate(:poll, options: %w(Blue Green)) } - it 'returns formatted poll options' do - source_texts = service.send(:source_texts) - expect(source_texts.size).to eq 3 - expect(source_texts.values).to eq %w(

Hello

Blue Green) + context 'with source texts from the service' do + let!(:source_texts) { service.send(:source_texts) } - expect(source_texts.keys.first).to eq :content + it 'returns formatted poll options' do + expect(source_texts.size).to eq 3 + expect(source_texts.values).to eq %w(

Hello

Blue Green) + end - option1 = source_texts.keys.second - expect(option1).to be_a Poll::Option - expect(option1.id).to eq '0' - expect(option1.title).to eq 'Blue' + it 'has a first key with content' do + expect(source_texts.keys.first).to eq :content + end - option2 = source_texts.keys.third - expect(option2).to be_a Poll::Option - expect(option2.id).to eq '1' - expect(option2.title).to eq 'Green' + it 'has the first option in the second key with correct options' do + option1 = source_texts.keys.second + expect(option1).to be_a Poll::Option + expect(option1.id).to eq '0' + expect(option1.title).to eq 'Blue' + end + + it 'has the second option in the third key with correct options' do + option2 = source_texts.keys.third + expect(option2).to be_a Poll::Option + expect(option2.id).to eq '1' + expect(option2.title).to eq 'Green' + end end end