environments_spec.rb 13.1 KB
Newer Older
1 2
require 'spec_helper'

3 4 5 6
describe 'Environments page', :js do
  let(:project) { create(:project) }
  let(:user) { create(:user) }
  let(:role) { :developer }
7

8
  before do
9
    project.add_role(user, role)
10
    sign_in(user)
11 12
  end

13 14 15 16
  def stop_button_selector
    %q{button[data-original-title="Stop environment"]}
  end

17
  describe 'page tabs' do
18 19 20
    it 'shows "Available" and "Stopped" tab with links' do
      visit_environments(project)

F
Filipa Lacerda 已提交
21 22 23 24
      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')
25
    end
F
Filipa Lacerda 已提交
26 27

    describe 'with one available environment' do
28 29 30
      before do
        create(:environment, project: project, state: :available)
      end
F
Filipa Lacerda 已提交
31 32 33

      describe 'in available tab page' do
        it 'should show one environment' do
34 35
          visit_environments(project, scope: 'available')

36
          expect(page).to have_css('.environments-container')
37
          expect(page.all('.environment-name').length).to eq(1)
F
Filipa Lacerda 已提交
38 39 40 41 42
        end
      end

      describe 'in stopped tab page' do
        it 'should show no environments' do
43 44
          visit_environments(project, scope: 'stopped')

45
          expect(page).to have_css('.environments-container')
F
Filipa Lacerda 已提交
46 47 48
          expect(page).to have_content('You don\'t have any environments right now')
        end
      end
49 50 51 52 53 54

      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
55
          allow_any_instance_of(Kubeclient::Client).to receive(:proxy_url).and_raise(Kubeclient::HttpError.new(401, 'Unauthorized', nil))
56 57 58 59 60 61 62 63 64
        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
F
Filipa Lacerda 已提交
65 66 67
    end

    describe 'with one stopped environment' do
68 69 70
      before do
        create(:environment, project: project, state: :stopped)
      end
F
Filipa Lacerda 已提交
71 72 73

      describe 'in available tab page' do
        it 'should show no environments' do
74 75
          visit_environments(project, scope: 'available')

76
          expect(page).to have_css('.environments-container')
F
Filipa Lacerda 已提交
77 78 79 80 81 82
          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
83 84
          visit_environments(project, scope: 'stopped')

85
          expect(page).to have_css('.environments-container')
86
          expect(page.all('.environment-name').length).to eq(1)
F
Filipa Lacerda 已提交
87 88 89
        end
      end
    end
90
  end
91

92
  context 'without environments' do
93 94
    before do
      visit_environments(project)
95 96
    end

97
    it 'does not show environments and counters are set to zero' do
G
George Tsiolis 已提交
98
      expect(page).to have_content('You don\'t have any environments right now')
99

F
Filipa Lacerda 已提交
100 101
      expect(page.find('.js-environments-tab-available .badge').text).to eq('0')
      expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
102 103 104
    end
  end

105
  describe 'environments table' do
106
    let!(:environment) do
107
      create(:environment, project: project, state: :available)
108
    end
109

110 111 112
    context 'when there are no deployments' do
      before do
        visit_environments(project)
113
      end
K
Kamil Trzcinski 已提交
114

115 116
      it 'shows environments names and counters' do
        expect(page).to have_link(environment.name)
K
Kamil Trzcinski 已提交
117

F
Filipa Lacerda 已提交
118 119
        expect(page.find('.js-environments-tab-available .badge').text).to eq('1')
        expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
K
Kamil Trzcinski 已提交
120 121
      end

122 123 124
      it 'does not show deployments' do
        expect(page).to have_content('No deployments yet')
      end
K
Kamil Trzcinski 已提交
125

126
      it 'does not show stip button when environment is not stoppable' do
127
        expect(page).not_to have_selector(stop_button_selector)
K
Kamil Trzcinski 已提交
128
      end
129 130
    end

131
    context 'when there are deployments' do
132
      let(:project) { create(:project, :repository) }
133

134
      let!(:deployment) do
S
Shinya Maeda 已提交
135 136
        create(:deployment, :success,
                            environment: environment,
137
                            sha: project.commit.id)
138
      end
139

140 141
      it 'shows deployment SHA and internal ID' do
        visit_environments(project)
142

143
        expect(page).to have_link(deployment.short_sha)
144
        expect(page).to have_content(deployment.iid)
145 146
      end

147
      context 'when builds and manual actions are present' do
148 149
        let!(:pipeline) { create(:ci_pipeline, project: project) }
        let!(:build) { create(:ci_build, pipeline: pipeline) }
150

151
        let!(:action) do
152
          create(:ci_build, :manual, pipeline: pipeline, name: 'deploy to production')
153 154
        end

155
        let!(:deployment) do
S
Shinya Maeda 已提交
156 157
          create(:deployment, :success,
                              environment: environment,
158
                              deployable: build,
159
                              sha: project.commit.id)
160
        end
161

162 163 164 165 166
        before do
          visit_environments(project)
        end

        it 'shows a play button' do
167
          find('.js-environment-actions-dropdown').click
168

169
          expect(page).to have_content(action.name.humanize)
K
Kamil Trzcinski 已提交
170 171
        end

172
        it 'allows to play a manual action', :js do
173
          expect(action).to be_manual
174

