Commit f6ac0382 authored by Nicolò Maria Mezzopera's avatar Nicolò Maria Mezzopera

Merge branch...

Merge branch '342898-add-a-drawer-to-the-merge-request-violations-compliance-report-application' into 'master'

Add the drawer to the compliance report application

See merge request gitlab-org/gitlab!76431
parents 848fe44b 7bc7d423
......@@ -2,7 +2,9 @@
import { GlTabs, GlTab } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { __ } from '~/locale';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { COMPLIANCE_TAB_COOKIE_KEY } from '../constants';
import { mapDashboardToDrawerData } from '../utils';
import MergeRequestDrawer from './drawer.vue';
import EmptyState from './empty_state.vue';
import MergeRequestsGrid from './merge_requests/grid.vue';
......@@ -41,7 +43,8 @@ export default {
data() {
return {
showDrawer: false,
drawerData: {},
drawerMergeRequest: {},
drawerProject: {},
};
},
computed: {
......@@ -51,27 +54,33 @@ export default {
hasMergeCommitsCsvExportPath() {
return this.mergeCommitsCsvExportPath !== '';
},
drawerMergeRequests() {
return this.mergeRequests.map(mapDashboardToDrawerData);
},
},
methods: {
showTabs() {
return Cookies.get(COMPLIANCE_TAB_COOKIE_KEY) === 'true';
},
toggleDrawer(mergeRequest) {
if (this.showDrawer && mergeRequest.id === this.drawerData.id) {
if (this.showDrawer && mergeRequest.id === this.drawerMergeRequest.id) {
this.closeDrawer();
} else {
this.openDrawer(mergeRequest);
this.openDrawer(this.drawerMergeRequests.find((mr) => mr.id === mergeRequest.id));
}
},
openDrawer(mergeRequest) {
openDrawer(data) {
this.showDrawer = true;
this.drawerData = mergeRequest;
this.drawerMergeRequest = data.mergeRequest;
this.drawerProject = data.project;
},
closeDrawer() {
this.showDrawer = false;
this.drawerData = {};
this.drawerMergeRequest = {};
this.drawerProject = {};
},
},
DRAWER_Z_INDEX,
strings: {
heading: __('Compliance report'),
subheading: __('Here you will find recent merge request activity'),
......@@ -113,8 +122,9 @@ export default {
/>
<merge-request-drawer
:show-drawer="showDrawer"
:merge-request="drawerData"
z-index="252"
:merge-request="drawerMergeRequest"
:project="drawerProject"
:z-index="$options.DRAWER_Z_INDEX"
@close="closeDrawer"
/>
</div>
......
<script>
import { GlDrawer } from '@gitlab/ui';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { convertArrayOfObjectsToCamelCase } from '~/lib/utils/common_utils';
import { COMPLIANCE_DRAWER_CONTAINER_CLASS } from '../constants';
import { getContentWrapperHeight } from '../../threat_monitoring/utils';
import BranchPath from './drawer_sections/branch_path.vue';
......@@ -26,6 +25,10 @@ export default {
type: Object,
required: true,
},
project: {
type: Object,
required: true,
},
showDrawer: {
type: Boolean,
required: false,
......@@ -34,20 +37,11 @@ export default {
},
computed: {
hasBranchDetails() {
return this.mergeRequest.source_branch && this.mergeRequest.target_branch;
return this.mergeRequest.sourceBranch && this.mergeRequest.targetBranch;
},
drawerHeaderHeight() {
return getContentWrapperHeight(COMPLIANCE_DRAWER_CONTAINER_CLASS);
},
committers() {
return convertArrayOfObjectsToCamelCase(this.mergeRequest.committers);
},
approvedByUsers() {
return convertArrayOfObjectsToCamelCase(this.mergeRequest.approved_by_users);
},
commenters() {
return convertArrayOfObjectsToCamelCase(this.mergeRequest.participants);
},
},
DRAWER_Z_INDEX,
};
......@@ -64,22 +58,25 @@ export default {
</template>
<template v-if="showDrawer" #default>
<project
:avatar-url="mergeRequest.project.avatar_url"
:compliance-framework="mergeRequest.compliance_management_framework"
:name="mergeRequest.project.name"
:url="mergeRequest.project.web_url"
:avatar-url="project.avatarUrl"
:compliance-framework="project.complianceFramework"
:name="project.name"
:url="project.webUrl"
/>
<reference :path="mergeRequest.path" :reference="mergeRequest.reference" />
<reference :path="mergeRequest.webUrl" :reference="mergeRequest.reference" />
<branch-path
v-if="hasBranchDetails"
:source-branch="mergeRequest.source_branch"
:source-branch-uri="mergeRequest.source_branch_uri"
:target-branch="mergeRequest.target_branch"
:target-branch-uri="mergeRequest.target_branch_uri"
:source-branch="mergeRequest.sourceBranch"
:source-branch-uri="mergeRequest.sourceBranchUri"
:target-branch="mergeRequest.targetBranch"
:target-branch-uri="mergeRequest.targetBranchUri"
/>
<committers :committers="mergeRequest.committers" />
<reviewers
:approvers="mergeRequest.approvedByUsers"
:commenters="mergeRequest.participants"
/>
<committers :committers="committers" />
<reviewers :approvers="approvedByUsers" :commenters="commenters" />
<merged-by :merged-by="mergeRequest.merged_by" />
<merged-by :merged-by="mergeRequest.mergedBy" />
</template>
</gl-drawer>
</template>
<script>
import { GlAvatarLabeled, GlAvatarLink } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import ComplianceFrameworkLabel from 'ee/vue_shared/components/compliance_framework_label/compliance_framework_label.vue';
import { __ } from '~/locale';
import { DRAWER_AVATAR_SIZE } from '../../constants';
......@@ -32,6 +33,11 @@ export default {
required: true,
},
},
computed: {
hasComplianceFramework() {
return !isEmpty(this.complianceFramework);
},
},
i18n: {
header: __('Project'),
},
......@@ -52,7 +58,7 @@ export default {
/>
</gl-avatar-link>
<compliance-framework-label
v-if="complianceFramework"
v-if="hasComplianceFramework"
class="gl-ml-3"
:name="complianceFramework.name"
:color="complianceFramework.color"
......
......@@ -4,9 +4,12 @@ import * as Sentry from '@sentry/browser';
import { __ } from '~/locale';
import { thWidthClass } from '~/lib/utils/table_utility';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import complianceViolationsQuery from '../graphql/compliance_violations.query.graphql';
import { mapViolations } from '../graphql/mappers';
import EmptyState from './empty_state.vue';
import MergeCommitsExportButton from './merge_requests/merge_commits_export_button.vue';
import MergeRequestDrawer from './drawer.vue';
import ViolationReason from './violations/reason.vue';
export default {
......@@ -17,6 +20,7 @@ export default {
GlLoadingIcon,
GlTable,
MergeCommitsExportButton,
MergeRequestDrawer,
ViolationReason,
TimeAgoTooltip,
},
......@@ -35,6 +39,9 @@ export default {
return {
queryError: false,
violations: [],
showDrawer: false,
drawerMergeRequest: {},
drawerProject: {},
};
},
apollo: {
......@@ -46,7 +53,7 @@ export default {
};
},
update(data) {
return data?.group?.mergeRequestViolations?.nodes;
return mapViolations(data?.group?.mergeRequestViolations?.nodes);
},
error(e) {
Sentry.captureException(e);
......@@ -65,6 +72,30 @@ export default {
return this.mergeCommitsCsvExportPath !== '';
},
},
methods: {
toggleDrawer(rows) {
const { id, mergeRequest, project } = rows[0] || {};
if (!mergeRequest || (this.showDrawer && id === this.drawerMergeRequest.id)) {
this.closeDrawer();
} else {
this.openDrawer(id, mergeRequest, project);
}
},
openDrawer(id, mergeRequest, project) {
this.showDrawer = true;
this.drawerMergeRequest = mergeRequest;
this.drawerProject = project;
},
closeDrawer() {
this.showDrawer = false;
// Refs are required by BTable to manipulate the selection
// issue: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1531
this.$refs.table.$children[0].clearSelected();
this.drawerMergeRequest = {};
this.drawerProject = {};
},
},
fields: [
{
key: 'severity',
......@@ -96,6 +127,7 @@ export default {
'Retrieving the compliance report failed. Please refresh the page and try again.',
),
},
DRAWER_Z_INDEX,
};
</script>
......@@ -120,11 +152,17 @@ export default {
/>
<gl-table
v-else-if="hasViolations"
ref="table"
:fields="$options.fields"
:items="violations"
head-variant="white"
stacked="lg"
select-mode="single"
selectable
hover
selected-variant="primary"
thead-class="gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
@row-selected="toggleDrawer"
>
<template #cell(reason)="{ item: { reason, violatingUser } }">
<violation-reason :reason="reason" :user="violatingUser" />
......@@ -137,5 +175,12 @@ export default {
</template>
</gl-table>
<empty-state v-else :image-path="emptyStateSvgPath" />
<merge-request-drawer
:show-drawer="showDrawer"
:merge-request="drawerMergeRequest"
:project="drawerProject"
:z-index="$options.DRAWER_Z_INDEX"
@close="closeDrawer"
/>
</section>
</template>
......@@ -59,7 +59,7 @@ query getComplianceViolations($fullPath: ID!) {
webUrl
}
}
ref: reference
reference
fullRef: reference(full: true)
sourceBranch
sourceBranchExists
......
export const mapViolations = (nodes = []) => {
return nodes.map((node) => ({
...node,
mergeRequest: {
...node.mergeRequest,
committers: node.mergeRequest.committers?.nodes || [],
approvedByUsers: node.mergeRequest.approvedBy?.nodes || [],
participants: node.mergeRequest.participants?.nodes || [],
},
project: {
...node.project,
complianceFramework: node.project?.complianceFrameworks?.nodes[0] || null,
},
}));
};
......@@ -32,7 +32,7 @@ export default {
title:
'Officiis architecto voluptas ut sit qui qui quisquam sequi consectetur porro.',
mergedAt: '2021-11-25T11:56:52.215Z',
webUrl: 'https://gdk.localhost:3443/gitlab-org/gitlab-shell/-/merge_requests/2',
webUrl: 'https://gdk.localhost:3443/gitlab-org/gitlab-shell/-/merge_requests/1',
author: {
__typename: 'Author',
id: 50,
......@@ -92,8 +92,8 @@ export default {
},
],
},
ref: 'gitlab-shell!2',
fullRef: '!2',
fullRef: 'gitlab-shell!1',
reference: '!1',
sourceBranch: 'ut-171ad4e263',
sourceBranchExists: false,
targetBranch: 'master',
......@@ -111,6 +111,104 @@ export default {
{
__typename: 'ComplianceFrameworks',
id: 1,
name: 'GDPR',
description: 'General Data Protection Regulation',
color: '#009966',
},
],
},
},
},
{
__typename: 'MergeRequestViolation',
id: 2,
severity: 2,
reason: 2,
violatingUser: {
__typename: 'Violator',
id: 50,
name: 'John Doe6',
username: 'user6',
avatarUrl:
'https://secure.gravatar.com/avatar/7ff9b8111da2e2109e7b66f37aa632cc?s=80&d=identicon',
webUrl: 'https://gdk.localhost:3443/user6',
},
mergeRequest: {
__typename: 'MergeRequest',
id: 25,
title:
'Officiis architecto voluptas ut sit qui qui quisquam sequi consectetur porro.',
mergedAt: '2021-11-25T11:56:52.215Z',
webUrl: 'https://gdk.localhost:3443/gitlab-org/gitlab-test/-/merge_requests/2',
author: {
__typename: 'Author',
id: 50,
name: 'John Doe6',
username: 'user6',
avatarUrl:
'https://secure.gravatar.com/avatar/7ff9b8111da2e2109e7b66f37aa632cc?s=80&d=identicon',
webUrl: 'https://gdk.localhost:3443/user6',
},
mergedBy: {
__typename: 'MergedBy',
id: 50,
name: 'John Doe6',
username: 'user6',
avatarUrl:
'https://secure.gravatar.com/avatar/7ff9b8111da2e2109e7b66f37aa632cc?s=80&d=identicon',
webUrl: 'https://gdk.localhost:3443/user6',
},
committers: {
__typename: 'Committers',
nodes: [],
},
participants: {
__typename: 'Participants',
nodes: [
{
__typename: 'User',
id: 50,
name: 'John Doe6',
username: 'user6',
avatarUrl:
'https://secure.gravatar.com/avatar/7ff9b8111da2e2109e7b66f37aa632cc?s=80&d=identicon',
webUrl: 'https://gdk.localhost:3443/user6',
},
],
},
approvedBy: {
__typename: 'ApprovedBy',
nodes: [
{
__typename: 'User',
id: 49,
name: 'John Doe5',
username: 'user5',
avatarUrl:
'https://secure.gravatar.com/avatar/eaafc9b0f704edaf23cd5cf7727df560?s=80&d=identicon',
webUrl: 'https://gdk.localhost:3443/user5',
},
],
},
fullRef: 'gitlab-test!2',
reference: '!2',
sourceBranch: 'ut-171ad4e264',
sourceBranchExists: false,
targetBranch: 'master',
targetBranchExists: true,
},
project: {
__typename: 'Project',
id: 2,
avatarUrl: null,
name: 'Gitlab Test',
webUrl: 'https://gdk.localhost:3443/gitlab-org/gitlab-test',
complianceFrameworks: {
__typename: 'ComplianceFrameworks',
nodes: [
{
__typename: 'ComplianceFrameworks',
id: 2,
name: 'SOX',
description: 'A framework',
color: '#00FF00',
......
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
export const mapDashboardToDrawerData = (mergeRequest) => ({
id: mergeRequest.id,
mergeRequest: {
...convertObjectPropsToCamelCase(mergeRequest, { deep: true }),
webUrl: mergeRequest.path,
},
project: {
...convertObjectPropsToCamelCase(mergeRequest.project, { deep: true }),
complianceFramework: convertObjectPropsToCamelCase(
mergeRequest.compliance_management_framework,
),
},
});
......@@ -46,6 +46,7 @@ exports[`ComplianceDashboard component when there are merge requests and the sho
<merge-request-drawer-stub
mergerequest="[object Object]"
project="[object Object]"
z-index="252"
/>
</div>
......@@ -81,6 +82,7 @@ exports[`ComplianceDashboard component when there are merge requests matches the
<merge-request-drawer-stub
mergerequest="[object Object]"
project="[object Object]"
z-index="252"
/>
</div>
......
......@@ -7,6 +7,7 @@ import MergeRequestDrawer from 'ee/compliance_dashboard/components/drawer.vue';
import MergeRequestGrid from 'ee/compliance_dashboard/components/merge_requests/grid.vue';
import MergeCommitsExportButton from 'ee/compliance_dashboard/components/merge_requests/merge_commits_export_button.vue';
import { COMPLIANCE_TAB_COOKIE_KEY } from 'ee/compliance_dashboard/constants';
import { mapDashboardToDrawerData } from 'ee/compliance_dashboard/utils';
import { createMergeRequests } from '../mock_data';
describe('ComplianceDashboard component', () => {
......@@ -109,23 +110,29 @@ describe('ComplianceDashboard component', () => {
});
});
describe('with the merge requests drawer', () => {
describe('with the merge request drawer', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('opens the drawer', async () => {
const drawerData = mapDashboardToDrawerData(mergeRequests[0]);
await findMergeRequestsGrid().vm.$emit('toggleDrawer', mergeRequests[0]);
expect(findMergeRequestsDrawer().props('showDrawer')).toBe(true);
expect(findMergeRequestsDrawer().props('mergeRequest')).toStrictEqual(mergeRequests[0]);
expect(findMergeRequestsDrawer().props('mergeRequest')).toStrictEqual(
drawerData.mergeRequest,
);
expect(findMergeRequestsDrawer().props('project')).toStrictEqual(drawerData.project);
});
it('closes the drawer via the drawer close event', async () => {
await findMergeRequestsDrawer().vm.$emit('close');
expect(findMergeRequestsDrawer().props('showDrawer')).toBe(false);
expect(findMergeRequestsDrawer().props('mergeRequest')).toEqual({});
expect(findMergeRequestsDrawer().props('mergeRequest')).toStrictEqual({});
expect(findMergeRequestsDrawer().props('project')).toStrictEqual({});
});
it('closes the drawer via the grid toggle event', async () => {
......@@ -133,15 +140,21 @@ describe('ComplianceDashboard component', () => {
await findMergeRequestsGrid().vm.$emit('toggleDrawer', mergeRequests[0]);
expect(findMergeRequestsDrawer().props('showDrawer')).toBe(false);
expect(findMergeRequestsDrawer().props('mergeRequest')).toEqual({});
expect(findMergeRequestsDrawer().props('mergeRequest')).toStrictEqual({});
expect(findMergeRequestsDrawer().props('project')).toStrictEqual({});
});
it('swaps the drawer when a new merge request is selected', async () => {
const drawerData = mapDashboardToDrawerData(mergeRequests[1]);
await findMergeRequestsGrid().vm.$emit('toggleDrawer', mergeRequests[0]);
await findMergeRequestsGrid().vm.$emit('toggleDrawer', mergeRequests[1]);
expect(findMergeRequestsDrawer().props('showDrawer')).toBe(true);
expect(findMergeRequestsDrawer().props('mergeRequest')).toStrictEqual(mergeRequests[1]);
expect(findMergeRequestsDrawer().props('mergeRequest')).toStrictEqual(
drawerData.mergeRequest,
);
expect(findMergeRequestsDrawer().props('project')).toStrictEqual(drawerData.project);
});
});
});
......@@ -21,6 +21,7 @@ describe('Project component', () => {
propsData: {
name: projectName,
url,
complianceFramework: {},
...props,
},
});
......
import { GlDrawer } from '@gitlab/ui';
import { convertArrayOfObjectsToCamelCase } from '~/lib/utils/common_utils';
import MergeRequestDrawer from 'ee/compliance_dashboard/components/drawer.vue';
import BranchPath from 'ee/compliance_dashboard/components/drawer_sections/branch_path.vue';
import Committers from 'ee/compliance_dashboard/components/drawer_sections/committers.vue';
......@@ -7,10 +6,11 @@ import MergedBy from 'ee/compliance_dashboard/components/drawer_sections/merged_
import Project from 'ee/compliance_dashboard/components/drawer_sections/project.vue';
import Reference from 'ee/compliance_dashboard/components/drawer_sections/reference.vue';
import Reviewers from 'ee/compliance_dashboard/components/drawer_sections/reviewers.vue';
import { complianceFramework } from 'ee_jest/vue_shared/components/compliance_framework_label/mock_data';
import { getContentWrapperHeight } from 'ee/threat_monitoring/utils';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createApprovers, createMergeRequests } from '../mock_data';
import resolvers from 'ee/compliance_dashboard/graphql/resolvers';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { mapViolations } from 'ee/compliance_dashboard/graphql/mappers';
jest.mock('ee/threat_monitoring/utils', () => ({
getContentWrapperHeight: jest.fn(),
......@@ -18,15 +18,18 @@ jest.mock('ee/threat_monitoring/utils', () => ({
describe('MergeRequestDrawer component', () => {
let wrapper;
const mergeRequest = createMergeRequests({
count: 1,
props: {
compliance_management_framework: complianceFramework,
committers: createApprovers(3),
approved_by_users: createApprovers(2),
participants: createApprovers(3),
const defaultData = mapViolations(resolvers.Query.group().mergeRequestViolations.nodes)[0];
const data = {
id: defaultData.id,
mergeRequest: {
...defaultData.mergeRequest,
sourceBranch: null,
sourceBranchUri: null,
targetBranch: null,
targetBranchUri: null,
},
})[0];
project: defaultData.project,
};
const findTitle = () => wrapper.findByTestId('dashboard-drawer-title');
const findDrawer = () => wrapper.findComponent(GlDrawer);
......@@ -40,7 +43,8 @@ describe('MergeRequestDrawer component', () => {
const createComponent = (props) => {
return shallowMountExtended(MergeRequestDrawer, {
propsData: {
mergeRequest,
mergeRequest: data.mergeRequest,
project: data.project,
...props,
},
});
......@@ -61,7 +65,7 @@ describe('MergeRequestDrawer component', () => {
it('configures the drawer with header height and z-index', () => {
expect(findDrawer().props()).toMatchObject({
headerHeight: mockHeaderHeight,
zIndex: 252,
zIndex: DRAWER_Z_INDEX,
});
});
});
......@@ -90,22 +94,22 @@ describe('MergeRequestDrawer component', () => {
});
it('has the drawer title', () => {
expect(findTitle().text()).toEqual(mergeRequest.title);
expect(findTitle().text()).toEqual(data.mergeRequest.title);
});
it('has the project section', () => {
expect(findProject().props()).toStrictEqual({
avatarUrl: mergeRequest.project.avatar_url,
complianceFramework,
name: mergeRequest.project.name,
url: mergeRequest.project.web_url,
avatarUrl: data.project.avatarUrl,
complianceFramework: data.project.complianceFramework,
name: data.project.name,
url: data.project.webUrl,
});
});
it('has the reference section', () => {
expect(findReference().props()).toStrictEqual({
path: mergeRequest.path,
reference: mergeRequest.reference,
path: data.mergeRequest.webUrl,
reference: data.mergeRequest.reference,
});
});
......@@ -115,20 +119,20 @@ describe('MergeRequestDrawer component', () => {
it('has the committers section with users array converted to camel case', () => {
expect(findCommitters().props()).toStrictEqual({
committers: convertArrayOfObjectsToCamelCase(mergeRequest.committers),
committers: data.mergeRequest.committers,
});
});
it('has the reviewers section with users array converted to camel case', () => {
expect(findReviewers().props()).toStrictEqual({
approvers: convertArrayOfObjectsToCamelCase(mergeRequest.approved_by_users),
commenters: convertArrayOfObjectsToCamelCase(mergeRequest.participants),
approvers: data.mergeRequest.approvedByUsers,
commenters: data.mergeRequest.participants,
});
});
it('has the merged by section', () => {
expect(findMergedBy().props()).toStrictEqual({
mergedBy: mergeRequest.merged_by,
mergedBy: data.mergeRequest.mergedBy,
});
});
});
......@@ -143,11 +147,11 @@ describe('MergeRequestDrawer component', () => {
wrapper = createComponent({
showDrawer: true,
mergeRequest: {
...mergeRequest,
source_branch: sourceBranch,
source_branch_uri: sourceBranchUri,
target_branch: targetBranch,
target_branch_uri: targetBranchUri,
...data.mergeRequest,
sourceBranch,
sourceBranchUri,
targetBranch,
targetBranchUri,
},
});
});
......
import { GlAlert, GlLoadingIcon, GlTable } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import * as Sentry from '@sentry/browser';
import ComplianceReport from 'ee/compliance_dashboard/components/report.vue';
import EmptyState from 'ee/compliance_dashboard/components/empty_state.vue';
import MergeRequestDrawer from 'ee/compliance_dashboard/components/drawer.vue';
import MergeCommitsExportButton from 'ee/compliance_dashboard/components/merge_requests/merge_commits_export_button.vue';
import ViolationReason from 'ee/compliance_dashboard/components/violations/reason.vue';
import resolvers from 'ee/compliance_dashboard/graphql/resolvers';
import { mapViolations } from 'ee/compliance_dashboard/graphql/mappers';
import { stripTypenames } from 'helpers/graphql_helpers';
import waitForPromises from 'helpers/wait_for_promises';
import createMockApollo from 'helpers/mock_apollo_helper';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
......@@ -25,6 +28,7 @@ describe('ComplianceReport component', () => {
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findErrorMessage = () => wrapper.findComponent(GlAlert);
const findViolationsTable = () => wrapper.findComponent(GlTable);
const findMergeRequestDrawer = () => wrapper.findComponent(MergeRequestDrawer);
const findEmptyState = () => wrapper.findComponent(EmptyState);
const findMergeCommitsExportButton = () => wrapper.findComponent(MergeCommitsExportButton);
const findViolationReason = () => wrapper.findComponent(ViolationReason);
......@@ -33,6 +37,12 @@ describe('ComplianceReport component', () => {
const findTableHeaders = () => findViolationsTable().findAll('th');
const findTablesFirstRowData = () =>
findViolationsTable().findAll('tbody > tr').at(0).findAll('td');
const findSelectedRows = () => findViolationsTable().findAll('tr.b-table-row-selected');
const selectRow = async (idx) => {
await findViolationsTable().findAll('tbody > tr').at(idx).trigger('click');
await nextTick();
};
function createMockApolloProvider() {
return createMockApollo([], { Query: { group: mockResolver } });
......@@ -144,6 +154,61 @@ describe('ComplianceReport component', () => {
expect(findTimeAgoTooltip().props('time')).toBe(mergedAt);
});
describe('with the merge request drawer', () => {
it('opens the drawer', async () => {
const drawerData = mapViolations(mockResolver().mergeRequestViolations.nodes)[0];
await selectRow(0);
expect(findMergeRequestDrawer().props('showDrawer')).toBe(true);
expect(findMergeRequestDrawer().props('mergeRequest')).toStrictEqual(
stripTypenames(drawerData.mergeRequest),
);
expect(findMergeRequestDrawer().props('project')).toStrictEqual(
stripTypenames(drawerData.project),
);
});
it('closes the drawer via the drawer close event', async () => {
await selectRow(0);
expect(findSelectedRows()).toHaveLength(1);
await findMergeRequestDrawer().vm.$emit('close');
expect(findMergeRequestDrawer().props('showDrawer')).toBe(false);
expect(findSelectedRows()).toHaveLength(0);
expect(findMergeRequestDrawer().props('mergeRequest')).toStrictEqual({});
expect(findMergeRequestDrawer().props('project')).toStrictEqual({});
});
it('closes the drawer via the row-selected event', async () => {
await selectRow(0);
expect(findSelectedRows()).toHaveLength(1);
await selectRow(0);
expect(findMergeRequestDrawer().props('showDrawer')).toBe(false);
expect(findMergeRequestDrawer().props('mergeRequest')).toStrictEqual({});
expect(findMergeRequestDrawer().props('project')).toStrictEqual({});
});
it('swaps the drawer when a new row is selected', async () => {
const drawerData = mapViolations(mockResolver().mergeRequestViolations.nodes)[1];
await selectRow(0);
await selectRow(1);
expect(findMergeRequestDrawer().props('showDrawer')).toBe(true);
expect(findMergeRequestDrawer().props('mergeRequest')).toStrictEqual(
stripTypenames(drawerData.mergeRequest),
);
expect(findMergeRequestDrawer().props('project')).toStrictEqual(
stripTypenames(drawerData.project),
);
});
});
});
describe('when there are no violations', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment