1# frozen_string_literal: true
2
3require 'spec_helper'
4
5RSpec.describe EnvironmentPolicy do
6  using RSpec::Parameterized::TableSyntax
7
8  let(:user) { create(:user) }
9
10  let(:policy) do
11    described_class.new(user, environment)
12  end
13
14  describe '#rules' do
15    shared_examples 'project permissions' do
16      context 'with stop action' do
17        let(:environment) do
18          create(:environment, :with_review_app, project: project)
19        end
20
21        where(:access_level, :allowed?) do
22          nil         | false
23          :guest      | false
24          :reporter   | false
25          :developer  | true
26          :maintainer | true
27        end
28
29        with_them do
30          before do
31            project.add_user(user, access_level) unless access_level.nil?
32          end
33
34          it { expect(policy.allowed?(:stop_environment)).to be allowed? }
35        end
36
37        context 'when an admin user' do
38          let(:user) { create(:user, :admin) }
39
40          context 'when admin mode is enabled', :enable_admin_mode do
41            it { expect(policy).to be_allowed :stop_environment }
42          end
43
44          context 'when admin mode is disabled' do
45            it { expect(policy).to be_disallowed :stop_environment }
46          end
47        end
48
49        context 'with protected branch' do
50          with_them do
51            before do
52              project.add_user(user, access_level) unless access_level.nil?
53              create(:protected_branch, :no_one_can_push,
54                     name: 'master', project: project)
55            end
56
57            it { expect(policy).to be_disallowed :stop_environment }
58          end
59
60          context 'when an admin user' do
61            let(:user) { create(:user, :admin) }
62
63            context 'when admin mode is enabled', :enable_admin_mode do
64              it { expect(policy).to be_allowed :stop_environment }
65            end
66
67            context 'when admin mode is disabled' do
68              it { expect(policy).to be_disallowed :stop_environment }
69            end
70          end
71        end
72      end
73
74      context 'without stop action' do
75        let(:environment) do
76          create(:environment, project: project)
77        end
78
79        where(:access_level, :allowed?) do
80          nil         | false
81          :guest      | false
82          :reporter   | false
83          :developer  | true
84          :maintainer | true
85        end
86
87        with_them do
88          before do
89            project.add_user(user, access_level) unless access_level.nil?
90          end
91
92          it { expect(policy.allowed?(:stop_environment)).to be allowed? }
93        end
94
95        context 'when an admin user' do
96          let(:user) { create(:user, :admin) }
97
98          context 'when admin mode is enabled', :enable_admin_mode do
99            it { expect(policy).to be_allowed :stop_environment }
100          end
101
102          context 'when admin mode is disabled' do
103            it { expect(policy).to be_disallowed :stop_environment }
104          end
105        end
106      end
107
108      describe '#destroy_environment' do
109        let(:environment) do
110          create(:environment, project: project)
111        end
112
113        where(:access_level, :allowed?) do
114          nil         | false
115          :guest      | false
116          :reporter   | false
117          :developer  | true
118          :maintainer | true
119        end
120
121        with_them do
122          before do
123            project.add_user(user, access_level) unless access_level.nil?
124          end
125
126          it { expect(policy).to be_disallowed :destroy_environment }
127
128          context 'when environment is stopped' do
129            before do
130              environment.stop!
131            end
132
133            it { expect(policy.allowed?(:destroy_environment)).to be allowed? }
134          end
135        end
136
137        context 'when an admin user' do
138          let(:user) { create(:user, :admin) }
139
140          it { expect(policy).to be_disallowed :destroy_environment }
141
142          context 'when environment is stopped' do
143            before do
144              environment.stop!
145            end
146
147            context 'when admin mode is enabled', :enable_admin_mode do
148              it { expect(policy).to be_allowed :destroy_environment }
149            end
150
151            context 'when admin mode is disabled' do
152              it { expect(policy).to be_disallowed :destroy_environment }
153            end
154          end
155        end
156      end
157    end
158
159    context 'when project is public' do
160      let(:project) { create(:project, :public, :repository) }
161
162      include_examples 'project permissions'
163    end
164
165    context 'when project is private' do
166      let(:project) { create(:project, :private, :repository) }
167
168      include_examples 'project permissions'
169    end
170  end
171end
172