2021-01-29 00:20:46 +05:30
|
|
|
import { GlModal } from '@gitlab/ui';
|
2021-03-11 19:13:27 +05:30
|
|
|
import { shallowMount } from '@vue/test-utils';
|
2018-05-09 12:01:36 +05:30
|
|
|
import MockAdapter from 'axios-mock-adapter';
|
2020-04-22 19:07:51 +05:30
|
|
|
import { TEST_HOST } from 'helpers/test_constants';
|
2021-04-17 20:07:23 +05:30
|
|
|
import { deprecatedCreateFlash as createFlash } from '~/flash';
|
2020-01-01 13:55:28 +05:30
|
|
|
import axios from '~/lib/utils/axios_utils';
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
import UpdateUsername from '~/profile/account/components/update_username.vue';
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
jest.mock('~/flash');
|
|
|
|
|
2018-05-09 12:01:36 +05:30
|
|
|
describe('UpdateUsername component', () => {
|
2020-04-22 19:07:51 +05:30
|
|
|
const rootUrl = TEST_HOST;
|
|
|
|
const actionUrl = `${TEST_HOST}/update/username`;
|
2021-01-29 00:20:46 +05:30
|
|
|
const defaultProps = {
|
|
|
|
actionUrl,
|
|
|
|
rootUrl,
|
|
|
|
initialUsername: 'hasnoname',
|
|
|
|
};
|
|
|
|
let wrapper;
|
2018-05-09 12:01:36 +05:30
|
|
|
let axiosMock;
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
const createComponent = (props = {}) => {
|
|
|
|
wrapper = shallowMount(UpdateUsername, {
|
|
|
|
propsData: {
|
|
|
|
...defaultProps,
|
|
|
|
...props,
|
|
|
|
},
|
|
|
|
stubs: {
|
|
|
|
GlModal,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2018-05-09 12:01:36 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
axiosMock = new MockAdapter(axios);
|
2021-01-29 00:20:46 +05:30
|
|
|
createComponent();
|
2018-05-09 12:01:36 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
2021-01-29 00:20:46 +05:30
|
|
|
wrapper.destroy();
|
2018-05-09 12:01:36 +05:30
|
|
|
axiosMock.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
const findElements = () => {
|
2021-01-29 00:20:46 +05:30
|
|
|
const modal = wrapper.find(GlModal);
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
return {
|
2021-01-29 00:20:46 +05:30
|
|
|
modal,
|
|
|
|
input: wrapper.find(`#${wrapper.vm.$options.inputId}`),
|
|
|
|
openModalBtn: wrapper.find('[data-testid="username-change-confirmation-modal"]'),
|
|
|
|
modalBody: modal.find('.modal-body'),
|
|
|
|
modalHeader: modal.find('.modal-title'),
|
|
|
|
confirmModalBtn: wrapper.find('.btn-warning'),
|
2018-05-09 12:01:36 +05:30
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it('has a disabled button if the username was not changed', async () => {
|
|
|
|
const { openModalBtn } = findElements();
|
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
expect(openModalBtn.props('disabled')).toBe(true);
|
2018-05-09 12:01:36 +05:30
|
|
|
});
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it('has an enabled button which if the username was changed', async () => {
|
2018-05-09 12:01:36 +05:30
|
|
|
const { input, openModalBtn } = findElements();
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
input.element.value = 'newUsername';
|
|
|
|
input.trigger('input');
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
await wrapper.vm.$nextTick();
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
expect(openModalBtn.props('disabled')).toBe(false);
|
2018-05-09 12:01:36 +05:30
|
|
|
});
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
describe('changing username', () => {
|
|
|
|
const newUsername = 'new_username';
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
beforeEach(async () => {
|
|
|
|
createComponent();
|
|
|
|
wrapper.setData({ newUsername });
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
});
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it('confirmation modal contains proper header and body', async () => {
|
|
|
|
const { modal } = findElements();
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
expect(modal.props('title')).toBe('Change username?');
|
2021-01-29 00:20:46 +05:30
|
|
|
expect(modal.text()).toContain(
|
|
|
|
`You are going to change the username ${defaultProps.initialUsername} to ${newUsername}`,
|
|
|
|
);
|
|
|
|
});
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it('executes API call on confirmation button click', async () => {
|
|
|
|
axiosMock.onPut(actionUrl).replyOnce(() => [200, { message: 'Username changed' }]);
|
|
|
|
jest.spyOn(axios, 'put');
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
await wrapper.vm.onConfirm();
|
|
|
|
await wrapper.vm.$nextTick();
|
2018-12-13 13:39:08 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } });
|
|
|
|
});
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it('sets the username after a successful update', async () => {
|
|
|
|
const { input, openModalBtn } = findElements();
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
axiosMock.onPut(actionUrl).replyOnce(() => {
|
|
|
|
expect(input.attributes('disabled')).toBe('disabled');
|
2021-04-17 20:07:23 +05:30
|
|
|
expect(openModalBtn.props('disabled')).toBe(false);
|
|
|
|
expect(openModalBtn.props('loading')).toBe(true);
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
return [200, { message: 'Username changed' }];
|
|
|
|
});
|
|
|
|
|
|
|
|
await wrapper.vm.onConfirm();
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
expect(input.attributes('disabled')).toBe(undefined);
|
|
|
|
expect(openModalBtn.props('disabled')).toBe(true);
|
2021-04-17 20:07:23 +05:30
|
|
|
expect(openModalBtn.props('loading')).toBe(false);
|
2018-05-09 12:01:36 +05:30
|
|
|
});
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it('does not set the username after a erroneous update', async () => {
|
|
|
|
const { input, openModalBtn } = findElements();
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
axiosMock.onPut(actionUrl).replyOnce(() => {
|
|
|
|
expect(input.attributes('disabled')).toBe('disabled');
|
2021-04-17 20:07:23 +05:30
|
|
|
expect(openModalBtn.props('disabled')).toBe(false);
|
|
|
|
expect(openModalBtn.props('loading')).toBe(true);
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
return [400, { message: 'Invalid username' }];
|
|
|
|
});
|
2018-05-09 12:01:36 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
await expect(wrapper.vm.onConfirm()).rejects.toThrow();
|
|
|
|
expect(input.attributes('disabled')).toBe(undefined);
|
|
|
|
expect(openModalBtn.props('disabled')).toBe(false);
|
2021-04-17 20:07:23 +05:30
|
|
|
expect(openModalBtn.props('loading')).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows an error message if the error response has a `message` property', async () => {
|
|
|
|
axiosMock.onPut(actionUrl).replyOnce(() => {
|
|
|
|
return [400, { message: 'Invalid username' }];
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(wrapper.vm.onConfirm()).rejects.toThrow();
|
|
|
|
|
|
|
|
expect(createFlash).toBeCalledWith('Invalid username');
|
|
|
|
});
|
|
|
|
|
|
|
|
it("shows a fallback error message if the error response doesn't have a `message` property", async () => {
|
|
|
|
axiosMock.onPut(actionUrl).replyOnce(() => {
|
|
|
|
return [400];
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(wrapper.vm.onConfirm()).rejects.toThrow();
|
|
|
|
|
|
|
|
expect(createFlash).toBeCalledWith(
|
|
|
|
'An error occurred while updating your username, please try again.',
|
|
|
|
);
|
2018-05-09 12:01:36 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|