diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2017-07-07 15:17:02 +0000 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2017-07-07 15:17:02 +0000 |
commit | a77158ff31d84bf978038e5c3c7aec3faa509035 (patch) | |
tree | e03b73302ecd7eef1c607a4a6b8ee7659977bf18 /spec/controllers | |
parent | 897240289877f768709c31a1b5f369574595344d (diff) | |
parent | e0c150da2f8f266cfa045e7ded0e579a83a964c3 (diff) | |
download | gitlab-ce-a77158ff31d84bf978038e5c3c7aec3faa509035.tar.gz |
Merge branch 'feature/intermediate/32568-adding-variables-to-pipelines-schedules' into 'master'
Add variables to pipelines schedules
Closes #32568
See merge request !12372
Diffstat (limited to 'spec/controllers')
-rw-r--r-- | spec/controllers/projects/pipeline_schedules_controller_spec.rb | 330 |
1 files changed, 294 insertions, 36 deletions
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb index a8c44d5c313..41bf5580993 100644 --- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb +++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' describe Projects::PipelineSchedulesController do + include AccessMatchersForController + set(:project) { create(:empty_project, :public) } let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } @@ -17,6 +19,14 @@ describe Projects::PipelineSchedulesController do expect(response).to render_template(:index) end + it 'avoids N + 1 queries' do + control_count = ActiveRecord::QueryRecorder.new { visit_pipelines_schedules }.count + + create_list(:ci_pipeline_schedule, 2, project: project) + + expect { visit_pipelines_schedules }.not_to exceed_query_limit(control_count) + end + context 'when the scope is set to active' do let(:scope) { 'active' } @@ -36,104 +46,352 @@ describe Projects::PipelineSchedulesController do end end - describe 'GET edit' do - let(:user) { create(:user) } + describe 'GET #new' do + set(:user) { create(:user) } before do - project.add_master(user) - + project.add_developer(user) sign_in(user) end - it 'loads the pipeline schedule' do - get :edit, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + it 'initializes a pipeline schedule model' do + get :new, namespace_id: project.namespace.to_param, project_id: project expect(response).to have_http_status(:ok) - expect(assigns(:schedule)).to eq(pipeline_schedule) + expect(assigns(:schedule)).to be_a_new(Ci::PipelineSchedule) end end - describe 'DELETE #destroy' do - set(:user) { create(:user) } + describe 'POST #create' do + describe 'functionality' do + set(:user) { create(:user) } - context 'when a developer makes the request' do before do project.add_developer(user) sign_in(user) + end - delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + let(:basic_param) do + attributes_for(:ci_pipeline_schedule) end - it 'does not delete the pipeline schedule' do - expect(response).not_to have_http_status(:ok) + context 'when variables_attributes has one variable' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ key: 'AAA', value: 'AAA123' }] + }) + end + + it 'creates a new schedule' do + expect { go } + .to change { Ci::PipelineSchedule.count }.by(1) + .and change { Ci::PipelineScheduleVariable.count }.by(1) + + expect(response).to have_http_status(:found) + + Ci::PipelineScheduleVariable.last.tap do |v| + expect(v.key).to eq("AAA") + expect(v.value).to eq("AAA123") + end + end + end + + context 'when variables_attributes has two variables and duplicted' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ key: 'AAA', value: 'AAA123' }, { key: 'AAA', value: 'BBB123' }] + }) + end + + it 'returns an error that the keys of variable are duplicated' do + expect { go } + .to change { Ci::PipelineSchedule.count }.by(0) + .and change { Ci::PipelineScheduleVariable.count }.by(0) + + expect(assigns(:schedule).errors['variables']).not_to be_empty + end end end - context 'when a master makes the request' do + describe 'security' do + let(:schedule) { attributes_for(:ci_pipeline_schedule) } + + it { expect { go }.to be_allowed_for(:admin) } + it { expect { go }.to be_allowed_for(:owner).of(project) } + it { expect { go }.to be_allowed_for(:master).of(project) } + it { expect { go }.to be_allowed_for(:developer).of(project) } + it { expect { go }.to be_denied_for(:reporter).of(project) } + it { expect { go }.to be_denied_for(:guest).of(project) } + it { expect { go }.to be_denied_for(:user) } + it { expect { go }.to be_denied_for(:external) } + it { expect { go }.to be_denied_for(:visitor) } + end + + def go + post :create, namespace_id: project.namespace.to_param, project_id: project, schedule: schedule + end + end + + describe 'PUT #update' do + describe 'functionality' do + set(:user) { create(:user) } + let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project, owner: user) } + before do - project.add_master(user) + project.add_developer(user) sign_in(user) end - it 'destroys the pipeline schedule' do - expect do - delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id - end.to change { project.pipeline_schedules.count }.by(-1) + context 'when a pipeline schedule has no variables' do + let(:basic_param) do + { description: 'updated_desc', cron: '0 1 * * *', cron_timezone: 'UTC', ref: 'patch-x', active: true } + end - expect(response).to have_http_status(302) + context 'when params include one variable' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ key: 'AAA', value: 'AAA123' }] + }) + end + + it 'inserts new variable to the pipeline schedule' do + expect { go }.to change { Ci::PipelineScheduleVariable.count }.by(1) + + pipeline_schedule.reload + expect(response).to have_http_status(:found) + expect(pipeline_schedule.variables.last.key).to eq('AAA') + expect(pipeline_schedule.variables.last.value).to eq('AAA123') + end + end + + context 'when params include two duplicated variables' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ key: 'AAA', value: 'AAA123' }, { key: 'AAA', value: 'BBB123' }] + }) + end + + it 'returns an error that variables are duplciated' do + go + + expect(assigns(:schedule).errors['variables']).not_to be_empty + end + end + end + + context 'when a pipeline schedule has one variable' do + let(:basic_param) do + { description: 'updated_desc', cron: '0 1 * * *', cron_timezone: 'UTC', ref: 'patch-x', active: true } + end + + let!(:pipeline_schedule_variable) do + create(:ci_pipeline_schedule_variable, + key: 'CCC', pipeline_schedule: pipeline_schedule) + end + + context 'when adds a new variable' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ key: 'AAA', value: 'AAA123' }] + }) + end + + it 'adds the new variable' do + expect { go }.to change { Ci::PipelineScheduleVariable.count }.by(1) + + pipeline_schedule.reload + expect(pipeline_schedule.variables.last.key).to eq('AAA') + end + end + + context 'when adds a new duplicated variable' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ key: 'CCC', value: 'AAA123' }] + }) + end + + it 'returns an error' do + expect { go }.not_to change { Ci::PipelineScheduleVariable.count } + + pipeline_schedule.reload + expect(assigns(:schedule).errors['variables']).not_to be_empty + end + end + + context 'when updates a variable' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ id: pipeline_schedule_variable.id, value: 'new_value' }] + }) + end + + it 'updates the variable' do + expect { go }.not_to change { Ci::PipelineScheduleVariable.count } + + pipeline_schedule_variable.reload + expect(pipeline_schedule_variable.value).to eq('new_value') + end + end + + context 'when deletes a variable' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ id: pipeline_schedule_variable.id, _destroy: true }] + }) + end + + it 'delete the existsed variable' do + expect { go }.to change { Ci::PipelineScheduleVariable.count }.by(-1) + end + end + + context 'when deletes and creates a same key simultaneously' do + let(:schedule) do + basic_param.merge({ + variables_attributes: [{ id: pipeline_schedule_variable.id, _destroy: true }, + { key: 'CCC', value: 'CCC123' }] + }) + end + + it 'updates the variable' do + expect { go }.not_to change { Ci::PipelineScheduleVariable.count } + + pipeline_schedule.reload + expect(pipeline_schedule.variables.last.key).to eq('CCC') + expect(pipeline_schedule.variables.last.value).to eq('CCC123') + end + end end end - end - describe 'security' do - include AccessMatchersForController + describe 'security' do + let(:schedule) { { description: 'updated_desc' } } - describe 'GET edit' do it { expect { go }.to be_allowed_for(:admin) } it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_allowed_for(:developer).of(project) } + it { expect { go }.to be_allowed_for(:developer).of(project).own(pipeline_schedule) } it { expect { go }.to be_denied_for(:reporter).of(project) } it { expect { go }.to be_denied_for(:guest).of(project) } it { expect { go }.to be_denied_for(:user) } it { expect { go }.to be_denied_for(:external) } it { expect { go }.to be_denied_for(:visitor) } - def go + context 'when a developer created a pipeline schedule' do + let(:developer_1) { create(:user) } + let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project, owner: developer_1) } + + before do + project.add_developer(developer_1) + end + + it { expect { go }.to be_allowed_for(developer_1) } + it { expect { go }.to be_denied_for(:developer).of(project) } + it { expect { go }.to be_allowed_for(:master).of(project) } + end + + context 'when a master created a pipeline schedule' do + let(:master_1) { create(:user) } + let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project, owner: master_1) } + + before do + project.add_master(master_1) + end + + it { expect { go }.to be_allowed_for(master_1) } + it { expect { go }.to be_allowed_for(:master).of(project) } + it { expect { go }.to be_denied_for(:developer).of(project) } + end + end + + def go + put :update, namespace_id: project.namespace.to_param, + project_id: project, id: pipeline_schedule, + schedule: schedule + end + end + + describe 'GET #edit' do + describe 'functionality' do + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + end + + it 'loads the pipeline schedule' do get :edit, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + + expect(response).to have_http_status(:ok) + expect(assigns(:schedule)).to eq(pipeline_schedule) end end - describe 'GET take_ownership' do + describe 'security' do it { expect { go }.to be_allowed_for(:admin) } it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_allowed_for(:developer).of(project) } + it { expect { go }.to be_allowed_for(:developer).of(project).own(pipeline_schedule) } it { expect { go }.to be_denied_for(:reporter).of(project) } it { expect { go }.to be_denied_for(:guest).of(project) } it { expect { go }.to be_denied_for(:user) } it { expect { go }.to be_denied_for(:external) } it { expect { go }.to be_denied_for(:visitor) } + end - def go - post :take_ownership, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id - end + def go + get :edit, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id end + end - describe 'PUT update' do + describe 'GET #take_ownership' do + describe 'security' do it { expect { go }.to be_allowed_for(:admin) } it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_allowed_for(:developer).of(project) } + it { expect { go }.to be_allowed_for(:developer).of(project).own(pipeline_schedule) } it { expect { go }.to be_denied_for(:reporter).of(project) } it { expect { go }.to be_denied_for(:guest).of(project) } it { expect { go }.to be_denied_for(:user) } it { expect { go }.to be_denied_for(:external) } it { expect { go }.to be_denied_for(:visitor) } + end + + def go + post :take_ownership, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + end + end + + describe 'DELETE #destroy' do + set(:user) { create(:user) } + + context 'when a developer makes the request' do + before do + project.add_developer(user) + sign_in(user) - def go - put :update, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id, - schedule: { description: 'a' } + delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + end + + it 'does not delete the pipeline schedule' do + expect(response).to have_http_status(:not_found) + end + end + + context 'when a master makes the request' do + before do + project.add_master(user) + sign_in(user) + end + + it 'destroys the pipeline schedule' do + expect do + delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + end.to change { project.pipeline_schedules.count }.by(-1) + + expect(response).to have_http_status(302) end end end |