Commit fa65c340 authored by Winnie Hellmann's avatar Winnie Hellmann Committed by Clement Ho

Display reCAPTCHA modal when making issue public

parent 287d0eaf
...@@ -5,6 +5,7 @@ import tooltip from '~/vue_shared/directives/tooltip'; ...@@ -5,6 +5,7 @@ import tooltip from '~/vue_shared/directives/tooltip';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import eventHub from '~/sidebar/event_hub'; import eventHub from '~/sidebar/event_hub';
import editForm from './edit_form.vue'; import editForm from './edit_form.vue';
import recaptchaModalImplementor from '~/vue_shared/mixins/recaptcha_modal_implementor';
export default { export default {
components: { components: {
...@@ -14,6 +15,7 @@ export default { ...@@ -14,6 +15,7 @@ export default {
directives: { directives: {
tooltip, tooltip,
}, },
mixins: [recaptchaModalImplementor],
props: { props: {
isConfidential: { isConfidential: {
required: true, required: true,
...@@ -54,9 +56,14 @@ export default { ...@@ -54,9 +56,14 @@ export default {
updateConfidentialAttribute(confidential) { updateConfidentialAttribute(confidential) {
this.service this.service
.update('issue', { confidential }) .update('issue', { confidential })
.then(({ data }) => this.checkForSpam(data))
.then(() => window.location.reload()) .then(() => window.location.reload())
.catch(() => { .catch(error => {
if (error.name === 'SpamError') {
this.openRecaptcha();
} else {
Flash(__('Something went wrong trying to change the confidentiality of this issue')); Flash(__('Something went wrong trying to change the confidentiality of this issue'));
}
}); });
}, },
}, },
...@@ -112,5 +119,7 @@ export default { ...@@ -112,5 +119,7 @@ export default {
{{ __('This issue is confidential') }} {{ __('This issue is confidential') }}
</div> </div>
</div> </div>
<recaptcha-modal v-if="showRecaptcha" :html="recaptchaHTML" @close="closeRecaptcha" />
</div> </div>
</template> </template>
...@@ -32,6 +32,10 @@ export default { ...@@ -32,6 +32,10 @@ export default {
mounted() { mounted() {
eventHub.$on('submit', this.submit); eventHub.$on('submit', this.submit);
if (this.html) {
this.appendRecaptchaScript();
}
}, },
beforeDestroy() { beforeDestroy() {
......
---
title: Display reCAPTCHA modal when making issue public
merge_request: 17553
author:
type: fixed
...@@ -49,6 +49,8 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = false and ...@@ -49,6 +49,8 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = false and
</div> </div>
</div> </div>
<!---->
</div> </div>
`; `;
...@@ -111,6 +113,8 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = false and ...@@ -111,6 +113,8 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = false and
</div> </div>
</div> </div>
<!---->
</div> </div>
`; `;
...@@ -163,6 +167,8 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = true and ...@@ -163,6 +167,8 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = true and
</div> </div>
</div> </div>
<!---->
</div> </div>
`; `;
...@@ -225,5 +231,7 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = true and ...@@ -225,5 +231,7 @@ exports[`Confidential Issue Sidebar Block renders for isConfidential = true and
</div> </div>
</div> </div>
<!---->
</div> </div>
`; `;
...@@ -2,15 +2,36 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,15 +2,36 @@ import { shallowMount } from '@vue/test-utils';
import ConfidentialIssueSidebar from '~/sidebar/components/confidential/confidential_issue_sidebar.vue'; import ConfidentialIssueSidebar from '~/sidebar/components/confidential/confidential_issue_sidebar.vue';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper'; import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import EditForm from '~/sidebar/components/confidential/edit_form.vue'; import EditForm from '~/sidebar/components/confidential/edit_form.vue';
import SidebarService from '~/sidebar/services/sidebar_service';
import createFlash from '~/flash';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal';
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
describe('Confidential Issue Sidebar Block', () => { describe('Confidential Issue Sidebar Block', () => {
let wrapper; let wrapper;
const createComponent = propsData => { const findRecaptchaModal = () => wrapper.find(RecaptchaModal);
const service = {
update: () => Promise.resolve(true), const triggerUpdateConfidentialAttribute = () => {
wrapper.setData({ edit: true });
return (
// wait for edit form to become visible
wrapper.vm
.$nextTick()
.then(() => {
const editForm = wrapper.find(EditForm);
const { updateConfidentialAttribute } = editForm.props();
updateConfidentialAttribute();
})
// wait for reCAPTCHA modal to render
.then(() => wrapper.vm.$nextTick())
);
}; };
const createComponent = propsData => {
const service = new SidebarService();
wrapper = shallowMount(ConfidentialIssueSidebar, { wrapper = shallowMount(ConfidentialIssueSidebar, {
propsData: { propsData: {
service, service,
...@@ -20,6 +41,15 @@ describe('Confidential Issue Sidebar Block', () => { ...@@ -20,6 +41,15 @@ describe('Confidential Issue Sidebar Block', () => {
}); });
}; };
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(window.location, 'reload').mockImplementation();
});
afterEach(() => {
wrapper.destroy();
});
it.each` it.each`
isConfidential | isEditable isConfidential | isEditable
${false} | ${false} ${false} | ${false}
...@@ -38,10 +68,6 @@ describe('Confidential Issue Sidebar Block', () => { ...@@ -38,10 +68,6 @@ describe('Confidential Issue Sidebar Block', () => {
}, },
); );
afterEach(() => {
wrapper.destroy();
});
describe('if editable', () => { describe('if editable', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ createComponent({
...@@ -81,5 +107,61 @@ describe('Confidential Issue Sidebar Block', () => { ...@@ -81,5 +107,61 @@ describe('Confidential Issue Sidebar Block', () => {
property: 'confidentiality', property: 'confidentiality',
}); });
}); });
describe('for successful update', () => {
beforeEach(() => {
SidebarService.prototype.update.mockResolvedValue({ data: 'irrelevant' });
});
it('reloads the page', () =>
triggerUpdateConfidentialAttribute().then(() => {
expect(window.location.reload).toHaveBeenCalled();
}));
it('does not show an error message', () =>
triggerUpdateConfidentialAttribute().then(() => {
expect(createFlash).not.toHaveBeenCalled();
}));
});
describe('for update error', () => {
beforeEach(() => {
SidebarService.prototype.update.mockRejectedValue(new Error('updating failed!'));
});
it('does not reload the page', () =>
triggerUpdateConfidentialAttribute().then(() => {
expect(window.location.reload).not.toHaveBeenCalled();
}));
it('shows an error message', () =>
triggerUpdateConfidentialAttribute().then(() => {
expect(createFlash).toHaveBeenCalled();
}));
});
describe('for spam error', () => {
beforeEach(() => {
SidebarService.prototype.update.mockRejectedValue({ name: 'SpamError' });
});
it('does not reload the page', () =>
triggerUpdateConfidentialAttribute().then(() => {
expect(window.location.reload).not.toHaveBeenCalled();
}));
it('does not show an error message', () =>
triggerUpdateConfidentialAttribute().then(() => {
expect(createFlash).not.toHaveBeenCalled();
}));
it('shows a reCAPTCHA modal', () => {
expect(findRecaptchaModal().exists()).toBe(false);
return triggerUpdateConfidentialAttribute().then(() => {
expect(findRecaptchaModal().exists()).toBe(true);
});
});
});
}); });
}); });
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