diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-10 00:10:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-10 00:10:17 +0300 |
commit | 413c91fda942270905873684a58041f8c65f878c (patch) | |
tree | 8053b007997cc1266b5d9c86794fd8f6beff0eae /spec | |
parent | 7d112a9002182130f6a06f890bb17450b03406f9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
12 files changed, 576 insertions, 296 deletions
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb index ae3859280b1..0312efeb9ce 100644 --- a/spec/features/abuse_report_spec.rb +++ b/spec/features/abuse_report_spec.rb @@ -13,10 +13,19 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do before do sign_in(reporter1) stub_feature_flags(moved_mr_sidebar: false) - stub_feature_flags(user_profile_overflow_menu_vue: false) end describe 'report abuse to administrator' do + shared_examples 'cancel report' do + it 'redirects backs to user profile when cancel button is clicked' do + fill_and_submit_abuse_category_form + + click_link 'Cancel' + + expect(page).to have_current_path(user_path(abusive_user)) + end + end + context 'when reporting an issue for abuse' do before do visit project_issue_path(project, issue) @@ -46,54 +55,102 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do it_behaves_like 'reports the user with an abuse category' end - context 'when reporting a user profile for abuse' do - let_it_be(:reporter2) { create(:user) } + describe 'when user_profile_overflow_menu FF turned on' do + context 'when reporting a user profile for abuse' do + let_it_be(:reporter2) { create(:user) } - before do - visit user_path(abusive_user) - end + before do + visit user_path(abusive_user) + find('[data-testid="base-dropdown-toggle"').click + end - it_behaves_like 'reports the user with an abuse category' + it_behaves_like 'reports the user with an abuse category' - it 'allows the reporter to report the same user for different abuse categories' do - visit user_path(abusive_user) + it 'allows the reporter to report the same user for different abuse categories' do + visit user_path(abusive_user) - fill_and_submit_abuse_category_form - fill_and_submit_report_abuse_form + find('[data-testid="base-dropdown-toggle"').click + fill_and_submit_abuse_category_form + fill_and_submit_report_abuse_form - expect(page).to have_content 'Thank you for your report' + expect(page).to have_content 'Thank you for your report' - visit user_path(abusive_user) + visit user_path(abusive_user) - fill_and_submit_abuse_category_form("They're being offensive or abusive.") - fill_and_submit_report_abuse_form + find('[data-testid="base-dropdown-toggle"').click + fill_and_submit_abuse_category_form("They're being offensive or abusive.") + fill_and_submit_report_abuse_form - expect(page).to have_content 'Thank you for your report' - end + expect(page).to have_content 'Thank you for your report' + end - it 'allows multiple users to report the same user' do - fill_and_submit_abuse_category_form - fill_and_submit_report_abuse_form + it 'allows multiple users to report the same user' do + fill_and_submit_abuse_category_form + fill_and_submit_report_abuse_form - expect(page).to have_content 'Thank you for your report' + expect(page).to have_content 'Thank you for your report' - gitlab_sign_out - gitlab_sign_in(reporter2) + gitlab_sign_out + gitlab_sign_in(reporter2) - visit user_path(abusive_user) + visit user_path(abusive_user) - fill_and_submit_abuse_category_form - fill_and_submit_report_abuse_form + find('[data-testid="base-dropdown-toggle"').click + fill_and_submit_abuse_category_form + fill_and_submit_report_abuse_form - expect(page).to have_content 'Thank you for your report' + expect(page).to have_content 'Thank you for your report' + end + + it_behaves_like 'cancel report' end + end - it 'redirects backs to user profile when cancel button is clicked' do - fill_and_submit_abuse_category_form + describe 'when user_profile_overflow_menu FF turned off' do + context 'when reporting a user profile for abuse' do + let_it_be(:reporter2) { create(:user) } - click_link 'Cancel' + before do + stub_feature_flags(user_profile_overflow_menu_vue: false) + visit user_path(abusive_user) + end - expect(page).to have_current_path(user_path(abusive_user)) + it_behaves_like 'reports the user with an abuse category' + + it 'allows the reporter to report the same user for different abuse categories' do + visit user_path(abusive_user) + + fill_and_submit_abuse_category_form + fill_and_submit_report_abuse_form + + expect(page).to have_content 'Thank you for your report' + + visit user_path(abusive_user) + + fill_and_submit_abuse_category_form("They're being offensive or abusive.") + fill_and_submit_report_abuse_form + + expect(page).to have_content 'Thank you for your report' + end + + it 'allows multiple users to report the same user' do + fill_and_submit_abuse_category_form + fill_and_submit_report_abuse_form + + expect(page).to have_content 'Thank you for your report' + + gitlab_sign_out + gitlab_sign_in(reporter2) + + visit user_path(abusive_user) + + fill_and_submit_abuse_category_form + fill_and_submit_report_abuse_form + + expect(page).to have_content 'Thank you for your report' + end + + it_behaves_like 'cancel report' end end diff --git a/spec/frontend/organizations/groups_and_projects/components/groups_page_spec.js b/spec/frontend/organizations/groups_and_projects/components/groups_page_spec.js new file mode 100644 index 00000000000..537f8114fcf --- /dev/null +++ b/spec/frontend/organizations/groups_and_projects/components/groups_page_spec.js @@ -0,0 +1,88 @@ +import VueApollo from 'vue-apollo'; +import Vue from 'vue'; +import { GlLoadingIcon } from '@gitlab/ui'; +import GroupsPage from '~/organizations/groups_and_projects/components/groups_page.vue'; +import { formatGroups } from '~/organizations/groups_and_projects/utils'; +import resolvers from '~/organizations/groups_and_projects/graphql/resolvers'; +import GroupsList from '~/vue_shared/components/groups_list/groups_list.vue'; +import { createAlert } from '~/alert'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import { organizationGroups } from '../mock_data'; + +jest.mock('~/alert'); + +Vue.use(VueApollo); +jest.useFakeTimers(); + +describe('GroupsPage', () => { + let wrapper; + let mockApollo; + + const createComponent = ({ mockResolvers = resolvers } = {}) => { + mockApollo = createMockApollo([], mockResolvers); + + wrapper = shallowMountExtended(GroupsPage, { apolloProvider: mockApollo }); + }; + + afterEach(() => { + mockApollo = null; + }); + + describe('when API call is loading', () => { + beforeEach(() => { + const mockResolvers = { + Query: { + organization: jest.fn().mockReturnValueOnce(new Promise(() => {})), + }, + }; + + createComponent({ mockResolvers }); + }); + + it('renders loading icon', () => { + expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true); + }); + }); + + describe('when API call is successful', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders `GroupsList` component and passes correct props', async () => { + jest.runAllTimers(); + await waitForPromises(); + + expect(wrapper.findComponent(GroupsList).props()).toEqual({ + groups: formatGroups(organizationGroups.nodes), + showGroupIcon: true, + }); + }); + }); + + describe('when API call is not successful', () => { + const error = new Error(); + + beforeEach(() => { + const mockResolvers = { + Query: { + organization: jest.fn().mockRejectedValueOnce(error), + }, + }; + + createComponent({ mockResolvers }); + }); + + it('displays error alert', async () => { + await waitForPromises(); + + expect(createAlert).toHaveBeenCalledWith({ + message: GroupsPage.i18n.errorMessage, + error, + captureError: true, + }); + }); + }); +}); diff --git a/spec/frontend/organizations/groups_and_projects/components/projects_page_spec.js b/spec/frontend/organizations/groups_and_projects/components/projects_page_spec.js index 07f9f0da7c7..7cadcab5021 100644 --- a/spec/frontend/organizations/groups_and_projects/components/projects_page_spec.js +++ b/spec/frontend/organizations/groups_and_projects/components/projects_page_spec.js @@ -56,7 +56,7 @@ describe('ProjectsPage', () => { await waitForPromises(); expect(wrapper.findComponent(ProjectsList).props()).toEqual({ - projects: formatProjects(organizationProjects.projects.nodes), + projects: formatProjects(organizationProjects.nodes), showProjectIcon: true, }); }); diff --git a/spec/frontend/organizations/groups_and_projects/mock_data.js b/spec/frontend/organizations/groups_and_projects/mock_data.js index c3276450745..b1f91e2f42f 100644 --- a/spec/frontend/organizations/groups_and_projects/mock_data.js +++ b/spec/frontend/organizations/groups_and_projects/mock_data.js @@ -1,98 +1,247 @@ -export const organizationProjects = { +export const organization = { id: 'gid://gitlab/Organization/1', __typename: 'Organization', - projects: { - nodes: [ - { - id: 'gid://gitlab/Project/8', - nameWithNamespace: 'Twitter / Typeahead.Js', - webUrl: 'http://127.0.0.1:3000/twitter/Typeahead.Js', - topics: ['JavaScript', 'Vue.js'], - forksCount: 4, - avatarUrl: null, - starCount: 0, - visibility: 'public', - openIssuesCount: 48, - descriptionHtml: - '<p data-sourcepos="1:1-1:59" dir="auto">Optio et reprehenderit enim doloremque deserunt et commodi.</p>', - issuesAccessLevel: 'enabled', - forkingAccessLevel: 'enabled', - accessLevel: { - integerValue: 30, - }, +}; + +export const organizationProjects = { + nodes: [ + { + id: 'gid://gitlab/Project/8', + nameWithNamespace: 'Twitter / Typeahead.Js', + webUrl: 'http://127.0.0.1:3000/twitter/Typeahead.Js', + topics: ['JavaScript', 'Vue.js'], + forksCount: 4, + avatarUrl: null, + starCount: 0, + visibility: 'public', + openIssuesCount: 48, + descriptionHtml: + '<p data-sourcepos="1:1-1:59" dir="auto">Optio et reprehenderit enim doloremque deserunt et commodi.</p>', + issuesAccessLevel: 'enabled', + forkingAccessLevel: 'enabled', + accessLevel: { + integerValue: 30, + }, + }, + { + id: 'gid://gitlab/Project/7', + nameWithNamespace: 'Flightjs / Flight', + webUrl: 'http://127.0.0.1:3000/flightjs/Flight', + topics: [], + forksCount: 0, + avatarUrl: null, + starCount: 0, + visibility: 'private', + openIssuesCount: 37, + descriptionHtml: + '<p data-sourcepos="1:1-1:49" dir="auto">Dolor dicta rerum et ut eius voluptate earum qui.</p>', + issuesAccessLevel: 'enabled', + forkingAccessLevel: 'enabled', + accessLevel: { + integerValue: 20, + }, + }, + { + id: 'gid://gitlab/Project/6', + nameWithNamespace: 'Jashkenas / Underscore', + webUrl: 'http://127.0.0.1:3000/jashkenas/Underscore', + topics: [], + forksCount: 0, + avatarUrl: null, + starCount: 0, + visibility: 'private', + openIssuesCount: 34, + descriptionHtml: + '<p data-sourcepos="1:1-1:52" dir="auto">Incidunt est aliquam autem nihil eveniet quis autem.</p>', + issuesAccessLevel: 'enabled', + forkingAccessLevel: 'enabled', + accessLevel: { + integerValue: 40, + }, + }, + { + id: 'gid://gitlab/Project/5', + nameWithNamespace: 'Commit451 / Lab Coat', + webUrl: 'http://127.0.0.1:3000/Commit451/lab-coat', + topics: [], + forksCount: 0, + avatarUrl: null, + starCount: 0, + visibility: 'internal', + openIssuesCount: 49, + descriptionHtml: + '<p data-sourcepos="1:1-1:34" dir="auto">Sint eos dolorem impedit rerum et.</p>', + issuesAccessLevel: 'enabled', + forkingAccessLevel: 'enabled', + accessLevel: { + integerValue: 10, + }, + }, + { + id: 'gid://gitlab/Project/1', + nameWithNamespace: 'Toolbox / Gitlab Smoke Tests', + webUrl: 'http://127.0.0.1:3000/toolbox/gitlab-smoke-tests', + topics: [], + forksCount: 0, + avatarUrl: null, + starCount: 0, + visibility: 'internal', + openIssuesCount: 34, + descriptionHtml: + '<p data-sourcepos="1:1-1:40" dir="auto">Veritatis error laboriosam libero autem.</p>', + issuesAccessLevel: 'enabled', + forkingAccessLevel: 'enabled', + accessLevel: { + integerValue: 30, + }, + }, + ], +}; + +export const organizationGroups = { + nodes: [ + { + id: 'gid://gitlab/Group/29', + fullName: 'Commit451', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/Commit451', + descriptionHtml: + '<p data-sourcepos="1:1-1:52" dir="auto">Autem praesentium vel ut ratione itaque ullam culpa.</p>', + avatarUrl: null, + descendantGroupsCount: 0, + projectsCount: 3, + groupMembersCount: 2, + visibility: 'public', + accessLevel: { + integerValue: 30, + }, + }, + { + id: 'gid://gitlab/Group/33', + fullName: 'Flightjs', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/flightjs', + descriptionHtml: + '<p data-sourcepos="1:1-1:60" dir="auto">Ipsa reiciendis deleniti officiis illum nostrum quo aliquam.</p>', + avatarUrl: null, + descendantGroupsCount: 4, + projectsCount: 3, + groupMembersCount: 1, + visibility: 'private', + accessLevel: { + integerValue: 20, + }, + }, + { + id: 'gid://gitlab/Group/24', + fullName: 'Gitlab Org', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/gitlab-org', + descriptionHtml: + '<p data-sourcepos="1:1-1:64" dir="auto">Dolorem dolorem omnis impedit cupiditate pariatur officia velit.</p>', + avatarUrl: null, + descendantGroupsCount: 1, + projectsCount: 1, + groupMembersCount: 2, + visibility: 'internal', + accessLevel: { + integerValue: 10, + }, + }, + { + id: 'gid://gitlab/Group/27', + fullName: 'Gnuwget', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/gnuwgetf', + descriptionHtml: + '<p data-sourcepos="1:1-1:47" dir="auto">Culpa soluta aut eius dolores est vel sapiente.</p>', + avatarUrl: null, + descendantGroupsCount: 4, + projectsCount: 2, + groupMembersCount: 3, + visibility: 'public', + accessLevel: { + integerValue: 40, + }, + }, + { + id: 'gid://gitlab/Group/31', + fullName: 'Jashkenas', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/jashkenas', + descriptionHtml: '<p data-sourcepos="1:1-1:25" dir="auto">Ut ut id aliquid nostrum.</p>', + avatarUrl: null, + descendantGroupsCount: 3, + projectsCount: 3, + groupMembersCount: 10, + visibility: 'private', + accessLevel: { + integerValue: 10, + }, + }, + { + id: 'gid://gitlab/Group/22', + fullName: 'Toolbox', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/toolbox', + descriptionHtml: + '<p data-sourcepos="1:1-1:46" dir="auto">Quo voluptatem magnam facere voluptates alias.</p>', + avatarUrl: null, + descendantGroupsCount: 2, + projectsCount: 3, + groupMembersCount: 40, + visibility: 'internal', + accessLevel: { + integerValue: 30, }, - { - id: 'gid://gitlab/Project/7', - nameWithNamespace: 'Flightjs / Flight', - webUrl: 'http://127.0.0.1:3000/flightjs/Flight', - topics: [], - forksCount: 0, - avatarUrl: null, - starCount: 0, - visibility: 'private', - openIssuesCount: 37, - descriptionHtml: - '<p data-sourcepos="1:1-1:49" dir="auto">Dolor dicta rerum et ut eius voluptate earum qui.</p>', - issuesAccessLevel: 'enabled', - forkingAccessLevel: 'enabled', - accessLevel: { - integerValue: 20, - }, + }, + { + id: 'gid://gitlab/Group/35', + fullName: 'Twitter', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/twitter', + descriptionHtml: + '<p data-sourcepos="1:1-1:40" dir="auto">Quae nulla consequatur assumenda id quo.</p>', + avatarUrl: null, + descendantGroupsCount: 20, + projectsCount: 30, + groupMembersCount: 100, + visibility: 'public', + accessLevel: { + integerValue: 40, }, - { - id: 'gid://gitlab/Project/6', - nameWithNamespace: 'Jashkenas / Underscore', - webUrl: 'http://127.0.0.1:3000/jashkenas/Underscore', - topics: [], - forksCount: 0, - avatarUrl: null, - starCount: 0, - visibility: 'private', - openIssuesCount: 34, - descriptionHtml: - '<p data-sourcepos="1:1-1:52" dir="auto">Incidunt est aliquam autem nihil eveniet quis autem.</p>', - issuesAccessLevel: 'enabled', - forkingAccessLevel: 'enabled', - accessLevel: { - integerValue: 40, - }, + }, + { + id: 'gid://gitlab/Group/73', + fullName: 'test', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/test', + descriptionHtml: '', + avatarUrl: null, + descendantGroupsCount: 1, + projectsCount: 1, + groupMembersCount: 1, + visibility: 'private', + accessLevel: { + integerValue: 30, }, - { - id: 'gid://gitlab/Project/5', - nameWithNamespace: 'Commit451 / Lab Coat', - webUrl: 'http://127.0.0.1:3000/Commit451/lab-coat', - topics: [], - forksCount: 0, - avatarUrl: null, - starCount: 0, - visibility: 'internal', - openIssuesCount: 49, - descriptionHtml: - '<p data-sourcepos="1:1-1:34" dir="auto">Sint eos dolorem impedit rerum et.</p>', - issuesAccessLevel: 'enabled', - forkingAccessLevel: 'enabled', - accessLevel: { - integerValue: 10, - }, + }, + { + id: 'gid://gitlab/Group/74', + fullName: 'Twitter / test subgroup', + parent: { + id: 'gid://gitlab/Group/35', }, - { - id: 'gid://gitlab/Project/1', - nameWithNamespace: 'Toolbox / Gitlab Smoke Tests', - webUrl: 'http://127.0.0.1:3000/toolbox/gitlab-smoke-tests', - topics: [], - forksCount: 0, - avatarUrl: null, - starCount: 0, - visibility: 'internal', - openIssuesCount: 34, - descriptionHtml: - '<p data-sourcepos="1:1-1:40" dir="auto">Veritatis error laboriosam libero autem.</p>', - issuesAccessLevel: 'enabled', - forkingAccessLevel: 'enabled', - accessLevel: { - integerValue: 30, - }, + webUrl: 'http://127.0.0.1:3000/groups/twitter/test-subgroup', + descriptionHtml: '', + avatarUrl: null, + descendantGroupsCount: 4, + projectsCount: 4, + groupMembersCount: 4, + visibility: 'internal', + accessLevel: { + integerValue: 20, }, - ], - }, + }, + ], }; diff --git a/spec/frontend/organizations/groups_and_projects/utils_spec.js b/spec/frontend/organizations/groups_and_projects/utils_spec.js index 5aae26802ac..fe745116f33 100644 --- a/spec/frontend/organizations/groups_and_projects/utils_spec.js +++ b/spec/frontend/organizations/groups_and_projects/utils_spec.js @@ -1,11 +1,11 @@ -import { formatProjects } from '~/organizations/groups_and_projects/utils'; +import { formatProjects, formatGroups } from '~/organizations/groups_and_projects/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { organizationProjects } from './mock_data'; +import { organizationProjects, organizationGroups } from './mock_data'; describe('formatProjects', () => { it('correctly formats the projects', () => { - const [firstMockProject] = organizationProjects.projects.nodes; - const formattedProjects = formatProjects(organizationProjects.projects.nodes); + const [firstMockProject] = organizationProjects.nodes; + const formattedProjects = formatProjects(organizationProjects.nodes); const [firstFormattedProject] = formattedProjects; expect(firstFormattedProject).toMatchObject({ @@ -17,6 +17,17 @@ describe('formatProjects', () => { }, }, }); - expect(formattedProjects.length).toBe(organizationProjects.projects.nodes.length); + expect(formattedProjects.length).toBe(organizationProjects.nodes.length); + }); +}); + +describe('formatGroups', () => { + it('correctly formats the groups', () => { + const [firstMockGroup] = organizationGroups.nodes; + const formattedGroups = formatGroups(organizationGroups.nodes); + const [firstFormattedGroup] = formattedGroups; + + expect(firstFormattedGroup.id).toBe(getIdFromGraphQLId(firstMockGroup.id)); + expect(formattedGroups.length).toBe(organizationGroups.nodes.length); }); }); diff --git a/spec/frontend/users/profile/actions/components/user_actions_app_spec.js b/spec/frontend/users/profile/actions/components/user_actions_app_spec.js index c2ae3d8364f..a33474375e6 100644 --- a/spec/frontend/users/profile/actions/components/user_actions_app_spec.js +++ b/spec/frontend/users/profile/actions/components/user_actions_app_spec.js @@ -1,6 +1,7 @@ import { GlDisclosureDropdown } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import UserActionsApp from '~/users/profile/actions/components/user_actions_app.vue'; +import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue'; describe('User Actions App', () => { let wrapper; @@ -40,6 +41,15 @@ describe('User Actions App', () => { }); expect(findActions()).toHaveLength(2); }); + + it('should show items with report abuse', () => { + createWrapper({ + rssSubscriptionPath: '/test/path', + reportedUserId: 1, + reportedFromUrl: '/report/path', + }); + expect(findActions()).toHaveLength(3); + }); }); it('shows copy user id action', () => { @@ -60,4 +70,21 @@ describe('User Actions App', () => { expect(rssLink.attributes('href')).toBe(testSubscriptionPath); expect(rssLink.text()).toBe('Subscribe'); }); + + it('shows report abuse action when reported user id was presented', () => { + const reportUrl = '/path/to/report'; + const reportUserId = 1; + createWrapper({ + rssSubscriptionPath: '/test/path', + reportedUserId: reportUserId, + reportedFromUrl: reportUrl, + }); + const abuseCategorySelector = wrapper.findComponent(AbuseCategorySelector); + expect(abuseCategorySelector.exists()).toBe(true); + expect(abuseCategorySelector.props()).toEqual({ + reportedUserId: reportUserId, + reportedFromUrl: reportUrl, + showDrawer: false, + }); + }); }); diff --git a/spec/frontend/vue_shared/components/badges/__snapshots__/beta_badge_spec.js.snap b/spec/frontend/vue_shared/components/badges/__snapshots__/beta_badge_spec.js.snap index 5c49ea1b9f4..24b2c54f20b 100644 --- a/spec/frontend/vue_shared/components/badges/__snapshots__/beta_badge_spec.js.snap +++ b/spec/frontend/vue_shared/components/badges/__snapshots__/beta_badge_spec.js.snap @@ -4,9 +4,10 @@ exports[`Beta badge component renders the badge 1`] = ` <div> <gl-badge-stub class="gl-cursor-pointer" + href="#" iconsize="md" size="md" - variant="muted" + variant="neutral" > Beta </gl-badge-stub> @@ -33,7 +34,7 @@ exports[`Beta badge component renders the badge 1`] = ` class="gl-pl-4" > <li> - May have performance or stability issues. + May be unstable. </li> <li> diff --git a/spec/frontend/vue_shared/components/badges/beta_badge_spec.js b/spec/frontend/vue_shared/components/badges/beta_badge_spec.js index 6109fad9310..c930c6d5708 100644 --- a/spec/frontend/vue_shared/components/badges/beta_badge_spec.js +++ b/spec/frontend/vue_shared/components/badges/beta_badge_spec.js @@ -1,12 +1,32 @@ import { shallowMount } from '@vue/test-utils'; +import { GlBadge } from '@gitlab/ui'; import BetaBadge from '~/vue_shared/components/badges/beta_badge.vue'; describe('Beta badge component', () => { let wrapper; + const findBadge = () => wrapper.findComponent(GlBadge); + const createWrapper = (props = {}) => { + wrapper = shallowMount(BetaBadge, { + propsData: { ...props }, + }); + }; + it('renders the badge', () => { - wrapper = shallowMount(BetaBadge); + createWrapper(); expect(wrapper.element).toMatchSnapshot(); }); + + it('passes default size to badge', () => { + createWrapper(); + + expect(findBadge().props('size')).toBe('md'); + }); + + it('passes given size to badge', () => { + createWrapper({ size: 'sm' }); + + expect(findBadge().props('size')).toBe('sm'); + }); }); diff --git a/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js b/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js index 2bef6dd15df..e4689a84900 100644 --- a/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js +++ b/spec/frontend/vue_shared/components/markdown/comment_templates_dropdown_spec.js @@ -1,6 +1,8 @@ +import { GlCollapsibleListbox } from '@gitlab/ui'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; import savedRepliesResponse from 'test_fixtures/graphql/comment_templates/saved_replies.query.graphql.json'; +import { mockTracking } from 'helpers/tracking_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; @@ -31,6 +33,10 @@ function createComponent(options = {}) { }); } +function findDropdownComponent() { + return wrapper.findComponent(GlCollapsibleListbox); +} + describe('Comment templates dropdown', () => { it('fetches data when dropdown gets opened', async () => { const mockApollo = createMockApolloProvider(savedRepliesResponse); @@ -43,16 +49,42 @@ describe('Comment templates dropdown', () => { expect(savedRepliesResp).toHaveBeenCalled(); }); - it('adds emits a select event on selecting a comment', async () => { - const mockApollo = createMockApolloProvider(savedRepliesResponse); - wrapper = createComponent({ mockApollo }); + describe('when selecting a comment', () => { + let trackingSpy; + let mockApollo; - wrapper.find('.js-comment-template-toggle').trigger('click'); + beforeEach(() => { + trackingSpy = mockTracking(undefined, window.document, jest.spyOn); + mockApollo = createMockApolloProvider(savedRepliesResponse); + wrapper = createComponent({ mockApollo }); + }); - await waitForPromises(); + it('emits a select event', async () => { + wrapper.find('.js-comment-template-toggle').trigger('click'); + + await waitForPromises(); + + wrapper.find('.gl-new-dropdown-item').trigger('click'); + + expect(wrapper.emitted().select[0]).toEqual(['Saved Reply Content']); + }); + + it('tracks the usage of the saved comment', async () => { + const dropdown = findDropdownComponent(); + + dropdown.vm.$emit('shown'); + + await waitForPromises(); + + dropdown.vm.$emit('select', savedRepliesResponse.data.currentUser.savedReplies.nodes[0].id); - wrapper.find('.gl-new-dropdown-item').trigger('click'); + await waitForPromises(); - expect(wrapper.emitted().select[0]).toEqual(['Saved Reply Content']); + expect(trackingSpy).toHaveBeenCalledWith( + expect.any(String), + 'i_code_review_saved_replies_use', + expect.any(Object), + ); + }); }); }); diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 6745dba2f3c..ad8aef276bb 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -682,4 +682,58 @@ RSpec.describe UsersHelper do it { is_expected.to eq('Active') } end end + + describe '#user_profile_actions_data' do + let(:user_1) { create(:user) } + let(:user_2) { create(:user) } + let(:user_path) { '/users/root' } + + subject { helper.user_profile_actions_data(user_1) } + + before do + allow(helper).to receive(:user_path).and_return(user_path) + allow(helper).to receive(:user_url).and_return(user_path) + end + + shared_examples 'user cannot report' do + it 'returns data without reporting related data' do + is_expected.to match({ + user_id: user_1.id, + rss_subscription_path: user_path + }) + end + end + + context 'user is current user' do + before do + allow(helper).to receive(:current_user).and_return(user_1) + end + + it_behaves_like 'user cannot report' + end + + context 'user is not current user' do + before do + allow(helper).to receive(:current_user).and_return(user_2) + end + + it 'returns data for reporting related data' do + is_expected.to match({ + user_id: user_1.id, + rss_subscription_path: user_path, + report_abuse_path: add_category_abuse_reports_path, + reported_user_id: user_1.id, + reported_from_url: user_path + }) + end + end + + context 'when logged out' do + before do + allow(helper).to receive(:current_user).and_return(nil) + end + + it_behaves_like 'user cannot report' + end + end end diff --git a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb index ae884c58f86..11b587e4905 100644 --- a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb @@ -12,7 +12,6 @@ RSpec.describe Gitlab::Metrics::Dashboard::Processor do describe 'process' do let(:sequence) do [ - Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter, Gitlab::Metrics::Dashboard::Stages::UrlValidator ] end @@ -20,12 +19,6 @@ RSpec.describe Gitlab::Metrics::Dashboard::Processor do let(:process_params) { [project, dashboard_yml, sequence, { environment: environment }] } let(:dashboard) { described_class.new(*process_params).process } - it 'includes an id for each dashboard panel' do - expect(all_panels).to satisfy_all do |panel| - panel[:id].present? - end - end - context 'when the dashboard is not present' do let(:dashboard_yml) { nil } @@ -33,69 +26,5 @@ RSpec.describe Gitlab::Metrics::Dashboard::Processor do expect(dashboard).to be_nil end end - - shared_examples_for 'errors with message' do |expected_message| - it 'raises a DashboardLayoutError' do - error_class = Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError - - expect { dashboard }.to raise_error(error_class, expected_message) - end - end - - context 'when the dashboard is missing panel_groups' do - let(:dashboard_yml) { {} } - - it_behaves_like 'errors with message', 'Top-level key :panel_groups must be an array' - end - - context 'when the dashboard contains a panel_group which is missing panels' do - let(:dashboard_yml) { { panel_groups: [{}] } } - - it_behaves_like 'errors with message', 'Each "panel_group" must define an array :panels' - end - end - - private - - def all_metrics - all_panels.flat_map { |panel| panel[:metrics] } - end - - def all_panels - dashboard[:panel_groups].flat_map { |group| group[:panels] } - end - - def get_metric_details(metric) - { - query_range: metric.query, - unit: metric.unit, - label: metric.legend, - metric_id: metric.id, - edit_path: edit_metric_path(metric) - } - end - - def prometheus_path(query) - Gitlab::Routing.url_helpers.prometheus_api_project_environment_path( - project, - environment, - proxy_path: :query_range, - query: query - ) - end - - def sample_metrics_path(metric) - Gitlab::Routing.url_helpers.sample_metrics_project_environment_path( - project, - environment, - identifier: metric - ) - end - - def edit_metric_path(metric) - Gitlab::Routing.url_helpers.edit_project_prometheus_metric_path( - project, - metric.id - ) end end diff --git a/spec/lib/gitlab/metrics/dashboard/stages/panel_ids_inserter_spec.rb b/spec/lib/gitlab/metrics/dashboard/stages/panel_ids_inserter_spec.rb deleted file mode 100644 index 7a3a9021f86..00000000000 --- a/spec/lib/gitlab/metrics/dashboard/stages/panel_ids_inserter_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter do - include MetricsDashboardHelpers - - let(:project) { build_stubbed(:project) } - - def fetch_panel_ids(dashboard_hash) - dashboard_hash[:panel_groups].flat_map { |group| group[:panels].flat_map { |panel| panel[:id] } } - end - - describe '#transform!' do - subject(:transform!) { described_class.new(project, dashboard, nil).transform! } - - let(:dashboard) { load_sample_dashboard.deep_symbolize_keys } - - context 'when dashboard panels are present' do - it 'assigns unique ids to each panel using PerformanceMonitoring::PrometheusPanel', :aggregate_failures do - dashboard.fetch(:panel_groups).each do |group| - group.fetch(:panels).each do |panel| - panel_double = instance_double(::PerformanceMonitoring::PrometheusPanel) - - expect(::PerformanceMonitoring::PrometheusPanel).to receive(:new).with(panel).and_return(panel_double) - expect(panel_double).to receive(:id).with(group[:group]).and_return(FFaker::Lorem.unique.characters(125)) - end - end - - transform! - - expect(fetch_panel_ids(dashboard)).not_to include nil - end - end - - context 'when dashboard panels has duplicated ids' do - it 'no panel has assigned id' do - panel_double = instance_double(::PerformanceMonitoring::PrometheusPanel) - allow(::PerformanceMonitoring::PrometheusPanel).to receive(:new).and_return(panel_double) - allow(panel_double).to receive(:id).and_return('duplicated id') - - transform! - - expect(fetch_panel_ids(dashboard)).to all be_nil - expect(fetch_panel_ids(dashboard)).not_to include 'duplicated id' - end - end - - context 'when there are no panels in the dashboard' do - it 'raises a processing error' do - dashboard[:panel_groups][0].delete(:panels) - - expect { transform! }.to( - raise_error(::Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError) - ) - end - end - - context 'when there are no panel_groups in the dashboard' do - it 'raises a processing error' do - dashboard.delete(:panel_groups) - - expect { transform! }.to( - raise_error(::Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError) - ) - end - end - - context 'when dashboard panels has unknown schema attributes' do - before do - error = ActiveModel::UnknownAttributeError.new(double, 'unknown_panel_attribute') - allow(::PerformanceMonitoring::PrometheusPanel).to receive(:new).and_raise(error) - end - - it 'no panel has assigned id' do - transform! - - expect(fetch_panel_ids(dashboard)).to all be_nil - end - - it 'logs the failure' do - expect(Gitlab::ErrorTracking).to receive(:log_exception) - - transform! - end - end - end -end |