diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index e243253c5f1..5837f913d16 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -9,8 +9,12 @@ class Projects::EnvironmentsController < Projects::ApplicationController def index @scope = params[:scope] @all_environments = project.environments - @environments = @scope == 'stopped' ? - @all_environments.stopped : @all_environments.available + @environments = + if @scope == 'stopped' then + @all_environments.stopped + else + @all_environments.available + end end def show @@ -45,8 +49,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController def stop return render_404 unless @environment.stoppable? - action = @environment.stop_action - new_action = action.active? ? action : action.play(current_user) + new_action = @environment.stop!(current_user) redirect_to polymorphic_path([project.namespace.becomes(Namespace), project, new_action]) end diff --git a/app/models/environment.rb b/app/models/environment.rb index ff55e751f70..d575f1dc73a 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -88,4 +88,10 @@ class Environment < ActiveRecord::Base def stoppable? available? && stop_action.present? end + + def stop!(current_user) + return unless stoppable? + + stop_action.play(current_user) + end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 1c1fef57fc4..e1755f940b3 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -128,4 +128,41 @@ describe Environment, models: true do end end end + + 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 + is_expected.to eq(close_action) + is_expected.to include(user: user) + 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 + is_expected.to include(name: close_action.name, user: user) + end + end + end + end end