debian-mirror-gitlab/spec/frontend/profile/preferences/components/profile_preferences_spec.js

267 lines
7.3 KiB
JavaScript
Raw Normal View History

2021-03-11 19:13:27 +05:30
import { GlButton } from '@gitlab/ui';
2021-01-29 00:20:46 +05:30
import { shallowMount } from '@vue/test-utils';
2021-04-17 20:07:23 +05:30
import { nextTick } from 'vue';
2021-03-11 19:13:27 +05:30
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
2021-01-29 00:20:46 +05:30
import IntegrationView from '~/profile/preferences/components/integration_view.vue';
2021-03-11 19:13:27 +05:30
import ProfilePreferences from '~/profile/preferences/components/profile_preferences.vue';
import { i18n } from '~/profile/preferences/constants';
2021-04-17 20:07:23 +05:30
import {
integrationViews,
userFields,
bodyClasses,
themes,
lightModeThemeId1,
darkModeThemeId,
lightModeThemeId2,
} from '../mock_data';
2021-03-11 19:13:27 +05:30
const expectedUrl = '/foo';
2021-01-29 00:20:46 +05:30
describe('ProfilePreferences component', () => {
let wrapper;
const defaultProvide = {
integrationViews: [],
userFields,
2021-03-11 19:13:27 +05:30
bodyClasses,
2021-04-17 20:07:23 +05:30
themes,
2021-03-11 19:13:27 +05:30
profilePreferencesPath: '/update-profile',
formEl: document.createElement('form'),
2021-01-29 00:20:46 +05:30
};
function createComponent(options = {}) {
2021-03-11 19:13:27 +05:30
const { props = {}, provide = {}, attachTo } = options;
return extendedWrapper(
shallowMount(ProfilePreferences, {
provide: {
...defaultProvide,
...provide,
},
propsData: props,
attachTo,
}),
);
}
function findIntegrationsDivider() {
return wrapper.findByTestId('profile-preferences-integrations-rule');
}
function findIntegrationsHeading() {
return wrapper.findByTestId('profile-preferences-integrations-heading');
}
function findSubmitButton() {
return wrapper.findComponent(GlButton);
2021-01-29 00:20:46 +05:30
}
2021-03-11 19:13:27 +05:30
function findFlashError() {
return document.querySelector('.flash-container .flash-text');
}
2021-04-17 20:07:23 +05:30
function createThemeInput(themeId = lightModeThemeId1) {
const input = document.createElement('input');
input.setAttribute('name', 'user[theme_id]');
input.setAttribute('type', 'radio');
input.setAttribute('value', themeId.toString());
input.setAttribute('checked', 'checked');
return input;
}
function createForm(themeInput = createThemeInput()) {
const form = document.createElement('form');
form.setAttribute('url', expectedUrl);
form.setAttribute('method', 'put');
form.appendChild(themeInput);
return form;
}
function setupBody() {
const div = document.createElement('div');
div.classList.add('container-fluid');
document.body.appendChild(div);
document.body.classList.add('content-wrapper');
}
2021-03-11 19:13:27 +05:30
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
2021-01-29 00:20:46 +05:30
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('should not render Integrations section', () => {
wrapper = createComponent();
const views = wrapper.findAll(IntegrationView);
2021-03-11 19:13:27 +05:30
const divider = findIntegrationsDivider();
const heading = findIntegrationsHeading();
2021-01-29 00:20:46 +05:30
expect(divider.exists()).toBe(false);
expect(heading.exists()).toBe(false);
expect(views).toHaveLength(0);
});
it('should render Integration section', () => {
wrapper = createComponent({ provide: { integrationViews } });
2021-03-11 19:13:27 +05:30
const divider = findIntegrationsDivider();
const heading = findIntegrationsHeading();
2021-01-29 00:20:46 +05:30
const views = wrapper.findAll(IntegrationView);
expect(divider.exists()).toBe(true);
expect(heading.exists()).toBe(true);
expect(views).toHaveLength(integrationViews.length);
});
2021-03-11 19:13:27 +05:30
describe('form submit', () => {
let form;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
beforeEach(() => {
2021-04-17 20:07:23 +05:30
setupBody();
form = createForm();
2021-03-11 19:13:27 +05:30
wrapper = createComponent({ provide: { formEl: form }, attachTo: document.body });
const beforeSendEvent = new CustomEvent('ajax:beforeSend');
form.dispatchEvent(beforeSendEvent);
});
it('disables the submit button', async () => {
2021-04-17 20:07:23 +05:30
await nextTick();
2021-03-11 19:13:27 +05:30
const button = findSubmitButton();
expect(button.props('disabled')).toBe(true);
});
it('success re-enables the submit button', async () => {
const successEvent = new CustomEvent('ajax:success');
form.dispatchEvent(successEvent);
2021-04-17 20:07:23 +05:30
await nextTick();
2021-03-11 19:13:27 +05:30
const button = findSubmitButton();
expect(button.props('disabled')).toBe(false);
});
it('error re-enables the submit button', async () => {
const errorEvent = new CustomEvent('ajax:error');
form.dispatchEvent(errorEvent);
2021-04-17 20:07:23 +05:30
await nextTick();
2021-03-11 19:13:27 +05:30
const button = findSubmitButton();
expect(button.props('disabled')).toBe(false);
});
it('displays the default success message', () => {
const successEvent = new CustomEvent('ajax:success');
form.dispatchEvent(successEvent);
expect(findFlashError().innerText.trim()).toEqual(i18n.defaultSuccess);
});
it('displays the custom success message', () => {
const message = 'foo';
const successEvent = new CustomEvent('ajax:success', { detail: [{ message }] });
form.dispatchEvent(successEvent);
expect(findFlashError().innerText.trim()).toEqual(message);
});
it('displays the default error message', () => {
const errorEvent = new CustomEvent('ajax:error');
form.dispatchEvent(errorEvent);
expect(findFlashError().innerText.trim()).toEqual(i18n.defaultError);
});
it('displays the custom error message', () => {
const message = 'bar';
const errorEvent = new CustomEvent('ajax:error', { detail: [{ message }] });
form.dispatchEvent(errorEvent);
expect(findFlashError().innerText.trim()).toEqual(message);
});
2021-01-29 00:20:46 +05:30
});
2021-04-17 20:07:23 +05:30
describe('theme changes', () => {
const { location } = window;
let themeInput;
let form;
function setupWrapper() {
wrapper = createComponent({ provide: { formEl: form }, attachTo: document.body });
}
function selectThemeId(themeId) {
themeInput.setAttribute('value', themeId.toString());
}
function dispatchBeforeSendEvent() {
const beforeSendEvent = new CustomEvent('ajax:beforeSend');
form.dispatchEvent(beforeSendEvent);
}
function dispatchSuccessEvent() {
const successEvent = new CustomEvent('ajax:success');
form.dispatchEvent(successEvent);
}
beforeAll(() => {
delete window.location;
window.location = {
...location,
reload: jest.fn(),
};
});
afterAll(() => {
window.location = location;
});
beforeEach(() => {
setupBody();
themeInput = createThemeInput();
form = createForm(themeInput);
});
it('reloads the page when switching from light to dark mode', async () => {
selectThemeId(lightModeThemeId1);
setupWrapper();
selectThemeId(darkModeThemeId);
dispatchBeforeSendEvent();
await nextTick();
dispatchSuccessEvent();
await nextTick();
expect(window.location.reload).toHaveBeenCalledTimes(1);
});
it('reloads the page when switching from dark to light mode', async () => {
selectThemeId(darkModeThemeId);
setupWrapper();
selectThemeId(lightModeThemeId1);
dispatchBeforeSendEvent();
await nextTick();
dispatchSuccessEvent();
await nextTick();
expect(window.location.reload).toHaveBeenCalledTimes(1);
});
it('does not reload the page when switching between light mode themes', async () => {
selectThemeId(lightModeThemeId1);
setupWrapper();
selectThemeId(lightModeThemeId2);
dispatchBeforeSendEvent();
await nextTick();
dispatchSuccessEvent();
await nextTick();
expect(window.location.reload).not.toHaveBeenCalled();
});
});
2021-01-29 00:20:46 +05:30
});