338 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require 'spec_helper'
 | |
| 
 | |
| RSpec.describe 'Pipeline Schedules', :js do
 | |
|   include Spec::Support::Helpers::ModalHelpers
 | |
| 
 | |
|   let!(:project) { create(:project, :repository) }
 | |
|   let!(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) }
 | |
|   let!(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) }
 | |
|   let(:scope) { nil }
 | |
|   let!(:user) { create(:user) }
 | |
| 
 | |
|   before do
 | |
|     stub_feature_flags(pipeline_schedules_vue: false)
 | |
|   end
 | |
| 
 | |
|   context 'logged in as the pipeline schedule owner' do
 | |
|     before do
 | |
|       project.add_developer(user)
 | |
|       pipeline_schedule.update!(owner: user)
 | |
|       gitlab_sign_in(user)
 | |
|     end
 | |
| 
 | |
|     describe 'GET /projects/pipeline_schedules' do
 | |
|       before do
 | |
|         visit_pipelines_schedules
 | |
|       end
 | |
| 
 | |
|       it 'edits the pipeline' do
 | |
|         page.within('.pipeline-schedule-table-row') do
 | |
|           click_link 'Edit'
 | |
|         end
 | |
| 
 | |
|         expect(page).to have_content('Edit Pipeline Schedule')
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     describe 'PATCH /projects/pipelines_schedules/:id/edit' do
 | |
|       before do
 | |
|         edit_pipeline_schedule
 | |
|       end
 | |
| 
 | |
|       it 'displays existing properties' do
 | |
|         description = find_field('schedule_description').value
 | |
|         expect(description).to eq('pipeline schedule')
 | |
|         expect(page).to have_button('master')
 | |
|         expect(page).to have_button('UTC')
 | |
|       end
 | |
| 
 | |
|       it 'edits the scheduled pipeline' do
 | |
|         fill_in 'schedule_description', with: 'my brand new description'
 | |
| 
 | |
|         save_pipeline_schedule
 | |
| 
 | |
|         expect(page).to have_content('my brand new description')
 | |
|       end
 | |
| 
 | |
|       context 'when ref is nil' do
 | |
|         before do
 | |
|           pipeline_schedule.update_attribute(:ref, nil)
 | |
|           edit_pipeline_schedule
 | |
|         end
 | |
| 
 | |
|         it 'shows the pipeline schedule with default ref' do
 | |
|           page.within('[data-testid="schedule-target-ref"]') do
 | |
|             expect(first('.gl-new-dropdown-button-text').text).to eq('master')
 | |
|           end
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       context 'when ref is empty' do
 | |
|         before do
 | |
|           pipeline_schedule.update_attribute(:ref, '')
 | |
|           edit_pipeline_schedule
 | |
|         end
 | |
| 
 | |
|         it 'shows the pipeline schedule with default ref' do
 | |
|           page.within('[data-testid="schedule-target-ref"]') do
 | |
|             expect(first('.gl-new-dropdown-button-text').text).to eq('master')
 | |
|           end
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context 'logged in as a project maintainer' do
 | |
|     before do
 | |
|       project.add_maintainer(user)
 | |
|       gitlab_sign_in(user)
 | |
|     end
 | |
| 
 | |
|     describe 'GET /projects/pipeline_schedules' do
 | |
|       before do
 | |
|         visit_pipelines_schedules
 | |
|       end
 | |
| 
 | |
|       describe 'The view' do
 | |
|         it 'displays the required information description' do
 | |
|           page.within('.pipeline-schedule-table-row') do
 | |
|             expect(page).to have_content('pipeline schedule')
 | |
|             expect(find("[data-testid='next-run-cell'] time")['title'])
 | |
|               .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y'))
 | |
|             expect(page).to have_link('master')
 | |
|             expect(page).to have_link("##{pipeline.id}")
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         it 'creates a new scheduled pipeline' do
 | |
|           click_link 'New schedule'
 | |
| 
 | |
|           expect(page).to have_content('Schedule a new pipeline')
 | |
|         end
 | |
| 
 | |
|         it 'changes ownership of the pipeline' do
 | |
|           click_button 'Take ownership'
 | |
| 
 | |
|           page.within('#pipeline-take-ownership-modal') do
 | |
|             click_link 'Take ownership'
 | |
|           end
 | |
| 
 | |
|           page.within('.pipeline-schedule-table-row') do
 | |
|             expect(page).not_to have_content('No owner')
 | |
|             expect(page).to have_link('Sidney Jones')
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         it 'deletes the pipeline' do
 | |
|           click_link 'Delete'
 | |
| 
 | |
|           accept_gl_confirm(button_text: 'Delete pipeline schedule')
 | |
| 
 | |
|           expect(page).not_to have_css(".pipeline-schedule-table-row")
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       context 'when ref is nil' do
 | |
|         before do
 | |
|           pipeline_schedule.update_attribute(:ref, nil)
 | |
|           visit_pipelines_schedules
 | |
|         end
 | |
| 
 | |
|         it 'shows a list of the pipeline schedules with empty ref column' do
 | |
|           expect(first('.branch-name-cell').text).to eq('')
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       context 'when ref is empty' do
 | |
|         before do
 | |
|           pipeline_schedule.update_attribute(:ref, '')
 | |
|           visit_pipelines_schedules
 | |
|         end
 | |
| 
 | |
|         it 'shows a list of the pipeline schedules with empty ref column' do
 | |
|           expect(first('.branch-name-cell').text).to eq('')
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     describe 'POST /projects/pipeline_schedules/new' do
 | |
|       before do
 | |
|         visit_new_pipeline_schedule
 | |
|       end
 | |
| 
 | |
