summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinnie Hellmann <winnie@gitlab.com>2018-01-03 10:21:17 +0100
committerWinnie Hellmann <winnie@gitlab.com>2018-01-04 17:45:26 +0100
commit75f9cf94f6f3fcfddc8efb546599cbf61078a245 (patch)
tree792048797802dc4d9daa533b6b9873e897dc83af
parentb1e1990ee263bcae73f0e55526a55cff66103220 (diff)
downloadgitlab-ce-winh-modal-target-id.tar.gz
Add id to modal.vue to support data-toggle="modal"winh-modal-target-id
-rw-r--r--app/assets/javascripts/dispatcher.js3
-rw-r--r--app/assets/javascripts/groups/components/item_actions.vue6
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/index.vue8
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/modal.vue8
-rw-r--r--app/assets/javascripts/ide/components/repo_commit_section.vue2
-rw-r--r--app/assets/javascripts/ide/components/repo_edit_button.vue2
-rw-r--r--app/assets/javascripts/pages/profiles/accounts/show/components/delete_account_modal.vue127
-rw-r--r--app/assets/javascripts/pages/profiles/accounts/show/index.js40
-rw-r--r--app/assets/javascripts/profile/account/components/delete_account_modal.vue146
-rw-r--r--app/assets/javascripts/profile/account/index.js21
-rw-r--r--app/assets/javascripts/vue_shared/components/modal.vue30
-rw-r--r--app/assets/javascripts/vue_shared/components/recaptcha_modal.vue2
-rw-r--r--app/views/profiles/accounts/show.html.haml14
-rw-r--r--changelogs/unreleased/winh-modal-target-id.yml5
-rw-r--r--config/webpack.config.js1
-rw-r--r--spec/javascripts/groups/components/item_actions_spec.js12
-rw-r--r--spec/javascripts/pages/profiles/accounts/show/components/delete_account_modal_spec.js (renamed from spec/javascripts/profile/account/components/delete_account_modal_spec.js)4
-rw-r--r--spec/javascripts/pages/profiles/accounts/show/index_spec.js33
-rw-r--r--spec/javascripts/repo/components/new_dropdown/index_spec.js13
-rw-r--r--spec/javascripts/vue_shared/components/modal_spec.js66
20 files changed, 323 insertions, 220 deletions
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 42f61d33f6e..64090695d53 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -158,6 +158,9 @@ import Activities from './activities';
const filteredSearchEnabled = gl.FilteredSearchManager && document.querySelector('.filtered-search');
switch (page) {
+ case 'profiles:accounts:show':
+ import('./pages/profiles/accounts/show').then(m => m.default()).catch(fail);
+ break;
case 'profiles:preferences:show':
initExperimentalFlags();
break;
diff --git a/app/assets/javascripts/groups/components/item_actions.vue b/app/assets/javascripts/groups/components/item_actions.vue
index 58ba5aff7cf..b98cfcf7563 100644
--- a/app/assets/javascripts/groups/components/item_actions.vue
+++ b/app/assets/javascripts/groups/components/item_actions.vue
@@ -45,11 +45,9 @@ export default {
onLeaveGroup() {
this.modalStatus = true;
},
- leaveGroup(leaveConfirmed) {
+ leaveGroup() {
this.modalStatus = false;
- if (leaveConfirmed) {
- eventHub.$emit('leaveGroup', this.group, this.parentGroup);
- }
+ eventHub.$emit('leaveGroup', this.group, this.parentGroup);
},
},
};
diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue
index 6e67e99a70f..d475813c4f7 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/index.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/index.vue
@@ -32,10 +32,10 @@
methods: {
createNewItem(type) {
this.modalType = type;
- this.toggleModalOpen();
+ this.openModal = true;
},
- toggleModalOpen() {
- this.openModal = !this.openModal;
+ hideModal() {
+ this.openModal = false;
},
},
};
@@ -95,7 +95,7 @@
:branch-id="branch"
:path="path"
:parent="parent"
- @toggle="toggleModalOpen"
+ @hide="hideModal"
/>
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
index a0650d37690..0312f56efbd 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
@@ -43,10 +43,10 @@
type: this.type,
});
- this.toggleModalOpen();
+ this.hideModal();
},
- toggleModalOpen() {
- this.$emit('toggle');
+ hideModal() {
+ this.$emit('hide');
},
},
computed: {
@@ -86,7 +86,7 @@
:title="modalTitle"
:primary-button-label="buttonLabel"
kind="success"
- @toggle="toggleModalOpen"
+ @cancel="hideModal"
@submit="createEntryInStore"
>
<form
diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue
index 470db2c9650..979721dcb5a 100644
--- a/app/assets/javascripts/ide/components/repo_commit_section.vue
+++ b/app/assets/javascripts/ide/components/repo_commit_section.vue
@@ -110,7 +110,7 @@ export default {
kind="primary"
:title="__('Branch has changed')"
:text="__('This branch has changed since you started editing. Would you like to create a new branch?')"
- @toggle="showNewBranchModal = false"
+ @cancel="showNewBranchModal = false"
@submit="makeCommit(true)"
/>
<commit-files-list
diff --git a/app/assets/javascripts/ide/components/repo_edit_button.vue b/app/assets/javascripts/ide/components/repo_edit_button.vue
index 37bd9003e96..42d5d709209 100644
--- a/app/assets/javascripts/ide/components/repo_edit_button.vue
+++ b/app/assets/javascripts/ide/components/repo_edit_button.vue
@@ -50,7 +50,7 @@ export default {
kind="warning"
:title="__('Are you sure?')"
:text="__('Are you sure you want to discard your changes?')"
- @toggle="closeDiscardPopup"
+ @cancel="closeDiscardPopup"
@submit="toggleEditMode(true)"
/>
</div>
diff --git a/app/assets/javascripts/pages/profiles/accounts/show/components/delete_account_modal.vue b/app/assets/javascripts/pages/profiles/accounts/show/components/delete_account_modal.vue
new file mode 100644
index 00000000000..1107498c12e
--- /dev/null
+++ b/app/assets/javascripts/pages/profiles/accounts/show/components/delete_account_modal.vue
@@ -0,0 +1,127 @@
+<script>
+ import Vue from 'vue';
+
+ import modal from '~/vue_shared/components/modal.vue';
+ import { __, s__, sprintf } from '~/locale';
+ import csrf from '~/lib/utils/csrf';
+
+ export default {
+ props: {
+ actionUrl: {
+ type: String,
+ required: true,
+ },
+ confirmWithPassword: {
+ type: Boolean,
+ required: true,
+ },
+ username: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ enteredPassword: '',
+ enteredUsername: '',
+ };
+ },
+ components: {
+ modal,
+ },
+ computed: {
+ csrfToken() {
+ return csrf.token;
+ },
+ inputLabel() {
+ let confirmationValue;
+ if (this.confirmWithPassword) {
+ confirmationValue = __('password');
+ } else {
+ confirmationValue = __('username');
+ }
+
+ confirmationValue = `<code>${confirmationValue}</code>`;
+
+ return sprintf(
+ s__('Profiles|Type your %{confirmationValue} to confirm:'),
+ { confirmationValue },
+ false,
+ );
+ },
+ text() {
+ return sprintf(
+ s__(`Profiles|
+You are about to permanently delete %{yourAccount}, and all of the issues, merge requests, and groups linked to your account.
+Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
+ {
+ yourAccount: `<strong>${s__('Profiles|your account')}</strong>`,
+ deleteAccount: `<strong>${s__('Profiles|Delete Account')}</strong>`,
+ },
+ false,
+ );
+ },
+ },
+ methods: {
+ canSubmit() {
+ if (this.confirmWithPassword) {
+ return this.enteredPassword !== '';
+ }
+
+ return this.enteredUsername === this.username;
+ },
+ onSubmit(event) {
+ this.$refs.form.submit();
+ },
+ },
+ };
+</script>
+
+<template>
+ <modal
+ id="delete-account-modal"
+ :title="s__('Profiles|Delete your account?')"
+ :text="text"
+ kind="danger"
+ :primary-button-label="s__('Profiles|Delete account')"
+ @submit="onSubmit"
+ :submitDisabled="!canSubmit()">
+
+ <template slot="body" slot-scope="props">
+ <p v-html="props.text"></p>
+
+ <form
+ ref="form"
+ :action="actionUrl"
+ method="post">
+
+ <input
+ type="hidden"
+ name="_method"
+ value="delete" />
+ <input
+ type="hidden"
+ name="authenticity_token"
+ :value="csrfToken" />
+
+ <p id="input-label" v-html="inputLabel"></p>
+
+ <input
+ v-if="confirmWithPassword"
+ name="password"
+ class="form-control"
+ type="password"
+ v-model="enteredPassword"
+ aria-labelledby="input-label" />
+ <input
+ v-else
+ name="username"
+ class="form-control"
+ type="text"
+ v-model="enteredUsername"
+ aria-labelledby="input-label" />
+ </form>
+ </template>
+
+ </modal>
+</template>
diff --git a/app/assets/javascripts/pages/profiles/accounts/show/index.js b/app/assets/javascripts/pages/profiles/accounts/show/index.js
new file mode 100644
index 00000000000..2ad89ca6cfa
--- /dev/null
+++ b/app/assets/javascripts/pages/profiles/accounts/show/index.js
@@ -0,0 +1,40 @@
+import Vue from 'vue';
+
+import Translate from '~/vue_shared/translate';
+
+import deleteAccountModal from './components/delete_account_modal.vue';
+
+Vue.use(Translate);
+
+export function mountDeleteAccountModal() {
+ const deleteAccountButton = document.getElementById('delete-account-button');
+ if (!deleteAccountButton) {
+ return null;
+ }
+
+ const deleteAccountModalEl = document.createElement('div');
+ deleteAccountButton.parentNode.appendChild(deleteAccountModalEl);
+
+ return new Vue({
+ el: deleteAccountModalEl,
+ components: {
+ deleteAccountModal,
+ },
+ mounted() {
+ deleteAccountButton.classList.remove('disabled');
+ },
+ render(createElement) {
+ return createElement('delete-account-modal', {
+ props: {
+ actionUrl: deleteAccountButton.dataset.actionUrl,
+ confirmWithPassword: !!deleteAccountButton.dataset.confirmWithPassword,
+ username: deleteAccountButton.dataset.username,
+ },
+ });
+ },
+ });
+}
+
+export default () => {
+ mountDeleteAccountModal();
+};
diff --git a/app/assets/javascripts/profile/account/components/delete_account_modal.vue b/app/assets/javascripts/profile/account/components/delete_account_modal.vue
deleted file mode 100644
index 78be6b6e884..00000000000
--- a/app/assets/javascripts/profile/account/components/delete_account_modal.vue
+++ /dev/null
@@ -1,146 +0,0 @@
-<script>
- import modal from '../../../vue_shared/components/modal.vue';
- import { __, s__, sprintf } from '../../../locale';
- import csrf from '../../../lib/utils/csrf';
-
- export default {
- props: {
- actionUrl: {
- type: String,
- required: true,
- },
- confirmWithPassword: {
- type: Boolean,
- required: true,
- },
- username: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- enteredPassword: '',
- enteredUsername: '',
- isOpen: false,
- };
- },
- components: {
- modal,
- },
- computed: {
- csrfToken() {
- return csrf.token;
- },
- inputLabel() {
- let confirmationValue;
- if (this.confirmWithPassword) {
- confirmationValue = __('password');
- } else {
- confirmationValue = __('username');
- }
-
- confirmationValue = `<code>${confirmationValue}</code>`;
-
- return sprintf(
- s__('Profiles|Type your %{confirmationValue} to confirm:'),
- { confirmationValue },
- false,
- );
- },
- text() {
- return sprintf(
- s__(`Profiles|
-You are about to permanently delete %{yourAccount}, and all of the issues, merge requests, and groups linked to your account.
-Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
- {
- yourAccount: `<strong>${s__('Profiles|your account')}</strong>`,
- deleteAccount: `<strong>${s__('Profiles|Delete Account')}</strong>`,
- },
- false,
- );
- },
- },
- methods: {
- canSubmit() {
- if (this.confirmWithPassword) {
- return this.enteredPassword !== '';
- }
-
- return this.enteredUsername === this.username;
- },
- onSubmit(status) {
- if (status) {
- if (!this.canSubmit()) {
- return;
- }
-
- this.$refs.form.submit();
- }
-
- this.toggleOpen(false);
- },
- toggleOpen(isOpen) {
- this.isOpen = isOpen;
- },
- },
- };
-</script>
-
-<template>
- <div>
- <modal
- v-if="isOpen"
- :title="s__('Profiles|Delete your account?')"
- :text="text"
- :kind="`danger ${!canSubmit() && 'disabled'}`"
- :primary-button-label="s__('Profiles|Delete account')"
- @toggle="toggleOpen"
- @submit="onSubmit">
-
- <template slot="body" slot-scope="props">
- <p v-html="props.text"></p>
-
- <form
- ref="form"
- :action="actionUrl"
- method="post">
-
- <input
- type="hidden"
- name="_method"
- value="delete" />
- <input
- type="hidden"
- name="authenticity_token"
- :value="csrfToken" />
-
- <p id="input-label" v-html="inputLabel"></p>
-
- <input
- v-if="confirmWithPassword"
- name="password"
- class="form-control"
- type="password"
- v-model="enteredPassword"
- aria-labelledby="input-label" />
- <input
- v-else
- name="username"
- class="form-control"
- type="text"
- v-model="enteredUsername"
- aria-labelledby="input-label" />
- </form>
- </template>
-
- </modal>
-
- <button
- type="button"
- class="btn btn-danger"
- @click="toggleOpen(true)">
- {{ s__('Profiles|Delete account') }}
- </button>
- </div>
-</template>
diff --git a/app/assets/javascripts/profile/account/index.js b/app/assets/javascripts/profile/account/index.js
deleted file mode 100644
index 635056e0eeb..00000000000
--- a/app/assets/javascripts/profile/account/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import Vue from 'vue';
-
-import deleteAccountModal from './components/delete_account_modal.vue';
-
-const deleteAccountModalEl = document.getElementById('delete-account-modal');
-// eslint-disable-next-line no-new
-new Vue({
- el: deleteAccountModalEl,
- components: {
- deleteAccountModal,
- },
- render(createElement) {
- return createElement('delete-account-modal', {
- props: {
- actionUrl: deleteAccountModalEl.dataset.actionUrl,
- confirmWithPassword: !!deleteAccountModalEl.dataset.confirmWithPassword,
- username: deleteAccountModalEl.dataset.username,
- },
- });
- },
-});
diff --git a/app/assets/javascripts/vue_shared/components/modal.vue b/app/assets/javascripts/vue_shared/components/modal.vue
index 55f466b7b41..00089dfef38 100644
--- a/app/assets/javascripts/vue_shared/components/modal.vue
+++ b/app/assets/javascripts/vue_shared/components/modal.vue
@@ -3,6 +3,10 @@ export default {
name: 'modal',
props: {
+ id: {
+ type: String,
+ required: false,
+ },
title: {
type: String,
required: false,
@@ -62,11 +66,11 @@ export default {
},
methods: {
- close() {
- this.$emit('toggle', false);
+ emitCancel(event) {
+ this.$emit('cancel', event);
},
- emitSubmit(status) {
- this.$emit('submit', status);
+ emitSubmit(event) {
+ this.$emit('submit', event);
},
},
};
@@ -75,7 +79,9 @@ export default {
<template>
<div class="modal-open">
<div
- class="modal show"
+ :id="id"
+ class="modal"
+ :class="id ? '' : 'show'"
role="dialog"
tabindex="-1"
>
@@ -93,7 +99,8 @@ export default {
<button
type="button"
class="close pull-right"
- @click="close"
+ @click="emitCancel($event)"
+ data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">&times;</span>
@@ -110,7 +117,8 @@ export default {
type="button"
class="btn pull-left"
:class="btnCancelKindClass"
- @click="close">
+ @click="emitCancel($event)"
+ data-dismiss="modal">
{{ closeButtonLabel }}
</button>
<button
@@ -119,13 +127,17 @@ export default {
class="btn pull-right js-primary-button"
:disabled="submitDisabled"
:class="btnKindClass"
- @click="emitSubmit(true)">
+ @click="emitSubmit($event)"
+ data-dismiss="modal">
{{ primaryButtonLabel }}
</button>
</div>
</div>
</div>
</div>
- <div class="modal-backdrop fade in" />
+ <div
+ v-if="!id"
+ class="modal-backdrop fade in">
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/recaptcha_modal.vue b/app/assets/javascripts/vue_shared/components/recaptcha_modal.vue
index 8053c65d498..16d60bb2876 100644
--- a/app/assets/javascripts/vue_shared/components/recaptcha_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/recaptcha_modal.vue
@@ -70,7 +70,7 @@ export default {
class="recaptcha-modal js-recaptcha-modal"
:hide-footer="true"
:title="__('Please solve the reCAPTCHA')"
- @toggle="close"
+ @cancel="close"
>
<div slot="body">
<p>
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index f1313b79589..ef168b6aff3 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -84,11 +84,14 @@
= s_('Profiles|Deleting an account has the following effects:')
= render 'users/deletion_guidance', user: current_user
- #delete-account-modal{ data: { action_url: user_registration_path,
+ %button#delete-account-button.btn.btn-danger.disabled{ data: { toggle: 'modal',
+ target: '#delete-account-modal',
+ action_url: user_registration_path,
confirm_with_password: ('true' if current_user.confirm_deletion_with_password?),
- username: current_user.username } }
- %button.btn.btn-danger.disabled
- = s_('Profiles|Delete account')
+ username: current_user.username },
+ type: 'button' }
+ = s_('Profiles|Delete account')
+
- else
- if @user.solo_owned_groups.present?
%p
@@ -100,6 +103,3 @@
%p
= s_("Profiles|You don't have access to delete this user.")
.append-bottom-default
-
-- content_for :page_specific_javascripts do
- = webpack_bundle_tag('account')
diff --git a/changelogs/unreleased/winh-modal-target-id.yml b/changelogs/unreleased/winh-modal-target-id.yml
new file mode 100644
index 00000000000..f8d5b72be50
--- /dev/null
+++ b/changelogs/unreleased/winh-modal-target-id.yml
@@ -0,0 +1,5 @@
+---
+title: Add id to modal.vue to support data-toggle="modal"
+merge_request: 16189
+author:
+type: other
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 5f95255334c..222c5084abf 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -26,7 +26,6 @@ var config = {
},
context: path.join(ROOT_PATH, 'app/assets/javascripts'),
entry: {
- account: './profile/account/index.js',
balsamiq_viewer: './blob/balsamiq_viewer.js',
blob: './blob_edit/blob_bundle.js',
boards: './boards/boards_bundle.js',
diff --git a/spec/javascripts/groups/components/item_actions_spec.js b/spec/javascripts/groups/components/item_actions_spec.js
index 7a5c1da4d1d..6d6fb410859 100644
--- a/spec/javascripts/groups/components/item_actions_spec.js
+++ b/spec/javascripts/groups/components/item_actions_spec.js
@@ -47,17 +47,11 @@ describe('ItemActionsComponent', () => {
it('should change `modalStatus` prop to `false` and emit `leaveGroup` event with required params when called with `leaveConfirmed` as `true`', () => {
spyOn(eventHub, '$emit');
vm.modalStatus = true;
- vm.leaveGroup(true);
- expect(vm.modalStatus).toBeFalsy();
- expect(eventHub.$emit).toHaveBeenCalledWith('leaveGroup', vm.group, vm.parentGroup);
- });
- it('should change `modalStatus` prop to `false` and should NOT emit `leaveGroup` event when called with `leaveConfirmed` as `false`', () => {
- spyOn(eventHub, '$emit');
- vm.modalStatus = true;
- vm.leaveGroup(false);
+ vm.leaveGroup();
+
expect(vm.modalStatus).toBeFalsy();
- expect(eventHub.$emit).not.toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalledWith('leaveGroup', vm.group, vm.parentGroup);
});
});
});
diff --git a/spec/javascripts/profile/account/components/delete_account_modal_spec.js b/spec/javascripts/pages/profiles/accounts/show/components/delete_account_modal_spec.js
index 2e94948cfb2..12ce81719f6 100644
--- a/spec/javascripts/profile/account/components/delete_account_modal_spec.js
+++ b/spec/javascripts/pages/profiles/accounts/show/components/delete_account_modal_spec.js
@@ -1,8 +1,8 @@
import Vue from 'vue';
-import deleteAccountModal from '~/profile/account/components/delete_account_modal.vue';
+import deleteAccountModal from '~/pages/profiles/accounts/show/components/delete_account_modal.vue';
-import mountComponent from '../../../helpers/vue_mount_component_helper';
+import mountComponent from '../../../../../helpers/vue_mount_component_helper';
describe('DeleteAccountModal component', () => {
const actionUrl = `${gl.TEST_HOST}/delete/user`;
diff --git a/spec/javascripts/pages/profiles/accounts/show/index_spec.js b/spec/javascripts/pages/profiles/accounts/show/index_spec.js
new file mode 100644
index 00000000000..af393893bf5
--- /dev/null
+++ b/spec/javascripts/pages/profiles/accounts/show/index_spec.js
@@ -0,0 +1,33 @@
+import * as profileAccountModule from '~/pages/profiles/accounts/show';
+
+describe('Profile Account bundle', () => {
+ beforeEach(() => {
+ setFixtures(`
+ <div id="container">
+ <button
+ id="delete-account-button"
+ class="disabled"
+ data-action-url="dummy-action-url"
+ data-username="dummy-username"></button>
+ </div>
+ `);
+ });
+
+ it('mounts the delete account modal', () => {
+ const container = document.getElementById('container');
+
+ profileAccountModule.default();
+
+ expect(container.querySelector('#delete-account-modal')).not.toBeNull();
+ });
+
+ describe('mountDeleteAccountModal', () => {
+ it('passes the props from delete account button to the modal', () => {
+ const vm = profileAccountModule.mountDeleteAccountModal();
+ const modal = vm.$children[0];
+
+ expect(modal.actionUrl).toBe('dummy-action-url');
+ expect(modal.username).toBe('dummy-username');
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/new_dropdown/index_spec.js b/spec/javascripts/repo/components/new_dropdown/index_spec.js
index b001c1655b4..6efbbf6d75e 100644
--- a/spec/javascripts/repo/components/new_dropdown/index_spec.js
+++ b/spec/javascripts/repo/components/new_dropdown/index_spec.js
@@ -57,16 +57,17 @@ describe('new dropdown component', () => {
});
});
- describe('toggleModalOpen', () => {
+ describe('hideModal', () => {
+ beforeAll((done) => {
+ vm.openModal = true;
+ Vue.nextTick(done);
+ });
+
it('closes modal after toggling', (done) => {
- vm.toggleModalOpen();
+ vm.hideModal();
Vue.nextTick()
.then(() => {
- expect(vm.$el.querySelector('.modal')).not.toBeNull();
- })
- .then(vm.toggleModalOpen)
- .then(() => {
expect(vm.$el.querySelector('.modal')).toBeNull();
})
.then(done)
diff --git a/spec/javascripts/vue_shared/components/modal_spec.js b/spec/javascripts/vue_shared/components/modal_spec.js
index 721f4044659..75b67bcc792 100644
--- a/spec/javascripts/vue_shared/components/modal_spec.js
+++ b/spec/javascripts/vue_shared/components/modal_spec.js
@@ -2,11 +2,69 @@ import Vue from 'vue';
import modal from '~/vue_shared/components/modal.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
+const modalComponent = Vue.extend(modal);
+
describe('Modal', () => {
- it('does not render a primary button if no primaryButtonLabel', () => {
- const modalComponent = Vue.extend(modal);
- const vm = mountComponent(modalComponent);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('props', () => {
+ describe('without primaryButtonLabel', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, {
+ primaryButtonLabel: null,
+ });
+ });
+
+ it('does not render a primary button', () => {
+ expect(vm.$el.querySelector('.js-primary-button')).toBeNull();
+ });
+ });
+
+ describe('with id', () => {
+ it('does not render a primary button', () => {
+ beforeEach(() => {
+ vm = mountComponent(modalComponent, {
+ id: 'my-modal',
+ });
+ });
+
+ it('assigns the id to the modal', () => {
+ expect(vm.$el.querySelector('#my-modal.modal')).not.toBeNull();
+ });
+
+ it('does not show the modal immediately', () => {
+ expect(vm.$el.querySelector('#my-modal.modal')).not.toHaveClass('show');
+ });
+
+ it('does not show a backdrop', () => {
+ expect(vm.$el.querySelector('modal-backdrop')).toBeNull();
+ });
+ });
+ });
+
+ it('works with data-toggle="modal"', (done) => {
+ setFixtures(`
+ <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
+ <div id="modal-container"></div>
+ `);
+
+ const modalContainer = document.getElementById('modal-container');
+ const modalButton = document.getElementById('modal-button');
+ vm = mountComponent(modalComponent, {
+ id: 'my-modal',
+ }, modalContainer);
+ const modalElement = vm.$el.querySelector('#my-modal');
+ expect(modalElement).not.toHaveClass('in');
+ $(modalElement).on('shown.bs.modal', () => {
+ expect(modalElement).toHaveClass('in');
+ done();
+ });
- expect(vm.$el.querySelector('.js-primary-button')).toBeNull();
+ modalButton.click();
+ });
});
});