File: associations_spec.rb

package info (click to toggle)
ruby-factory-bot 6.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,372 kB
  • sloc: ruby: 7,827; makefile: 6
file content (145 lines) | stat: -rw-r--r-- 4,068 bytes parent folder | download
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