gitlab-org--gitlab-foss/spec/frontend/terms/components/app_spec.js

171 lines
5.3 KiB
JavaScript

import $ from 'jquery';
import { merge } from 'lodash';
import { GlIntersectionObserver } from '@gitlab/ui';
import { nextTick } from 'vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { FLASH_TYPES, FLASH_CLOSED_EVENT } from '~/flash';
import { isLoggedIn } from '~/lib/utils/common_utils';
import TermsApp from '~/terms/components/app.vue';
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
jest.mock('~/lib/utils/common_utils');
describe('TermsApp', () => {
let wrapper;
let renderGFMSpy;
const defaultProvide = {
terms: 'foo bar',
paths: {
accept: '/-/users/terms/1/accept',
decline: '/-/users/terms/1/decline',
root: '/',
},
permissions: {
canAccept: true,
canDecline: true,
},
};
const createComponent = (provide = {}) => {
wrapper = mountExtended(TermsApp, {
provide: merge({}, defaultProvide, provide),
});
};
beforeEach(() => {
renderGFMSpy = jest.spyOn($.fn, 'renderGFM');
isLoggedIn.mockReturnValue(true);
});
afterEach(() => {
wrapper.destroy();
});
const findFormWithAction = (path) => wrapper.find(`form[action="${path}"]`);
const findButton = (path) => findFormWithAction(path).find('button[type="submit"]');
const findScrollableViewport = () => wrapper.findByTestId('scrollable-viewport');
const expectFormWithSubmitButton = (buttonText, path) => {
const form = findFormWithAction(path);
const submitButton = findButton(path);
expect(form.exists()).toBe(true);
expect(submitButton.exists()).toBe(true);
expect(submitButton.text()).toBe(buttonText);
expect(
form
.find('input[type="hidden"][name="authenticity_token"][value="mock-csrf-token"]')
.exists(),
).toBe(true);
};
it('renders terms of service as markdown', () => {
createComponent();
expect(wrapper.findByText(defaultProvide.terms).exists()).toBe(true);
expect(renderGFMSpy).toHaveBeenCalled();
});
describe('accept button', () => {
it('is disabled until user scrolls to the bottom of the terms', async () => {
createComponent();
expect(findButton(defaultProvide.paths.accept).attributes('disabled')).toBe('disabled');
wrapper.findComponent(GlIntersectionObserver).vm.$emit('appear');
await nextTick();
expect(findButton(defaultProvide.paths.accept).attributes('disabled')).toBeUndefined();
});
describe('when user has permissions to accept', () => {
it('renders form and button to accept terms', () => {
createComponent();
expectFormWithSubmitButton(TermsApp.i18n.accept, defaultProvide.paths.accept);
});
});
describe('when user does not have permissions to accept', () => {
it('renders continue button', () => {
createComponent({ permissions: { canAccept: false } });
expect(wrapper.findByText(TermsApp.i18n.continue).exists()).toBe(true);
});
});
});
describe('decline button', () => {
describe('when user has permissions to decline', () => {
it('renders form and button to decline terms', () => {
createComponent();
expectFormWithSubmitButton(TermsApp.i18n.decline, defaultProvide.paths.decline);
});
});
describe('when user does not have permissions to decline', () => {
it('does not render decline button', () => {
createComponent({ permissions: { canDecline: false } });
expect(wrapper.findByText(TermsApp.i18n.decline).exists()).toBe(false);
});
});
});
it('sets height of scrollable viewport', () => {
jest.spyOn(document.documentElement, 'scrollHeight', 'get').mockImplementation(() => 800);
jest.spyOn(document.documentElement, 'clientHeight', 'get').mockImplementation(() => 600);
createComponent();
expect(findScrollableViewport().attributes('style')).toBe('max-height: calc(100vh - 200px);');
});
describe('when flash is closed', () => {
let flashEl;
beforeEach(() => {
flashEl = document.createElement('div');
flashEl.classList.add(`flash-${FLASH_TYPES.ALERT}`);
document.body.appendChild(flashEl);
});
afterEach(() => {
document.body.innerHTML = '';
});
it('recalculates height of scrollable viewport', () => {
jest.spyOn(document.documentElement, 'scrollHeight', 'get').mockImplementation(() => 800);
jest.spyOn(document.documentElement, 'clientHeight', 'get').mockImplementation(() => 600);
createComponent();
expect(findScrollableViewport().attributes('style')).toBe('max-height: calc(100vh - 200px);');
jest.spyOn(document.documentElement, 'scrollHeight', 'get').mockImplementation(() => 700);
jest.spyOn(document.documentElement, 'clientHeight', 'get').mockImplementation(() => 600);
flashEl.dispatchEvent(new Event(FLASH_CLOSED_EVENT));
expect(findScrollableViewport().attributes('style')).toBe('max-height: calc(100vh - 100px);');
});
});
describe('when user is signed out', () => {
beforeEach(() => {
isLoggedIn.mockReturnValue(false);
});
it('does not show any buttons', () => {
createComponent();
expect(wrapper.findByText(TermsApp.i18n.accept).exists()).toBe(false);
expect(wrapper.findByText(TermsApp.i18n.decline).exists()).toBe(false);
expect(wrapper.findByText(TermsApp.i18n.continue).exists()).toBe(false);
});
});
});