1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
describe "associations" do
context "when accidentally using an implicit declaration for the factory" do
it "raises an error" do
define_class("Post")
FactoryBot.define do
factory :post do
author factory: user
end
end
expect { FactoryBot.build(:post) }.to raise_error(
ArgumentError,
"Association 'author' received an invalid factory argument.\n" \
"Did you mean? 'factory: :user'\n"
)
end
end
context "when accidentally using an implicit declaration as an override" do
it "raises an error" do
define_class("Post")
FactoryBot.define do
factory :post do
author factory: :user, invalid_attribute: implicit_trait
end
end
expect { FactoryBot.build(:post) }.to raise_error(
ArgumentError,
"Association 'author' received an invalid attribute override.\n" \
"Did you mean? 'invalid_attribute: :implicit_trait'\n"
)
end
end
context "when building interrelated associations" do
it "assigns the instance passed as an association attribute" do
define_class("Supplier") do
attr_accessor :account
end
define_class("Account") do
attr_accessor :supplier
end
FactoryBot.define do
factory :supplier
factory :account do
supplier { association(:supplier, account: instance) }
end
end
account = FactoryBot.build(:account)
expect(account.supplier.account).to eq(account)
end
it "connects records with interdependent relationships" do
define_model("Student", school_id: :integer) do
belongs_to :school
has_one :profile
end
define_model("Profile", school_id: :integer, student_id: :integer) do
belongs_to :school
belongs_to :student
end
define_model("School") do
has_many :students
has_many :profiles
end
FactoryBot.define do
factory :student do
school
profile { association :profile, student: instance, school: school }
end
factory :profile do
school
student { association :student, profile: instance, school: school }
end
factory :school
end
student = FactoryBot.create(:student)
expect(student.profile.school).to eq(student.school)
expect(student.profile.student).to eq(student)
expect(student.school.students.map(&:id)).to eq([student.id])
expect(student.school.profiles.map(&:id)).to eq([student.profile.id])
profile = FactoryBot.create(:profile)
expect(profile.student.school).to eq(profile.school)
expect(profile.student.profile).to eq(profile)
expect(profile.school.profiles.map(&:id)).to eq([profile.id])
expect(profile.school.students.map(&:id)).to eq([profile.student.id])
end
end
context "when building collection associations" do
it "builds the association according to the given strategy" do
define_model("Photo", listing_id: :integer) do
belongs_to :listing
attr_accessor :name
end
define_model("Listing") do
has_many :photos
end
FactoryBot.define do
factory :photo
factory :listing do
photos { [association(:photo)] }
end
end
created_listing = FactoryBot.create(:listing)
expect(created_listing.photos.first).to be_a Photo
expect(created_listing.photos.first).to be_persisted
built_listing = FactoryBot.build(:listing)
expect(built_listing.photos.first).to be_a Photo
expect(built_listing.photos.first).not_to be_persisted
stubbed_listing = FactoryBot.build_stubbed(:listing)
expect(stubbed_listing.photos.first).to be_a Photo
expect(stubbed_listing.photos.first).to be_persisted
expect { stubbed_listing.photos.first.save! }.to raise_error(
"stubbed models are not allowed to access the database - Photo#save!()"
)
end
end
end
|