summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/settings/operations_controller_spec.rb88
-rw-r--r--spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb8
-rw-r--r--spec/fixtures/api/schemas/environment.json5
-rw-r--r--spec/frontend/blob/suggest_gitlab_ci_yml/components/popover_spec.js10
-rw-r--r--spec/frontend/environments/environment_delete_spec.js38
-rw-r--r--spec/frontend/environments/environment_item_spec.js25
-rw-r--r--spec/lib/gitlab/gitaly_client/blob_service_spec.rb6
-rw-r--r--spec/lib/gitlab/sidekiq_cluster/cli_spec.rb25
-rw-r--r--spec/lib/gitlab/sidekiq_cluster_spec.rb6
-rw-r--r--spec/models/commit_status_spec.rb13
-rw-r--r--spec/models/concerns/noteable_spec.rb15
-rw-r--r--spec/models/project_services/prometheus_service_spec.rb60
-rw-r--r--spec/policies/environment_policy_spec.rb44
-rw-r--r--spec/policies/project_policy_spec.rb46
-rw-r--r--spec/requests/api/environments_spec.rb14
-rw-r--r--spec/services/projects/operations/update_service_spec.rb81
16 files changed, 468 insertions, 16 deletions
diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb
index 62b906e8507..c9afff0b73d 100644
--- a/spec/controllers/projects/settings/operations_controller_spec.rb
+++ b/spec/controllers/projects/settings/operations_controller_spec.rb
@@ -295,6 +295,94 @@ describe Projects::Settings::OperationsController do
end
end
end
+
+ describe 'POST reset_alerting_token' do
+ let(:project) { create(:project) }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'with existing alerting setting' do
+ let!(:alerting_setting) do
+ create(:project_alerting_setting, project: project)
+ end
+
+ let!(:old_token) { alerting_setting.token }
+
+ it 'returns newly reset token' do
+ reset_alerting_token
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['token']).to eq(alerting_setting.reload.token)
+ expect(old_token).not_to eq(alerting_setting.token)
+ end
+ end
+
+ context 'without existing alerting setting' do
+ it 'creates a token' do
+ reset_alerting_token
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(project.alerting_setting).not_to be_nil
+ expect(json_response['token']).to eq(project.alerting_setting.token)
+ end
+ end
+
+ context 'when update fails' do
+ let(:operations_update_service) { spy(:operations_update_service) }
+ let(:alerting_params) do
+ { alerting_setting_attributes: { regenerate_token: true } }
+ end
+
+ before do
+ expect(::Projects::Operations::UpdateService)
+ .to receive(:new).with(project, user, alerting_params)
+ .and_return(operations_update_service)
+ expect(operations_update_service).to receive(:execute)
+ .and_return(status: :error)
+ end
+
+ it 'returns unprocessable_entity' do
+ reset_alerting_token
+
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ expect(json_response).to be_empty
+ end
+ end
+
+ context 'with insufficient permissions' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it 'returns 404' do
+ reset_alerting_token
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'as an anonymous user' do
+ before do
+ sign_out(user)
+ end
+
+ it 'returns a redirect' do
+ reset_alerting_token
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ end
+ end
+
+ private
+
+ def reset_alerting_token
+ post :reset_alerting_token,
+ params: project_params(project),
+ format: :json
+ end
+ end
end
private
diff --git a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
index b23cea65b37..09130d34281 100644
--- a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
+++ b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
describe 'User follows pipeline suggest nudge spec when feature is enabled', :js do
+ include CookieHelper
+
let(:user) { create(:user, :admin) }
let(:project) { create(:project, :empty_repo) }
@@ -38,6 +40,12 @@ describe 'User follows pipeline suggest nudge spec when feature is enabled', :js
expect(page).to have_content('1/2: Choose a template')
end
end
+
+ it 'sets the commit cookie when the Commit button is clicked' do
+ click_button 'Commit changes'
+
+ expect(get_cookie("suggest_gitlab_ci_yml_commit_#{project.id}")).to be_present
+ end
end
context 'when the page is visited without the param' do
diff --git a/spec/fixtures/api/schemas/environment.json b/spec/fixtures/api/schemas/environment.json
index 84217a2a01c..f42d701834a 100644
--- a/spec/fixtures/api/schemas/environment.json
+++ b/spec/fixtures/api/schemas/environment.json
@@ -44,7 +44,10 @@
"build_path": { "type": "string" }
}
]
- }
+ },
+ "can_delete": { "type": "boolean" }
+ ,
+ "delete_path": { "type": "string" }
},
"additionalProperties": false
}
diff --git a/spec/frontend/blob/suggest_gitlab_ci_yml/components/popover_spec.js b/spec/frontend/blob/suggest_gitlab_ci_yml/components/popover_spec.js
index 43e92bdca5f..68f4c5c9e02 100644
--- a/spec/frontend/blob/suggest_gitlab_ci_yml/components/popover_spec.js
+++ b/spec/frontend/blob/suggest_gitlab_ci_yml/components/popover_spec.js
@@ -1,6 +1,5 @@
import { shallowMount } from '@vue/test-utils';
import Popover from '~/blob/suggest_gitlab_ci_yml/components/popover.vue';
-import Cookies from 'js-cookie';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import * as utils from '~/lib/utils/common_utils';
@@ -10,9 +9,11 @@ jest.mock('~/lib/utils/common_utils', () => ({
}));
const target = 'gitlab-ci-yml-selector';
-const dismissKey = 'suggest_gitlab_ci_yml_99';
+const dismissKey = '99';
const defaultTrackLabel = 'suggest_gitlab_ci_yml';
const commitTrackLabel = 'suggest_commit_first_project_gitlab_ci_yml';
+
+const dismissCookie = 'suggest_gitlab_ci_yml_99';
const humanAccess = 'owner';
describe('Suggest gitlab-ci.yml Popover', () => {
@@ -46,7 +47,8 @@ describe('Suggest gitlab-ci.yml Popover', () => {
describe('when the dismiss cookie is set', () => {
beforeEach(() => {
- Cookies.set(dismissKey, true);
+ utils.setCookie(dismissCookie, true);
+
createWrapper(defaultTrackLabel);
});
@@ -55,7 +57,7 @@ describe('Suggest gitlab-ci.yml Popover', () => {
});
afterEach(() => {
- Cookies.remove(dismissKey);
+ utils.removeCookie(dismissCookie);
});
});
diff --git a/spec/frontend/environments/environment_delete_spec.js b/spec/frontend/environments/environment_delete_spec.js
new file mode 100644
index 00000000000..b4ecb24cbac
--- /dev/null
+++ b/spec/frontend/environments/environment_delete_spec.js
@@ -0,0 +1,38 @@
+import $ from 'jquery';
+import { shallowMount } from '@vue/test-utils';
+import DeleteComponent from '~/environments/components/environment_delete.vue';
+import LoadingButton from '~/vue_shared/components/loading_button.vue';
+import eventHub from '~/environments/event_hub';
+
+$.fn.tooltip = () => {};
+
+describe('External URL Component', () => {
+ let wrapper;
+
+ const createWrapper = () => {
+ wrapper = shallowMount(DeleteComponent, {
+ propsData: {
+ environment: {},
+ },
+ });
+ };
+
+ const findButton = () => wrapper.find(LoadingButton);
+
+ beforeEach(() => {
+ jest.spyOn(window, 'confirm');
+
+ createWrapper();
+ });
+
+ it('should render a button to delete the environment', () => {
+ expect(findButton().exists()).toBe(true);
+ expect(wrapper.attributes('title')).toEqual('Delete environment');
+ });
+
+ it('emits requestDeleteEnvironment in the event hub when button is clicked', () => {
+ jest.spyOn(eventHub, '$emit');
+ findButton().vm.$emit('click');
+ expect(eventHub.$emit).toHaveBeenCalledWith('requestDeleteEnvironment', wrapper.vm.environment);
+ });
+});
diff --git a/spec/frontend/environments/environment_item_spec.js b/spec/frontend/environments/environment_item_spec.js
index 004687fcf44..5d374a162ab 100644
--- a/spec/frontend/environments/environment_item_spec.js
+++ b/spec/frontend/environments/environment_item_spec.js
@@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
import { format } from 'timeago.js';
import EnvironmentItem from '~/environments/components/environment_item.vue';
import PinComponent from '~/environments/components/environment_pin.vue';
+import DeleteComponent from '~/environments/components/environment_delete.vue';
import { environment, folder, tableData } from './mock_data';
@@ -54,6 +55,10 @@ describe('Environment item', () => {
expect(wrapper.find('.environment-created-date-timeago').text()).toContain(formattedDate);
});
+ it('should not render the delete button', () => {
+ expect(wrapper.find(DeleteComponent).exists()).toBe(false);
+ });
+
describe('With user information', () => {
it('should render user avatar with link to profile', () => {
expect(wrapper.find('.js-deploy-user-container').attributes('href')).toEqual(
@@ -98,7 +103,7 @@ describe('Environment item', () => {
expect(findAutoStop().exists()).toBe(false);
});
- it('should not render the suto-stop button', () => {
+ it('should not render the auto-stop button', () => {
expect(wrapper.find(PinComponent).exists()).toBe(false);
});
});
@@ -205,4 +210,22 @@ describe('Environment item', () => {
expect(wrapper.find('.folder-name .badge').text()).toContain(folder.size);
});
});
+
+ describe('When environment can be deleted', () => {
+ beforeEach(() => {
+ factory({
+ propsData: {
+ model: {
+ can_delete: true,
+ delete_path: 'http://0.0.0.0:3000/api/v4/projects/8/environments/45',
+ },
+ tableData,
+ },
+ });
+ });
+
+ it('should render the delete button', () => {
+ expect(wrapper.find(DeleteComponent).exists()).toBe(true);
+ });
+ });
});
diff --git a/spec/lib/gitlab/gitaly_client/blob_service_spec.rb b/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
index fc6ac491671..e609acc8fb0 100644
--- a/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/blob_service_spec.rb
@@ -46,14 +46,12 @@ describe Gitlab::GitalyClient::BlobService do
end
describe '#get_all_lfs_pointers' do
- let(:revision) { 'master' }
-
- subject { client.get_all_lfs_pointers(revision) }
+ subject { client.get_all_lfs_pointers }
it 'sends a get_all_lfs_pointers message' do
expect_any_instance_of(Gitaly::BlobService::Stub)
.to receive(:get_all_lfs_pointers)
- .with(gitaly_request_with_params(revision: revision), kind_of(Hash))
+ .with(gitaly_request_with_params({}), kind_of(Hash))
.and_return([])
subject
diff --git a/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb b/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
index 5bda8ff8c72..72727aab601 100644
--- a/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
+++ b/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb
@@ -5,8 +5,9 @@ require 'rspec-parameterized'
describe Gitlab::SidekiqCluster::CLI do
let(:cli) { described_class.new('/dev/null') }
+ let(:timeout) { described_class::DEFAULT_SOFT_TIMEOUT_SECONDS }
let(:default_options) do
- { env: 'test', directory: Dir.pwd, max_concurrency: 50, min_concurrency: 0, dryrun: false }
+ { env: 'test', directory: Dir.pwd, max_concurrency: 50, min_concurrency: 0, dryrun: false, timeout: timeout }
end
before do
@@ -80,6 +81,22 @@ describe Gitlab::SidekiqCluster::CLI do
end
end
+ context '-timeout flag' do
+ it 'when given', 'starts Sidekiq workers with given timeout' do
+ expect(Gitlab::SidekiqCluster).to receive(:start)
+ .with([['foo']], default_options.merge(timeout: 10))
+
+ cli.run(%w(foo --timeout 10))
+ end
+
+ it 'when not given', 'starts Sidekiq workers with default timeout' do
+ expect(Gitlab::SidekiqCluster).to receive(:start)
+ .with([['foo']], default_options.merge(timeout: described_class::DEFAULT_SOFT_TIMEOUT_SECONDS))
+
+ cli.run(%w(foo))
+ end
+ end
+
context 'queue namespace expansion' do
it 'starts Sidekiq workers for all queues in all_queues.yml with a namespace in argv' do
expect(Gitlab::SidekiqConfig::CliMethods).to receive(:worker_queues).and_return(['cronjob:foo', 'cronjob:bar'])
@@ -222,7 +239,8 @@ describe Gitlab::SidekiqCluster::CLI do
.with([], :KILL)
stub_const("Gitlab::SidekiqCluster::CLI::CHECK_TERMINATE_INTERVAL_SECONDS", 0.1)
- stub_const("Gitlab::SidekiqCluster::CLI::TERMINATE_TIMEOUT_SECONDS", 1)
+ allow(cli).to receive(:terminate_timeout_seconds) { 1 }
+
cli.wait_for_termination
end
@@ -251,7 +269,8 @@ describe Gitlab::SidekiqCluster::CLI do
cli.run(%w(foo))
stub_const("Gitlab::SidekiqCluster::CLI::CHECK_TERMINATE_INTERVAL_SECONDS", 0.1)
- stub_const("Gitlab::SidekiqCluster::CLI::TERMINATE_TIMEOUT_SECONDS", 1)
+ allow(cli).to receive(:terminate_timeout_seconds) { 1 }
+
cli.wait_for_termination
end
end
diff --git a/spec/lib/gitlab/sidekiq_cluster_spec.rb b/spec/lib/gitlab/sidekiq_cluster_spec.rb
index fa5de04f2f3..9316ac29dd6 100644
--- a/spec/lib/gitlab/sidekiq_cluster_spec.rb
+++ b/spec/lib/gitlab/sidekiq_cluster_spec.rb
@@ -58,6 +58,7 @@ describe Gitlab::SidekiqCluster do
directory: 'foo/bar',
max_concurrency: 20,
min_concurrency: 10,
+ timeout: 25,
dryrun: true
}
@@ -74,6 +75,7 @@ describe Gitlab::SidekiqCluster do
max_concurrency: 50,
min_concurrency: 0,
worker_id: an_instance_of(Integer),
+ timeout: 25,
dryrun: false
}
@@ -87,10 +89,10 @@ describe Gitlab::SidekiqCluster do
describe '.start_sidekiq' do
let(:first_worker_id) { 0 }
let(:options) do
- { env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 0, worker_id: first_worker_id, dryrun: false }
+ { env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 0, worker_id: first_worker_id, timeout: 10, dryrun: false }
end
let(:env) { { "ENABLE_SIDEKIQ_CLUSTER" => "1", "SIDEKIQ_WORKER_ID" => first_worker_id.to_s } }
- let(:args) { ['bundle', 'exec', 'sidekiq', anything, '-eproduction', *([anything] * 5)] }
+ let(:args) { ['bundle', 'exec', 'sidekiq', anything, '-eproduction', '-t10', *([anything] * 5)] }
it 'starts a Sidekiq process' do
allow(Process).to receive(:spawn).and_return(1)
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index e1a748da7fd..40d9afcdd14 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -449,6 +449,19 @@ describe CommitStatus do
end
end
+ describe '.match_id_and_lock_version' do
+ let(:status_1) { create_status(lock_version: 1) }
+ let(:status_2) { create_status(lock_version: 2) }
+
+ it 'returns statuses that match the given id and lock versions' do
+ params = [
+ { id: status_1.id, lock_version: 1 },
+ { id: status_2.id, lock_version: 3 }
+ ]
+ expect(described_class.match_id_and_lock_version(params)).to contain_exactly(status_1)
+ end
+ end
+
describe '#before_sha' do
subject { commit_status.before_sha }
diff --git a/spec/models/concerns/noteable_spec.rb b/spec/models/concerns/noteable_spec.rb
index e8991a3a015..097bc24d90f 100644
--- a/spec/models/concerns/noteable_spec.rb
+++ b/spec/models/concerns/noteable_spec.rb
@@ -62,6 +62,21 @@ describe Noteable do
end
end
+ describe '#discussion_ids_relation' do
+ it 'returns ordered discussion_ids' do
+ discussion_ids = subject.discussion_ids_relation.pluck(:discussion_id)
+
+ expect(discussion_ids).to eq([
+ active_diff_note1,
+ active_diff_note3,
+ outdated_diff_note1,
+ discussion_note1,
+ note1,
+ note2
+ ].map(&:discussion_id))
+ end
+ end
+
describe '#grouped_diff_discussions' do
let(:grouped_diff_discussions) { subject.grouped_diff_discussions }
diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb
index fd4783a60f2..297411f7980 100644
--- a/spec/models/project_services/prometheus_service_spec.rb
+++ b/spec/models/project_services/prometheus_service_spec.rb
@@ -66,6 +66,18 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
end
end
+ it 'can query when local requests are allowed' do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+
+ aggregate_failures do
+ ['127.0.0.1', '192.168.2.3'].each do |url|
+ allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)])
+
+ expect(service.can_query?).to be true
+ end
+ end
+ end
+
context 'with self-monitoring project and internal Prometheus' do
before do
service.api_url = 'http://localhost:9090'
@@ -152,6 +164,54 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
expect(service.prometheus_client).to be_nil
end
end
+
+ context 'when local requests are allowed' do
+ let(:manual_configuration) { true }
+ let(:api_url) { 'http://192.168.1.1:9090' }
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+
+ stub_prometheus_request("#{api_url}/api/v1/query?query=1")
+ end
+
+ it 'allows local requests' do
+ expect(service.prometheus_client).not_to be_nil
+ expect { service.prometheus_client.ping }.not_to raise_error
+ end
+ end
+
+ context 'when local requests are blocked' do
+ let(:manual_configuration) { true }
+ let(:api_url) { 'http://192.168.1.1:9090' }
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+
+ stub_prometheus_request("#{api_url}/api/v1/query?query=1")
+ end
+
+ it 'blocks local requests' do
+ expect(service.prometheus_client).to be_nil
+ end
+
+ context 'with self monitoring project and internal Prometheus URL' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+ stub_application_setting(self_monitoring_project_id: project.id)
+
+ stub_config(prometheus: {
+ enable: true,
+ listen_address: api_url
+ })
+ end
+
+ it 'allows local requests' do
+ expect(service.prometheus_client).not_to be_nil
+ expect { service.prometheus_client.ping }.not_to raise_error
+ end
+ end
+ end
end
describe '#prometheus_available?' do
diff --git a/spec/policies/environment_policy_spec.rb b/spec/policies/environment_policy_spec.rb
index 63a9512afcd..a098b52023d 100644
--- a/spec/policies/environment_policy_spec.rb
+++ b/spec/policies/environment_policy_spec.rb
@@ -86,6 +86,50 @@ describe EnvironmentPolicy do
it { expect(policy).to be_allowed :stop_environment }
end
end
+
+ describe '#destroy_environment' do
+ let(:environment) do
+ create(:environment, project: project)
+ end
+
+ where(:access_level, :allowed?) do
+ nil | false
+ :guest | false
+ :reporter | false
+ :developer | true
+ :maintainer | true
+ end
+
+ with_them do
+ before do
+ project.add_user(user, access_level) unless access_level.nil?
+ end
+
+ it { expect(policy).to be_disallowed :destroy_environment }
+
+ context 'when environment is stopped' do
+ before do
+ environment.stop!
+ end
+
+ it { expect(policy.allowed?(:destroy_environment)).to be allowed? }
+ end
+ end
+
+ context 'when an admin user' do
+ let(:user) { create(:user, :admin) }
+
+ it { expect(policy).to be_disallowed :destroy_environment }
+
+ context 'when environment is stopped' do
+ before do
+ environment.stop!
+ end
+
+ it { expect(policy).to be_allowed :destroy_environment }
+ end
+ end
+ end
end
context 'when project is public' do
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index e7d49377b78..a729da5afad 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -573,4 +573,50 @@ describe ProjectPolicy do
it { is_expected.to be_allowed(:admin_issue) }
end
end
+
+ describe 'read_prometheus_alerts' do
+ subject { described_class.new(current_user, project) }
+
+ context 'with admin' do
+ let(:current_user) { admin }
+
+ it { is_expected.to be_allowed(:read_prometheus_alerts) }
+ end
+
+ context 'with owner' do
+ let(:current_user) { owner }
+
+ it { is_expected.to be_allowed(:read_prometheus_alerts) }
+ end
+
+ context 'with maintainer' do
+ let(:current_user) { maintainer }
+
+ it { is_expected.to be_allowed(:read_prometheus_alerts) }
+ end
+
+ context 'with developer' do
+ let(:current_user) { developer }
+
+ it { is_expected.to be_disallowed(:read_prometheus_alerts) }
+ end
+
+ context 'with reporter' do
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_disallowed(:read_prometheus_alerts) }
+ end
+
+ context 'with guest' do
+ let(:current_user) { guest }
+
+ it { is_expected.to be_disallowed(:read_prometheus_alerts) }
+ end
+
+ context 'with anonymous' do
+ let(:current_user) { nil }
+
+ it { is_expected.to be_disallowed(:read_prometheus_alerts) }
+ end
+ end
end
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
index 56af64342c0..4e2dfe7725e 100644
--- a/spec/requests/api/environments_spec.rb
+++ b/spec/requests/api/environments_spec.rb
@@ -171,7 +171,15 @@ describe API::Environments do
describe 'DELETE /projects/:id/environments/:environment_id' do
context 'as a maintainer' do
- it 'returns a 200 for an existing environment' do
+ it "rejects the requests in environment isn't stopped" do
+ delete api("/projects/#{project.id}/environments/#{environment.id}", user)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+
+ it 'returns a 200 for stopped environment' do
+ environment.stop
+
delete api("/projects/#{project.id}/environments/#{environment.id}", user)
expect(response).to have_gitlab_http_status(:no_content)
@@ -185,6 +193,10 @@ describe API::Environments do
end
it_behaves_like '412 response' do
+ before do
+ environment.stop
+ end
+
let(:request) { api("/projects/#{project.id}/environments/#{environment.id}", user) }
end
end
diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index de028ecb693..99a9fdd4184 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -11,6 +11,87 @@ describe Projects::Operations::UpdateService do
subject { described_class.new(project, user, params) }
describe '#execute' do
+ context 'alerting setting' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ shared_examples 'no operation' do
+ it 'does nothing' do
+ expect(result[:status]).to eq(:success)
+ expect(project.reload.alerting_setting).to be_nil
+ end
+ end
+
+ context 'with valid params' do
+ let(:params) { { alerting_setting_attributes: alerting_params } }
+
+ shared_examples 'setting creation' do
+ it 'creates a setting' do
+ expect(project.alerting_setting).to be_nil
+
+ expect(result[:status]).to eq(:success)
+ expect(project.reload.alerting_setting).not_to be_nil
+ end
+ end
+
+ context 'when regenerate_token is not set' do
+ let(:alerting_params) { { token: 'some token' } }
+
+ context 'with an existing setting' do
+ let!(:alerting_setting) do
+ create(:project_alerting_setting, project: project)
+ end
+
+ it 'ignores provided token' do
+ expect(result[:status]).to eq(:success)
+ expect(project.reload.alerting_setting.token)
+ .to eq(alerting_setting.token)
+ end
+ end
+
+ context 'without an existing setting' do
+ it_behaves_like 'setting creation'
+ end
+ end
+
+ context 'when regenerate_token is set' do
+ let(:alerting_params) { { regenerate_token: true } }
+
+ context 'with an existing setting' do
+ let(:token) { 'some token' }
+
+ let!(:alerting_setting) do
+ create(:project_alerting_setting, project: project, token: token)
+ end
+
+ it 'regenerates token' do
+ expect(result[:status]).to eq(:success)
+ expect(project.reload.alerting_setting.token).not_to eq(token)
+ end
+ end
+
+ context 'without an existing setting' do
+ it_behaves_like 'setting creation'
+
+ context 'with insufficient permissions' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like 'no operation'
+ end
+ end
+ end
+ end
+
+ context 'with empty params' do
+ let(:params) { {} }
+
+ it_behaves_like 'no operation'
+ end
+ end
+
context 'metrics dashboard setting' do
let(:params) do
{