|       it 'sets defaults for timezone and target branch' do
 | |
|         expect(page).to have_button('master')
 | |
|         expect(page).to have_button('UTC')
 | |
|       end
 | |
| 
 | |
|       it 'creates a new scheduled pipeline' do
 | |
|         fill_in_schedule_form
 | |
|         save_pipeline_schedule
 | |
| 
 | |
|         expect(page).to have_content('my fancy description')
 | |
|       end
 | |
| 
 | |
|       it 'prevents an invalid form from being submitted' do
 | |
|         save_pipeline_schedule
 | |
| 
 | |
|         expect(page).to have_content('This field is required')
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when user creates a new pipeline schedule with variables' do
 | |
|       before do
 | |
|         visit_pipelines_schedules
 | |
|         click_link 'New schedule'
 | |
|         fill_in_schedule_form
 | |
|         all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA')
 | |
|         all('[name="schedule[variables_attributes][][secret_value]"]')[0].set('AAA123')
 | |
|         all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB')
 | |
|         all('[name="schedule[variables_attributes][][secret_value]"]')[1].set('BBB123')
 | |
|         save_pipeline_schedule
 | |
|       end
 | |
| 
 | |
|       it 'user sees the new variable in edit window' do
 | |
|         find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
 | |
|         page.within('.ci-variable-list') do
 | |
|           expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('AAA')
 | |
|           expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('AAA123')
 | |
|           expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-key").value).to eq('BBB')
 | |
|           expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-value", visible: false).value).to eq('BBB123')
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when user edits a variable of a pipeline schedule' do
 | |
|       before do
 | |
|         create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
 | |
|           create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule)
 | |
|         end
 | |
| 
 | |
|         visit_pipelines_schedules
 | |
|         find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
 | |
| 
 | |
|         find('.js-ci-variable-list-section .js-secret-value-reveal-button').click
 | |
|         first('.js-ci-variable-input-key').set('foo')
 | |
|         first('.js-ci-variable-input-value').set('bar')
 | |
|         click_button 'Save pipeline schedule'
 | |
|       end
 | |
| 
 | |
|       it 'user sees the updated variable in edit window' do
 | |
|         find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
 | |
|         page.within('.ci-variable-list') do
 | |
|           expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('foo')
 | |
|           expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('bar')
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when user removes a variable of a pipeline schedule' do
 | |
|       before do
 | |
|         create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
 | |
|           create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule)
 | |
|         end
 | |
| 
 | |
|         visit_pipelines_schedules
 | |
|         find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
 | |
|         find('.ci-variable-list .ci-variable-row-remove-button').click
 | |
|         click_button 'Save pipeline schedule'
 | |
|       end
 | |
| 
 | |
|       it 'user does not see the removed variable in edit window' do
 | |
|         find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
 | |
|         page.within('.ci-variable-list') do
 | |
|           expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('')
 | |
|           expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('')
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     context 'when active is true and next_run_at is NULL' do
 | |
|       before do
 | |
|         create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
 | |
|           pipeline_schedule.update_attribute(:next_run_at, nil) # Consequently next_run_at will be nil
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       it 'user edit and recover the problematic pipeline schedule' do
 | |
|         visit_pipelines_schedules
 | |
|         find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
 | |
|         fill_in 'schedule_cron', with: '* 1 2 3 4'
 | |
|         click_button 'Save pipeline schedule'
 | |
| 
 | |
|         page.within('.pipeline-schedule-table-row:nth-child(1)') do
 | |
|           expect(page).to have_css("[data-testid='next-run-cell'] time")
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context 'logged in as non-member' do
 | |
|     before do
 | |
|       gitlab_sign_in(user)
 | |
|     end
 | |
| 
 | |
|     describe 'GET /projects/pipeline_schedules' do
 | |
|       before do
 | |
|         visit_pipelines_schedules
 | |
|       end
 | |
| 
 | |
|       describe 'The view' do
 | |
|         it 'does not show create schedule button' do
 | |
|           expect(page).not_to have_link('New schedule')
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context 'not logged in' do
 | |
|     describe 'GET /projects/pipeline_schedules' do
 | |
|       before do
 | |
|         visit_pipelines_schedules
 | |
|       end
 | |
| 
 | |
|       describe 'The view' do
 | |
|         it 'does not show create schedule button' do
 | |
|           expect(page).not_to have_link('New schedule')
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def visit_new_pipeline_schedule
 | |
|     visit new_project_pipeline_schedule_path(project, pipeline_schedule)
 | |
|   end
 | |
| 
 | |
|   def edit_pipeline_schedule
 | |
|     visit edit_project_pipeline_schedule_path(project, pipeline_schedule)
 | |
|   end
 | |
| 
 | |
|   def visit_pipelines_schedules
 | |
|     visit project_pipeline_schedules_path(project, scope: scope)
 | |
|   end
 | |
| 
 | |
|   def select_timezone
 | |
|     find('.js-timezone-dropdown').click
 | |
|     click_link 'American Samoa'
 | |
|   end
 | |
| 
 | |
|   def select_target_branch
 | |
|     find('[data-testid="schedule-target-ref"] .dropdown-toggle').click
 | |
|     click_button 'master'
 | |
|   end
 | |
| 
 | |
|   def save_pipeline_schedule
 | |
|     click_button 'Save pipeline schedule'
 | |
|   end
 | |
| 
 | |
|   def fill_in_schedule_form
 | |
|     fill_in 'schedule_description', with: 'my fancy description'
 | |
|     fill_in 'schedule_cron', with: '* 1 2 3 4'
 | |
| 
 | |
|     select_timezone
 | |
|     select_target_branch
 | |
|   end
 | |
| end
 |