summaryrefslogtreecommitdiff
path: root/spec/frontend/pages
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
commit8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch)
treea77e7fe7a93de11213032ed4ab1f33a3db51b738 /spec/frontend/pages
parent00b35af3db1abfe813a778f643dad221aad51fca (diff)
downloadgitlab-ce-8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781.tar.gz
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'spec/frontend/pages')
-rw-r--r--spec/frontend/pages/dashboard/todos/index/todos_spec.js111
-rw-r--r--spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js47
-rw-r--r--spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap88
-rw-r--r--spec/frontend/pages/projects/graphs/code_coverage_spec.js164
-rw-r--r--spec/frontend/pages/projects/graphs/mock_data.js60
-rw-r--r--spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js25
-rw-r--r--spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js218
7 files changed, 704 insertions, 9 deletions
diff --git a/spec/frontend/pages/dashboard/todos/index/todos_spec.js b/spec/frontend/pages/dashboard/todos/index/todos_spec.js
new file mode 100644
index 00000000000..204fe3d0a68
--- /dev/null
+++ b/spec/frontend/pages/dashboard/todos/index/todos_spec.js
@@ -0,0 +1,111 @@
+import $ from 'jquery';
+import MockAdapter from 'axios-mock-adapter';
+import Todos from '~/pages/dashboard/todos/index/todos';
+import '~/lib/utils/common_utils';
+import '~/gl_dropdown';
+import axios from '~/lib/utils/axios_utils';
+import { addDelimiter } from '~/lib/utils/text_utility';
+import { visitUrl } from '~/lib/utils/url_utility';
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn().mockName('visitUrl'),
+}));
+
+const TEST_COUNT_BIG = 2000;
+const TEST_DONE_COUNT_BIG = 7300;
+
+describe('Todos', () => {
+ preloadFixtures('todos/todos.html');
+ let todoItem;
+ let mock;
+
+ beforeEach(() => {
+ loadFixtures('todos/todos.html');
+ todoItem = document.querySelector('.todos-list .todo');
+ mock = new MockAdapter(axios);
+
+ return new Todos();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('goToTodoUrl', () => {
+ it('opens the todo url', done => {
+ const todoLink = todoItem.dataset.url;
+
+ visitUrl.mockImplementation(url => {
+ expect(url).toEqual(todoLink);
+ done();
+ });
+
+ todoItem.click();
+ });
+
+ describe('meta click', () => {
+ let windowOpenSpy;
+ let metakeyEvent;
+
+ beforeEach(() => {
+ metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
+ windowOpenSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
+ });
+
+ it('opens the todo url in another tab', () => {
+ const todoLink = todoItem.dataset.url;
+
+ $('.todos-list .todo').trigger(metakeyEvent);
+
+ expect(visitUrl).not.toHaveBeenCalled();
+ expect(windowOpenSpy).toHaveBeenCalledWith(todoLink, '_blank');
+ });
+
+ it('run native funcionality when avatar is clicked', () => {
+ $('.todos-list a').on('click', e => e.preventDefault());
+ $('.todos-list img').trigger(metakeyEvent);
+
+ expect(visitUrl).not.toHaveBeenCalled();
+ expect(windowOpenSpy).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('on done todo click', () => {
+ let onToggleSpy;
+
+ beforeEach(done => {
+ const el = document.querySelector('.js-done-todo');
+ const path = el.dataset.href;
+
+ // Arrange
+ mock
+ .onDelete(path)
+ .replyOnce(200, { count: TEST_COUNT_BIG, done_count: TEST_DONE_COUNT_BIG });
+ onToggleSpy = jest.fn();
+ $(document).on('todo:toggle', onToggleSpy);
+
+ // Act
+ el.click();
+
+ // Wait for axios and HTML to udpate
+ setImmediate(done);
+ });
+
+ it('dispatches todo:toggle', () => {
+ expect(onToggleSpy).toHaveBeenCalledWith(expect.anything(), TEST_COUNT_BIG);
+ });
+
+ it('updates pending text', () => {
+ expect(document.querySelector('.todos-pending .badge').innerHTML).toEqual(
+ addDelimiter(TEST_COUNT_BIG),
+ );
+ });
+
+ it('updates done text', () => {
+ expect(document.querySelector('.todos-done .badge').innerHTML).toEqual(
+ addDelimiter(TEST_DONE_COUNT_BIG),
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
new file mode 100644
index 00000000000..0bb96ee33d4
--- /dev/null
+++ b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js
@@ -0,0 +1,47 @@
+import { shallowMount } from '@vue/test-utils';
+
+import { GlButton } from '@gitlab/ui';
+import BitbucketServerStatusTable from '~/pages/import/bitbucket_server/status/components/bitbucket_server_status_table.vue';
+import BitbucketStatusTable from '~/import_projects/components/bitbucket_status_table.vue';
+
+const BitbucketStatusTableStub = {
+ name: 'BitbucketStatusTable',
+ template: '<div><slot name="actions"></slot></div>',
+};
+
+describe('BitbucketServerStatusTable', () => {
+ let wrapper;
+
+ const findReconfigureButton = () =>
+ wrapper
+ .findAll(GlButton)
+ .filter(w => w.props().variant === 'info')
+ .at(0);
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ function createComponent(bitbucketStatusTableStub = true) {
+ wrapper = shallowMount(BitbucketServerStatusTable, {
+ propsData: { providerTitle: 'Test', reconfigurePath: '/reconfigure' },
+ stubs: {
+ BitbucketStatusTable: bitbucketStatusTableStub,
+ },
+ });
+ }
+
+ it('renders bitbucket status table component', () => {
+ createComponent();
+ expect(wrapper.contains(BitbucketStatusTable)).toBe(true);
+ });
+
+ it('renders Reconfigure button', async () => {
+ createComponent(BitbucketStatusTableStub);
+ expect(findReconfigureButton().attributes().href).toBe('/reconfigure');
+ expect(findReconfigureButton().text()).toBe('Reconfigure');
+ });
+});
diff --git a/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
new file mode 100644
index 00000000000..94089ea922b
--- /dev/null
+++ b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
@@ -0,0 +1,88 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Code Coverage when fetching data is successful matches the snapshot 1`] = `
+<div>
+ <div
+ class="gl-mt-3 gl-mb-3"
+ >
+ <!---->
+
+ <!---->
+
+ <gl-dropdown-stub
+ text="rspec"
+ >
+ <gl-dropdown-item-stub
+ value="rspec"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <gl-icon-stub
+ class="gl-absolute"
+ name="mobile-issue-close"
+ size="16"
+ />
+
+ <span
+ class="gl-display-flex align-items-center ml-4"
+ >
+
+ rspec
+
+ </span>
+ </div>
+ </gl-dropdown-item-stub>
+ <gl-dropdown-item-stub
+ value="cypress"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+
+ <span
+ class="gl-display-flex align-items-center ml-4"
+ >
+
+ cypress
+
+ </span>
+ </div>
+ </gl-dropdown-item-stub>
+ <gl-dropdown-item-stub
+ value="karma"
+ >
+ <div
+ class="gl-display-flex"
+ >
+ <!---->
+
+ <span
+ class="gl-display-flex align-items-center ml-4"
+ >
+
+ karma
+
+ </span>
+ </div>
+ </gl-dropdown-item-stub>
+ </gl-dropdown-stub>
+ </div>
+
+ <gl-area-chart-stub
+ annotations=""
+ data="[object Object]"
+ formattooltiptext="function () { [native code] }"
+ height="200"
+ includelegendavgmax="true"
+ legendaveragetext="Avg"
+ legendcurrenttext="Current"
+ legendlayout="inline"
+ legendmaxtext="Max"
+ legendmintext="Min"
+ option="[object Object]"
+ thresholds=""
+ />
+</div>
+`;
diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
new file mode 100644
index 00000000000..4990985b076
--- /dev/null
+++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
@@ -0,0 +1,164 @@
+import MockAdapter from 'axios-mock-adapter';
+import { shallowMount } from '@vue/test-utils';
+import { GlAlert, GlIcon, GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlAreaChart } from '@gitlab/ui/dist/charts';
+
+import axios from '~/lib/utils/axios_utils';
+import CodeCoverage from '~/pages/projects/graphs/components/code_coverage.vue';
+import codeCoverageMockData from './mock_data';
+import waitForPromises from 'helpers/wait_for_promises';
+import httpStatusCodes from '~/lib/utils/http_status';
+
+describe('Code Coverage', () => {
+ let wrapper;
+ let mockAxios;
+
+ const graphEndpoint = '/graph';
+
+ const findAlert = () => wrapper.find(GlAlert);
+ const findAreaChart = () => wrapper.find(GlAreaChart);
+ const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findFirstDropdownItem = () => findAllDropdownItems().at(0);
+ const findSecondDropdownItem = () => findAllDropdownItems().at(1);
+
+ const createComponent = () => {
+ wrapper = shallowMount(CodeCoverage, {
+ propsData: {
+ graphEndpoint,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when fetching data is successful', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, codeCoverageMockData);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('renders the area chart', () => {
+ expect(findAreaChart().exists()).toBe(true);
+ });
+
+ it('matches the snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('shows no error messages', () => {
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+
+ describe('when fetching data fails', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.BAD_REQUEST);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('renders an error message', () => {
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().attributes().variant).toBe('danger');
+ });
+
+ it('still renders an empty graph', () => {
+ expect(findAreaChart().exists()).toBe(true);
+ });
+ });
+
+ describe('when fetching data succeed but returns an empty state', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, []);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ afterEach(() => {
+ mockAxios.restore();
+ });
+
+ it('renders an information message', () => {
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().attributes().variant).toBe('info');
+ });
+
+ it('still renders an empty graph', () => {
+ expect(findAreaChart().exists()).toBe(true);
+ });
+ });
+
+ describe('dropdown options', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, codeCoverageMockData);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ it('renders the dropdown with all custom names as options', () => {
+ expect(wrapper.contains(GlDropdown)).toBeDefined();
+ expect(findAllDropdownItems()).toHaveLength(codeCoverageMockData.length);
+ expect(findFirstDropdownItem().text()).toBe(codeCoverageMockData[0].group_name);
+ });
+ });
+
+ describe('interactions', () => {
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onGet().replyOnce(httpStatusCodes.OK, codeCoverageMockData);
+
+ createComponent();
+
+ return waitForPromises();
+ });
+
+ it('updates the selected dropdown option with an icon', async () => {
+ findSecondDropdownItem().vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(
+ findFirstDropdownItem()
+ .find(GlIcon)
+ .exists(),
+ ).toBe(false);
+ expect(findSecondDropdownItem().contains(GlIcon)).toBe(true);
+ });
+
+ it('updates the graph data when selecting a different option in dropdown', async () => {
+ const originalSelectedData = wrapper.vm.selectedDailyCoverage;
+ const expectedData = codeCoverageMockData[1];
+
+ findSecondDropdownItem().vm.$emit('click');
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.vm.selectedDailyCoverage).not.toBe(originalSelectedData);
+ expect(wrapper.vm.selectedDailyCoverage).toBe(expectedData);
+ });
+ });
+});
diff --git a/spec/frontend/pages/projects/graphs/mock_data.js b/spec/frontend/pages/projects/graphs/mock_data.js
new file mode 100644
index 00000000000..a15f861ee7a
--- /dev/null
+++ b/spec/frontend/pages/projects/graphs/mock_data.js
@@ -0,0 +1,60 @@
+export default [
+ {
+ group_name: 'rspec',
+ data: [
+ { date: '2020-04-30', coverage: 40.0 },
+ { date: '2020-05-01', coverage: 80.0 },
+ { date: '2020-05-02', coverage: 99.0 },
+ { date: '2020-05-10', coverage: 80.0 },
+ { date: '2020-05-15', coverage: 70.0 },
+ { date: '2020-05-20', coverage: 69.0 },
+ ],
+ },
+ {
+ group_name: 'cypress',
+ data: [
+ { date: '2022-07-30', coverage: 1.0 },
+ { date: '2022-08-01', coverage: 2.4 },
+ { date: '2022-08-02', coverage: 5.0 },
+ { date: '2022-08-10', coverage: 15.0 },
+ { date: '2022-08-15', coverage: 30.0 },
+ { date: '2022-08-20', coverage: 40.0 },
+ ],
+ },
+ {
+ group_name: 'karma',
+ data: [
+ { date: '2020-05-01', coverage: 94.0 },
+ { date: '2020-05-02', coverage: 94.0 },
+ { date: '2020-05-03', coverage: 94.0 },
+ { date: '2020-05-04', coverage: 94.0 },
+ { date: '2020-05-05', coverage: 92.0 },
+ { date: '2020-05-06', coverage: 91.0 },
+ { date: '2020-05-07', coverage: 78.0 },
+ { date: '2020-05-08', coverage: 94.0 },
+ { date: '2020-05-09', coverage: 94.0 },
+ { date: '2020-05-10', coverage: 94.0 },
+ { date: '2020-05-11', coverage: 94.0 },
+ { date: '2020-05-12', coverage: 94.0 },
+ { date: '2020-05-13', coverage: 92.0 },
+ { date: '2020-05-14', coverage: 91.0 },
+ { date: '2020-05-15', coverage: 78.0 },
+ { date: '2020-05-16', coverage: 94.0 },
+ { date: '2020-05-17', coverage: 94.0 },
+ { date: '2020-05-18', coverage: 93.0 },
+ { date: '2020-05-19', coverage: 92.0 },
+ { date: '2020-05-20', coverage: 91.0 },
+ { date: '2020-05-21', coverage: 90.0 },
+ { date: '2020-05-22', coverage: 91.0 },
+ { date: '2020-05-23', coverage: 92.0 },
+ { date: '2020-05-24', coverage: 75.0 },
+ { date: '2020-05-25', coverage: 74.0 },
+ { date: '2020-05-26', coverage: 74.0 },
+ { date: '2020-05-27', coverage: 74.0 },
+ { date: '2020-05-28', coverage: 80.0 },
+ { date: '2020-05-29', coverage: 85.0 },
+ { date: '2020-05-30', coverage: 92.0 },
+ { date: '2020-05-31', coverage: 91.0 },
+ ],
+ },
+];
diff --git a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
index 1809e92e1d9..0d9af0cb856 100644
--- a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
+++ b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
@@ -2,6 +2,12 @@ import $ from 'jquery';
import preserveUrlFragment from '~/pages/sessions/new/preserve_url_fragment';
describe('preserve_url_fragment', () => {
+ const findFormAction = selector => {
+ return $(`.omniauth-container ${selector}`)
+ .parent('form')
+ .attr('action');
+ };
+
preloadFixtures('sessions/new.html');
beforeEach(() => {
@@ -25,35 +31,36 @@ describe('preserve_url_fragment', () => {
it('does not add an empty query parameter to OmniAuth login buttons', () => {
preserveUrlFragment();
- expect($('#oauth-login-cas3').attr('href')).toBe('http://test.host/users/auth/cas3');
+ expect(findFormAction('#oauth-login-cas3')).toBe('http://test.host/users/auth/cas3');
- expect($('.omniauth-container #oauth-login-auth0').attr('href')).toBe(
- 'http://test.host/users/auth/auth0',
- );
+ expect(findFormAction('#oauth-login-auth0')).toBe('http://test.host/users/auth/auth0');
});
describe('adds "redirect_fragment" query parameter to OmniAuth login buttons', () => {
it('when "remember_me" is not present', () => {
preserveUrlFragment('#L65');
- expect($('#oauth-login-cas3').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-cas3')).toBe(
'http://test.host/users/auth/cas3?redirect_fragment=L65',
);
- expect($('.omniauth-container #oauth-login-auth0').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-auth0')).toBe(
'http://test.host/users/auth/auth0?redirect_fragment=L65',
);
});
it('when "remember-me" is present', () => {
- $('a.omniauth-btn').attr('href', (i, href) => `${href}?remember_me=1`);
+ $('.omniauth-btn')
+ .parent('form')
+ .attr('action', (i, href) => `${href}?remember_me=1`);
+
preserveUrlFragment('#L65');
- expect($('#oauth-login-cas3').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-cas3')).toBe(
'http://test.host/users/auth/cas3?remember_me=1&redirect_fragment=L65',
);
- expect($('#oauth-login-auth0').attr('href')).toBe(
+ expect(findFormAction('#oauth-login-auth0')).toBe(
'http://test.host/users/auth/auth0?remember_me=1&redirect_fragment=L65',
);
});
diff --git a/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
new file mode 100644
index 00000000000..738498edbd3
--- /dev/null
+++ b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
@@ -0,0 +1,218 @@
+import AccessorUtilities from '~/lib/utils/accessor';
+import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer';
+import trackData from '~/pages/sessions/new/index';
+import Tracking from '~/tracking';
+import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+
+useLocalStorageSpy();
+
+describe('SigninTabsMemoizer', () => {
+ const fixtureTemplate = 'static/signin_tabs.html';
+ const tabSelector = 'ul.new-session-tabs';
+ const currentTabKey = 'current_signin_tab';
+ let memo;
+
+ function createMemoizer() {
+ memo = new SigninTabsMemoizer({
+ currentTabKey,
+ tabSelector,
+ });
+ return memo;
+ }
+
+ preloadFixtures(fixtureTemplate);
+
+ beforeEach(() => {
+ loadFixtures(fixtureTemplate);
+
+ jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
+ });
+
+ it('does nothing if no tab was previously selected', () => {
+ createMemoizer();
+
+ expect(document.querySelector(`${tabSelector} > li.active a`).getAttribute('href')).toEqual(
+ '#ldap',
+ );
+ });
+
+ it('shows last selected tab on boot', () => {
+ createMemoizer().saveData('#ldap');
+ const fakeTab = {
+ click: () => {},
+ };
+ jest.spyOn(document, 'querySelector').mockReturnValue(fakeTab);
+ jest.spyOn(fakeTab, 'click').mockImplementation(() => {});
+
+ memo.bootstrap();
+
+ // verify that triggers click on the last selected tab
+ expect(document.querySelector).toHaveBeenCalledWith(`${tabSelector} a[href="#ldap"]`);
+ expect(fakeTab.click).toHaveBeenCalled();
+ });
+
+ it('clicks the first tab if value in local storage is bad', () => {
+ createMemoizer().saveData('#bogus');
+ const fakeTab = {
+ click: jest.fn().mockName('fakeTab_click'),
+ };
+ jest
+ .spyOn(document, 'querySelector')
+ .mockImplementation(selector =>
+ selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab,
+ );
+
+ memo.bootstrap();
+
+ // verify that triggers click on stored selector and fallback
+ expect(document.querySelector.mock.calls).toEqual([
+ ['ul.new-session-tabs a[href="#bogus"]'],
+ ['ul.new-session-tabs a'],
+ ]);
+
+ expect(fakeTab.click).toHaveBeenCalled();
+ });
+
+ it('saves last selected tab on change', () => {
+ createMemoizer();
+
+ document.querySelector('a[href="#login-pane"]').click();
+
+ expect(memo.readData()).toEqual('#login-pane');
+ });
+
+ it('overrides last selected tab with hash tag when given', () => {
+ window.location.hash = '#ldap';
+ createMemoizer();
+
+ expect(memo.readData()).toEqual('#ldap');
+ });
+
+ describe('class constructor', () => {
+ beforeEach(() => {
+ memo = createMemoizer();
+ });
+
+ it('should set .isLocalStorageAvailable', () => {
+ expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(memo.isLocalStorageAvailable).toBe(true);
+ });
+ });
+
+ describe('trackData', () => {
+ beforeEach(() => {
+ jest.spyOn(Tracking, 'event').mockImplementation(() => {});
+ });
+
+ describe('with tracking data', () => {
+ beforeEach(() => {
+ gon.tracking_data = {
+ category: 'Growth::Acquisition::Experiment::SignUpFlow',
+ action: 'start',
+ label: 'uuid',
+ property: 'control_group',
+ };
+ trackData();
+ });
+
+ it('should track data when the "click" event of the register tab is triggered', () => {
+ document.querySelector('a[href="#register-pane"]').click();
+
+ expect(Tracking.event).toHaveBeenCalledWith(
+ 'Growth::Acquisition::Experiment::SignUpFlow',
+ 'start',
+ {
+ label: 'uuid',
+ property: 'control_group',
+ },
+ );
+ });
+ });
+
+ describe('without tracking data', () => {
+ beforeEach(() => {
+ gon.tracking_data = undefined;
+ trackData();
+ });
+
+ it('should not track data when the "click" event of the register tab is triggered', () => {
+ document.querySelector('a[href="#register-pane"]').click();
+
+ expect(Tracking.event).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('saveData', () => {
+ beforeEach(() => {
+ memo = {
+ currentTabKey,
+ };
+ });
+
+ describe('if .isLocalStorageAvailable is `false`', () => {
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = false;
+
+ SigninTabsMemoizer.prototype.saveData.call(memo);
+ });
+
+ it('should not call .setItem', () => {
+ expect(localStorage.setItem).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('if .isLocalStorageAvailable is `true`', () => {
+ const value = 'value';
+
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = true;
+
+ SigninTabsMemoizer.prototype.saveData.call(memo, value);
+ });
+
+ it('should call .setItem', () => {
+ expect(localStorage.setItem).toHaveBeenCalledWith(currentTabKey, value);
+ });
+ });
+ });
+
+ describe('readData', () => {
+ const itemValue = 'itemValue';
+ let readData;
+
+ beforeEach(() => {
+ memo = {
+ currentTabKey,
+ };
+
+ localStorage.getItem.mockReturnValue(itemValue);
+ });
+
+ describe('if .isLocalStorageAvailable is `false`', () => {
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = false;
+
+ readData = SigninTabsMemoizer.prototype.readData.call(memo);
+ });
+
+ it('should not call .getItem and should return `null`', () => {
+ expect(localStorage.getItem).not.toHaveBeenCalled();
+ expect(readData).toBe(null);
+ });
+ });
+
+ describe('if .isLocalStorageAvailable is `true`', () => {
+ beforeEach(() => {
+ memo.isLocalStorageAvailable = true;
+
+ readData = SigninTabsMemoizer.prototype.readData.call(memo);
+ });
+
+ it('should call .getItem and return the localStorage value', () => {
+ expect(window.localStorage.getItem).toHaveBeenCalledWith(currentTabKey);
+ expect(readData).toBe(itemValue);
+ });
+ });
+ });
+});