summaryrefslogtreecommitdiff
path: root/qa/spec/factory/base_spec.rb
blob: 04e04886699f217adf5e3354845e9206d64eff3f (plain)
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
describe QA::Factory::Base do
  let(:factory) { spy('factory') }
  let(:product) { spy('product') }

  describe '.fabricate!' do
    subject { Class.new(described_class) }

    before do
      allow(QA::Factory::Product).to receive(:new).and_return(product)
      allow(QA::Factory::Product).to receive(:populate!).and_return(product)
    end

    it 'instantiates the factory and calls factory method' do
      expect(subject).to receive(:new).and_return(factory)

      subject.fabricate!('something')

      expect(factory).to have_received(:fabricate!).with('something')
    end

    it 'returns fabrication product' do
      allow(subject).to receive(:new).and_return(factory)

      result = subject.fabricate!('something')

      expect(result).to eq product
    end

    it 'yields factory before calling factory method' do
      allow(subject).to receive(:new).and_return(factory)

      subject.fabricate! do |factory|
        factory.something!
      end

      expect(factory).to have_received(:something!).ordered
      expect(factory).to have_received(:fabricate!).ordered
    end
  end

  describe '.dependency' do
    let(:dependency) { spy('dependency') }

    before do
      stub_const('Some::MyDependency', dependency)
    end

    subject do
      Class.new(described_class) do
        dependency Some::MyDependency, as: :mydep do |factory|
          factory.something!
        end
      end
    end

    it 'appends a new dependency and accessors' do
      expect(subject.dependencies).to be_one
    end

    it 'defines dependency accessors' do
      expect(subject.new).to respond_to :mydep, :mydep=
    end

    describe 'dependencies fabrication' do
      let(:dependency) { double('dependency') }
      let(:instance) { spy('instance') }

      subject do
        Class.new(described_class) do
          dependency Some::MyDependency, as: :mydep
        end
      end

      before do
        stub_const('Some::MyDependency', dependency)

        allow(subject).to receive(:new).and_return(instance)
        allow(instance).to receive(:mydep).and_return(nil)
        allow(QA::Factory::Product).to receive(:new)
        allow(QA::Factory::Product).to receive(:populate!)
      end

      it 'builds all dependencies first' do
        expect(dependency).to receive(:fabricate!).once

        subject.fabricate!
      end
    end
  end

  describe '.product' do
    subject do
      Class.new(described_class) do
        def fabricate!
          "any"
        end

        # Defined only to be stubbed
        def self.find_page
        end

        product :token do
          find_page.do_something_on_page!
          'resulting value'
        end
      end
    end

    it 'appends new product attribute' do
      expect(subject.attributes).to be_one
      expect(subject.attributes).to have_key(:token)
    end

    describe 'populating fabrication product with data' do
      let(:page) { spy('page') }

      before do
        allow(factory).to receive(:class).and_return(subject)
        allow(QA::Factory::Product).to receive(:new).and_return(product)
        allow(product).to receive(:page).and_return(page)
        allow(subject).to receive(:find_page).and_return(page)
      end

      it 'populates product after fabrication' do
        subject.fabricate!

        expect(product.token).to eq 'resulting value'
        expect(page).to have_received(:do_something_on_page!)
      end
    end
  end
end