175
          find('.js-environment-actions-dropdown').click
176
          expect(page).to have_content(action.name.humanize)
177

178
          expect { find('.js-manual-action-link').click }
179 180
            .not_to change { Ci::Pipeline.count }
        end
181

182
        it 'shows build name and id' do
183 184
          expect(page).to have_link("#{build.name} ##{build.id}")
        end
185

186
        it 'shows a stop button' do
187
          expect(page).not_to have_selector(stop_button_selector)
188
        end
189

190
        it 'does not show external link button' do
191 192
          expect(page).not_to have_css('external-url')
        end
193

194
        it 'does not show terminal button' do
195 196 197
          expect(page).not_to have_terminal_button
        end

198
        context 'with external_url' do
199 200
          let(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') }
          let(:build) { create(:ci_build, pipeline: pipeline) }
S
Shinya Maeda 已提交
201
          let(:deployment) { create(:deployment, :success, environment: environment, deployable: build) }
202

203
          it 'shows an external link button' do
204
            expect(page).to have_link(nil, href: environment.external_url)
205
          end
206
        end
207

208
        context 'with stop action' do
209
          let(:action) do
210 211 212
            create(:ci_build, :manual, pipeline: pipeline, name: 'close_app')
          end

213
          let(:deployment) do
S
Shinya Maeda 已提交
214 215
            create(:deployment, :success,
                                environment: environment,
216 217 218
                                deployable: build,
                                on_stop: 'close_app')
          end
219

220
          it 'shows a stop button' do
221
            expect(page).to have_selector(stop_button_selector)
222
          end
K
Kamil Trzcinski 已提交
223

224
          context 'when user is a reporter' do
225
            let(:role) { :reporter }
K
Kamil Trzcinski 已提交
226

227
            it 'does not show stop button' do
228
              expect(page).not_to have_selector(stop_button_selector)
K
Kamil Trzcinski 已提交
229
            end
F
Filipa Lacerda 已提交
230
          end
231
        end
K
Kamil Trzcinski 已提交
232

233
        context 'when kubernetes terminal is available' do
234
          shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
235 236
            context 'for project maintainer' do
              let(:role) { :maintainer }
237

238 239 240 241 242 243 244
              it 'shows the terminal button' do
                expect(page).to have_terminal_button
              end
            end

            context 'when user is a developer' do
              let(:role) { :developer }
K
Kamil Trzcinski 已提交
245

246 247 248
              it 'does not show terminal button' do
                expect(page).not_to have_terminal_button
              end
K
Kamil Trzcinski 已提交
249
            end
250
          end
S
Shinya Maeda 已提交
251

252 253
          context 'when user configured kubernetes from Integration > Kubernetes' do
            let(:project) { create(:kubernetes_project, :test_repo) }
K
Kamil Trzcinski 已提交
254

255
            it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
256
          end
K
Kamil Trzcinski 已提交
257

258
          context 'when user configured kubernetes from CI/CD > Clusters' do
S
Shinya Maeda 已提交
259
            let(:cluster) { create(:cluster, :provided_by_gcp, projects: [create(:project, :repository)]) }
260 261
            let(:project) { cluster.project }

262
            it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
F
Filipa Lacerda 已提交
263
          end
264
        end
265
      end
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280

      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',
                 commands: 'test')
        end

        let!(:deployment) do
          create(:deployment,
S
Shinya Maeda 已提交
281
                 :success,
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
                 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')
S
Shinya Maeda 已提交
299
          expect(page).to have_content(/\d{2}:\d{2}:\d{2}/)
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
        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',
                   commands: '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
330 331 332
    end
  end

333 334 335
  it 'does have a new environment button' do
    visit_environments(project)

336
    expect(page).to have_link('New environment')
337
  end
338

339
  describe 'creating a new environment' do
340
    before do
341
      visit_environments(project)
342
    end
343

344
    context 'user is a developer' do
345
      let(:role) { :developer }
346

347
      it 'developer creates a new environment with a valid name' do
348 349 350
        within(".top-area") { click_link 'New environment' }
        fill_in('Name', with: 'production')
        click_on 'Save'
351

352
        expect(page).to have_content('production')
353 354
      end

355
      it 'developer creates a new environmetn with invalid name' do
356 357 358
        within(".top-area") { click_link 'New environment' }
        fill_in('Name', with: 'name,with,commas')
        click_on 'Save'
359

360
        expect(page).to have_content('Name can contain only letters')
361 362 363
      end
    end

364
    context 'user is a reporter' do
365
      let(:role) { :reporter }
366

367
      it 'reporters tries to create a new environment' do
368 369 370 371
        expect(page).not_to have_link('New environment')
      end
    end
  end
372

373 374 375 376 377 378 379 380 381 382
  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

383
    it 'users unfurls an environment folder' do
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
      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

F
Filipa Lacerda 已提交
399 400 401 402 403 404 405 406 407 408
  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

409
    it 'user opens folder view' do
F
Filipa Lacerda 已提交
410 411 412 413 414 415 416 417 418
      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

419
  def have_terminal_button
420
    have_link(nil, href: terminal_project_environment_path(project, environment))
421 422
  end

423 424
  def visit_environments(project, **opts)
    visit project_environments_path(project, **opts)
F
Filipa Lacerda 已提交
425
    wait_for_requests
426
  end
427
end