gitlab-org--gitlab-foss/spec/frontend/access_tokens/components/new_access_token_app_spec.js

171 lines
5.7 KiB
JavaScript

import { GlAlert } from '@gitlab/ui';
import { nextTick } from 'vue';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import NewAccessTokenApp from '~/access_tokens/components/new_access_token_app.vue';
import { createAlert, VARIANT_INFO } from '~/flash';
import { __, sprintf } from '~/locale';
import DomElementListener from '~/vue_shared/components/dom_element_listener.vue';
import InputCopyToggleVisibility from '~/vue_shared/components/form/input_copy_toggle_visibility.vue';
jest.mock('~/flash');
describe('~/access_tokens/components/new_access_token_app', () => {
let wrapper;
const accessTokenType = 'personal access token';
const createComponent = (provide = { accessTokenType }) => {
wrapper = mountExtended(NewAccessTokenApp, {
provide,
});
};
const triggerSuccess = async (newToken = 'new token') => {
wrapper
.find(DomElementListener)
.vm.$emit('ajax:success', { detail: [{ new_token: newToken }] });
await nextTick();
};
const triggerError = async (errors = ['1', '2']) => {
wrapper.find(DomElementListener).vm.$emit('ajax:error', { detail: [{ errors }] });
await nextTick();
};
beforeEach(() => {
// NewAccessTokenApp observes a form element
setHTMLFixture('<form id="js-new-access-token-form"><input type="submit"/></form>');
createComponent();
});
afterEach(() => {
resetHTMLFixture();
wrapper.destroy();
createAlert.mockClear();
});
it('should render nothing', () => {
expect(wrapper.findComponent(InputCopyToggleVisibility).exists()).toBe(false);
expect(wrapper.findComponent(GlAlert).exists()).toBe(false);
});
describe('on success', () => {
it('should render `InputCopyToggleVisibility` component', async () => {
const newToken = '12345';
await triggerSuccess(newToken);
expect(wrapper.findComponent(GlAlert).exists()).toBe(false);
const InputCopyToggleVisibilityComponent = wrapper.findComponent(InputCopyToggleVisibility);
expect(InputCopyToggleVisibilityComponent.props('value')).toBe(newToken);
expect(InputCopyToggleVisibilityComponent.props('copyButtonTitle')).toBe(
sprintf(__('Copy %{accessTokenType}'), { accessTokenType }),
);
expect(InputCopyToggleVisibilityComponent.props('initialVisibility')).toBe(true);
expect(InputCopyToggleVisibilityComponent.attributes('label')).toBe(
sprintf(__('Your new %{accessTokenType}'), { accessTokenType }),
);
});
it('input field should contain QA-related selectors', async () => {
const newToken = '12345';
await triggerSuccess(newToken);
expect(wrapper.findComponent(GlAlert).exists()).toBe(false);
const inputAttributes = wrapper
.findByLabelText(sprintf(__('Your new %{accessTokenType}'), { accessTokenType }))
.attributes();
expect(inputAttributes).toMatchObject({
class: expect.stringContaining('qa-created-access-token'),
'data-qa-selector': 'created_access_token_field',
});
});
it('should render an info alert', async () => {
await triggerSuccess();
expect(createAlert).toHaveBeenCalledWith({
message: sprintf(__('Your new %{accessTokenType} has been created.'), {
accessTokenType,
}),
variant: VARIANT_INFO,
});
});
it('should reset the form', async () => {
const resetSpy = jest.spyOn(wrapper.vm.form, 'reset');
await triggerSuccess();
expect(resetSpy).toHaveBeenCalled();
});
});
describe('on error', () => {
it('should render an error alert', async () => {
await triggerError(['first', 'second']);
expect(wrapper.findComponent(InputCopyToggleVisibility).exists()).toBe(false);
let GlAlertComponent = wrapper.findComponent(GlAlert);
expect(GlAlertComponent.props('title')).toBe(__('The form contains the following errors:'));
expect(GlAlertComponent.props('variant')).toBe('danger');
let itemEls = wrapper.findAll('li');
expect(itemEls).toHaveLength(2);
expect(itemEls.at(0).text()).toBe('first');
expect(itemEls.at(1).text()).toBe('second');
await triggerError(['one']);
GlAlertComponent = wrapper.findComponent(GlAlert);
expect(GlAlertComponent.props('title')).toBe(__('The form contains the following error:'));
expect(GlAlertComponent.props('variant')).toBe('danger');
itemEls = wrapper.findAll('li');
expect(itemEls).toHaveLength(1);
});
it('the error alert should be dismissible', async () => {
await triggerError();
const GlAlertComponent = wrapper.findComponent(GlAlert);
expect(GlAlertComponent.exists()).toBe(true);
GlAlertComponent.vm.$emit('dismiss');
await nextTick();
expect(wrapper.findComponent(GlAlert).exists()).toBe(false);
});
});
describe('before error or success', () => {
it('should scroll to the container', async () => {
const containerEl = wrapper.vm.$refs.container;
const scrollIntoViewSpy = jest.spyOn(containerEl, 'scrollIntoView');
await triggerSuccess();
expect(scrollIntoViewSpy).toHaveBeenCalledWith(false);
expect(scrollIntoViewSpy).toHaveBeenCalledTimes(1);
await triggerError();
expect(scrollIntoViewSpy).toHaveBeenCalledWith(false);
expect(scrollIntoViewSpy).toHaveBeenCalledTimes(2);
});
it('should dismiss the info alert', async () => {
const dismissSpy = jest.fn();
createAlert.mockReturnValue({ dismiss: dismissSpy });
await triggerSuccess();
await triggerError();
expect(dismissSpy).toHaveBeenCalled();
expect(dismissSpy).toHaveBeenCalledTimes(1);
});
});
});