Read about our upcoming Code of Conduct on this issue

environment_spec.rb 6.28 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
require 'spec_helper'

describe Environment, models: true do
  let(:environment) { create(:environment) }

  it { is_expected.to belong_to(:project) }
  it { is_expected.to have_many(:deployments) }

  it { is_expected.to delegate_method(:last_deployment).to(:deployments).as(:last) }

Kamil Trzcinski's avatar
Kamil Trzcinski committed
11
  it { is_expected.to delegate_method(:stop_action).to(:last_deployment) }
12
  it { is_expected.to delegate_method(:manual_actions).to(:last_deployment) }
Kamil Trzcinski's avatar
Kamil Trzcinski committed
13

14
15
  it { is_expected.to validate_presence_of(:name) }
  it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
16
  it { is_expected.to validate_length_of(:name).is_at_most(255) }
17

18
  it { is_expected.to validate_length_of(:external_url).is_at_most(255) }
19
20
21
22
23
24
25
26

  # To circumvent a not null violation of the name column:
  # https://github.com/thoughtbot/shoulda-matchers/issues/336
  it 'validates uniqueness of :external_url' do
    create(:environment)

    is_expected.to validate_uniqueness_of(:external_url).scoped_to(:project_id)
  end
Z.J. van de Weg's avatar
Z.J. van de Weg committed
27
28
29
30
31
32

  describe '#nullify_external_url' do
    it 'replaces a blank url with nil' do
      env = build(:environment, external_url: "")

      expect(env.save).to be true
33
      expect(env.external_url).to be_nil
Z.J. van de Weg's avatar
Z.J. van de Weg committed
34
35
    end
  end
Z.J. van de Weg's avatar
Z.J. van de Weg committed
36

37
  describe '#includes_commit?' do
Z.J. van de Weg's avatar
Z.J. van de Weg committed
38
39
    context 'without a last deployment' do
      it "returns false" do
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
        expect(environment.includes_commit?('HEAD')).to be false
      end
    end

    context 'with a last deployment' do
      let(:project)     { create(:project) }
      let(:environment) { create(:environment, project: project) }

      let!(:deployment) do
        create(:deployment, environment: environment, sha: project.commit('master').id)
      end

      context 'in the same branch' do
        it 'returns true' do
          expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be true
        end
      end

      context 'not in the same branch' do
        before do
          deployment.update(sha: project.commit('feature').id)
        end

        it 'returns false' do
          expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be false
        end
Z.J. van de Weg's avatar
Z.J. van de Weg committed
66
67
68
      end
    end
  end
69

Z.J. van de Weg's avatar
Z.J. van de Weg committed
70
  describe '#first_deployment_for' do
71
72
73
74
75
76
77
78
    let(:project)       { create(:project) }
    let!(:environment)  { create(:environment, project: project) }
    let!(:deployment)   { create(:deployment, environment: environment, ref: commit.parent.id) }
    let!(:deployment1)  { create(:deployment, environment: environment, ref: commit.id) }
    let(:head_commit)   { project.commit }
    let(:commit)        { project.commit.parent }

    it 'returns deployment id for the environment' do
Z.J. van de Weg's avatar
Z.J. van de Weg committed
79
      expect(environment.first_deployment_for(commit)).to eq deployment1
80
81
82
    end

    it 'return nil when no deployment is found' do
Z.J. van de Weg's avatar
Z.J. van de Weg committed
83
      expect(environment.first_deployment_for(head_commit)).to eq nil
84
85
86
    end
  end

87
88
89
90
  describe '#environment_type' do
    subject { environment.environment_type }

    it 'sets a environment type if name has multiple segments' do
91
      environment.update!(name: 'production/worker.gitlab.com')
92
93
94
95
96

      is_expected.to eq('production')
    end

    it 'nullifies a type if it\'s a simple name' do
97
      environment.update!(name: 'production')
98
99
100
101

      is_expected.to be_nil
    end
  end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
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

  describe '#stoppable?' do
    subject { environment.stoppable? }

    context 'when no other actions' do
      it { is_expected.to be_falsey }
    end

    context 'when matching action is defined' do
      let(:build) { create(:ci_build) }
      let!(:deployment) { create(:deployment, environment: environment, deployable: build, on_stop: 'close_app') }
      let!(:close_action) { create(:ci_build, pipeline: build.pipeline, name: 'close_app', when: :manual) }

      context 'when environment is available' do
        before do
          environment.start
        end

        it { is_expected.to be_truthy }
      end

      context 'when environment is stopped' do
        before do
          environment.stop
        end

        it { is_expected.to be_falsey }
      end
    end
  end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

  describe '#stop!' do
    let(:user) { create(:user) }

    subject { environment.stop!(user) }

    before do
      expect(environment).to receive(:stoppable?).and_call_original
    end

    context 'when no other actions' do
      it { is_expected.to be_nil }
    end

    context 'when matching action is defined' do
      let(:build) { create(:ci_build) }
      let!(:deployment) { create(:deployment, environment: environment, deployable: build, on_stop: 'close_app') }

      context 'when action did not yet finish' do
        let!(:close_action) { create(:ci_build, :manual, pipeline: build.pipeline, name: 'close_app') }

        it 'returns the same action' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
154
155
          expect(subject).to eq(close_action)
          expect(subject.user).to eq(user)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
156
157
158
159
160
161
162
163
        end
      end

      context 'if action did finish' do
        let!(:close_action) { create(:ci_build, :manual, :success, pipeline: build.pipeline, name: 'close_app') }

        it 'returns a new action of the same type' do
          is_expected.to be_persisted
Kamil Trzcinski's avatar
Kamil Trzcinski committed
164
165
          expect(subject.name).to eq(close_action.name)
          expect(subject.user).to eq(user)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
166
167
168
169
        end
      end
    end
  end
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

  describe 'recently_updated_on_branch?' do
    subject { environment.recently_updated_on_branch?('feature') }

    context 'when last deployment to environment is the most recent one' do
      before do
        create(:deployment, environment: environment, ref: 'feature')
      end

      it { is_expected.to be true }
    end

    context 'when last deployment to environment is not the most recent' do
      before do
        create(:deployment, environment: environment, ref: 'feature')
        create(:deployment, environment: environment, ref: 'master')
      end

      it { is_expected.to be false }
    end
  end
191
192
193
194
195
196
197
198
199
200
201

  describe '#actions_for' do
    let(:deployment) { create(:deployment, environment: environment) }
    let(:pipeline) { deployment.deployable.pipeline }
    let!(:review_action) { create(:ci_build, :manual, name: 'review-apps', pipeline: pipeline, environment: 'review/$CI_BUILD_REF_NAME' )}
    let!(:production_action) { create(:ci_build, :manual, name: 'production', pipeline: pipeline, environment: 'production' )}

    it 'returns a list of actions with matching environment' do
      expect(environment.actions_for('review/master')).to contain_exactly(review_action)
    end
  end
202
end