Commit c163dae4 authored by Coung Ngo's avatar Coung Ngo Committed by Kushal Pandya

Add ability to initiate import of Jira project

Added ability to initiate import of Jira project
in a project on the frontend
parent 93d29d34
<script>
import getJiraProjects from '../queries/getJiraProjects.query.graphql';
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import getJiraImportDetailsQuery from '../queries/get_jira_import_details.query.graphql';
import initiateJiraImportMutation from '../queries/initiate_jira_import.mutation.graphql';
import { IMPORT_STATE, isInProgress } from '../utils';
import JiraImportForm from './jira_import_form.vue';
import JiraImportProgress from './jira_import_progress.vue';
import JiraImportSetup from './jira_import_setup.vue';
export default {
name: 'JiraImportApp',
components: {
GlAlert,
GlLoadingIcon,
JiraImportForm,
JiraImportProgress,
JiraImportSetup,
},
props: {
......@@ -14,6 +22,18 @@ export default {
type: Boolean,
required: true,
},
inProgressIllustration: {
type: String,
required: true,
},
issuesPath: {
type: String,
required: true,
},
jiraProjects: {
type: Array,
required: true,
},
projectPath: {
type: String,
required: true,
......@@ -23,26 +43,111 @@ export default {
required: true,
},
},
data() {
return {
errorMessage: '',
showAlert: false,
};
},
apollo: {
getJiraImports: {
query: getJiraProjects,
jiraImportDetails: {
query: getJiraImportDetailsQuery,
variables() {
return {
fullPath: this.projectPath,
};
},
update: data => data.project.jiraImports,
update: ({ project }) => ({
status: project.jiraImportStatus,
import: project.jiraImports.nodes[0],
}),
skip() {
return !this.isJiraConfigured;
},
},
},
computed: {
isImportInProgress() {
return isInProgress(this.jiraImportDetails?.status);
},
jiraProjectsOptions() {
return this.jiraProjects.map(([text, value]) => ({ text, value }));
},
},
methods: {
dismissAlert() {
this.showAlert = false;
},
initiateJiraImport(project) {
this.$apollo
.mutate({
mutation: initiateJiraImportMutation,
variables: {
input: {
projectPath: this.projectPath,
jiraProjectKey: project,
},
},
update: (store, { data }) => {
if (data.jiraImportStart.errors.length) {
return;
}
store.writeQuery({
query: getJiraImportDetailsQuery,
variables: {
fullPath: this.projectPath,
},
data: {
project: {
jiraImportStatus: IMPORT_STATE.SCHEDULED,
jiraImports: {
nodes: [data.jiraImportStart.jiraImport],
__typename: 'JiraImportConnection',
},
// eslint-disable-next-line @gitlab/require-i18n-strings
__typename: 'Project',
},
},
});
},
})
.then(({ data }) => {
if (data.jiraImportStart.errors.length) {
this.setAlertMessage(data.jiraImportStart.errors.join('. '));
}
})
.catch(() => this.setAlertMessage(__('There was an error importing the Jira project.')));
},
setAlertMessage(message) {
this.errorMessage = message;
this.showAlert = true;
},
},
};
</script>
<template>
<div>
<gl-alert v-if="showAlert" variant="danger" @dismiss="dismissAlert">
{{ errorMessage }}
</gl-alert>
<jira-import-setup v-if="!isJiraConfigured" :illustration="setupIllustration" />
<jira-import-form v-else />
<gl-loading-icon v-else-if="$apollo.loading" size="md" class="mt-3" />
<jira-import-progress
v-else-if="isImportInProgress"
:illustration="inProgressIllustration"
:import-initiator="jiraImportDetails.import.scheduledBy.name"
:import-project="jiraImportDetails.import.jiraProjectKey"
:import-time="jiraImportDetails.import.scheduledAt"
:issues-path="issuesPath"
/>
<jira-import-form
v-else
:issues-path="issuesPath"
:jira-projects="jiraProjectsOptions"
@initiateJiraImport="initiateJiraImport"
/>
</div>
</template>
......@@ -12,6 +12,39 @@ export default {
},
currentUserAvatarUrl: gon.current_user_avatar_url,
currentUsername: gon.current_username,
props: {
issuesPath: {
type: String,
required: true,
},
jiraProjects: {
type: Array,
required: true,
},
},
data() {
return {
selectedOption: null,
selectState: null,
};
},
methods: {
initiateJiraImport(event) {
event.preventDefault();
if (!this.selectedOption) {
this.showValidationError();
} else {
this.hideValidationError();
this.$emit('initiateJiraImport', this.selectedOption);
}
},
hideValidationError() {
this.selectState = null;
},
showValidationError() {
this.selectState = false;
},
},
};
</script>
......@@ -19,14 +52,21 @@ export default {
<div>
<h3 class="page-title">{{ __('New Jira import') }}</h3>
<hr />
<form>
<form @submit="initiateJiraImport">
<gl-form-group
class="row align-items-center"
:invalid-feedback="__('Please select a Jira project')"
:label="__('Import from')"
label-cols-sm="2"
label-for="jira-project-select"
>
<gl-form-select id="jira-project-select" class="mb-2" />
<gl-form-select
id="jira-project-select"
v-model="selectedOption"
class="mb-2"
:options="jiraProjects"
:state="selectState"
/>
</gl-form-group>
<gl-form-group
......@@ -86,8 +126,10 @@ export default {
</gl-form-group>
<div class="footer-block row-content-block d-flex justify-content-between">
<gl-button category="primary" variant="success">{{ __('Next') }}</gl-button>
<gl-button>{{ __('Cancel') }}</gl-button>
<gl-button type="submit" category="primary" variant="success" class="js-no-auto-disable">
{{ __('Next') }}
</gl-button>
<gl-button :href="issuesPath">{{ __('Cancel') }}</gl-button>
</div>
</form>
</div>
......
<script>
import { GlEmptyState } from '@gitlab/ui';
import { formatDate } from '~/lib/utils/datetime_utility';
import { __, sprintf } from '~/locale';
export default {
name: 'JiraImportProgress',
components: {
GlEmptyState,
},
props: {
illustration: {
type: String,
required: true,
},
importInitiator: {
type: String,
required: true,
},
importProject: {
type: String,
required: true,
},
importTime: {
type: String,
required: true,
},
issuesPath: {
type: String,
required: true,
},
},
computed: {
importInitiatorText() {
return sprintf(__('Import started by: %{importInitiator}'), {
importInitiator: this.importInitiator,
});
},
importProjectText() {
return sprintf(__('Jira project: %{importProject}'), {
importProject: this.importProject,
});
},
importTimeText() {
return sprintf(__('Time of import: %{importTime}'), {
importTime: formatDate(this.importTime),
});
},
},
};
</script>
<template>
<gl-empty-state
:svg-path="illustration"
:title="__('Import in progress')"
:primary-button-text="__('View issues')"
:primary-button-link="issuesPath"
>
<template #description>
<p class="mb-0">{{ importInitiatorText }}</p>
<p class="mb-0">{{ importTimeText }}</p>
<p class="mb-0">{{ importProjectText }}</p>
</template>
</gl-empty-state>
</template>
<script>
import { GlEmptyState } from '@gitlab/ui';
export default {
name: 'JiraImportSetup',
components: {
GlEmptyState,
},
props: {
illustration: {
type: String,
......@@ -11,15 +16,11 @@ export default {
</script>
<template>
<div class="empty-state">
<div class="svg-content">
<img :src="illustration" :alt="__('Set up Jira Integration illustration')" />
</div>
<div class="text-content d-flex flex-column align-items-center">
<p>{{ __('You will first need to set up Jira Integration to use this feature.') }}</p>
<a class="btn btn-success" href="../services/jira/edit">
{{ __('Set up Jira Integration') }}
</a>
</div>
</div>
<gl-empty-state
:svg-path="illustration"
title=""
:description="__('You will first need to set up Jira Integration to use this feature.')"
:primary-button-text="__('Set up Jira Integration')"
primary-button-link="../services/jira/edit"
/>
</template>
......@@ -24,7 +24,10 @@ export default function mountJiraImportApp() {
render(createComponent) {
return createComponent(App, {
props: {
inProgressIllustration: el.dataset.inProgressIllustration,
isJiraConfigured: parseBoolean(el.dataset.isJiraConfigured),
issuesPath: el.dataset.issuesPath,
jiraProjects: el.dataset.jiraProjects ? JSON.parse(el.dataset.jiraProjects) : [],
projectPath: el.dataset.projectPath,
setupIllustration: el.dataset.setupIllustration,
},
......
query getJiraProjects($fullPath: ID!) {
#import "./jira_import.fragment.graphql"
query($fullPath: ID!) {
project(fullPath: $fullPath) {
jiraImportStatus
jiraImports {
jiraImports(last: 1) {
nodes {
jiraProjectKey
scheduledAt
scheduledBy {
username
}
...JiraImport
}
}
}
......
#import "./jira_import.fragment.graphql"
mutation($input: JiraImportStartInput!) {
jiraImportStart(input: $input) {
clientMutationId
jiraImport {
...JiraImport
}
errors
}
}
fragment JiraImport on JiraImport {
jiraProjectKey
scheduledAt
scheduledBy {
name
}
}
export const IMPORT_STATE = {
FAILED: 'failed',
FINISHED: 'finished',
NONE: 'none',
SCHEDULED: 'scheduled',
STARTED: 'started',
};
export const isInProgress = state =>
state === IMPORT_STATE.SCHEDULED || state === IMPORT_STATE.STARTED;
......@@ -11,11 +11,10 @@ module Projects
before_action :authorize_admin_project!, only: [:import]
def show
@is_jira_configured = @project.jira_service.present?
return if Feature.enabled?(:jira_issue_import_vue, @project)
jira_service = @project.jira_service
if !@project.latest_jira_import&.in_progress? && current_user&.can?(:admin_project, @project)
jira_client = @project.jira_service.client
if jira_service.present? && !@project.latest_jira_import&.in_progress? && current_user&.can?(:admin_project, @project)
jira_client = jira_service.client
jira_projects = jira_client.Project.all
if jira_projects.present?
......@@ -25,7 +24,9 @@ module Projects
end
end
flash[:notice] = _("Import %{status}") % { status: @project.jira_import_status } unless @project.latest_jira_import&.initial?
unless Feature.enabled?(:jira_issue_import_vue, @project)
flash[:notice] = _("Import %{status}") % { status: @project.jira_import_status } unless @project.latest_jira_import&.initial?
end
end
def import
......
- if Feature.enabled?(:jira_issue_import_vue, @project)
.js-jira-import-root{ data: { project_path: @project.full_path,
is_jira_configured: @is_jira_configured.to_s,
issues_path: project_issues_path(@project),
is_jira_configured: @project.jira_service.present?.to_s,
jira_projects: @jira_projects.to_json,
in_progress_illustration: image_path('illustrations/export-import.svg'),
setup_illustration: image_path('illustrations/manual_action.svg') } }
- else
- title = _('Jira Issue Import')
......
......@@ -11031,6 +11031,9 @@ msgstr ""
msgid "Import repository"
msgstr ""
msgid "Import started by: %{importInitiator}"
msgstr ""
msgid "Import tasks"
msgstr ""
......@@ -11531,6 +11534,9 @@ msgstr ""
msgid "Jira integration not configured."
msgstr ""
msgid "Jira project: %{importProject}"
msgstr ""
msgid "JiraService|Events for %{noteable_model_name} are disabled."
msgstr ""
......@@ -15031,6 +15037,9 @@ msgstr ""
msgid "Please select"
msgstr ""
msgid "Please select a Jira project"
msgstr ""
msgid "Please select a country"
msgstr ""
......@@ -18591,9 +18600,6 @@ msgstr ""
msgid "Set up Jira Integration"
msgstr ""
msgid "Set up Jira Integration illustration"
msgstr ""
msgid "Set up a %{type} Runner automatically"
msgstr ""
......@@ -20768,6 +20774,9 @@ msgstr ""
msgid "There was an error getting the epic participants."
msgstr ""
msgid "There was an error importing the Jira project."
msgstr ""
msgid "There was an error loading users activity calendar."
msgstr ""
......@@ -21359,6 +21368,9 @@ msgstr ""
msgid "Time in seconds GitLab will wait for a response from the external service. When the service does not respond in time, access will be denied."
msgstr ""
msgid "Time of import: %{importTime}"
msgstr ""
msgid "Time remaining"
msgstr ""
......@@ -22951,6 +22963,9 @@ msgstr ""
msgid "View issue"
msgstr ""
msgid "View issues"
msgstr ""
msgid "View it on GitLab"
msgstr ""
......
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import JiraImportApp from '~/jira_import/components/jira_import_app.vue';
import JiraImportForm from '~/jira_import/components/jira_import_form.vue';
import JiraImportProgress from '~/jira_import/components/jira_import_progress.vue';
import JiraImportSetup from '~/jira_import/components/jira_import_setup.vue';
import initiateJiraImportMutation from '~/jira_import/queries/initiate_jira_import.mutation.graphql';
import { IMPORT_STATE } from '~/jira_import/utils';
const mountComponent = ({
isJiraConfigured = true,
errorMessage = '',
showAlert = true,
status = IMPORT_STATE.NONE,
loading = false,
mutate = jest.fn(() => Promise.resolve()),
} = {}) =>
shallowMount(JiraImportApp, {
propsData: {
isJiraConfigured,
inProgressIllustration: 'in-progress-illustration.svg',
issuesPath: 'gitlab-org/gitlab-test/-/issues',
jiraProjects: [
['My Jira Project', 'MJP'],
['My Second Jira Project', 'MSJP'],
['Migrate to GitLab', 'MTG'],
],
projectPath: 'gitlab-org/gitlab-test',
setupIllustration: 'setup-illustration.svg',
},
data() {
return {
errorMessage,
showAlert,
jiraImportDetails: {
status,
import: {
jiraProjectKey: 'MTG',
scheduledAt: '2020-04-08T12:17:25+00:00',
scheduledBy: {
name: 'Jane Doe',
},
},
},
};
},
mocks: {
$apollo: {
loading,
mutate,
},
},
});
describe('JiraImportApp', () => {
let wrapper;
const getFormComponent = () => wrapper.find(JiraImportForm);
const getProgressComponent = () => wrapper.find(JiraImportProgress);
const getSetupComponent = () => wrapper.find(JiraImportSetup);
const getAlert = () => wrapper.find(GlAlert);
const getLoadingIcon = () => wrapper.find(GlLoadingIcon);
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('set up Jira integration page', () => {
describe('when Jira integration is not configured', () => {
beforeEach(() => {
wrapper = mountComponent({ isJiraConfigured: false });
});
it('shows the "Set up Jira integration" screen', () => {
expect(getSetupComponent().exists()).toBe(true);
});
it('does not show loading icon', () => {
expect(getLoadingIcon().exists()).toBe(false);
});
it('does not show the "Import in progress" screen', () => {
expect(getProgressComponent().exists()).toBe(false);
});
it('does not show the "Import Jira project" form', () => {
expect(getFormComponent().exists()).toBe(false);
});
});
describe('when Jira integration is configured but data is being fetched', () => {
beforeEach(() => {
wrapper = mountComponent({ loading: true });
});
it('does not show the "Set up Jira integration" screen', () => {
expect(getSetupComponent().exists()).toBe(false);
});
it('shows loading icon', () => {
expect(getLoadingIcon().exists()).toBe(true);
});
it('does not show the "Import in progress" screen', () => {
expect(getProgressComponent().exists()).toBe(false);
});
it('does not show the "Import Jira project" form', () => {
expect(getFormComponent().exists()).toBe(false);
});
});
describe('when Jira integration is configured but import is in progress', () => {
beforeEach(() => {
wrapper = mountComponent({ status: IMPORT_STATE.SCHEDULED });
});
it('does not show the "Set up Jira integration" screen', () => {
expect(getSetupComponent().exists()).toBe(false);
});
it('does not show loading icon', () => {
expect(getLoadingIcon().exists()).toBe(false);
});
it('shows the "Import in progress" screen', () => {
expect(getProgressComponent().exists()).toBe(true);
});
it('does not show the "Import Jira project" form', () => {
expect(getFormComponent().exists()).toBe(false);
});
});
describe('when Jira integration is configured and there is no import in progress', () => {
beforeEach(() => {
wrapper = shallowMount(JiraImportApp, {
propsData: {
isJiraConfigured: true,
projectPath: 'gitlab-org/gitlab-test',
setupIllustration: 'illustration.svg',
wrapper = mountComponent();
});
it('does not show the "Set up Jira integration" screen', () => {
expect(getSetupComponent().exists()).toBe(false);
});
it('does not show loading icon', () => {
expect(getLoadingIcon().exists()).toBe(false);
});
it('does not show the Import in progress" screen', () => {
expect(getProgressComponent().exists()).toBe(false);
});
it('shows the "Import Jira project" form', () => {
expect(getFormComponent().exists()).toBe(true);
});
});
describe('initiating a Jira import', () => {
it('calls the mutation with the expected arguments', () => {
const mutate = jest.fn(() => Promise.resolve());
wrapper = mountComponent({ mutate });
const mutationArguments = {
mutation: initiateJiraImportMutation,
variables: {
input: {
jiraProjectKey: 'MTG',
projectPath: 'gitlab-org/gitlab-test',
},
},
});
};
getFormComponent().vm.$emit('initiateJiraImport', 'MTG');
expect(mutate).toHaveBeenCalledWith(expect.objectContaining(mutationArguments));
});
it('is shown when Jira integration is not configured', () => {
wrapper.setProps({
isJiraConfigured: false,
});
it('shows alert message with error message on error', () => {
const mutate = jest.fn(() => Promise.reject());
wrapper = mountComponent({ mutate });
getFormComponent().vm.$emit('initiateJiraImport', 'MTG');
// One tick doesn't update the dom to the desired state so we have two ticks here
return Vue.nextTick()
.then(Vue.nextTick)
.then(() => {
expect(getAlert().text()).toBe('There was an error importing the Jira project.');
});
});
});
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(JiraImportSetup).exists()).toBe(true);
});
it('can dismiss alert message', () => {
wrapper = mountComponent({
errorMessage: 'There was an error importing the Jira project.',
showAlert: true,
});
it('is not shown when Jira integration is configured', () => {
expect(wrapper.find(JiraImportSetup).exists()).toBe(false);
expect(getAlert().exists()).toBe(true);
getAlert().vm.$emit('dismiss');
return Vue.nextTick().then(() => {
expect(getAlert().exists()).toBe(false);
});
});
});
import { GlAvatar, GlButton, GlFormSelect, GlLabel } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { mount, shallowMount } from '@vue/test-utils';
import JiraImportForm from '~/jira_import/components/jira_import_form.vue';
const mountComponent = ({ mountType } = {}) => {
const mountFunction = mountType === 'mount' ? mount : shallowMount;
return mountFunction(JiraImportForm, {
propsData: {
issuesPath: 'gitlab-org/gitlab-test/-/issues',
jiraProjects: [
{
text: 'My Jira Project',
value: 'MJP',
},
{
text: 'My Second Jira Project',
value: 'MSJP',
},
{
text: 'Migrate to GitLab',
value: 'MTG',
},
],
},
});
};
describe('JiraImportForm', () => {
let wrapper;
beforeEach(() => {
wrapper = shallowMount(JiraImportForm);
});
const getCancelButton = () => wrapper.findAll(GlButton).at(1);
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('shows a dropdown to choose the Jira project to import from', () => {
expect(wrapper.find(GlFormSelect).exists()).toBe(true);
});
describe('select dropdown', () => {
it('is shown', () => {
wrapper = mountComponent();
it('shows a label which will be applied to imported Jira projects', () => {
expect(wrapper.find(GlLabel).attributes('title')).toBe('jira-import::KEY-1');
});
expect(wrapper.find(GlFormSelect).exists()).toBe(true);
});
it('shows information to the user', () => {
expect(wrapper.find('p').text()).toBe(
"For each Jira issue successfully imported, we'll create a new GitLab issue with the following data:",
);
});
it('contains a list of Jira projects to select from', () => {
wrapper = mountComponent({ mountType: 'mount' });
it('shows jira.issue.summary for the Title', () => {
expect(wrapper.find('[id="jira-project-title"]').text()).toBe('jira.issue.summary');
const optionItems = ['My Jira Project', 'My Second Jira Project', 'Migrate to GitLab'];
wrapper
.find(GlFormSelect)
.findAll('option')
.wrappers.forEach((optionEl, index) => {
expect(optionEl.text()).toBe(optionItems[index]);
});
});
});
it('shows an avatar for the Reporter', () => {
expect(wrapper.find(GlAvatar).exists()).toBe(true);
describe('form information', () => {
beforeEach(() => {
wrapper = mountComponent();
});
it('shows a label which will be applied to imported Jira projects', () => {
expect(wrapper.find(GlLabel).attributes('title')).toBe('jira-import::KEY-1');
});
it('shows information to the user', () => {
expect(wrapper.find('p').text()).toBe(
"For each Jira issue successfully imported, we'll create a new GitLab issue with the following data:",
);
});
it('shows jira.issue.summary for the Title', () => {
expect(wrapper.find('[id="jira-project-title"]').text()).toBe('jira.issue.summary');
});
it('shows an avatar for the Reporter', () => {
expect(wrapper.find(GlAvatar).exists()).toBe(true);
});
it('shows jira.issue.description.content for the Description', () => {
expect(wrapper.find('[id="jira-project-description"]').text()).toBe(
'jira.issue.description.content',
);
});
});
it('shows jira.issue.description.content for the Description', () => {
expect(wrapper.find('[id="jira-project-description"]').text()).toBe(
'jira.issue.description.content',
);
describe('Next button', () => {
beforeEach(() => {
wrapper = mountComponent();
});
it('is shown', () => {
expect(wrapper.find(GlButton).text()).toBe('Next');
});
});
it('shows a Next button', () => {
const nextButton = wrapper
.findAll(GlButton)
.at(0)
.text();
describe('Cancel button', () => {
beforeEach(() => {
wrapper = mountComponent();
});
it('is shown', () => {
expect(getCancelButton().text()).toBe('Cancel');
});
expect(nextButton).toBe('Next');
it('links to the Issues page', () => {
expect(getCancelButton().attributes('href')).toBe('gitlab-org/gitlab-test/-/issues');
});
});
it('shows a Cancel button', () => {
const cancelButton = wrapper
.findAll(GlButton)
.at(1)
.text();
it('emits an "initiateJiraImport" event with the selected dropdown value when submitted', () => {
const selectedOption = 'MTG';
wrapper = mountComponent();
wrapper.setData({
selectedOption,
});
wrapper.find('form').trigger('submit');
expect(cancelButton).toBe('Cancel');
expect(wrapper.emitted('initiateJiraImport')[0]).toEqual([selectedOption]);
});
});
import { GlEmptyState } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import JiraImportProgress from '~/jira_import/components/jira_import_progress.vue';
describe('JiraImportProgress', () => {
let wrapper;
const getGlEmptyStateAttribute = attribute => wrapper.find(GlEmptyState).attributes(attribute);
const getParagraphText = () => wrapper.find('p').text();
const mountComponent = ({ mountType = 'shallowMount' } = {}) => {
const mountFunction = mountType === 'shallowMount' ? shallowMount : mount;
return mountFunction(JiraImportProgress, {
propsData: {
illustration: 'illustration.svg',
importInitiator: 'Jane Doe',
importProject: 'JIRAPROJECT',
importTime: '2020-04-08T12:17:25+00:00',
issuesPath: 'gitlab-org/gitlab-test/-/issues',
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('empty state', () => {
beforeEach(() => {
wrapper = mountComponent();
});
it('contains illustration', () => {
expect(getGlEmptyStateAttribute('svgpath')).toBe('illustration.svg');
});
it('contains a title', () => {
const title = 'Import in progress';
expect(getGlEmptyStateAttribute('title')).toBe(title);
});
it('contains button text', () => {
expect(getGlEmptyStateAttribute('primarybuttontext')).toBe('View issues');
});
it('contains button url', () => {
expect(getGlEmptyStateAttribute('primarybuttonlink')).toBe('gitlab-org/gitlab-test/-/issues');
});
});
describe('description', () => {
beforeEach(() => {
wrapper = mountComponent({ mountType: 'mount' });
});
it('shows who initiated the import', () => {
expect(getParagraphText()).toContain('Import started by: Jane Doe');
});
it('shows the time of import', () => {
expect(getParagraphText()).toContain('Time of import: Apr 8, 2020 12:17pm GMT+0000');
});
it('shows the project key of the import', () => {
expect(getParagraphText()).toContain('Jira project: JIRAPROJECT');
});
});
});
import { GlEmptyState } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import JiraImportSetup from '~/jira_import/components/jira_import_setup.vue';
describe('JiraImportSetup', () => {
let wrapper;
const getGlEmptyStateAttribute = attribute => wrapper.find(GlEmptyState).attributes(attribute);
beforeEach(() => {
wrapper = shallowMount(JiraImportSetup, {
propsData: {
......@@ -17,12 +20,16 @@ describe('JiraImportSetup', () => {
wrapper = null;
});
it('displays a message to the user', () => {
const message = 'You will first need to set up Jira Integration to use this feature.';
expect(wrapper.find('p').text()).toBe(message);
it('contains illustration', () => {
expect(getGlEmptyStateAttribute('svgpath')).toBe('illustration.svg');
});
it('contains a description', () => {
const description = 'You will first need to set up Jira Integration to use this feature.';
expect(getGlEmptyStateAttribute('description')).toBe(description);
});
it('contains button to set up Jira integration', () => {
expect(wrapper.find('a').text()).toBe('Set up Jira Integration');
it('contains button text', () => {
expect(getGlEmptyStateAttribute('primarybuttontext')).toBe('Set up Jira Integration');
});
});
import { IMPORT_STATE, isInProgress } from '~/jira_import/utils';
describe('isInProgress', () => {
it('returns true when state is IMPORT_STATE.SCHEDULED', () => {
expect(isInProgress(IMPORT_STATE.SCHEDULED)).toBe(true);
});
it('returns true when state is IMPORT_STATE.STARTED', () => {
expect(isInProgress(IMPORT_STATE.STARTED)).toBe(true);
});
it('returns false when state is IMPORT_STATE.FAILED', () => {
expect(isInProgress(IMPORT_STATE.FAILED)).toBe(false);
});
it('returns false when state is IMPORT_STATE.FINISHED', () => {
expect(isInProgress(IMPORT_STATE.FINISHED)).toBe(false);
});
it('returns false when state is IMPORT_STATE.NONE', () => {
expect(isInProgress(IMPORT_STATE.NONE)).toBe(false);
});
it('returns false when state is undefined', () => {
expect(isInProgress()).toBe(false);
});
});
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