diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-28 09:15:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-28 09:15:42 +0300 |
commit | 66d107f9394f719c63cb30f53d62b5b5db888e4b (patch) | |
tree | 0c0df62dcf91fdd2509e0428a1808f237d22ee18 /spec/frontend/admin | |
parent | 9449a8c94313cd1cbe1c4cad885635aa7e3f6c01 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/admin')
3 files changed, 183 insertions, 0 deletions
diff --git a/spec/frontend/admin/abuse_reports/components/abuse_report_actions_spec.js b/spec/frontend/admin/abuse_reports/components/abuse_report_actions_spec.js new file mode 100644 index 00000000000..b9db78a0452 --- /dev/null +++ b/spec/frontend/admin/abuse_reports/components/abuse_report_actions_spec.js @@ -0,0 +1,166 @@ +import { mount, shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import axios from 'axios'; +import MockAdapter from 'axios-mock-adapter'; +import { GlButton, GlModal } from '@gitlab/ui'; +import AbuseReportActions from '~/admin/abuse_reports/components/abuse_report_actions.vue'; +import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; +import { HTTP_STATUS_OK } from '~/lib/utils/http_status'; +import { createAlert, VARIANT_SUCCESS } from '~/alert'; +import { sprintf } from '~/locale'; +import { ACTIONS_I18N } from '~/admin/abuse_reports/constants'; +import { mockAbuseReports } from '../mock_data'; + +jest.mock('~/alert'); + +describe('AbuseReportActions', () => { + let wrapper; + + const findRemoveUserAndReportButton = () => wrapper.findAllComponents(GlButton).at(0); + const findBlockUserButton = () => wrapper.findAllComponents(GlButton).at(1); + const findRemoveReportButton = () => wrapper.findAllComponents(GlButton).at(2); + const findConfirmationModal = () => wrapper.findComponent(GlModal); + + const report = mockAbuseReports[0]; + + const createComponent = ({ props, mountFn } = { props: {}, mountFn: mount }) => { + wrapper = mountFn(AbuseReportActions, { + propsData: { + report, + ...props, + }, + }); + }; + const createShallowComponent = (props) => createComponent({ props, mountFn: shallowMount }); + + describe('default', () => { + beforeEach(() => { + createShallowComponent(); + }); + + it('displays "Block user", "Remove user & report", and "Remove report" buttons', () => { + expect(findRemoveUserAndReportButton().text()).toBe(ACTIONS_I18N.removeUserAndReport); + + const blockButton = findBlockUserButton(); + expect(blockButton.text()).toBe(ACTIONS_I18N.blockUser); + expect(blockButton.attributes('disabled')).toBeUndefined(); + + expect(findRemoveReportButton().text()).toBe(ACTIONS_I18N.removeReport); + }); + + it('does not show the confirmation modal initially', () => { + expect(findConfirmationModal().props('visible')).toBe(false); + }); + }); + + describe('block button when user is already blocked', () => { + it('is disabled and has the correct text', () => { + createShallowComponent({ report: { ...report, userBlocked: true } }); + + const button = findBlockUserButton(); + expect(button.text()).toBe(ACTIONS_I18N.alreadyBlocked); + expect(button.attributes('disabled')).toBe('true'); + }); + }); + + describe('actions', () => { + let axiosMock; + + useMockLocationHelper(); + + beforeEach(() => { + axiosMock = new MockAdapter(axios); + + createComponent(); + }); + + afterEach(() => { + axiosMock.restore(); + createAlert.mockClear(); + }); + + describe('on remove user and report', () => { + it('shows confirmation modal and reloads the page on success', async () => { + findRemoveUserAndReportButton().trigger('click'); + await nextTick(); + + expect(findConfirmationModal().props()).toMatchObject({ + visible: true, + title: sprintf(ACTIONS_I18N.removeUserAndReportConfirm, { + user: report.reportedUser.name, + }), + }); + + axiosMock.onDelete(report.removeUserAndReportPath).reply(HTTP_STATUS_OK); + + findConfirmationModal().vm.$emit('primary'); + await axios.waitForAll(); + + expect(window.location.reload).toHaveBeenCalled(); + }); + }); + + describe('on block user', () => { + beforeEach(async () => { + findBlockUserButton().trigger('click'); + await nextTick(); + }); + + it('shows confirmation modal', () => { + expect(findConfirmationModal().props()).toMatchObject({ + visible: true, + title: ACTIONS_I18N.blockUserConfirm, + }); + }); + + describe.each([ + { + responseData: { notice: 'Notice' }, + createAlertArgs: { message: 'Notice', variant: VARIANT_SUCCESS }, + blockButtonText: ACTIONS_I18N.alreadyBlocked, + blockButtonDisabled: 'disabled', + }, + { + responseData: { error: 'Error' }, + createAlertArgs: { message: 'Error' }, + blockButtonText: ACTIONS_I18N.blockUser, + blockButtonDisabled: undefined, + }, + ])( + 'when reponse JSON is $responseData', + ({ responseData, createAlertArgs, blockButtonText, blockButtonDisabled }) => { + beforeEach(async () => { + axiosMock.onPut(report.blockUserPath).reply(HTTP_STATUS_OK, responseData); + + findConfirmationModal().vm.$emit('primary'); + await axios.waitForAll(); + }); + + it('updates the block button correctly', async () => { + const button = findBlockUserButton(); + expect(button.text()).toBe(blockButtonText); + expect(button.attributes('disabled')).toBe(blockButtonDisabled); + }); + + it('displays the returned message', async () => { + expect(createAlert).toHaveBeenCalledWith(createAlertArgs); + }); + }, + ); + }); + + describe('on remove report', () => { + it('reloads the page on success', async () => { + axiosMock.onDelete(report.removeReportPath).reply(HTTP_STATUS_OK); + + findRemoveReportButton().trigger('click'); + + expect(findConfirmationModal().props('visible')).toBe(false); + + await axios.waitForAll(); + + expect(window.location.reload).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/spec/frontend/admin/abuse_reports/components/abuse_report_row_spec.js b/spec/frontend/admin/abuse_reports/components/abuse_report_row_spec.js index 5a2bcad232e..599d52227c1 100644 --- a/spec/frontend/admin/abuse_reports/components/abuse_report_row_spec.js +++ b/spec/frontend/admin/abuse_reports/components/abuse_report_row_spec.js @@ -1,6 +1,7 @@ import { GlSprintf, GlLink } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import AbuseReportRow from '~/admin/abuse_reports/components/abuse_report_row.vue'; +import AbuseReportActions from '~/admin/abuse_reports/components/abuse_report_actions.vue'; import ListItem from '~/vue_shared/components/registry/list_item.vue'; import { getTimeago } from '~/lib/utils/datetime_utility'; import { mockAbuseReports } from '../mock_data'; @@ -10,6 +11,7 @@ describe('AbuseReportRow', () => { const mockAbuseReport = mockAbuseReports[0]; const findLinks = () => wrapper.findAllComponents(GlLink); + const findAbuseReportActions = () => wrapper.findComponent(AbuseReportActions); const findListItem = () => wrapper.findComponent(ListItem); const findTitle = () => wrapper.findByTestId('title'); const findUpdatedAt = () => wrapper.findByTestId('updated-at'); @@ -51,4 +53,11 @@ describe('AbuseReportRow', () => { `Updated ${getTimeago().format(mockAbuseReport.updatedAt)}`, ); }); + + it('renders AbuseReportRowActions with the correct props', () => { + const actions = findAbuseReportActions(); + + expect(actions.exists()).toBe(true); + expect(actions.props('report')).toMatchObject(mockAbuseReport); + }); }); diff --git a/spec/frontend/admin/abuse_reports/mock_data.js b/spec/frontend/admin/abuse_reports/mock_data.js index 5659aa3f223..92e50ad6c7e 100644 --- a/spec/frontend/admin/abuse_reports/mock_data.js +++ b/spec/frontend/admin/abuse_reports/mock_data.js @@ -6,6 +6,10 @@ export const mockAbuseReports = [ reportedUser: { name: 'Mr. Abuser' }, reportedUserPath: '/mr_abuser', reporterPath: '/admin', + userBlocked: false, + blockUserPath: '/block/user/mr_abuser/path', + removeUserAndReportPath: '/remove/user/mr_abuser/and/report/path', + removeReportPath: '/remove/report/path', }, { category: 'phishing', @@ -14,5 +18,9 @@ export const mockAbuseReports = [ reportedUser: { name: 'Mr. Phisher' }, reportedUserPath: '/mr_phisher', reporterPath: '/admin', + userBlocked: false, + blockUserPath: '/block/user/mr_phisher/path', + removeUserAndReportPath: '/remove/user/mr_phisher/and/report/path', + removeReportPath: '/remove/report/path', }, ]; |