Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions spec/factories/account_linked_accounts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

FactoryBot.define do
factory :account_linked_account do
association :account
association :linked_account, factory: :account
account_type { 'testing' }
end
end
161 changes: 161 additions & 0 deletions spec/models/account_linked_account_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe AccountLinkedAccount, type: :model do
describe 'associations' do
it 'has account association' do
expect(described_class.reflect_on_association(:account).macro).to eq(:belongs_to)
end

it 'has linked_account association with correct class_name' do
association = described_class.reflect_on_association(:linked_account)
expect(association.macro).to eq(:belongs_to)
expect(association.class_name).to eq('Account')
end

context 'when creating with associated records' do
let(:account) { create(:account, name: 'Primary Account') }
let(:linked_account_record) { create(:account, name: 'Linked Account') }
let(:account_linked) { create(:account_linked_account, account: account, linked_account: linked_account_record) }

it 'properly associates with account' do
expect(account_linked.account).to eq(account)
expect(account_linked.account.name).to eq('Primary Account')
expect(account_linked.account_id).to eq(account.id)
end

it 'properly associates with linked_account' do
expect(account_linked.linked_account).to eq(linked_account_record)
expect(account_linked.linked_account.name).to eq('Linked Account')
expect(account_linked.linked_account_id).to eq(linked_account_record.id)
end
end
end

describe 'attribute default' do
context 'when account_type is not specified' do
let(:linked_account) { create(:account_linked_account) }

it "defaults account_type to 'testing'" do
expect(linked_account.account_type).to eq('testing')
expect(linked_account.testing?).to be true
end
end

context 'when account_type is explicitly set to nil' do
it 'raises not null constraint violation' do
expect { create(:account_linked_account, account_type: nil) }
.to raise_error(ActiveRecord::NotNullViolation)
end
end
end

describe 'database constraints' do
context 'with uniqueness constraint' do
let(:account) { create(:account) }

it 'prevents duplicate account_id and linked_account_id combinations' do
create(:account_linked_account, account: account, linked_account: account)
duplicate = build(:account_linked_account, account: account, linked_account: account)

expect { duplicate.save! }.to raise_error(ActiveRecord::RecordNotUnique)
end
end

context 'with foreign key constraints' do
let(:invalid_account_linked) { build(:account_linked_account, account_id: 999_999, linked_account_id: 999_999) }

it 'enforces account foreign key constraint with validation' do
expect { invalid_account_linked.save! }.to raise_error(ActiveRecord::RecordInvalid)
end

it 'enforces foreign key constraint at database level' do
expect { invalid_account_linked.save!(validate: false) }.to raise_error(ActiveRecord::InvalidForeignKey)
end
end

context 'with not null constraints' do
let(:invalid_record) { described_class.new }

it 'validates account presence' do
expect(invalid_record).not_to be_valid
expect(invalid_record.errors[:account]).to include('must exist')
end

it 'validates linked_account presence' do
expect(invalid_record).not_to be_valid
expect(invalid_record.errors[:linked_account]).to include('must exist')
end

it 'enforces account_type not null constraint at database level' do
account = create(:account)
expect do
described_class.create!(account: account, linked_account: account, account_type: nil)
end.to raise_error(ActiveRecord::NotNullViolation)
end
end
end

describe '#testing?' do
context "when account_type is the default 'testing' value" do
let(:linked_account) { create(:account_linked_account) }

it 'returns true for default account_type' do
expect(linked_account.testing?).to be true
expect(linked_account.account_type).to eq('testing')
end
end

context "when account_type is explicitly set to 'testing'" do
let(:linked_account) { create(:account_linked_account, account_type: 'testing') }

it "returns true when account_type is explicitly 'testing'" do
expect(linked_account.testing?).to be true
expect(linked_account.account_type).to eq('testing')
end
end

context 'when account_type is set to a different value' do
let(:linked_account) { create(:account_linked_account, account_type: 'production') }

it "returns false when account_type is 'production'" do
expect(linked_account.testing?).to be false
expect(linked_account.account_type).to eq('production')
end
end

context 'when account_type is case variation' do
let(:linked_account) { create(:account_linked_account, account_type: 'TESTING') }

it "returns false when account_type is uppercase 'TESTING'" do
expect(linked_account.testing?).to be false
expect(linked_account.account_type).to eq('TESTING')
end

it "returns false when account_type is lowercase 'testing' but with different casing" do
linked_account = create(:account_linked_account, account_type: 'TeStInG')
expect(linked_account.testing?).to be false
expect(linked_account.account_type).to eq('TeStInG')
end
end

context 'when testing multiple instances with different account_types' do
let(:testing_account) { create(:account_linked_account, account_type: 'testing') }
let(:production_account) { create(:account_linked_account, account_type: 'production') }
let(:staging_account) { create(:account_linked_account, account_type: 'staging') }

it 'correctly identifies testing versus non-testing accounts' do
expect(testing_account.testing?).to be true
expect(production_account.testing?).to be false
expect(staging_account.testing?).to be false
end

it 'maintains correct account_type values after testing' do
expect(testing_account.account_type).to eq('testing')
expect(production_account.account_type).to eq('production')
expect(staging_account.account_type).to eq('staging')
end
end
end
end