diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/projects/settings/operations_controller_spec.rb | 88 | ||||
-rw-r--r-- | spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb | 8 | ||||
-rw-r--r-- | spec/fixtures/api/schemas/environment.json | 5 | ||||
-rw-r--r-- | spec/frontend/blob/suggest_gitlab_ci_yml/components/popover_spec.js | 10 | ||||
-rw-r--r-- | spec/frontend/environments/environment_delete_spec.js | 38 | ||||
-rw-r--r-- | spec/frontend/environments/environment_item_spec.js | 25 | ||||
-rw-r--r-- | spec/lib/gitlab/gitaly_client/blob_service_spec.rb | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/sidekiq_cluster/cli_spec.rb | 25 | ||||
-rw-r--r-- | spec/lib/gitlab/sidekiq_cluster_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/commit_status_spec.rb | 13 | ||||
-rw-r--r-- | spec/models/concerns/noteable_spec.rb | 15 | ||||
-rw-r--r-- | spec/models/project_services/prometheus_service_spec.rb | 60 | ||||
-rw-r--r-- | spec/policies/environment_policy_spec.rb | 44 | ||||
-rw-r--r-- | spec/policies/project_policy_spec.rb | 46 | ||||
-rw-r--r-- | spec/requests/api/environments_spec.rb | 14 | ||||
-rw-r--r-- | spec/services/projects/operations/update_service_spec.rb | 81 |
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 { |