From 326b4d3216d107b40142ee847c06f2c41a1ef220 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 25 Aug 2021 09:10:52 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- spec/controllers/admin/runners_controller_spec.rb | 28 ---- spec/controllers/invites_controller_spec.rb | 26 +++- spec/controllers/registrations_controller_spec.rb | 34 +++++ spec/features/invites_spec.rb | 14 ++ spec/frontend/issue_show/components/app_spec.js | 44 ++++-- .../runner/components/runner_update_form_spec.js | 14 +- .../issuable/issuable_header_warnings_spec.js | 74 ++++++---- spec/helpers/issuables_helper_spec.rb | 3 +- spec/helpers/issues_helper_spec.rb | 51 +++++++ spec/helpers/notify_helper_spec.rb | 22 +++ .../load_balancing/service_discovery_spec.rb | 79 +++++++++-- .../gitlab/database/transaction/context_spec.rb | 28 +--- spec/lib/gitlab/git/repository_spec.rb | 87 ++++-------- spec/mailers/notify_spec.rb | 29 ++++ spec/policies/issue_policy_spec.rb | 149 +++++++++++---------- spec/requests/api/commits_spec.rb | 20 +++ 16 files changed, 454 insertions(+), 248 deletions(-) (limited to 'spec') diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index 8e57b4f03a7..996964fdcf0 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -23,10 +23,6 @@ RSpec.describe Admin::RunnersController do describe '#show' do render_views - before do - stub_feature_flags(runner_detailed_view_vue_ui: false) - end - let_it_be(:project) { create(:project) } let_it_be(:project_two) { create(:project) } @@ -61,30 +57,6 @@ RSpec.describe Admin::RunnersController do expect(response).to have_gitlab_http_status(:ok) end - - describe 'Cost factors values' do - context 'when it is Gitlab.com' do - before do - expect(Gitlab).to receive(:com?).at_least(:once) { true } - end - - it 'renders cost factors fields' do - get :show, params: { id: runner.id } - - expect(response.body).to match /Private projects Minutes cost factor/ - expect(response.body).to match /Public projects Minutes cost factor/ - end - end - - context 'when it is not Gitlab.com' do - it 'does not show cost factor fields' do - get :show, params: { id: runner.id } - - expect(response.body).not_to match /Private projects Minutes cost factor/ - expect(response.body).not_to match /Public projects Minutes cost factor/ - end - end - end end describe '#update' do diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index dc1fb0454df..d4091461062 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -120,6 +120,29 @@ RSpec.describe InvitesController do end end + context 'when it is part of the invite_email_from experiment' do + let(:extra_params) { { invite_type: 'initial_email', experiment_name: 'invite_email_from' } } + + it 'tracks the initial join click from email' do + experiment = double(track: true) + allow(controller).to receive(:experiment).with(:invite_email_from, actor: member).and_return(experiment) + + request + + expect(experiment).to have_received(:track).with(:join_clicked) + end + + context 'when member does not exist' do + let(:raw_invite_token) { '_bogus_token_' } + + it 'does not track the experiment' do + expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member) + + request + end + end + end + context 'when member does not exist' do let(:raw_invite_token) { '_bogus_token_' } @@ -147,8 +170,9 @@ RSpec.describe InvitesController do end context 'when it is not part of our invite email experiment' do - it 'does not track via experiment' do + it 'does not track via experiment', :aggregate_failures do expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member) + expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member) request end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 301c60e89c8..a5a0f16f2b1 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -227,6 +227,40 @@ RSpec.describe RegistrationsController do end end end + + context 'with the invite_email_preview_text experiment', :experiment do + let(:extra_session_params) { { invite_email_experiment_name: 'invite_email_from' } } + + context 'when member and invite_email_experiment_name exists from the session key value' do + it 'tracks the invite acceptance' do + expect(experiment(:invite_email_from)).to track(:accepted) + .with_context(actor: member) + .on_next_instance + + subject + end + end + + context 'when member does not exist from the session key value' do + let(:originating_member_id) { -1 } + + it 'does not track invite acceptance' do + expect(experiment(:invite_email_from)).not_to track(:accepted) + + subject + end + end + + context 'when invite_email_experiment_name does not exist from the session key value' do + let(:extra_session_params) { {} } + + it 'does not track invite acceptance' do + expect(experiment(:invite_email_from)).not_to track(:accepted) + + subject + end + end + end end context 'when invite email matches email used on registration' do diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb index d56bedd4852..583daba37f1 100644 --- a/spec/features/invites_spec.rb +++ b/spec/features/invites_spec.rb @@ -216,6 +216,20 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do end end + context 'with invite email acceptance for the invite_email_from experiment', :experiment do + let(:extra_params) do + { invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_from' } + end + + it 'tracks the accepted invite' do + expect(experiment(:invite_email_from)).to track(:accepted) + .with_context(actor: group_invite) + .on_next_instance + + fill_in_sign_up_form(new_user) + end + end + it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do fill_in_sign_up_form(new_user) fill_in_welcome_form diff --git a/spec/frontend/issue_show/components/app_spec.js b/spec/frontend/issue_show/components/app_spec.js index babe3a66578..bd05cb1ac5a 100644 --- a/spec/frontend/issue_show/components/app_spec.js +++ b/spec/frontend/issue_show/components/app_spec.js @@ -1,7 +1,8 @@ import { GlIntersectionObserver } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { nextTick } from 'vue'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; import '~/behaviors/markdown/render_gfm'; import IssuableApp from '~/issue_show/components/app.vue'; import DescriptionComponent from '~/issue_show/components/description.vue'; @@ -33,13 +34,17 @@ describe('Issuable output', () => { let realtimeRequestCount = 0; let wrapper; - const findStickyHeader = () => wrapper.find('[data-testid="issue-sticky-header"]'); - const findLockedBadge = () => wrapper.find('[data-testid="locked"]'); - const findConfidentialBadge = () => wrapper.find('[data-testid="confidential"]'); + const findStickyHeader = () => wrapper.findByTestId('issue-sticky-header'); + const findLockedBadge = () => wrapper.findByTestId('locked'); + const findConfidentialBadge = () => wrapper.findByTestId('confidential'); + const findHiddenBadge = () => wrapper.findByTestId('hidden'); const findAlert = () => wrapper.find('.alert'); const mountComponent = (props = {}, options = {}, data = {}) => { - wrapper = mount(IssuableApp, { + wrapper = mountExtended(IssuableApp, { + directives: { + GlTooltip: createMockDirective(), + }, propsData: { ...appProps, ...props }, provide: { fullPath: 'gitlab-org/incidents', @@ -539,8 +544,8 @@ describe('Issuable output', () => { it.each` title | isConfidential - ${'does not show confidential badge when issue is not confidential'} | ${true} - ${'shows confidential badge when issue is confidential'} | ${false} + ${'does not show confidential badge when issue is not confidential'} | ${false} + ${'shows confidential badge when issue is confidential'} | ${true} `('$title', async ({ isConfidential }) => { wrapper.setProps({ isConfidential }); @@ -551,8 +556,8 @@ describe('Issuable output', () => { it.each` title | isLocked - ${'does not show locked badge when issue is not locked'} | ${true} - ${'shows locked badge when issue is locked'} | ${false} + ${'does not show locked badge when issue is not locked'} | ${false} + ${'shows locked badge when issue is locked'} | ${true} `('$title', async ({ isLocked }) => { wrapper.setProps({ isLocked }); @@ -560,6 +565,27 @@ describe('Issuable output', () => { expect(findLockedBadge().exists()).toBe(isLocked); }); + + it.each` + title | isHidden + ${'does not show hidden badge when issue is not hidden'} | ${false} + ${'shows hidden badge when issue is hidden'} | ${true} + `('$title', async ({ isHidden }) => { + wrapper.setProps({ isHidden }); + + await nextTick(); + + const hiddenBadge = findHiddenBadge(); + + expect(hiddenBadge.exists()).toBe(isHidden); + + if (isHidden) { + expect(hiddenBadge.attributes('title')).toBe( + 'This issue is hidden because its author has been banned', + ); + expect(getBinding(hiddenBadge.element, 'gl-tooltip')).not.toBeUndefined(); + } + }); }); }); diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js index 15029d7a911..0e0844a785b 100644 --- a/spec/frontend/runner/components/runner_update_form_spec.js +++ b/spec/frontend/runner/components/runner_update_form_spec.js @@ -54,7 +54,7 @@ describe('RunnerUpdateForm', () => { ? ACCESS_LEVEL_REF_PROTECTED : ACCESS_LEVEL_NOT_PROTECTED, runUntagged: findRunUntaggedCheckbox().element.checked, - locked: findLockedCheckbox().element.checked, + locked: findLockedCheckbox().element?.checked || false, ipAddress: findIpInput().element.value, maximumTimeout: findMaxJobTimeoutInput().element.value || null, tagList: findTagsInput().element.value.split(',').filter(Boolean), @@ -153,15 +153,15 @@ describe('RunnerUpdateForm', () => { }); it.each` - runnerType | attrDisabled | outcome - ${INSTANCE_TYPE} | ${'disabled'} | ${'disabled'} - ${GROUP_TYPE} | ${'disabled'} | ${'disabled'} - ${PROJECT_TYPE} | ${undefined} | ${'enabled'} - `(`When runner is $runnerType, locked field is $outcome`, ({ runnerType, attrDisabled }) => { + runnerType | exists | outcome + ${INSTANCE_TYPE} | ${false} | ${'hidden'} + ${GROUP_TYPE} | ${false} | ${'hidden'} + ${PROJECT_TYPE} | ${true} | ${'shown'} + `(`When runner is $runnerType, locked field is $outcome`, ({ runnerType, exists }) => { const runner = { ...mockRunner, runnerType }; createComponent({ props: { runner } }); - expect(findLockedCheckbox().attributes('disabled')).toBe(attrDisabled); + expect(findLockedCheckbox().exists()).toBe(exists); }); describe('On submit, runner gets updated', () => { diff --git a/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js b/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js index 573501233b9..ad8331afcff 100644 --- a/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js +++ b/spec/frontend/vue_shared/components/issuable/issuable_header_warnings_spec.js @@ -1,5 +1,7 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { createLocalVue } from '@vue/test-utils'; import Vuex from 'vuex'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { createStore as createMrStore } from '~/mr_notes/stores'; import createIssueStore from '~/notes/stores'; import IssuableHeaderWarnings from '~/vue_shared/components/issuable/issuable_header_warnings.vue'; @@ -12,52 +14,53 @@ localVue.use(Vuex); describe('IssuableHeaderWarnings', () => { let wrapper; - let store; - const findConfidentialIcon = () => wrapper.find('[data-testid="confidential"]'); - const findLockedIcon = () => wrapper.find('[data-testid="locked"]'); + const findConfidentialIcon = () => wrapper.findByTestId('confidential'); + const findLockedIcon = () => wrapper.findByTestId('locked'); + const findHiddenIcon = () => wrapper.findByTestId('hidden'); const renderTestMessage = (renders) => (renders ? 'renders' : 'does not render'); - const setLock = (locked) => { - store.getters.getNoteableData.discussion_locked = locked; - }; - - const setConfidential = (confidential) => { - store.getters.getNoteableData.confidential = confidential; - }; - - const createComponent = () => { - wrapper = shallowMount(IssuableHeaderWarnings, { store, localVue }); + const createComponent = ({ store, provide }) => { + wrapper = shallowMountExtended(IssuableHeaderWarnings, { + store, + localVue, + provide, + directives: { + GlTooltip: createMockDirective(), + }, + }); }; afterEach(() => { wrapper.destroy(); wrapper = null; - store = null; }); describe.each` issuableType ${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR} `(`when issuableType=$issuableType`, ({ issuableType }) => { - beforeEach(() => { - store = issuableType === ISSUABLE_TYPE_ISSUE ? createIssueStore() : createMrStore(); - createComponent(); - }); - describe.each` - lockStatus | confidentialStatus - ${true} | ${true} - ${true} | ${false} - ${false} | ${true} - ${false} | ${false} + lockStatus | confidentialStatus | hiddenStatus + ${true} | ${true} | ${false} + ${true} | ${false} | ${false} + ${false} | ${true} | ${false} + ${false} | ${false} | ${false} + ${true} | ${true} | ${true} + ${true} | ${false} | ${true} + ${false} | ${true} | ${true} + ${false} | ${false} | ${true} `( - `when locked=$lockStatus and confidential=$confidentialStatus`, - ({ lockStatus, confidentialStatus }) => { + `when locked=$lockStatus, confidential=$confidentialStatus, and hidden=$hiddenStatus`, + ({ lockStatus, confidentialStatus, hiddenStatus }) => { + const store = issuableType === ISSUABLE_TYPE_ISSUE ? createIssueStore() : createMrStore(); + beforeEach(() => { - setLock(lockStatus); - setConfidential(confidentialStatus); + store.getters.getNoteableData.confidential = confidentialStatus; + store.getters.getNoteableData.discussion_locked = lockStatus; + + createComponent({ store, provide: { hidden: hiddenStatus } }); }); it(`${renderTestMessage(lockStatus)} the locked icon`, () => { @@ -67,6 +70,19 @@ describe('IssuableHeaderWarnings', () => { it(`${renderTestMessage(confidentialStatus)} the confidential icon`, () => { expect(findConfidentialIcon().exists()).toBe(confidentialStatus); }); + + it(`${renderTestMessage(confidentialStatus)} the hidden icon`, () => { + const hiddenIcon = findHiddenIcon(); + + expect(hiddenIcon.exists()).toBe(hiddenStatus); + + if (hiddenStatus) { + expect(hiddenIcon.attributes('title')).toBe( + 'This issue is hidden because its author has been banned', + ); + expect(getBinding(hiddenIcon.element, 'gl-tooltip')).not.toBeUndefined(); + } + }); }, ); }); diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index ecaee03eeea..679871b6672 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -285,7 +285,8 @@ RSpec.describe IssuablesHelper do initialDescriptionText: 'issue text', initialTaskStatus: '0 of 0 tasks completed', issueType: 'issue', - iid: issue.iid.to_s + iid: issue.iid.to_s, + isHidden: false } expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data)) end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 4cb795b4eab..53c3e845e10 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -410,4 +410,55 @@ RSpec.describe IssuesHelper do end end end + + describe '#issue_hidden?' do + context 'when issue is hidden' do + let_it_be(:banned_user) { build(:user, :banned) } + let_it_be(:hidden_issue) { build(:issue, author: banned_user) } + + context 'when `ban_user_feature_flag` feature flag is enabled' do + it 'returns `true`' do + expect(helper.issue_hidden?(hidden_issue)).to eq(true) + end + end + + context 'when `ban_user_feature_flag` feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it 'returns `false`' do + expect(helper.issue_hidden?(hidden_issue)).to eq(false) + end + end + end + + context 'when issue is not hidden' do + it 'returns `false`' do + expect(helper.issue_hidden?(issue)).to eq(false) + end + end + end + + describe '#hidden_issue_icon' do + let_it_be(:banned_user) { build(:user, :banned) } + let_it_be(:hidden_issue) { build(:issue, author: banned_user) } + let_it_be(:mock_svg) { ''.html_safe } + + before do + allow(helper).to receive(:sprite_icon).and_return(mock_svg) + end + + context 'when issue is hidden' do + it 'returns icon with tooltip' do + expect(helper.hidden_issue_icon(hidden_issue)).to eq("") + end + end + + context 'when issue is not hidden' do + it 'returns `nil`' do + expect(helper.hidden_issue_icon(issue)).to be_nil + end + end + end end diff --git a/spec/helpers/notify_helper_spec.rb b/spec/helpers/notify_helper_spec.rb index 633a4b65139..a4193444528 100644 --- a/spec/helpers/notify_helper_spec.rb +++ b/spec/helpers/notify_helper_spec.rb @@ -70,6 +70,28 @@ RSpec.describe NotifyHelper do expect(helper.invited_join_url(token, member)) .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_preview_text&invite_type=initial_email") end + + context 'when invite_email_from is enabled' do + before do + stub_experiments(invite_email_from: :control) + end + + it 'has correct params' do + expect(helper.invited_join_url(token, member)) + .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_from&invite_type=initial_email") + end + end + end + + context 'when invite_email_from is enabled' do + before do + stub_experiments(invite_email_from: :control) + end + + it 'has correct params' do + expect(helper.invited_join_url(token, member)) + .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_from&invite_type=initial_email") + end end context 'when invite_email_preview_text is disabled' do diff --git a/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb b/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb index a27341a3324..c1a8a612254 100644 --- a/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb +++ b/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb @@ -69,18 +69,69 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do end describe '#perform_service_discovery' do - it 'reports exceptions to Sentry' do - error = StandardError.new + context 'without any failures' do + it 'runs once' do + expect(service) + .to receive(:refresh_if_necessary).once - expect(service) - .to receive(:refresh_if_necessary) - .and_raise(error) + expect(service).not_to receive(:sleep) - expect(Gitlab::ErrorTracking) - .to receive(:track_exception) - .with(error) + expect(Gitlab::ErrorTracking).not_to receive(:track_exception) - service.perform_service_discovery + service.perform_service_discovery + end + end + context 'with failures' do + before do + allow(Gitlab::ErrorTracking).to receive(:track_exception) + allow(service).to receive(:sleep) + end + + let(:valid_retry_sleep_duration) { satisfy { |val| described_class::RETRY_DELAY_RANGE.include?(val) } } + + it 'retries service discovery when under the retry limit' do + error = StandardError.new + + expect(service) + .to receive(:refresh_if_necessary) + .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES - 1).times.ordered + + expect(service) + .to receive(:sleep).with(valid_retry_sleep_duration) + .exactly(described_class::MAX_DISCOVERY_RETRIES - 1).times + + expect(service).to receive(:refresh_if_necessary).and_return(45).ordered + + expect(service.perform_service_discovery).to eq(45) + end + + it 'does not retry service discovery after exceeding the limit' do + error = StandardError.new + + expect(service) + .to receive(:refresh_if_necessary) + .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times + + expect(service) + .to receive(:sleep).with(valid_retry_sleep_duration) + .exactly(described_class::MAX_DISCOVERY_RETRIES).times + + service.perform_service_discovery + end + + it 'reports exceptions to Sentry' do + error = StandardError.new + + expect(service) + .to receive(:refresh_if_necessary) + .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times + + expect(Gitlab::ErrorTracking) + .to receive(:track_exception) + .with(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times + + service.perform_service_discovery + end end end @@ -224,6 +275,16 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do expect(service.addresses_from_dns).to eq([90, addresses]) end end + + context 'when the resolver returns an empty response' do + let(:packet) { double(:packet, answer: []) } + + let(:record_type) { 'A' } + + it 'raises EmptyDnsResponse' do + expect { service.addresses_from_dns }.to raise_error(Gitlab::Database::LoadBalancing::ServiceDiscovery::EmptyDnsResponse) + end + end end describe '#new_wait_time_for' do diff --git a/spec/lib/gitlab/database/transaction/context_spec.rb b/spec/lib/gitlab/database/transaction/context_spec.rb index 65d52b4d099..3c2c5649784 100644 --- a/spec/lib/gitlab/database/transaction/context_spec.rb +++ b/spec/lib/gitlab/database/transaction/context_spec.rb @@ -70,24 +70,6 @@ RSpec.describe Gitlab::Database::Transaction::Context do it { expect(subject.duration).to be >= 0 } end - context 'when depth is low' do - it 'does not log data upon COMMIT' do - expect(subject).not_to receive(:application_info) - - subject.commit - end - - it 'does not log data upon ROLLBACK' do - expect(subject).not_to receive(:application_info) - - subject.rollback - end - - it '#should_log? returns false' do - expect(subject.should_log?).to be false - end - end - shared_examples 'logs transaction data' do it 'logs once upon COMMIT' do expect(subject).to receive(:application_info).and_call_original @@ -116,17 +98,9 @@ RSpec.describe Gitlab::Database::Transaction::Context do end end - context 'when depth exceeds threshold' do - before do - subject.set_depth(described_class::LOG_DEPTH_THRESHOLD + 1) - end - - it_behaves_like 'logs transaction data' - end - context 'when savepoints count exceeds threshold' do before do - data[:savepoints] = described_class::LOG_SAVEPOINTS_THRESHOLD + 1 + data[:savepoints] = 1 end it_behaves_like 'logs transaction data' diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 926883022b0..1dcf12b1049 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -1710,83 +1710,42 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do end describe '#set_full_path' do - shared_examples '#set_full_path' do - before do - repository_rugged.config["gitlab.fullpath"] = repository_path - end - - context 'is given a path' do - it 'writes it to disk' do - repository.set_full_path(full_path: "not-the/real-path.git") - - config = File.read(File.join(repository_path, "config")) - - expect(config).to include("[gitlab]") - expect(config).to include("fullpath = not-the/real-path.git") - end - end - - context 'it is given an empty path' do - it 'does not write it to disk' do - repository.set_full_path(full_path: "") - - config = File.read(File.join(repository_path, "config")) - - expect(config).to include("[gitlab]") - expect(config).to include("fullpath = #{repository_path}") - end - end + before do + repository_rugged.config["gitlab.fullpath"] = repository_path + end - context 'repository does not exist' do - it 'raises NoRepository and does not call Gitaly WriteConfig' do - repository = Gitlab::Git::Repository.new('default', 'does/not/exist.git', '', 'group/project') + context 'is given a path' do + it 'writes it to disk' do + repository.set_full_path(full_path: "not-the/real-path.git") - expect(repository.gitaly_repository_client).not_to receive(:set_full_path) + config = File.read(File.join(repository_path, "config")) - expect do - repository.set_full_path(full_path: 'foo/bar.git') - end.to raise_error(Gitlab::Git::Repository::NoRepository) - end + expect(config).to include("[gitlab]") + expect(config).to include("fullpath = not-the/real-path.git") end end - context 'with :set_full_path enabled' do - before do - stub_feature_flags(set_full_path: true) - end + context 'it is given an empty path' do + it 'does not write it to disk' do + repository.set_full_path(full_path: "") - it_behaves_like '#set_full_path' - end + config = File.read(File.join(repository_path, "config")) - context 'with :set_full_path disabled' do - before do - stub_feature_flags(set_full_path: false) + expect(config).to include("[gitlab]") + expect(config).to include("fullpath = #{repository_path}") end - - it_behaves_like '#set_full_path' - end - end - - describe '#set_config' do - let(:repository) { mutable_repository } - let(:entries) do - { - 'test.foo1' => 'bla bla', - 'test.foo2' => 1234, - 'test.foo3' => true - } end - it 'can set config settings' do - expect(repository.set_config(entries)).to be_nil + context 'repository does not exist' do + it 'raises NoRepository and does not call Gitaly WriteConfig' do + repository = Gitlab::Git::Repository.new('default', 'does/not/exist.git', '', 'group/project') - expect(repository_rugged.config['test.foo1']).to eq('bla bla') - expect(repository_rugged.config['test.foo2']).to eq('1234') - expect(repository_rugged.config['test.foo3']).to eq('true') - end + expect(repository.gitaly_repository_client).not_to receive(:set_full_path) - after do - entries.keys.each { |k| repository_rugged.config.delete(k) } + expect do + repository.set_full_path(full_path: 'foo/bar.git') + end.to raise_error(Gitlab::Git::Repository::NoRepository) + end end end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 5d2b136043e..ecff5c15816 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -834,6 +834,35 @@ RSpec.describe Notify do invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_preview_text')) end + + it 'tracks the sent invite' do + expect(experiment(:invite_email_preview_text)).to track(:assignment) + .with_context(actor: project_member) + .on_next_instance + + invite_email.deliver_now + end + end + + context 'with invite_email_from enabled', :experiment do + before do + stub_experiments(invite_email_from: :control) + end + + it 'has the correct invite_url with params' do + is_expected.to have_link('Join now', + href: invite_url(project_member.invite_token, + invite_type: Emails::Members::INITIAL_INVITE, + experiment_name: 'invite_email_from')) + end + + it 'tracks the sent invite' do + expect(experiment(:invite_email_from)).to track(:assignment) + .with_context(actor: project_member) + .on_next_instance + + invite_email.deliver_now + end end context 'when invite email sent is tracked', :snowplow do diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb index d62271eedf6..3805976b3e7 100644 --- a/spec/policies/issue_policy_spec.rb +++ b/spec/policies/issue_policy_spec.rb @@ -27,17 +27,17 @@ RSpec.describe IssuePolicy do end it 'allows support_bot to read issues, create and set metadata on new issues' do - expect(permissions(support_bot, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(support_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(support_bot, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(support_bot, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(support_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(support_bot, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end end shared_examples 'support bot with service desk disabled' do - it 'allows support_bot to read issues, create and set metadata on new issues' do - expect(permissions(support_bot, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata) + it 'does not allow support_bot to read issues, create and set metadata on new issues' do + expect(permissions(support_bot, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality) end end @@ -60,50 +60,50 @@ RSpec.describe IssuePolicy do it 'allows guests to read issues' do expect(permissions(guest, issue)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(guest, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters to read, update, and admin issues' do - expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters from group links to read, update, and admin issues' do - expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(reporter_from_group_link, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter_from_group_link, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue authors to read and update their issues' do expect(permissions(author, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(author, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(author, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(author, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue assignees to read and update their issues' do expect(permissions(assignee, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(assignee, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(assignee, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(assignee, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'does not allow non-members to read, update or create issues' do - expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata) + expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it_behaves_like 'support bot with service desk disabled' @@ -115,49 +115,49 @@ RSpec.describe IssuePolicy do it 'does not allow non-members to read confidential issues' do expect(permissions(non_member, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue) - expect(permissions(non_member, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(non_member, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'does not allow guests to read confidential issues' do expect(permissions(guest, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue) - expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters to read, update, and admin confidential issues' do - expect(permissions(reporter, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(reporter, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters from group links to read, update, and admin confidential issues' do - expect(permissions(reporter_from_group_link, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(reporter_from_group_link, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue authors to read and update their confidential issues' do expect(permissions(author, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue) - expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) end it 'does not allow issue author to read or update confidential issue moved to an private project' do confidential_issue.project = create(:project, :private) - expect(permissions(author, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata) + expect(permissions(author, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue assignees to read and update their confidential issues' do expect(permissions(assignee, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'does not allow issue assignees to read or update confidential issue moved to an private project' do confidential_issue.project = create(:project, :private) - expect(permissions(assignee, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata) + expect(permissions(assignee, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :set_issue_metadata, :set_confidentiality) end end end @@ -180,48 +180,48 @@ RSpec.describe IssuePolicy do it 'does not allow anonymous user to create todos' do expect(permissions(nil, issue)).to be_allowed(:read_issue) - expect(permissions(nil, issue)).to be_disallowed(:create_todo, :update_subscription, :set_issue_metadata) - expect(permissions(nil, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata) + expect(permissions(nil, issue)).to be_disallowed(:create_todo, :update_subscription, :set_issue_metadata, :set_confidentiality) + expect(permissions(nil, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows guests to read issues' do expect(permissions(guest, issue)).to be_allowed(:read_issue, :read_issue_iid, :create_todo, :update_subscription) - expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(guest, issue)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(guest, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(guest, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(guest, issue_locked)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(guest, issue_locked)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(guest, issue_locked)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(guest, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters to read, update, reopen, and admin issues' do - expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) - expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) - expect(permissions(reporter, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(reporter, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(reporter, issue_locked)).to be_disallowed(:reopen_issue) - expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters from group links to read, update, reopen and admin issues' do - expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) - expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) - expect(permissions(reporter_from_group_link, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(reporter_from_group_link, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter_from_group_link, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(reporter_from_group_link, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(reporter_from_group_link, issue_locked)).to be_disallowed(:reopen_issue) - expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata) + expect(permissions(reporter, new_issue)).to be_allowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue authors to read, reopen and update their issues' do expect(permissions(author, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :reopen_issue) - expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(author, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(author, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(author, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(author, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(author, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(author, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(author, new_issue)).to be_allowed(:create_issue) expect(permissions(author, new_issue)).to be_disallowed(:set_issue_metadata) @@ -229,13 +229,13 @@ RSpec.describe IssuePolicy do it 'allows issue assignees to read, reopen and update their issues' do expect(permissions(assignee, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :reopen_issue) - expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(assignee, issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(assignee, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(assignee, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(assignee, issue_locked)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(assignee, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata) + expect(permissions(assignee, issue_locked)).to be_disallowed(:admin_issue, :reopen_issue, :set_issue_metadata, :set_confidentiality) end it 'allows non-members to read and create issues' do @@ -249,22 +249,25 @@ RSpec.describe IssuePolicy do expect(permissions(non_member, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) end - it 'does not allow non-members to update, admin or set metadata' do - expect(permissions(non_member, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + it 'does not allow non-members to update, admin or set metadata except for set confidential flag' do + expect(permissions(non_member, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(non_member, new_issue)).to be_disallowed(:set_issue_metadata) + # this is allowed for non-members in a public project, as we want to let users report security issues + # see https://gitlab.com/gitlab-org/gitlab/-/issues/337665 + expect(permissions(non_member, new_issue)).to be_allowed(:set_confidentiality) end it 'allows support_bot to read issues' do # support_bot is still allowed read access in public projects through :public_access permission, # see project_policy public_access rules policy (rule { can?(:public_access) }.policy {...}) expect(permissions(support_bot, issue)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(support_bot, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(support_bot, issue)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) expect(permissions(support_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid) - expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(support_bot, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata) + expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it_behaves_like 'support bot with service desk enabled' @@ -318,9 +321,9 @@ RSpec.describe IssuePolicy do end it 'does not allow non-members to update or create issues' do - expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata) - expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata) + expect(permissions(non_member, issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(non_member, issue_no_assignee)).to be_disallowed(:update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) + expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality) end it_behaves_like 'support bot with service desk disabled' @@ -333,31 +336,31 @@ RSpec.describe IssuePolicy do it 'does not allow guests to read confidential issues' do expect(permissions(guest, confidential_issue)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue) - expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(guest, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporters to read, update, and admin confidential issues' do expect(permissions(reporter, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue) - expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(reporter, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows reporter from group links to read, update, and admin confidential issues' do expect(permissions(reporter_from_group_link, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue) - expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(reporter_from_group_link, confidential_issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue authors to read and update their confidential issues' do expect(permissions(author, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(author, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(author, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end it 'allows issue assignees to read and update their confidential issues' do expect(permissions(assignee, confidential_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue) - expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata) + expect(permissions(assignee, confidential_issue)).to be_disallowed(:admin_issue, :set_issue_metadata, :set_confidentiality) - expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata) + expect(permissions(assignee, confidential_issue_no_assignee)).to be_disallowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality) end end diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index 1162ae76d15..1d76c281dee 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -1879,6 +1879,26 @@ RSpec.describe API::Commits do expect(json_response['line_type']).to eq('new') end + it 'correctly adds a note for the "old" line type' do + commit = project.repository.commit("markdown") + commit_id = commit.id + route = "/projects/#{project_id}/repository/commits/#{commit_id}/comments" + + post api(route, current_user), params: { + note: 'My comment', + path: commit.raw_diffs.first.old_path, + line: 4, + line_type: 'old' + } + + expect(response).to have_gitlab_http_status(:created) + expect(response).to match_response_schema('public_api/v4/commit_note') + expect(json_response['note']).to eq('My comment') + expect(json_response['path']).to eq(commit.raw_diffs.first.old_path) + expect(json_response['line']).to eq(4) + expect(json_response['line_type']).to eq('old') + end + context 'when ref does not exist' do let(:commit_id) { 'unknown' } -- cgit v1.2.3