Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/terms/components/app_spec.js')
-rw-r--r--spec/frontend/terms/components/app_spec.js171
1 files changed, 171 insertions, 0 deletions
diff --git a/spec/frontend/terms/components/app_spec.js b/spec/frontend/terms/components/app_spec.js
new file mode 100644
index 00000000000..ee78b35843a
--- /dev/null
+++ b/spec/frontend/terms/components/app_spec.js
@@ -0,0 +1,171 @@
+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.find(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);
+ });
+ });
+});