environments_spec.rb 13.0 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 98 99
    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.')

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
135 136
        create(:deployment, environment: environment,
                            sha: project.commit.id)
137
      end
138

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

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

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

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

154
        let!(:deployment) do
155
          create(:deployment, environment: environment,
156
                              deployable: build,
157
                              sha: project.commit.id)
158
        end
159

160 161 162 163 164
        before do
          visit_environments(project)
        end

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

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

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

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

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

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

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

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

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

196
        context 'with external_url' do
197 198 199
          let(:environment) { create(:environment, project: project, external_url: 'https://git.gitlab.com') }
          let(:build) { create(:ci_build, pipeline: pipeline) }
          let(:deployment) { create(:deployment, environment: environment, deployable: build) }
200

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

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

211
          let(:deployment) do
212 213 214 215
            create(:deployment, environment: environment,
                                deployable: build,
                                on_stop: 'close_app')
          end
216

217
          it 'shows a stop button' do
218
            expect(page).to have_selector(stop_button_selector)
219
          end
K
Kamil Trzcinski 已提交
220

221
          context 'when user is a reporter' do
222
            let(:role) { :reporter }
K
Kamil Trzcinski 已提交
223

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

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

235 236 237 238 239 240 241
              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 已提交
242

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

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

252
            it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
253
          end
K
Kamil Trzcinski 已提交
254

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

259
            it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
F
Filipa Lacerda 已提交
260
          end
261
        end
262
      end
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 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

      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,
                 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

          time_diff = [0, delayed_job.scheduled_at - Time.now].max
          expect(page).to have_button('Delayed job')
          expect(page).to have_content(Time.at(time_diff).utc.strftime("%H:%M:%S"))
        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
327 328 329
    end
  end

330 331 332
  it 'does have a new environment button' do
    visit_environments(project)

333
    expect(page).to have_link('New environment')
334
  end
335

336
  describe 'creating a new environment' do
337
    before do
338
      visit_environments(project)
339
    end
340

341
    context 'user is a developer' do
342
      let(:role) { :developer }
343

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

349
        expect(page).to have_content('production')
350 351
      end

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

357
        expect(page).to have_content('Name can contain only letters')
358 359 360
      end
    end

361
    context 'user is a reporter' do
362
      let(:role) { :reporter }
363

364
      it 'reporters tries to create a new environment' do
365 366 367 368
        expect(page).not_to have_link('New environment')
      end
    end
  end
369

370 371 372 373 374 375 376 377 378 379
  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

380
    it 'users unfurls an environment folder' do
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
      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 已提交
396 397 398 399 400 401 402 403 404 405
  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

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

416
  def have_terminal_button
417
    have_link(nil, href: terminal_project_environment_path(project, environment))
418 419
  end

420 421
  def visit_environments(project, **opts)
    visit project_environments_path(project, **opts)
F
Filipa Lacerda 已提交
422
    wait_for_requests
423
  end
424
end