From ff549ec680715e4ea1daf0cee457f29dfe3b6062 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 25 Jan 2023 18:08:56 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../merge_request/user_sees_merge_widget_spec.rb | 1 - .../projects/issues/email_participants_spec.rb | 44 ++++++------ .../projects/releases/user_views_releases_spec.rb | 4 +- .../components/abuse_category_selector_spec.js | 2 +- .../ci/runner/components/runner_jobs_table_spec.js | 8 +-- .../incidents/timeline_events_item_spec.js | 19 ++--- .../incidents/timeline_events_list_spec.js | 18 +---- .../frontend/notes/components/note_actions_spec.js | 8 +-- spec/frontend/projects/commit/mock_data.js | 6 +- .../frontend/projects/commit/store/getters_spec.js | 8 ++- .../components/report_abuse_dropdown_item_spec.js | 73 ------------------- .../components/report_abuse_dropdown_item_spec.js | 73 +++++++++++++++++++ .../components/release_block_assets_spec.js | 36 ++-------- .../mr_widget_security_reports_spec.js | 7 +- spec/helpers/issuables_helper_spec.rb | 35 +++++++++ .../pull_requests/review_requests_importer_spec.rb | 4 +- spec/lib/gitlab/slug/path_spec.rb | 33 +++++++++ spec/lib/gitlab/utils/email_spec.rb | 42 +++++++++++ spec/lib/gitlab_spec.rb | 82 ++++++---------------- spec/lib/service_ping/build_payload_spec.rb | 2 +- spec/models/ci_platform_metric_spec.rb | 2 +- spec/models/concerns/bulk_insert_safe_spec.rb | 2 +- spec/models/design_management/design_spec.rb | 2 +- spec/models/issue_email_participant_spec.rb | 6 ++ spec/models/merge_request_diff_commit_spec.rb | 2 +- spec/models/merge_request_diff_file_spec.rb | 2 +- spec/models/namespace_spec.rb | 17 ++++- .../namespaces/randomized_suffix_path_spec.rb | 37 ++++++++++ spec/models/repository_spec.rb | 10 --- .../issue_email_participant_presenter_spec.rb | 59 ++++++++++++++++ spec/presenters/issue_presenter_spec.rb | 74 +++++++++++++++++++ spec/serializers/issue_entity_spec.rb | 52 +++++++++++--- spec/services/notes/create_service_spec.rb | 8 +-- .../debian/generate_distribution_service_spec.rb | 2 +- .../policies/project_policy_shared_context.rb | 2 +- .../features/reportable_note_shared_examples.rb | 22 +++--- .../integrations/integration_settings_form.rb | 2 +- .../serializers/note_entity_shared_examples.rb | 4 ++ .../views/projects/issues/_issue.html.haml_spec.rb | 53 ++++++++++++++ .../notes/_more_actions_dropdown.html.haml_spec.rb | 5 +- .../debian/generate_distribution_worker_spec.rb | 3 +- 41 files changed, 586 insertions(+), 285 deletions(-) delete mode 100644 spec/frontend/projects/merge_requests/components/report_abuse_dropdown_item_spec.js create mode 100644 spec/frontend/projects/report_abuse/components/report_abuse_dropdown_item_spec.js create mode 100644 spec/lib/gitlab/slug/path_spec.rb create mode 100644 spec/lib/gitlab/utils/email_spec.rb create mode 100644 spec/models/namespaces/randomized_suffix_path_spec.rb create mode 100644 spec/presenters/issue_email_participant_presenter_spec.rb (limited to 'spec') diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb index 0297bb5b935..237f361bd72 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -18,7 +18,6 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: end before do - stub_feature_flags(refactor_security_extension: false) project.add_maintainer(user) project_only_mwps.add_maintainer(user) sign_in(user) diff --git a/spec/features/projects/issues/email_participants_spec.rb b/spec/features/projects/issues/email_participants_spec.rb index 4dedbff608e..fdfd926b763 100644 --- a/spec/features/projects/issues/email_participants_spec.rb +++ b/spec/features/projects/issues/email_participants_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'viewing an issue', :js, feature_category: :issue_email_participants do let_it_be(:user) { create(:user) } + let_it_be(:non_member) { create(:user) } let_it_be(:project) { create(:project, :public) } let_it_be_with_refind(:issue) { create(:issue, project: project) } let_it_be(:note) { create(:note_on_issue, project: project, noteable: issue) } @@ -19,19 +20,7 @@ RSpec.describe 'viewing an issue', :js, feature_category: :issue_email_participa end end - shared_examples 'no email participants warning' do |selector| - it 'does not show email participants warning' do - expect(find(selector)).not_to have_content(", and 1 more will be notified of your comment") - end - end - - context 'when issue is confidential' do - before do - issue.update!(confidential: true) - sign_in(user) - visit project_issue_path(project, issue) - end - + shared_examples 'email participants warning in all editors' do context 'for a new note' do it_behaves_like 'email participants warning', '.new-note' end @@ -45,22 +34,35 @@ RSpec.describe 'viewing an issue', :js, feature_category: :issue_email_participa end end - context 'when issue is not confidential' do + context 'when issue is confidential' do before do + issue.update!(confidential: true) sign_in(user) visit project_issue_path(project, issue) end - context 'for a new note' do - it_behaves_like 'no email participants warning', '.new-note' - end + it_behaves_like 'email participants warning in all editors' + end - context 'for a reply form' do - before do - find('.js-reply-button').click + context 'when issue is not confidential' do + context 'with signed in user' do + context 'when user has no role in project' do + before do + sign_in(non_member) + visit project_issue_path(project, issue) + end + + it_behaves_like 'email participants warning in all editors' end - it_behaves_like 'no email participants warning', '.note-edit-form' + context 'when user has (at least) reporter role in project' do + before do + sign_in(user) + visit project_issue_path(project, issue) + end + + it_behaves_like 'email participants warning in all editors' + end end end end diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb index 13dde57d885..0a4075be02f 100644 --- a/spec/features/projects/releases/user_views_releases_spec.rb +++ b/spec/features/projects/releases/user_views_releases_spec.rb @@ -46,10 +46,10 @@ RSpec.describe 'User views releases', :js, feature_category: :continuous_deliver external_link_indicator_selector = '[data-testid="external-link-indicator"]' expect(page).to have_link internal_link.name, href: internal_link.url - expect(find_link(internal_link.name)).not_to have_css(external_link_indicator_selector) + expect(find_link(internal_link.name)).to have_css(external_link_indicator_selector) expect(page).to have_link internal_link_with_redirect.name, href: Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << "/downloads#{internal_link_with_redirect.filepath}" - expect(find_link(internal_link_with_redirect.name)).not_to have_css(external_link_indicator_selector) + expect(find_link(internal_link_with_redirect.name)).to have_css(external_link_indicator_selector) expect(page).to have_link external_link.name, href: external_link.url expect(find_link(external_link.name)).to have_css(external_link_indicator_selector) diff --git a/spec/frontend/abuse_reports/components/abuse_category_selector_spec.js b/spec/frontend/abuse_reports/components/abuse_category_selector_spec.js index 3383a5c86ec..ec20088c443 100644 --- a/spec/frontend/abuse_reports/components/abuse_category_selector_spec.js +++ b/spec/frontend/abuse_reports/components/abuse_category_selector_spec.js @@ -106,7 +106,7 @@ describe('AbuseCategorySelector', () => { expect(findUserId().attributes()).toMatchObject({ type: 'hidden', name: 'user_id', - value: `${USER_ID}`, + value: USER_ID.toString(), }); }); diff --git a/spec/frontend/ci/runner/components/runner_jobs_table_spec.js b/spec/frontend/ci/runner/components/runner_jobs_table_spec.js index 8defe568df8..281aa1aeb77 100644 --- a/spec/frontend/ci/runner/components/runner_jobs_table_spec.js +++ b/spec/frontend/ci/runner/components/runner_jobs_table_spec.js @@ -72,7 +72,7 @@ describe('RunnerJobsTable', () => { }); it('Displays details of a job', () => { - const { id, detailedStatus, pipeline, shortSha, commitPath } = mockJobs[0]; + const { id, detailedStatus, project, shortSha, commitPath } = mockJobs[0]; expect(findCell({ field: 'status' }).text()).toMatchInterpolatedText(detailedStatus.text); @@ -81,10 +81,8 @@ describe('RunnerJobsTable', () => { detailedStatus.detailsPath, ); - expect(findCell({ field: 'project' }).text()).toBe(pipeline.project.name); - expect(findCell({ field: 'project' }).find('a').attributes('href')).toBe( - pipeline.project.webUrl, - ); + expect(findCell({ field: 'project' }).text()).toBe(project.name); + expect(findCell({ field: 'project' }).find('a').attributes('href')).toBe(project.webUrl); expect(findCell({ field: 'commit' }).text()).toBe(shortSha); expect(findCell({ field: 'commit' }).find('a').attributes('href')).toBe(commitPath); diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js index ba0527e5395..acff5d9ed43 100644 --- a/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js +++ b/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js @@ -27,7 +27,7 @@ describe('IncidentTimelineEventList', () => { const findCommentIcon = () => wrapper.findComponent(GlIcon); const findEventTime = () => wrapper.findByTestId('event-time'); - const findEventTag = () => wrapper.findComponent(GlBadge); + const findEventTags = () => wrapper.findAllComponents(GlBadge); const findDropdown = () => wrapper.findComponent(GlDropdown); const findDeleteButton = () => wrapper.findByText(timelineItemI18n.delete); @@ -69,15 +69,16 @@ describe('IncidentTimelineEventList', () => { }); }); - describe('timeline event tag', () => { - it('does not show when tag is not provided', () => { - expect(findEventTag().exists()).toBe(false); - }); - - it('shows when tag is provided', () => { - mountComponent({ propsData: { eventTag: 'Start time' } }); + describe.each([ + { eventTags: [], expected: 0 }, + { eventTags: ['Start time'], expected: 1 }, + { eventTags: ['Start time', 'End time'], expected: 2 }, + ])('timeline event tags', ({ eventTags, expected }) => { + it(`shows ${expected} badges when ${expected} tags are provided`, () => { + mountComponent({ propsData: { eventTags } }); - expect(findEventTag().exists()).toBe(true); + expect(findEventTags().exists()).toBe(Boolean(expected)); + expect(findEventTags().length).toBe(eventTags.length); }); }); diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js index 8a353668153..26fda877089 100644 --- a/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js +++ b/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js @@ -93,9 +93,7 @@ describe('IncidentTimelineEventList', () => { expect(findItems().at(1).props('occurredAt')).toBe(mockEvents[1].occurredAt); expect(findItems().at(1).props('action')).toBe(mockEvents[1].action); expect(findItems().at(1).props('noteHtml')).toBe(mockEvents[1].noteHtml); - expect(findItems().at(1).props('eventTag')).toBe( - mockEvents[1].timelineEventTags.nodes[0].name, - ); + expect(findItems().at(1).props('eventTags')).toBe(mockEvents[1].timelineEventTags.nodes); }); it('formats dates correctly', () => { @@ -124,20 +122,6 @@ describe('IncidentTimelineEventList', () => { }); }); - describe('getFirstTag', () => { - it('returns undefined, when timelineEventTags contains an empty array', () => { - const returnedTag = wrapper.vm.getFirstTag(mockEvents[0].timelineEventTags); - - expect(returnedTag).toEqual(undefined); - }); - - it('returns the first string, when timelineEventTags contains array with at least one tag', () => { - const returnedTag = wrapper.vm.getFirstTag(mockEvents[1].timelineEventTags); - - expect(returnedTag).toBe(mockEvents[1].timelineEventTags.nodes[0].name); - }); - }); - describe('delete functionality', () => { beforeEach(() => { mockConfirmAction({ confirmed: true }); diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js index d95e357f24c..1c336a68acf 100644 --- a/spec/frontend/notes/components/note_actions_spec.js +++ b/spec/frontend/notes/components/note_actions_spec.js @@ -413,15 +413,15 @@ describe('noteActions', () => { }); it('opens the drawer when report abuse button is clicked', async () => { - findReportAbuseButton().trigger('click'); - - await nextTick(); + await findReportAbuseButton().trigger('click'); expect(findAbuseCategorySelector().props('showDrawer')).toEqual(true); }); it('closes the drawer', async () => { - await findAbuseCategorySelector().vm.$emit('close-drawer'); + findAbuseCategorySelector().vm.$emit('close-drawer'); + + await nextTick(); expect(findAbuseCategorySelector().props('showDrawer')).toEqual(false); }); diff --git a/spec/frontend/projects/commit/mock_data.js b/spec/frontend/projects/commit/mock_data.js index 34e9c400af4..e398d46e69c 100644 --- a/spec/frontend/projects/commit/mock_data.js +++ b/spec/frontend/projects/commit/mock_data.js @@ -24,5 +24,9 @@ export default { openModal: '_open_modal_', }, mockBranches: ['_branch_1', '_abc_', '_main_'], - mockProjects: ['_project_1', '_abc_', '_project_'], + mockProjects: [ + { id: 1, name: '_project_1', refsUrl: '/_project_1/refs' }, + { id: 2, name: '_abc_', refsUrl: '/_abc_/refs' }, + { id: 3, name: '_project_', refsUrl: '/_project_/refs' }, + ], }; diff --git a/spec/frontend/projects/commit/store/getters_spec.js b/spec/frontend/projects/commit/store/getters_spec.js index 38c45af7aa0..f45f3114550 100644 --- a/spec/frontend/projects/commit/store/getters_spec.js +++ b/spec/frontend/projects/commit/store/getters_spec.js @@ -29,9 +29,15 @@ describe('Commit form modal getters', () => { }); it('should provide a uniq list of projects', () => { - const projects = ['_project_', '_project_', '_some_other_project']; + const projects = [ + { id: 1, name: '_project_', refsUrl: '/_project_/refs' }, + { id: 1, name: '_project_', refsUrl: '/_project_/refs' }, + { id: 3, name: '_some_other_project', refsUrl: '/_some_other_project/refs' }, + ]; const state = { projects }; + expect(state.projects.length).toBe(3); + expect(getters.sortedProjects(state).length).toBe(2); expect(getters.sortedProjects(state)).toEqual(projects.slice(1)); }); }); diff --git a/spec/frontend/projects/merge_requests/components/report_abuse_dropdown_item_spec.js b/spec/frontend/projects/merge_requests/components/report_abuse_dropdown_item_spec.js deleted file mode 100644 index 11f770fb05e..00000000000 --- a/spec/frontend/projects/merge_requests/components/report_abuse_dropdown_item_spec.js +++ /dev/null @@ -1,73 +0,0 @@ -import { nextTick } from 'vue'; -import { GlDropdownItem } from '@gitlab/ui'; -import { MountingPortal } from 'portal-vue'; -import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; - -import ReportAbuseDropdownItem from '~/projects/merge_requests/components/report_abuse_dropdown_item.vue'; -import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue'; - -describe('ReportAbuseDropdownItem', () => { - let wrapper; - - const ACTION_PATH = '/abuse_reports/add_category'; - const USER_ID = 1; - const REPORTED_FROM_URL = 'http://example.com'; - - const createComponent = (props) => { - wrapper = shallowMountExtended(ReportAbuseDropdownItem, { - propsData: { - ...props, - }, - provide: { - reportAbusePath: ACTION_PATH, - reportedUserId: USER_ID, - reportedFromUrl: REPORTED_FROM_URL, - }, - }); - }; - - beforeEach(() => { - createComponent(); - }); - - const findReportAbuseItem = () => wrapper.findComponent(GlDropdownItem); - const findAbuseCategorySelector = () => wrapper.findComponent(AbuseCategorySelector); - const findMountingPortal = () => wrapper.findComponent(MountingPortal); - - it('renders report abuse dropdown item', () => { - expect(findReportAbuseItem().text()).toBe(ReportAbuseDropdownItem.i18n.reportAbuse); - }); - - it('renders abuse category selector with the drawer initially closed', () => { - expect(findAbuseCategorySelector().exists()).toBe(true); - - expect(findAbuseCategorySelector().props('showDrawer')).toBe(false); - }); - - it('renders abuse category selector inside MountingPortal', () => { - expect(findMountingPortal().props()).toMatchObject({ - mountTo: '#js-report-abuse-drawer', - append: true, - name: 'abuse-category-selector', - }); - }); - - describe('when dropdown item is clicked', () => { - beforeEach(() => { - findReportAbuseItem().vm.$emit('click'); - return nextTick(); - }); - - it('opens the abuse category selector', () => { - expect(findAbuseCategorySelector().props('showDrawer')).toBe(true); - }); - - it('closes the abuse category selector', async () => { - findAbuseCategorySelector().vm.$emit('close-drawer'); - - await nextTick(); - - expect(findAbuseCategorySelector().props('showDrawer')).toBe(false); - }); - }); -}); diff --git a/spec/frontend/projects/report_abuse/components/report_abuse_dropdown_item_spec.js b/spec/frontend/projects/report_abuse/components/report_abuse_dropdown_item_spec.js new file mode 100644 index 00000000000..de0c889e8c9 --- /dev/null +++ b/spec/frontend/projects/report_abuse/components/report_abuse_dropdown_item_spec.js @@ -0,0 +1,73 @@ +import { nextTick } from 'vue'; +import { GlDropdownItem } from '@gitlab/ui'; +import { MountingPortal } from 'portal-vue'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; + +import ReportAbuseDropdownItem from '~/projects/report_abuse/components/report_abuse_dropdown_item.vue'; +import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue'; + +describe('ReportAbuseDropdownItem', () => { + let wrapper; + + const ACTION_PATH = '/abuse_reports/add_category'; + const USER_ID = 1; + const REPORTED_FROM_URL = 'http://example.com'; + + const createComponent = (props) => { + wrapper = shallowMountExtended(ReportAbuseDropdownItem, { + propsData: { + ...props, + }, + provide: { + reportAbusePath: ACTION_PATH, + reportedUserId: USER_ID, + reportedFromUrl: REPORTED_FROM_URL, + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + const findReportAbuseItem = () => wrapper.findComponent(GlDropdownItem); + const findAbuseCategorySelector = () => wrapper.findComponent(AbuseCategorySelector); + const findMountingPortal = () => wrapper.findComponent(MountingPortal); + + it('renders report abuse dropdown item', () => { + expect(findReportAbuseItem().text()).toBe(ReportAbuseDropdownItem.i18n.reportAbuse); + }); + + it('renders abuse category selector with the drawer initially closed', () => { + expect(findAbuseCategorySelector().exists()).toBe(true); + + expect(findAbuseCategorySelector().props('showDrawer')).toBe(false); + }); + + it('renders abuse category selector inside MountingPortal', () => { + expect(findMountingPortal().props()).toMatchObject({ + mountTo: '#js-report-abuse-drawer', + append: true, + name: 'abuse-category-selector', + }); + }); + + describe('when dropdown item is clicked', () => { + beforeEach(() => { + findReportAbuseItem().vm.$emit('click'); + return nextTick(); + }); + + it('opens the abuse category selector', () => { + expect(findAbuseCategorySelector().props('showDrawer')).toBe(true); + }); + + it('closes the abuse category selector', async () => { + findAbuseCategorySelector().vm.$emit('close-drawer'); + + await nextTick(); + + expect(findAbuseCategorySelector().props('showDrawer')).toBe(false); + }); + }); +}); diff --git a/spec/frontend/releases/components/release_block_assets_spec.js b/spec/frontend/releases/components/release_block_assets_spec.js index 4f94e4dfd55..6d53bf5a49e 100644 --- a/spec/frontend/releases/components/release_block_assets_spec.js +++ b/spec/frontend/releases/components/release_block_assets_spec.js @@ -123,42 +123,14 @@ describe('Release block assets', () => { }); }); - describe('external vs internal links', () => { + describe('links', () => { const containsExternalSourceIndicator = () => wrapper.find('[data-testid="external-link-indicator"]').exists(); - describe('when a link is external', () => { - beforeEach(() => { - defaultProps.assets.sources = []; - defaultProps.assets.links = [ - { - ...defaultProps.assets.links[0], - external: true, - }, - ]; - createComponent(defaultProps); - }); - - it('renders the link with an "external source" indicator', () => { - expect(containsExternalSourceIndicator()).toBe(true); - }); - }); + beforeEach(() => createComponent(defaultProps)); - describe('when a link is internal', () => { - beforeEach(() => { - defaultProps.assets.sources = []; - defaultProps.assets.links = [ - { - ...defaultProps.assets.links[0], - external: false, - }, - ]; - createComponent(defaultProps); - }); - - it('renders the link without the "external source" indicator', () => { - expect(containsExternalSourceIndicator()).toBe(false); - }); + it('renders with an external source indicator (except for sections with no title)', () => { + expect(containsExternalSourceIndicator()).toBe(true); }); }); }); diff --git a/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js b/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js index 16c2adaffaf..e23cd92f53e 100644 --- a/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js +++ b/spec/frontend/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports_spec.js @@ -82,11 +82,8 @@ describe('vue_merge_request_widget/extensions/security_reports/mr_widget_securit createComponent({ mockResponse: { data: { project: { id: 'project-id' } } } }); }); - it('displays the correct message', () => { - expect(wrapper.findByText('Security scans have run').exists()).toBe(true); - }); - - it('should not display the artifacts dropdown', () => { + it('does not render the widget', () => { + expect(wrapper.html()).toBe(''); expect(findDropdown().exists()).toBe(false); }); }); diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 467c8d96cfb..5470476c45a 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -200,6 +200,41 @@ RSpec.describe IssuablesHelper, feature_category: :team_planning do expect(content).not_to match('gl-emoji') end end + + describe 'service desk reply to email address' do + let(:email) { 'user@example.com' } + let(:obfuscated_email) { 'us*****@e*****.c**' } + let(:service_desk_issue) { build_stubbed(:issue, project: project, author: User.support_bot, service_desk_reply_to: email) } + + subject { helper.issuable_meta(service_desk_issue, project) } + + context 'with anonymous user' do + before do + allow(helper).to receive(:current_user).and_return(nil) + end + + it { is_expected.to have_content(obfuscated_email) } + end + + context 'with signed in user' do + context 'when user has no role in project' do + before do + allow(helper).to receive(:current_user).and_return(user) + end + + it { is_expected.to have_content(obfuscated_email) } + end + + context 'when user has reporter role in project' do + before do + project.add_reporter(user) + allow(helper).to receive(:current_user).and_return(user) + end + + it { is_expected.to have_content(email) } + end + end + end end describe '#issuables_state_counter_text' do diff --git a/spec/lib/gitlab/github_import/importer/pull_requests/review_requests_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_requests/review_requests_importer_spec.rb index 06005a447a8..53a0e718eb6 100644 --- a/spec/lib/gitlab/github_import/importer/pull_requests/review_requests_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/pull_requests/review_requests_importer_spec.rb @@ -108,10 +108,10 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequests::ReviewRequestsImpor it 'schedule import for each merge request reviewers' do expect(Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker) - .to receive(:perform_in).with(1.minute, *expected_worker_payload.first).ordered + .to receive(:perform_in).with(1.minute, *expected_worker_payload.first) expect(Gitlab::GithubImport::PullRequests::ImportReviewRequestWorker) - .to receive(:perform_in).with(1.minute, *expected_worker_payload.second).ordered + .to receive(:perform_in).with(1.minute, *expected_worker_payload.second) importer.parallel_import end diff --git a/spec/lib/gitlab/slug/path_spec.rb b/spec/lib/gitlab/slug/path_spec.rb new file mode 100644 index 00000000000..9a7067e40a2 --- /dev/null +++ b/spec/lib/gitlab/slug/path_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +RSpec.describe Gitlab::Slug::Path, feature_category: :not_owned do + describe '#generate' do + { + 'name': 'name', + 'james.atom@bond.com': 'james', + '--foobar--': 'foobar--', + '--foo_bar--': 'foo_bar--', + '--foo$^&_bar--': 'foo_bar--', + 'john@doe.com': 'john', + '-john+gitlab-ETC%.git@gmail.com': 'johngitlab-ETC', + 'this.is.git.atom.': 'this.is', + '#$%^.': 'blank', + '---.git#$.atom%@atom^.': 'blank', # use default when all characters are filtered out + '--gitlab--hey.git#$.atom%@atom^.': 'gitlab--hey' + }.each do |input, output| + it "yields a slug #{output} when given #{input}" do + slug = described_class.new(input).generate + + expect(slug).to match(/\A#{output}\z/) + end + end + end + + describe '#to_s' do + it 'presents with a cleaned slug' do + expect(described_class.new('---show-me-what-you.got.git').to_s).to match(/\Ashow-me-what-you.got\z/) + end + end +end diff --git a/spec/lib/gitlab/utils/email_spec.rb b/spec/lib/gitlab/utils/email_spec.rb new file mode 100644 index 00000000000..d7a881d8655 --- /dev/null +++ b/spec/lib/gitlab/utils/email_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require 'rspec-parameterized' + +RSpec.describe Gitlab::Utils::Email, feature_category: :service_desk do + using RSpec::Parameterized::TableSyntax + + describe '.obfuscated_email' do + where(:input, :output) do + 'alex@gitlab.com' | 'al**@g*****.com' + 'alex@gl.co.uk' | 'al**@g****.uk' + 'a@b.c' | 'a@b.c' + 'q@example.com' | 'q@e******.com' + 'q@w.' | 'q@w.' + 'a@b' | 'a@b' + 'no mail' | 'no mail' + end + + with_them do + it { expect(described_class.obfuscated_email(input)).to eq(output) } + end + + context 'when deform is active' do + where(:input, :output) do + 'alex@gitlab.com' | 'al*****@g*****.c**' + 'alex@gl.co.uk' | 'al*****@g*****.u**' + 'a@b.c' | 'aa*****@b*****.c**' + 'qqwweerrttyy@example.com' | 'qq*****@e*****.c**' + 'getsuperfancysupport@paywhatyouwant.accounting' | 'ge*****@p*****.a**' + 'q@example.com' | 'qq*****@e*****.c**' + 'q@w.' | 'q@w.' + 'a@b' | 'a@b' + 'no mail' | 'no mail' + end + + with_them do + it { expect(described_class.obfuscated_email(input, deform: true)).to eq(output) } + end + end + end +end diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb index c44bb64a5c0..a554e0b26a8 100644 --- a/spec/lib/gitlab_spec.rb +++ b/spec/lib/gitlab_spec.rb @@ -81,10 +81,6 @@ RSpec.describe Gitlab do describe '.com?' do context 'when not simulating SaaS' do - before do - stub_env('GITLAB_SIMULATE_SAAS', '0') - end - it "is true when on #{Gitlab::Saas.com_url}" do stub_config_setting(url: Gitlab::Saas.com_url) @@ -118,17 +114,31 @@ RSpec.describe Gitlab do end end - it 'is true when GITLAB_SIMULATE_SAAS is true and in development' do - stub_rails_env('development') - stub_env('GITLAB_SIMULATE_SAAS', '1') + context 'when simulating SaaS' do + before do + stub_const('Gitlab::GITLAB_SIMULATE_SAAS', '1') + end - expect(described_class.com?).to eq true - end + it 'is false in tests' do + expect(described_class.com?).to eq false + end + + it 'is true in development' do + stub_rails_env('development') - it 'is false when GITLAB_SIMULATE_SAAS is true and in test' do - stub_env('GITLAB_SIMULATE_SAAS', '1') + expect(described_class.com?).to eq true + end - expect(described_class.com?).to eq false + # See ee/spec/lib/gitlab_spec.rb for EE-specific changes to this behavior. + context 'in a production environment' do + before do + stub_rails_env('production') + end + + it 'is false' do + expect(described_class.com?).to eq false + end + end end end @@ -236,54 +246,6 @@ RSpec.describe Gitlab do end end - describe '.simulate_com?' do - subject { described_class.simulate_com? } - - context 'when GITLAB_SIMULATE_SAAS is true' do - before do - stub_env('GITLAB_SIMULATE_SAAS', '1') - end - - it 'is false when test env' do - expect(subject).to eq false - end - - it 'is true when dev env' do - stub_rails_env('development') - - expect(subject).to eq true - end - - it 'is false when env is not dev' do - stub_rails_env('production') - - expect(subject).to eq false - end - end - - context 'when GITLAB_SIMULATE_SAAS is false' do - before do - stub_env('GITLAB_SIMULATE_SAAS', '0') - end - - it 'is false when test env' do - expect(subject).to eq false - end - - it 'is false when dev env' do - stub_rails_env('development') - - expect(subject).to eq false - end - - it 'is false when env is not dev or test' do - stub_rails_env('production') - - expect(subject).to eq false - end - end - end - describe '.dev_or_test_env?' do subject { described_class.dev_or_test_env? } diff --git a/spec/lib/service_ping/build_payload_spec.rb b/spec/lib/service_ping/build_payload_spec.rb index b10c9fd5bc0..6c37168f5a0 100644 --- a/spec/lib/service_ping/build_payload_spec.rb +++ b/spec/lib/service_ping/build_payload_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ServicePing::BuildPayload do +RSpec.describe ServicePing::BuildPayload, feature_category: :service_ping do describe '#execute', :without_license do subject(:service_ping_payload) { described_class.new.execute } diff --git a/spec/models/ci_platform_metric_spec.rb b/spec/models/ci_platform_metric_spec.rb index f73db713791..e59730792b8 100644 --- a/spec/models/ci_platform_metric_spec.rb +++ b/spec/models/ci_platform_metric_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe CiPlatformMetric do +RSpec.describe CiPlatformMetric, feature_category: :continuous_integration do subject { build(:ci_platform_metric) } it_behaves_like 'a BulkInsertSafe model', CiPlatformMetric do diff --git a/spec/models/concerns/bulk_insert_safe_spec.rb b/spec/models/concerns/bulk_insert_safe_spec.rb index 577004c2cf6..65b7da20bbc 100644 --- a/spec/models/concerns/bulk_insert_safe_spec.rb +++ b/spec/models/concerns/bulk_insert_safe_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkInsertSafe do +RSpec.describe BulkInsertSafe, feature_category: :database do before(:all) do ActiveRecord::Schema.define do create_table :_test_bulk_insert_parent_items, force: true do |t| diff --git a/spec/models/design_management/design_spec.rb b/spec/models/design_management/design_spec.rb index b0601ea3f08..57e0d1cad8b 100644 --- a/spec/models/design_management/design_spec.rb +++ b/spec/models/design_management/design_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe DesignManagement::Design do +RSpec.describe DesignManagement::Design, feature_category: :design_management do include DesignManagementTestHelpers let_it_be(:issue) { create(:issue) } diff --git a/spec/models/issue_email_participant_spec.rb b/spec/models/issue_email_participant_spec.rb index 09c231bbfda..8ddc9a5f478 100644 --- a/spec/models/issue_email_participant_spec.rb +++ b/spec/models/issue_email_participant_spec.rb @@ -7,6 +7,12 @@ RSpec.describe IssueEmailParticipant do it { is_expected.to belong_to(:issue) } end + describe 'Modules' do + subject { described_class } + + it { is_expected.to include_module(Presentable) } + end + describe 'Validations' do subject { build(:issue_email_participant) } diff --git a/spec/models/merge_request_diff_commit_spec.rb b/spec/models/merge_request_diff_commit_spec.rb index 25e5e40feb7..78f9fb5b7d3 100644 --- a/spec/models/merge_request_diff_commit_spec.rb +++ b/spec/models/merge_request_diff_commit_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe MergeRequestDiffCommit do +RSpec.describe MergeRequestDiffCommit, feature_category: :code_review_workflow do let(:merge_request) { create(:merge_request) } let(:project) { merge_request.project } diff --git a/spec/models/merge_request_diff_file_spec.rb b/spec/models/merge_request_diff_file_spec.rb index 7e127caa649..eee7fe67ffb 100644 --- a/spec/models/merge_request_diff_file_spec.rb +++ b/spec/models/merge_request_diff_file_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe MergeRequestDiffFile do +RSpec.describe MergeRequestDiffFile, feature_category: :code_review_workflow do it_behaves_like 'a BulkInsertSafe model', MergeRequestDiffFile do let(:valid_items_for_bulk_insertion) do build_list(:merge_request_diff_file, 10) do |mr_diff_file| diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 63b8ebcecab..852df3b8a90 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -1265,12 +1265,23 @@ RSpec.describe Namespace, feature_category: :subgroups do end describe ".clean_path" do - let!(:user) { create(:user, username: "johngitlab-etc") } - let!(:namespace) { create(:namespace, path: "JohnGitLab-etc1") } + it "cleans the path and makes sure it's available", time_travel_to: '2023-04-20 00:07 -0700' do + create :user, username: "johngitlab-etc" + create :namespace, path: "JohnGitLab-etc1" + [nil, 1, 2, 3].each do |count| + create :namespace, path: "pickle#{count}" + end - it "cleans the path and makes sure it's available" do expect(described_class.clean_path("-john+gitlab-ETC%.git@gmail.com")).to eq("johngitlab-ETC2") expect(described_class.clean_path("--%+--valid_*&%name=.git.%.atom.atom.@email.com")).to eq("valid_name") + + # when we have more than MAX_TRIES count of a path use a more randomized suffix + expect(described_class.clean_path("pickle@gmail.com")).to eq("pickle4") + create(:namespace, path: "pickle4") + expect(described_class.clean_path("pickle@gmail.com")).to eq("pickle716") + create(:namespace, path: "pickle716") + expect(described_class.clean_path("pickle@gmail.com")).to eq("pickle717") + expect(described_class.clean_path("--$--pickle@gmail.com")).to eq("pickle717") end end diff --git a/spec/models/namespaces/randomized_suffix_path_spec.rb b/spec/models/namespaces/randomized_suffix_path_spec.rb new file mode 100644 index 00000000000..a2484030f3c --- /dev/null +++ b/spec/models/namespaces/randomized_suffix_path_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Namespaces::RandomizedSuffixPath, feature_category: :not_owned do + let(:path) { 'backintime' } + + subject(:suffixed_path) { described_class.new(path) } + + describe '#to_s' do + it 'represents with given path' do + expect(suffixed_path.to_s).to eq('backintime') + end + end + + describe '#call' do + it 'returns path without count when count is 0' do + expect(suffixed_path.call(0)).to eq('backintime') + end + + it "returns path suffixed with count when between 0 and #{described_class::MAX_TRIES}" do + (1..described_class::MAX_TRIES).each do |count| + expect(suffixed_path.call(count)).to eq("backintime#{count}") + end + end + + it 'adds a "randomized" suffix when MAX_TRIES is exhausted', time_travel_to: '1955-11-12 06:38' do + count = described_class::MAX_TRIES + 1 + expect(suffixed_path.call(count)).to eq("backintime3845") + end + + it 'adds an offset to the "randomized" suffix when MAX_TRIES is exhausted', time_travel_to: '1955-11-12 06:38' do + count = described_class::MAX_TRIES + 2 + expect(suffixed_path.call(count)).to eq("backintime3846") + end + end +end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index b7dcf9919c7..3485c877373 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -566,16 +566,6 @@ RSpec.describe Repository, feature_category: :source_code_management do expect(commit_ids).to include(*expected_commit_ids) expect(commit_ids).not_to include('913c66a37b4a45b9769037c55c2d238bd0942d2e') end - - context 'when feature flag "commit_search_trailing_spaces" is disabled' do - before do - stub_feature_flags(commit_search_trailing_spaces: false) - end - - it 'returns an empty list' do - expect(commit_ids).to be_empty - end - end end describe 'when storage is broken', :broken_storage do diff --git a/spec/presenters/issue_email_participant_presenter_spec.rb b/spec/presenters/issue_email_participant_presenter_spec.rb new file mode 100644 index 00000000000..c270fae3058 --- /dev/null +++ b/spec/presenters/issue_email_participant_presenter_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe IssueEmailParticipantPresenter, feature_category: :service_desk do + # See https://gitlab.com/gitlab-org/gitlab/-/issues/389247 + # for details around build_stubbed for access level + let_it_be(:non_member) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate + let_it_be(:guest) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate + let_it_be(:reporter) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate + let_it_be(:developer) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate + let_it_be(:group) { create(:group) } # rubocop:todo RSpec/FactoryBot/AvoidCreate + let_it_be(:project) { create(:project, group: group) } # rubocop:todo RSpec/FactoryBot/AvoidCreate + let_it_be(:issue) { build_stubbed(:issue, project: project) } + let_it_be(:participant) { build_stubbed(:issue_email_participant, issue: issue, email: 'any@email.com') } + + let(:user) { nil } + let(:presenter) { described_class.new(participant, current_user: user) } + let(:obfuscated_email) { 'an*****@e*****.c**' } + let(:email) { 'any@email.com' } + + before_all do + group.add_guest(guest) + group.add_reporter(reporter) + group.add_developer(developer) + end + + describe '#email' do + subject { presenter.email } + + it { is_expected.to eq(obfuscated_email) } + + context 'with signed in user' do + context 'when user has no role in project' do + let(:user) { non_member } + + it { is_expected.to eq(obfuscated_email) } + end + + context 'when user has guest role in project' do + let(:user) { guest } + + it { is_expected.to eq(obfuscated_email) } + end + + context 'when user has reporter role in project' do + let(:user) { reporter } + + it { is_expected.to eq(email) } + end + + context 'when user has developer role in project' do + let(:user) { developer } + + it { is_expected.to eq(email) } + end + end + end +end diff --git a/spec/presenters/issue_presenter_spec.rb b/spec/presenters/issue_presenter_spec.rb index df43b0279dd..22a86d04a5a 100644 --- a/spec/presenters/issue_presenter_spec.rb +++ b/spec/presenters/issue_presenter_spec.rb @@ -6,16 +6,25 @@ RSpec.describe IssuePresenter do include Gitlab::Routing.url_helpers let_it_be(:user) { create(:user) } + let_it_be(:reporter) { create(:user) } + let_it_be(:guest) { create(:user) } + let_it_be(:developer) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } let_it_be(:issue) { create(:issue, project: project) } let_it_be(:task) { create(:issue, :task, project: project) } + let_it_be(:non_member) { create(:user) } let(:presented_issue) { issue } let(:presenter) { described_class.new(presented_issue, current_user: user) } + let(:obfuscated_email) { 'an*****@e*****.c**' } + let(:email) { 'any@email.com' } before_all do group.add_developer(user) + group.add_developer(developer) + group.add_reporter(reporter) + group.add_guest(guest) end describe '#web_url' do @@ -99,4 +108,69 @@ RSpec.describe IssuePresenter do it { is_expected.to be(true) } end end + + describe '#service_desk_reply_to' do + context 'when issue is not a service desk issue' do + subject { presenter.service_desk_reply_to } + + it { is_expected.to be_nil } + end + + context 'when issue is a service desk issue' do + let(:service_desk_issue) do + create(:issue, project: project, author: User.support_bot, service_desk_reply_to: email) + end + + let(:user) { nil } + + subject { described_class.new(service_desk_issue, current_user: user).service_desk_reply_to } + + it { is_expected.to eq obfuscated_email } + + context 'with signed in user' do + context 'when user has no role in project' do + let(:user) { non_member } + + it { is_expected.to eq obfuscated_email } + end + + context 'when user has guest role in project' do + let(:user) { guest } + + it { is_expected.to eq obfuscated_email } + end + + context 'when user has reporter role in project' do + let(:user) { reporter } + + it { is_expected.to eq email } + end + + context 'when user has developer role in project' do + let(:user) { developer } + + it { is_expected.to eq email } + end + end + end + end + + describe '#issue_email_participants' do + let(:participants_issue) { create(:issue, project: project) } + + subject { described_class.new(participants_issue, current_user: user).issue_email_participants } + + it { is_expected.to be_empty } + + context "when an issue email participant exists" do + before do + participants_issue.issue_email_participants.create!(email: email) + end + + it "has one element that is a presenter" do + expect(subject.size).to eq(1) + expect(subject.first).to be_a(IssueEmailParticipantPresenter) + end + end + end end diff --git a/spec/serializers/issue_entity_spec.rb b/spec/serializers/issue_entity_spec.rb index 9d53d8bb235..4bb1e00fa18 100644 --- a/spec/serializers/issue_entity_spec.rb +++ b/spec/serializers/issue_entity_spec.rb @@ -164,21 +164,57 @@ RSpec.describe IssueEntity do it_behaves_like 'issuable entity current_user properties' context 'when issue has email participants' do + let(:obfuscated_email) { 'an*****@e*****.c**' } + let(:email) { 'any@email.com' } + before do - resource.issue_email_participants.create!(email: 'any@email.com') + resource.issue_email_participants.create!(email: email) end - context 'when issue is confidential' do - it 'returns email participants' do - resource.update!(confidential: true) + context 'with anonymous user' do + it 'returns obfuscated email participants email' do + request = double('request', current_user: nil) - expect(subject[:issue_email_participants]).to match_array([{ email: "any@email.com" }]) + response = described_class.new(resource, request: request).as_json + expect(response[:issue_email_participants]).to eq([{ email: obfuscated_email }]) end end - context 'when issue is not confidential' do - it 'returns empty array' do - expect(subject[:issue_email_participants]).to be_empty + context 'with signed in user' do + context 'when user has no role in project' do + it 'returns obfuscated email participants email' do + expect(subject[:issue_email_participants]).to eq([{ email: obfuscated_email }]) + end + end + + context 'when user has guest role in project' do + let(:member) { create(:user) } + + before do + project.add_guest(member) + end + + it 'returns obfuscated email participants email' do + request = double('request', current_user: member) + + response = described_class.new(resource, request: request).as_json + expect(response[:issue_email_participants]).to eq([{ email: obfuscated_email }]) + end + end + + context 'when user has (at least) reporter role in project' do + let(:member) { create(:user) } + + before do + project.add_reporter(member) + end + + it 'returns full email participants email' do + request = double('request', current_user: member) + + response = described_class.new(resource, request: request).as_json + expect(response[:issue_email_participants]).to eq([{ email: email }]) + end end end end diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb index 17ef8a85c2b..8c90946e09e 100644 --- a/spec/services/notes/create_service_spec.rb +++ b/spec/services/notes/create_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Notes::CreateService do +RSpec.describe Notes::CreateService, feature_category: :team_planning do let_it_be(:project) { create(:project, :repository) } let_it_be(:issue) { create(:issue, project: project) } let_it_be(:user) { create(:user) } @@ -438,7 +438,7 @@ RSpec.describe Notes::CreateService do end end - context 'for merge requests' do + context 'for merge requests', feature_category: :code_review_workflow do let_it_be(:merge_request) { create(:merge_request, source_project: project, labels: [bug_label]) } let(:issuable) { merge_request } @@ -512,7 +512,7 @@ RSpec.describe Notes::CreateService do end end - context 'personal snippet note' do + context 'personal snippet note', feature_category: :snippets do subject { described_class.new(nil, user, params).execute } let(:snippet) { create(:personal_snippet) } @@ -533,7 +533,7 @@ RSpec.describe Notes::CreateService do end end - context 'design note' do + context 'design note', feature_category: :design_management do subject(:service) { described_class.new(project, user, params) } let_it_be(:design) { create(:design, :with_file) } diff --git a/spec/services/packages/debian/generate_distribution_service_spec.rb b/spec/services/packages/debian/generate_distribution_service_spec.rb index 53805d03655..6d179c791a3 100644 --- a/spec/services/packages/debian/generate_distribution_service_spec.rb +++ b/spec/services/packages/debian/generate_distribution_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Packages::Debian::GenerateDistributionService do +RSpec.describe Packages::Debian::GenerateDistributionService, feature_category: :package_registry do describe '#execute' do subject { described_class.new(distribution).execute } diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb index 6e2caa853f8..616f8f2345c 100644 --- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb @@ -38,7 +38,7 @@ RSpec.shared_context 'ProjectPolicy context' do read_commit_status read_confidential_issues read_container_image read_harbor_registry read_deployment read_environment read_merge_request read_metrics_dashboard_annotation read_pipeline read_prometheus - read_sentry_issue update_issue create_merge_request_in + read_sentry_issue update_issue create_merge_request_in read_external_emails ] end diff --git a/spec/support/shared_examples/features/reportable_note_shared_examples.rb b/spec/support/shared_examples/features/reportable_note_shared_examples.rb index e9056edbafa..bb3fab5b23e 100644 --- a/spec/support/shared_examples/features/reportable_note_shared_examples.rb +++ b/spec/support/shared_examples/features/reportable_note_shared_examples.rb @@ -20,9 +20,10 @@ RSpec.shared_examples 'reportable note' do |type| dropdown = comment.find(more_actions_selector) open_dropdown(dropdown) + expect(dropdown).to have_button('Report abuse to administrator') + if type == 'issue' || type == 'merge_request' expect(dropdown).to have_button('Delete comment') - expect(dropdown).to have_button('Report abuse to administrator') else expect(dropdown).to have_link('Delete comment', href: note_url(note, project)) end @@ -32,21 +33,14 @@ RSpec.shared_examples 'reportable note' do |type| dropdown = comment.find(more_actions_selector) open_dropdown(dropdown) - if type == 'issue' || type == 'merge_request' - dropdown.click_button('Report abuse to administrator') + dropdown.click_button('Report abuse to administrator') - choose "They're posting spam." - click_button "Next" + choose "They're posting spam." + click_button "Next" - expect(find('#user_name')['value']).to match(note.author.username) - expect(find('#abuse_report_reported_from_url')['value']).to match(noteable_note_url(note)) - expect(find('#abuse_report_category', visible: false)['value']).to match('spam') - else - dropdown.click_link('Report abuse to administrator') - - expect(find('#user_name')['value']).to match(note.author.username) - expect(find('#abuse_report_reported_from_url')['value']).to match(noteable_note_url(note)) - end + expect(find('#user_name')['value']).to match(note.author.username) + expect(find('#abuse_report_reported_from_url')['value']).to match(noteable_note_url(note)) + expect(find('#abuse_report_category', visible: false)['value']).to match('spam') end def open_dropdown(dropdown) diff --git a/spec/support/shared_examples/integrations/integration_settings_form.rb b/spec/support/shared_examples/integrations/integration_settings_form.rb index 5eeefdf7e50..1074bcc420c 100644 --- a/spec/support/shared_examples/integrations/integration_settings_form.rb +++ b/spec/support/shared_examples/integrations/integration_settings_form.rb @@ -4,7 +4,7 @@ RSpec.shared_examples 'integration settings form' do include IntegrationsHelper # Note: these specs don't validate channel fields # which are present on a few integrations - it 'displays all the integrations' do + it 'displays all the integrations', feature_category: :integrations do aggregate_failures do integrations.each do |integration| stub_feature_flags(integration_slack_app_notifications: false) diff --git a/spec/support/shared_examples/serializers/note_entity_shared_examples.rb b/spec/support/shared_examples/serializers/note_entity_shared_examples.rb index 2e557ca090c..b5e3a407b53 100644 --- a/spec/support/shared_examples/serializers/note_entity_shared_examples.rb +++ b/spec/support/shared_examples/serializers/note_entity_shared_examples.rb @@ -38,6 +38,10 @@ RSpec.shared_examples 'note entity' do expect(subject[:current_user]).to include(:can_edit, :can_award_emoji, :can_resolve, :can_resolve_discussion) end + it 'exposes the report_abuse_path' do + expect(subject[:report_abuse_path]).to eq(add_category_abuse_reports_path) + end + describe ':can_resolve_discussion' do context 'discussion is resolvable' do before do diff --git a/spec/views/projects/issues/_issue.html.haml_spec.rb b/spec/views/projects/issues/_issue.html.haml_spec.rb index 29bef557304..e4485f253b6 100644 --- a/spec/views/projects/issues/_issue.html.haml_spec.rb +++ b/spec/views/projects/issues/_issue.html.haml_spec.rb @@ -37,6 +37,59 @@ RSpec.describe 'projects/issues/_issue.html.haml' do end end + context 'when issue is service desk issue' do + let_it_be(:email) { 'user@example.com' } + let_it_be(:obfuscated_email) { 'us*****@e*****.c**' } + let_it_be(:issue) { create(:issue, author: User.support_bot, service_desk_reply_to: email) } + + context 'with anonymous user' do + it 'obfuscates service_desk_reply_to email for anonymous user' do + expect(rendered).to have_content(obfuscated_email) + end + end + + context 'with signed in user' do + let_it_be(:user) { create(:user) } + + before do + allow(view).to receive(:current_user).and_return(user) + allow(view).to receive(:issue).and_return(issue) + end + + context 'when user has no role in project' do + it 'obfuscates service_desk_reply_to email' do + render + + expect(rendered).to have_content(obfuscated_email) + end + end + + context 'when user has guest role in project' do + before do + issue.project.add_guest(user) + end + + it 'obfuscates service_desk_reply_to email' do + render + + expect(rendered).to have_content(obfuscated_email) + end + end + + context 'when user has (at least) reporter role in project' do + before do + issue.project.add_reporter(user) + end + + it 'shows full service_desk_reply_to email' do + render + + expect(rendered).to have_content(email) + end + end + end + end + def format_timestamp(time) l(time, format: "%b %d, %Y") end diff --git a/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb b/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb index 7886a811c9a..d604eb2c8d6 100644 --- a/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb +++ b/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb @@ -17,7 +17,7 @@ RSpec.describe 'projects/notes/_more_actions_dropdown' do it 'shows Report abuse to admin button if not editable and not current users comment' do render 'projects/notes/more_actions_dropdown', current_user: not_author_user, note_editable: false, note: note - expect(rendered).to have_link('Report abuse to administrator') + expect(rendered).to have_selector('.js-report-abuse-dropdown-item') end it 'does not show the More actions button if not editable and current users comment' do @@ -29,7 +29,8 @@ RSpec.describe 'projects/notes/_more_actions_dropdown' do it 'shows Report abuse and Delete buttons if editable and not current users comment' do render 'projects/notes/more_actions_dropdown', current_user: not_author_user, note_editable: true, note: note - expect(rendered).to have_link('Report abuse to administrator') + expect(rendered).to have_selector('.js-report-abuse-dropdown-item') + expect(rendered).to have_link('Delete comment') end diff --git a/spec/workers/packages/debian/generate_distribution_worker_spec.rb b/spec/workers/packages/debian/generate_distribution_worker_spec.rb index a4627ec5d36..390a5e15e66 100644 --- a/spec/workers/packages/debian/generate_distribution_worker_spec.rb +++ b/spec/workers/packages/debian/generate_distribution_worker_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe Packages::Debian::GenerateDistributionWorker, type: :worker do +RSpec.describe Packages::Debian::GenerateDistributionWorker, type: :worker, +feature_category: :package_registry do describe '#perform' do let(:container_type) { distribution.container_type } let(:distribution_id) { distribution.id } -- cgit v1.2.3