gitlab-org--gitlab-foss/spec/features/projects/environments/environments_spec.rb
Kamil Trzciński 0103d5be96 Add config_options|variables to BuildMetadata
These are data columns that store runtime configuration
of build needed to execute it on runner and within pipeline.

The definition of this data is that once used, and when no longer
needed (due to retry capability) they can be freely removed.

They use `jsonb` on PostgreSQL, and `text` on MySQL (due to lacking
support for json datatype on old enough version).
2019-01-04 16:38:17 +01:00

441 lines
14 KiB
Ruby

require 'spec_helper'
describe 'Environments page', :js do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
before do
project.add_role(user, role)
sign_in(user)
end
def stop_button_selector
%q{button[data-original-title="Stop environment"]}
end
describe 'page tabs' do
it 'shows "Available" and "Stopped" tab with links' do
visit_environments(project)
expect(page).to have_selector('.js-environments-tab-available')
expect(page).to have_content('Available')
expect(page).to have_selector('.js-environments-tab-stopped')
expect(page).to have_content('Stopped')
end
describe 'with one available environment' do
before do
create(:environment, project: project, state: :available)
end
describe 'in available tab page' do
it 'should show one environment' do
visit_environments(project, scope: 'available')
expect(page).to have_css('.environments-container')
expect(page.all('.environment-name').length).to eq(1)
end
end
describe 'in stopped tab page' do
it 'should show no environments' do
visit_environments(project, scope: 'stopped')
expect(page).to have_css('.environments-container')
expect(page).to have_content('You don\'t have any environments right now')
end
end
context 'when cluster is not reachable' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:application_prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
before do
allow_any_instance_of(Kubeclient::Client).to receive(:proxy_url).and_raise(Kubeclient::HttpError.new(401, 'Unauthorized', nil))
end
it 'should show one environment without error' do
visit_environments(project, scope: 'available')
expect(page).to have_css('.environments-container')
expect(page.all('.environment-name').length).to eq(1)
end
end
end
describe 'with one stopped environment' do
before do
create(:environment, project: project, state: :stopped)
end
describe 'in available tab page' do
it 'should show no environments' do
visit_environments(project, scope: 'available')
expect(page).to have_css('.environments-container')
expect(page).to have_content('You don\'t have any environments right now')
end
end
describe 'in stopped tab page' do
it 'should show one environment' do
visit_environments(project, scope: 'stopped')
expect(page).to have_css('.environments-container')
expect(page.all('.environment-name').length).to eq(1)
end
end
end
end
context 'without environments' do
before do
visit_environments(project)
end
it 'does not show environments and counters are set to zero' do
expect(page).to have_content('You don\'t have any environments right now')
expect(page.find('.js-environments-tab-available .badge').text).to eq('0')
expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
end
end
describe 'environments table' do
let!(:environment) do
create(:environment, project: project, state: :available)
end
context 'when there are no deployments' do
before do
visit_environments(project)
end
it 'shows environments names and counters' do
expect(page).to have_link(environment.name)
expect(page.find('.js-environments-tab-available .badge').text).to eq('1')
expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
end
it 'does not show deployments' do
expect(page).to have_content('No deployments yet')
end
it 'does not show stip button when environment is not stoppable' do
expect(page).not_to have_selector(stop_button_selector)
end
end
context 'when there are successful deployments' do
let(:project) { create(:project, :repository) }
let!(:deployment) do
create(:deployment, :success,
environment: environment,
sha: project.commit.id)
end
it 'shows deployment SHA and internal ID' do
visit_environments(project)
expect(page).to have_link(deployment.short_sha)
expect(page).to have_content(deployment.iid)
end
context 'when builds and manual actions are present' do
let!(:pipeline) { create(:ci_pipeline, project: project) }
let!(:build) { create(:ci_build, pipeline: pipeline) }
let!(:action) do
create(:ci_build, :manual, pipeline: pipeline, name: 'deploy to production')
end
let!(:deployment) do
create(:deployment, :success,
environment: environment,
deployable: build,
sha: project.commit.id)
end
before do
visit_environments(project)
end
it 'shows a play button' do
find('.js-environment-actions-dropdown').click
expect(page).to have_content(action.name.humanize)
end
it 'allows to play a manual action', :js do
expect(action).to be_manual
find('.js-environment-actions-dropdown').click
expect(page).to have_content(action.name.humanize)
expect { find('.js-manual-action-link').click }
.not_to change { Ci::Pipeline.count }
end
it 'shows build name and id' do
expect(page).to have_link("#{build.name} ##{build.id}")
end
it 'shows a stop button' do
expect(page).not_to have_selector(stop_button_selector)
end
it 'does not show external link button' do
expect(page).not_to have_css('external-url')
end
it 'does not show terminal button' do
expect(page).not_to have_terminal_button
end
context 'with external_url' do
let(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') }
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:deployment) { create(:deployment, :success, environment: environment, deployable: build) }
it 'shows an external link button' do
expect(page).to have_link(nil, href: environment.external_url)
end
end
context 'with stop action' do
let(:action) do
create(:ci_build, :manual, pipeline: pipeline, name: 'close_app')
end
let(:deployment) do
create(:deployment, :success,
environment: environment,
deployable: build,
on_stop: 'close_app')
end
it 'shows a stop button' do
expect(page).to have_selector(stop_button_selector)
end
context 'when user is a reporter' do
let(:role) { :reporter }
it 'does not show stop button' do
expect(page).not_to have_selector(stop_button_selector)
end
end
end
context 'when kubernetes terminal is available' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'for project maintainer' do
let(:role) { :maintainer }
it 'shows the terminal button' do
expect(page).to have_terminal_button
end
end
context 'when user is a developer' do
let(:role) { :developer }
it 'does not show terminal button' do
expect(page).not_to have_terminal_button
end
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project, :test_repo) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [create(:project, :repository)]) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
end
context 'when there is a delayed job' do
let!(:pipeline) { create(:ci_pipeline, project: project) }
let!(:build) { create(:ci_build, pipeline: pipeline) }
let!(:delayed_job) do
create(:ci_build, :scheduled,
pipeline: pipeline,
name: 'delayed job',
stage: 'test')
end
let!(:deployment) do
create(:deployment,
:success,
environment: environment,
deployable: build,
sha: project.commit.id)
end
before do
visit_environments(project)
end
it 'has a dropdown for actionable jobs' do
expect(page).to have_selector('.dropdown-new.btn.btn-default .ic-play')
end
it "has link to the delayed job's action" do
find('.js-environment-actions-dropdown').click
expect(page).to have_button('Delayed job')
expect(page).to have_content(/\d{2}:\d{2}:\d{2}/)
end
context 'when delayed job is expired already' do
let!(:delayed_job) do
create(:ci_build, :expired_scheduled,
pipeline: pipeline,
name: 'delayed job',
stage: 'test')
end
it "shows 00:00:00 as the remaining time" do
find('.js-environment-actions-dropdown').click
expect(page).to have_content("00:00:00")
end
end
context 'when user played a delayed job immediately' do
before do
find('.js-environment-actions-dropdown').click
page.accept_confirm { click_button('Delayed job') }
wait_for_requests
end
it 'enqueues the delayed job', :js do
expect(delayed_job.reload).to be_pending
end
end
end
end
context 'when there is a failed deployment' do
let(:project) { create(:project, :repository) }
let!(:deployment) do
create(:deployment, :failed,
environment: environment,
sha: project.commit.id)
end
it 'does not show deployments' do
visit_environments(project)
expect(page).to have_content('No deployments yet')
end
end
end
it 'does have a new environment button' do
visit_environments(project)
expect(page).to have_link('New environment')
end
describe 'creating a new environment' do
before do
visit_environments(project)
end
context 'user is a developer' do
let(:role) { :developer }
it 'developer creates a new environment with a valid name' do
within(".top-area") { click_link 'New environment' }
fill_in('Name', with: 'production')
click_on 'Save'
expect(page).to have_content('production')
end
it 'developer creates a new environmetn with invalid name' do
within(".top-area") { click_link 'New environment' }
fill_in('Name', with: 'name,with,commas')
click_on 'Save'
expect(page).to have_content('Name can contain only letters')
end
end
context 'user is a reporter' do
let(:role) { :reporter }
it 'reporters tries to create a new environment' do
expect(page).not_to have_link('New environment')
end
end
end
describe 'environments folders' do
before do
create(:environment, project: project,
name: 'staging/review-1',
state: :available)
create(:environment, project: project,
name: 'staging/review-2',
state: :available)
end
it 'users unfurls an environment folder' do
visit_environments(project)
expect(page).not_to have_content 'review-1'
expect(page).not_to have_content 'review-2'
expect(page).to have_content 'staging 2'
within('.folder-row') do
find('.folder-name', text: 'staging').click
end
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
end
end
describe 'environments folders view' do
before do
create(:environment, project: project,
name: 'staging.review/review-1',
state: :available)
create(:environment, project: project,
name: 'staging.review/review-2',
state: :available)
end
it 'user opens folder view' do
visit folder_project_environments_path(project, 'staging.review')
wait_for_requests
expect(page).to have_content('Environments / staging.review')
expect(page).to have_content('review-1')
expect(page).to have_content('review-2')
end
end
def have_terminal_button
have_link(nil, href: terminal_project_environment_path(project, environment))
end
def visit_environments(project, **opts)
visit project_environments_path(project, **opts)
wait_for_requests
end
end