Commit 3c86a842 authored by Martin Wortschack's avatar Martin Wortschack Committed by Brandon Labuschagne

Replace bootstrap modal in issuable_by_email HAML template

- Render Vue component instead of
HAML/bootstrap button and modal
parent ae3a69b5
...@@ -160,7 +160,6 @@ linters: ...@@ -160,7 +160,6 @@ linters:
- 'app/views/projects/_gitlab_import_modal.html.haml' - 'app/views/projects/_gitlab_import_modal.html.haml'
- 'app/views/projects/_home_panel.html.haml' - 'app/views/projects/_home_panel.html.haml'
- 'app/views/projects/_import_project_pane.html.haml' - 'app/views/projects/_import_project_pane.html.haml'
- 'app/views/projects/_issuable_by_email.html.haml'
- 'app/views/projects/_readme.html.haml' - 'app/views/projects/_readme.html.haml'
- 'app/views/projects/artifacts/_artifact.html.haml' - 'app/views/projects/artifacts/_artifact.html.haml'
- 'app/views/projects/artifacts/_tree_file.html.haml' - 'app/views/projects/artifacts/_tree_file.html.haml'
......
<script>
import {
GlButton,
GlModal,
GlModalDirective,
GlTooltipDirective,
GlSprintf,
GlLink,
GlFormInputGroup,
GlIcon,
} from '@gitlab/ui';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
import { sprintf, __ } from '~/locale';
import axios from '~/lib/utils/axios_utils';
export default {
name: 'IssuableByEmail',
components: {
GlButton,
GlModal,
GlSprintf,
GlLink,
GlFormInputGroup,
GlIcon,
ModalCopyButton,
},
directives: {
GlModal: GlModalDirective,
GlTooltip: GlTooltipDirective,
},
inject: {
initialEmail: {
default: null,
},
issuableType: {
default: '',
},
emailsHelpPagePath: {
default: '',
},
quickActionsHelpPath: {
default: '',
},
markdownHelpPath: {
default: '',
},
resetPath: {
default: '',
},
},
data() {
return {
email: this.initialEmail,
// eslint-disable-next-line @gitlab/require-i18n-strings
issuableName: this.issuableType === 'issue' ? 'issue' : 'merge request',
};
},
computed: {
mailToLink() {
const subject = sprintf(__('Enter the %{name} title'), {
name: this.issuableName,
});
const body = sprintf(__('Enter the %{name} description'), {
name: this.issuableName,
});
// eslint-disable-next-line @gitlab/require-i18n-strings
return `mailto:${this.email}?subject=${subject}&body=${body}`;
},
},
methods: {
async resetIncomingEmailToken() {
try {
const {
data: { new_address: newAddress },
} = await axios.put(this.resetPath);
this.email = newAddress;
} catch {
this.$toast.show(__('There was an error when reseting email token.'), { type: 'error' });
}
},
cancelHandler() {
this.$refs.modal.hide();
},
},
modalId: 'issuable-email-modal',
};
</script>
<template>
<div>
<gl-button v-gl-modal="$options.modalId" variant="link" data-testid="issuable-email-modal-btn"
><gl-sprintf :message="__('Email a new %{name} to this project')"
><template #name>{{ issuableName }}</template></gl-sprintf
></gl-button
>
<gl-modal ref="modal" :modal-id="$options.modalId">
<template #modal-title>
<gl-sprintf :message="__('Create new %{name} by email')">
<template #name>{{ issuableName }}</template>
</gl-sprintf>
</template>
<p>
<gl-sprintf
:message="
__(
'You can create a new %{name} inside this project by sending an email to the following email address:',
)
"
>
<template #name>{{ issuableName }}</template>
</gl-sprintf>
</p>
<gl-form-input-group :value="email" readonly select-on-click class="gl-mb-4">
<template #append>
<modal-copy-button :text="email" :title="__('Copy')" :modal-id="$options.modalId" />
<gl-button
v-gl-tooltip.hover
:href="mailToLink"
:title="__('Send email')"
icon="mail"
data-testid="mail-to-btn"
/>
</template>
</gl-form-input-group>
<p>
<gl-sprintf
:message="
__(
'The subject will be used as the title of the new issue, and the message will be the description. %{quickActionsLinkStart}Quick actions%{quickActionsLinkEnd} and styling with %{markdownLinkStart}Markdown%{markdownLinkEnd} are supported.',
)
"
>
<template #quickActionsLink="{ content }">
<gl-link :href="quickActionsHelpPath" target="_blank">{{ content }}</gl-link>
</template>
<template #markdownLink="{ content }">
<gl-link :href="markdownHelpPath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
<p>
<gl-sprintf
:message="
__(
'This is a private email address %{helpIcon} generated just for you. Anyone who gets ahold of it can create issues or merge requests as if they were you. You should %{resetLinkStart}reset it%{resetLinkEnd} if that ever happens.',
)
"
>
<template #helpIcon>
<gl-link :href="emailsHelpPagePath" target="_blank"
><gl-icon class="gl-text-blue-600" name="question-o"
/></gl-link>
</template>
<template #resetLink="{ content }">
<gl-button
variant="link"
data-testid="incoming-email-token-reset"
@click="resetIncomingEmailToken"
>{{ content }}</gl-button
>
</template>
</gl-sprintf>
</p>
<template #modal-footer>
<gl-button category="secondary" @click="cancelHandler">{{ s__('Cancel') }}</gl-button>
</template>
</gl-modal>
</div>
</template>
import Vue from 'vue';
import { GlToast } from '@gitlab/ui';
import IssuableByEmail from './components/issuable_by_email.vue';
Vue.use(GlToast);
export default () => {
const el = document.querySelector('.js-issueable-by-email');
if (!el) return null;
const {
initialEmail,
issuableType,
emailsHelpPagePath,
quickActionsHelpPath,
markdownHelpPath,
resetPath,
} = el.dataset;
return new Vue({
el,
provide: {
initialEmail,
issuableType,
emailsHelpPagePath,
quickActionsHelpPath,
markdownHelpPath,
resetPath,
},
render(h) {
return h(IssuableByEmail);
},
});
};
import $ from 'jquery';
import axios from './lib/utils/axios_utils';
import { deprecatedCreateFlash as flash } from './flash';
import { s__, __ } from './locale';
import issuableInitBulkUpdateSidebar from './issuable_init_bulk_update_sidebar'; import issuableInitBulkUpdateSidebar from './issuable_init_bulk_update_sidebar';
export default class IssuableIndex { export default class IssuableIndex {
constructor(pagePrefix) { constructor(pagePrefix) {
issuableInitBulkUpdateSidebar.init(pagePrefix); issuableInitBulkUpdateSidebar.init(pagePrefix);
IssuableIndex.resetIncomingEmailToken();
}
static resetIncomingEmailToken() {
const $resetToken = $('.incoming-email-token-reset');
$resetToken.on('click', (e) => {
e.preventDefault();
$resetToken.text(s__('EmailToken|resetting...'));
axios
.put($resetToken.attr('href'))
.then(({ data }) => {
$('#issuable_email').val(data.new_address).focus();
$resetToken.text(s__('EmailToken|reset it'));
})
.catch(() => {
flash(__('There was an error when reseting email token.'));
$resetToken.text(s__('EmailToken|reset it'));
});
});
} }
} }
...@@ -9,6 +9,7 @@ import { FILTERED_SEARCH } from '~/pages/constants'; ...@@ -9,6 +9,7 @@ import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants';
import initIssuablesList from '~/issues_list'; import initIssuablesList from '~/issues_list';
import initManualOrdering from '~/manual_ordering'; import initManualOrdering from '~/manual_ordering';
import initIssuableByEmail from '~/issuable/init_issuable_by_email';
IssuableFilteredSearchTokenKeys.addExtraTokensForIssues(); IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
...@@ -24,3 +25,4 @@ new UsersSelect(); ...@@ -24,3 +25,4 @@ new UsersSelect();
initManualOrdering(); initManualOrdering();
initIssuablesList(); initIssuablesList();
initIssuableByEmail();
...@@ -6,6 +6,7 @@ import initFilteredSearch from '~/pages/search/init_filtered_search'; ...@@ -6,6 +6,7 @@ import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants'; import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants';
import initIssuableByEmail from '~/issuable/init_issuable_by_email';
new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new
...@@ -19,3 +20,5 @@ initFilteredSearch({ ...@@ -19,3 +20,5 @@ initFilteredSearch({
new UsersSelect(); // eslint-disable-line no-new new UsersSelect(); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new
initIssuableByEmail();
...@@ -108,18 +108,6 @@ ul.related-merge-requests > li { ...@@ -108,18 +108,6 @@ ul.related-merge-requests > li {
} }
} }
.issuable-email-modal-btn {
padding: 0;
color: $blue-600;
background-color: transparent;
border: 0;
outline: 0;
&:hover {
text-decoration: underline;
}
}
.email-modal-input-group { .email-modal-input-group {
margin-bottom: 10px; margin-bottom: 10px;
......
- name = issuable_type == 'issue' ? 'issue' : 'merge request'
.issuable-footer.text-center
%button.issuable-email-modal-btn{ type: "button", data: { toggle: "modal", target: "#issuable-email-modal" } }
Email a new #{name} to this project
#issuable-email-modal.modal.fade{ tabindex: "-1", role: "dialog" }
.modal-dialog{ role: "document" }
.modal-content
.modal-header
%h4.modal-title
Create new #{name} by email
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": true } &times;
.modal-body
%p
You can create a new #{name} inside this project by sending an email to the following email address:
.email-modal-input-group.input-group
= text_field_tag :issuable_email, email, class: "monospace js-select-on-focus form-control", readonly: true
.input-group-append
= clipboard_button(target: '#issuable_email', class: 'btn btn-clipboard input-group-text btn-transparent d-none d-sm-block')
- if issuable_type == 'issue'
- enter_title_text = _('Enter the issue title')
- enter_description_text = _('Enter the issue description')
- else
- enter_title_text = _('Enter the merge request title')
- enter_description_text = _('Enter the merge request description')
= mail_to email, class: 'btn btn-clipboard btn-transparent',
subject: enter_title_text,
body: enter_description_text,
title: _('Send email'),
data: { toggle: 'tooltip', placement: 'bottom' } do
= sprite_icon('mail')
%p
= render 'by_email_description'
%p
This is a private email address
%span<
= link_to help_page_path('development/emails', anchor: 'email-namespace'), target: '_blank', rel: 'noopener', aria: { label: 'Learn more about incoming email addresses' } do
= sprite_icon('question-o')
generated just for you.
Anyone who gets ahold of it can create issues or merge requests as if they were you.
You should
= link_to 'reset it', new_issuable_address_project_path(@project, issuable_type: issuable_type), class: 'incoming-email-token-reset'
if that ever happens.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
- page_title _("Issues") - page_title _("Issues")
- new_issue_email = @project.new_issuable_address(current_user, 'issue') - new_issue_email = @project.new_issuable_address(current_user, 'issue')
- add_page_specific_style 'page_bundles/issues_list' - add_page_specific_style 'page_bundles/issues_list'
- issuable_type = 'issue'
= content_for :meta_tags do = content_for :meta_tags do
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues") = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues")
...@@ -24,7 +25,8 @@ ...@@ -24,7 +25,8 @@
.issues-holder .issues-holder
= render 'issues' = render 'issues'
- if new_issue_email - if new_issue_email
= render 'projects/issuable_by_email', email: new_issue_email, issuable_type: 'issue' .issuable-footer.text-center
.js-issueable-by-email{ data: { initial_email: new_issue_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
- else - else
- new_project_issue_button_path = @project.archived? ? false : new_project_issue_path(@project) - new_project_issue_button_path = @project.archived? ? false : new_project_issue_path(@project)
= render 'shared/empty_states/issues', new_project_issue_button_path: new_project_issue_button_path, show_import_button: true = render 'shared/empty_states/issues', new_project_issue_button_path: new_project_issue_button_path, show_import_button: true
- @can_bulk_update = can?(current_user, :admin_merge_request, @project) - @can_bulk_update = can?(current_user, :admin_merge_request, @project)
- merge_project = merge_request_source_project_for_project(@project) - merge_project = merge_request_source_project_for_project(@project)
- new_merge_request_path = project_new_merge_request_path(merge_project) if merge_project - new_merge_request_path = project_new_merge_request_path(merge_project) if merge_project
- issuable_type = 'merge_request'
- page_title _("Merge Requests") - page_title _("Merge Requests")
- new_merge_request_email = @project.new_issuable_address(current_user, 'merge_request') - new_merge_request_email = @project.new_issuable_address(current_user, 'merge_request')
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
.merge-requests-holder .merge-requests-holder
= render 'merge_requests' = render 'merge_requests'
- if new_merge_request_email - if new_merge_request_email
= render 'projects/issuable_by_email', email: new_merge_request_email, issuable_type: 'merge_request' .issuable-footer.text-center
.js-issueable-by-email{ data: { initial_email: new_merge_request_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } }
- else - else
= render 'shared/empty_states/merge_requests', button_path: new_merge_request_path = render 'shared/empty_states/merge_requests', button_path: new_merge_request_path
---
title: Replace bootstrap modal in issuable_by_email HAML template
merge_request: 53599
author:
type: changed
...@@ -8481,6 +8481,9 @@ msgstr "" ...@@ -8481,6 +8481,9 @@ msgstr ""
msgid "Create new" msgid "Create new"
msgstr "" msgstr ""
msgid "Create new %{name} by email"
msgstr ""
msgid "Create new Value Stream" msgid "Create new Value Stream"
msgstr "" msgstr ""
...@@ -10863,6 +10866,9 @@ msgstr "" ...@@ -10863,6 +10866,9 @@ msgstr ""
msgid "Email Notification" msgid "Email Notification"
msgstr "" msgstr ""
msgid "Email a new %{name} to this project"
msgstr ""
msgid "Email address to use for Support Desk" msgid "Email address to use for Support Desk"
msgstr "" msgstr ""
...@@ -10935,12 +10941,6 @@ msgstr "" ...@@ -10935,12 +10941,6 @@ msgstr ""
msgid "EmailParticipantsWarning|and %{moreCount} more" msgid "EmailParticipantsWarning|and %{moreCount} more"
msgstr "" msgstr ""
msgid "EmailToken|reset it"
msgstr ""
msgid "EmailToken|resetting..."
msgstr ""
msgid "Emails" msgid "Emails"
msgstr "" msgstr ""
...@@ -11226,19 +11226,13 @@ msgstr "" ...@@ -11226,19 +11226,13 @@ msgstr ""
msgid "Enter one or more user ID separated by commas" msgid "Enter one or more user ID separated by commas"
msgstr "" msgstr ""
msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes." msgid "Enter the %{name} description"
msgstr ""
msgid "Enter the issue description"
msgstr ""
msgid "Enter the issue title"
msgstr "" msgstr ""
msgid "Enter the merge request description" msgid "Enter the %{name} title"
msgstr "" msgstr ""
msgid "Enter the merge request title" msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
msgstr "" msgstr ""
msgid "Enter the name of your application, and we'll return a unique %{type}." msgid "Enter the name of your application, and we'll return a unique %{type}."
...@@ -29320,6 +29314,9 @@ msgstr "" ...@@ -29320,6 +29314,9 @@ msgstr ""
msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan." msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
msgstr "" msgstr ""
msgid "The subject will be used as the title of the new issue, and the message will be the description. %{quickActionsLinkStart}Quick actions%{quickActionsLinkEnd} and styling with %{markdownLinkStart}Markdown%{markdownLinkEnd} are supported."
msgstr ""
msgid "The tag name can't be changed for an existing release." msgid "The tag name can't be changed for an existing release."
msgstr "" msgstr ""
...@@ -29926,6 +29923,9 @@ msgstr "" ...@@ -29926,6 +29923,9 @@ msgstr ""
msgid "This is a merge train pipeline" msgid "This is a merge train pipeline"
msgstr "" msgstr ""
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who gets ahold of it can create issues or merge requests as if they were you. You should %{resetLinkStart}reset it%{resetLinkEnd} if that ever happens."
msgstr ""
msgid "This is a security log of important events involving your account." msgid "This is a security log of important events involving your account."
msgstr "" msgstr ""
...@@ -33349,6 +33349,9 @@ msgstr "" ...@@ -33349,6 +33349,9 @@ msgstr ""
msgid "You can create a new %{link}." msgid "You can create a new %{link}."
msgstr "" msgstr ""
msgid "You can create a new %{name} inside this project by sending an email to the following email address:"
msgstr ""
msgid "You can create a new Personal Access Token by visiting %{link}" msgid "You can create a new Personal Access Token by visiting %{link}"
msgstr "" msgstr ""
......
...@@ -12,7 +12,7 @@ RSpec.describe 'Issues > User creates issue by email' do ...@@ -12,7 +12,7 @@ RSpec.describe 'Issues > User creates issue by email' do
project.add_developer(user) project.add_developer(user)
end end
describe 'new issue by email' do describe 'new issue by email', :js do
shared_examples 'show the email in the modal' do shared_examples 'show the email in the modal' do
let(:issue) { create(:issue, project: project) } let(:issue) { create(:issue, project: project) }
...@@ -28,7 +28,7 @@ RSpec.describe 'Issues > User creates issue by email' do ...@@ -28,7 +28,7 @@ RSpec.describe 'Issues > User creates issue by email' do
page.within '#issuable-email-modal' do page.within '#issuable-email-modal' do
email = project.new_issuable_address(user, 'issue') email = project.new_issuable_address(user, 'issue')
expect(page).to have_selector("input[value='#{email}']") expect(page.find('input[type="text"]').value).to eq email
end end
end end
end end
......
...@@ -16,17 +16,17 @@ RSpec.describe 'Issues > User resets their incoming email token' do ...@@ -16,17 +16,17 @@ RSpec.describe 'Issues > User resets their incoming email token' do
end end
it 'changes incoming email address token', :js do it 'changes incoming email address token', :js do
find('.issuable-email-modal-btn').click page.find('[data-testid="issuable-email-modal-btn"]').click
previous_token = find('input#issuable_email').value
find('.incoming-email-token-reset').click page.within '#issuable-email-modal' do
previous_token = page.find('input[type="text"]').value
wait_for_requests page.find('[data-testid="incoming-email-token-reset"]').click
expect(page).to have_no_field('issuable_email', with: previous_token) wait_for_requests
new_token = project.new_issuable_address(user.reload, 'issue')
expect(page).to have_field( expect(page.find('input[type="text"]').value).not_to eq previous_token
'issuable_email', new_token = project.new_issuable_address(user.reload, 'issue')
with: new_token expect(page.find('input[type="text"]').value).to eq new_token
) end
end end
end end
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { shallowMount } from '@vue/test-utils';
import { GlModal, GlSprintf, GlFormInputGroup, GlButton } from '@gitlab/ui';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import httpStatus from '~/lib/utils/http_status';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
const initialEmail = 'user@gitlab.com';
const mockToastShow = jest.fn();
describe('IssuableByEmail', () => {
let wrapper;
let mockAxios;
let glModalDirective;
function createComponent(injectedProperties = {}) {
glModalDirective = jest.fn();
return extendedWrapper(
shallowMount(IssuableByEmail, {
stubs: {
GlModal,
GlSprintf,
GlFormInputGroup,
GlButton,
},
directives: {
glModal: {
bind(_, { value }) {
glModalDirective(value);
},
},
},
mocks: {
$toast: {
show: mockToastShow,
},
},
provide: {
issuableType: 'issue',
initialEmail,
...injectedProperties,
},
}),
);
}
beforeEach(() => {
mockAxios = new MockAdapter(axios);
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
mockAxios.restore();
});
const findFormInputGroup = () => wrapper.find(GlFormInputGroup);
const clickResetEmail = async () => {
wrapper.findByTestId('incoming-email-token-reset').vm.$emit('click');
await waitForPromises();
};
describe('modal button', () => {
it.each`
issuableType | buttonText
${'issue'} | ${'Email a new issue to this project'}
${'merge_request'} | ${'Email a new merge request to this project'}
`(
'renders a link with "$buttonText" when type is "$issuableType"',
({ issuableType, buttonText }) => {
wrapper = createComponent({ issuableType });
expect(wrapper.findByTestId('issuable-email-modal-btn').text()).toBe(buttonText);
},
);
it('opens the modal when the user clicks the button', () => {
wrapper = createComponent();
wrapper.findByTestId('issuable-email-modal-btn').vm.$emit('click');
expect(glModalDirective).toHaveBeenCalled();
});
});
describe('modal', () => {
it('renders a read-only email input field', () => {
wrapper = createComponent();
expect(findFormInputGroup().props('value')).toBe('user@gitlab.com');
});
it.each`
issuableType | subject | body
${'issue'} | ${'Enter the issue title'} | ${'Enter the issue description'}
${'merge_request'} | ${'Enter the merge request title'} | ${'Enter the merge request description'}
`('renders a mailto button when type is "$issuableType"', ({ issuableType, subject, body }) => {
wrapper = createComponent({
issuableType,
initialEmail,
});
expect(wrapper.findByTestId('mail-to-btn').attributes('href')).toBe(
`mailto:${initialEmail}?subject=${subject}&body=${body}`,
);
});
describe('reset email', () => {
const resetPath = 'gitlab-test/new_issuable_address?issuable_type=issue';
beforeEach(() => {
jest.spyOn(axios, 'put');
});
it('should send request to reset email token', async () => {
wrapper = createComponent({
issuableType: 'issue',
initialEmail,
resetPath,
});
await clickResetEmail();
expect(axios.put).toHaveBeenCalledWith(resetPath);
});
it('should update the email when the request succeeds', async () => {
mockAxios.onPut(resetPath).reply(httpStatus.OK, { new_address: 'foo@bar.com' });
wrapper = createComponent({
issuableType: 'issue',
initialEmail,
resetPath,
});
await clickResetEmail();
expect(findFormInputGroup().props('value')).toBe('foo@bar.com');
});
it('should show a toast message when the request fails', async () => {
mockAxios.onPut(resetPath).reply(httpStatus.NOT_FOUND, {});
wrapper = createComponent({
issuableType: 'issue',
initialEmail,
resetPath,
});
await clickResetEmail();
expect(mockToastShow).toHaveBeenCalledWith(
'There was an error when reseting email token.',
{ type: 'error' },
);
expect(findFormInputGroup().props('value')).toBe('user@gitlab.com');
});
});
});
});
import $ from 'jquery';
import MockAdaptor from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import IssuableIndex from '~/issuable_index'; import IssuableIndex from '~/issuable_index';
import issuableInitBulkUpdateSidebar from '~/issuable_init_bulk_update_sidebar'; import issuableInitBulkUpdateSidebar from '~/issuable_init_bulk_update_sidebar';
...@@ -22,43 +19,4 @@ describe('Issuable', () => { ...@@ -22,43 +19,4 @@ describe('Issuable', () => {
expect(issuableInitBulkUpdateSidebar.bulkUpdateSidebar).toBeDefined(); expect(issuableInitBulkUpdateSidebar.bulkUpdateSidebar).toBeDefined();
}); });
}); });
describe('resetIncomingEmailToken', () => {
let mock;
beforeEach(() => {
const element = document.createElement('a');
element.classList.add('incoming-email-token-reset');
element.setAttribute('href', 'foo');
document.body.appendChild(element);
const input = document.createElement('input');
input.setAttribute('id', 'issuable_email');
document.body.appendChild(input);
new IssuableIndex('issue_'); // eslint-disable-line no-new
mock = new MockAdaptor(axios);
mock.onPut('foo').reply(200, {
new_address: 'testing123',
});
});
afterEach(() => {
mock.restore();
});
it('should send request to reset email token', (done) => {
jest.spyOn(axios, 'put');
document.querySelector('.incoming-email-token-reset').click();
setImmediate(() => {
expect(axios.put).toHaveBeenCalledWith('foo');
expect($('#issuable_email').val()).toBe('testing123');
done();
});
});
});
}); });
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