Commit 1bff42e4 authored by Phil Hughes's avatar Phil Hughes

Add widget extension mock test

Adds a test to render a mock extension to the merge request widget
to allow us to actually test that what we want gets rendered.
parent 6bf44358
...@@ -100,7 +100,7 @@ export default { ...@@ -100,7 +100,7 @@ export default {
</script> </script>
<template> <template>
<section class="media-section mr-widget-border-top"> <section class="media-section mr-widget-border-top" data-testid="widget-extension">
<div class="media gl-p-5"> <div class="media gl-p-5">
<status-icon :status="statusIconName" class="align-self-center" /> <status-icon :status="statusIconName" class="align-self-center" />
<div class="media-body d-flex flex-align-self-center align-items-center"> <div class="media-body d-flex flex-align-self-center align-items-center">
...@@ -114,13 +114,18 @@ export default { ...@@ -114,13 +114,18 @@ export default {
v-if="isCollapsible" v-if="isCollapsible"
size="small" size="small"
class="float-right align-self-center" class="float-right align-self-center"
data-testid="toggle-button"
@click="toggleCollapsed" @click="toggleCollapsed"
> >
{{ isCollapsed ? __('Expand') : __('Collapse') }} {{ isCollapsed ? __('Expand') : __('Collapse') }}
</gl-button> </gl-button>
</div> </div>
</div> </div>
<div v-if="!isCollapsed" class="mr-widget-grouped-section"> <div
v-if="!isCollapsed"
class="mr-widget-grouped-section"
data-testid="widget-extension-collapsed-section"
>
<div v-if="isLoadingExpanded" class="report-block-container"> <div v-if="isLoadingExpanded" class="report-block-container">
<gl-loading-icon size="sm" inline /> {{ __('Loading...') }} <gl-loading-icon size="sm" inline /> {{ __('Loading...') }}
</div> </div>
......
import { extensions } from './index'; import { registeredExtensions } from './index';
export default { export default {
props: { props: {
...@@ -8,6 +8,8 @@ export default { ...@@ -8,6 +8,8 @@ export default {
}, },
}, },
render(h) { render(h) {
const { extensions } = registeredExtensions;
if (extensions.length === 0) return null; if (extensions.length === 0) return null;
return h('div', {}, [ return h('div', {}, [
......
import Vue from 'vue';
import ExtensionBase from './base.vue'; import ExtensionBase from './base.vue';
// Holds all the currently registered extensions // Holds all the currently registered extensions
export const extensions = []; export const registeredExtensions = Vue.observable({ extensions: [] });
export const registerExtension = (extension) => { export const registerExtension = (extension) => {
// Pushes into the extenions array a dynamically created Vue component // Pushes into the extenions array a dynamically created Vue component
// that gets exteneded from `base.vue` // that gets exteneded from `base.vue`
extensions.push({ registeredExtensions.extensions.push({
extends: ExtensionBase, extends: ExtensionBase,
name: extension.name, name: extension.name,
props: extension.props, props: extension.props,
......
import { registerExtension, extensions } from '~/vue_merge_request_widget/components/extensions'; import {
registerExtension,
registeredExtensions,
} from '~/vue_merge_request_widget/components/extensions';
import ExtensionBase from '~/vue_merge_request_widget/components/extensions/base.vue'; import ExtensionBase from '~/vue_merge_request_widget/components/extensions/base.vue';
describe('MR widget extension registering', () => { describe('MR widget extension registering', () => {
...@@ -14,7 +17,7 @@ describe('MR widget extension registering', () => { ...@@ -14,7 +17,7 @@ describe('MR widget extension registering', () => {
}, },
}); });
expect(extensions[0]).toEqual( expect(registeredExtensions.extensions[0]).toEqual(
expect.objectContaining({ expect.objectContaining({
extends: ExtensionBase, extends: ExtensionBase,
name: 'Test', name: 'Test',
......
import { GlBadge, GlLink, GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue'; import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { securityReportMergeRequestDownloadPathsQueryResponse } from 'jest/vue_shared/security_reports/mock_data'; import { securityReportMergeRequestDownloadPathsQueryResponse } from 'jest/vue_shared/security_reports/mock_data';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { setFaviconOverlay } from '~/lib/utils/favicon'; import { setFaviconOverlay } from '~/lib/utils/favicon';
import notify from '~/lib/utils/notify'; import notify from '~/lib/utils/notify';
import SmartInterval from '~/smart_interval'; import SmartInterval from '~/smart_interval';
import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants'; import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants';
import eventHub from '~/vue_merge_request_widget/event_hub'; import eventHub from '~/vue_merge_request_widget/event_hub';
import MrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue'; import MrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue';
...@@ -15,6 +18,7 @@ import { stateKey } from '~/vue_merge_request_widget/stores/state_maps'; ...@@ -15,6 +18,7 @@ import { stateKey } from '~/vue_merge_request_widget/stores/state_maps';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql'; import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql';
import { faviconDataUrl, overlayDataUrl } from '../lib/utils/mock_data'; import { faviconDataUrl, overlayDataUrl } from '../lib/utils/mock_data';
import mockData from './mock_data'; import mockData from './mock_data';
import testExtension from './test_extension';
jest.mock('~/smart_interval'); jest.mock('~/smart_interval');
...@@ -879,4 +883,46 @@ describe('MrWidgetOptions', () => { ...@@ -879,4 +883,46 @@ describe('MrWidgetOptions', () => {
}); });
}); });
}); });
describe('mock extension', () => {
beforeEach(() => {
createComponent();
});
it('renders collapsed data', async () => {
registerExtension(testExtension);
await waitForPromises();
expect(wrapper.text()).toContain('Test extension summary count: 1');
});
it('renders full data', async () => {
registerExtension(testExtension);
await waitForPromises();
wrapper
.find('[data-testid="widget-extension"] [data-testid="toggle-button"]')
.trigger('click');
await Vue.nextTick();
const collapsedSection = wrapper.find('[data-testid="widget-extension-collapsed-section"]');
expect(collapsedSection.exists()).toBe(true);
expect(collapsedSection.text()).toContain('Hello world');
// Renders icon in the row
expect(collapsedSection.find(GlIcon).exists()).toBe(true);
expect(collapsedSection.find(GlIcon).props('name')).toBe('status_failed_borderless');
// Renders badge in the row
expect(collapsedSection.find(GlBadge).exists()).toBe(true);
expect(collapsedSection.find(GlBadge).text()).toBe('Closed');
// Renders a link in the row
expect(collapsedSection.find(GlLink).exists()).toBe(true);
expect(collapsedSection.find(GlLink).text()).toBe('GitLab.com');
});
});
}); });
export default {
name: 'WidgetTestExtension',
props: ['targetProjectFullPath'],
computed: {
summary({ count, targetProjectFullPath }) {
return `Test extension summary count: ${count} & ${targetProjectFullPath}`;
},
statusIcon({ count }) {
return count > 0 ? 'warning' : 'success';
},
},
methods: {
fetchCollapsedData({ targetProjectFullPath }) {
return Promise.resolve({ targetProjectFullPath, count: 1 });
},
fetchFullData() {
return Promise.resolve([
{
id: 1,
text: 'Hello world',
icon: {
name: 'status_failed_borderless',
class: 'text-danger',
},
badge: {
text: 'Closed',
},
link: {
href: 'https://gitlab.com',
text: 'GitLab.com',
},
},
]);
},
},
};
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