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/lib/utils')
-rw-r--r--spec/frontend/lib/utils/breadcrumbs_spec.js22
-rw-r--r--spec/frontend/lib/utils/common_utils_spec.js2
-rw-r--r--spec/frontend/lib/utils/datetime/date_format_utility_spec.js12
-rw-r--r--spec/frontend/lib/utils/datetime/locale_dateformat_spec.js177
-rw-r--r--spec/frontend/lib/utils/datetime/timeago_utility_spec.js6
-rw-r--r--spec/frontend/lib/utils/datetime_utility_spec.js15
-rw-r--r--spec/frontend/lib/utils/secret_detection_spec.js1
-rw-r--r--spec/frontend/lib/utils/vuex_module_mappers_spec.js133
8 files changed, 213 insertions, 155 deletions
diff --git a/spec/frontend/lib/utils/breadcrumbs_spec.js b/spec/frontend/lib/utils/breadcrumbs_spec.js
index 3c29e3723d3..481e3db521c 100644
--- a/spec/frontend/lib/utils/breadcrumbs_spec.js
+++ b/spec/frontend/lib/utils/breadcrumbs_spec.js
@@ -26,24 +26,20 @@ describe('Breadcrumbs utils', () => {
`;
const mockRouter = jest.fn();
- let MockComponent;
- let mockApolloProvider;
- beforeEach(() => {
- MockComponent = Vue.component('MockComponent', {
- render: (createElement) =>
- createElement('span', {
- attrs: {
- 'data-testid': 'mock-component',
- },
- }),
- });
- mockApolloProvider = createMockApollo();
+ const MockComponent = Vue.component('MockComponent', {
+ render: (createElement) =>
+ createElement('span', {
+ attrs: {
+ 'data-testid': 'mock-component',
+ },
+ }),
});
+ const mockApolloProvider = createMockApollo();
+
afterEach(() => {
resetHTMLFixture();
- MockComponent = null;
});
describe('injectVueAppBreadcrumbs', () => {
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js
index 6295914b127..5c2bcd48f3e 100644
--- a/spec/frontend/lib/utils/common_utils_spec.js
+++ b/spec/frontend/lib/utils/common_utils_spec.js
@@ -151,7 +151,7 @@ describe('common_utils', () => {
jest.spyOn(window, 'scrollBy');
document.body.innerHTML += `
<div id="parent">
- <div class="navbar-gitlab" style="position: fixed; top: 0; height: 50px;"></div>
+ <div class="header-logged-out" style="position: fixed; top: 0; height: 50px;"></div>
<div style="height: 2000px; margin-top: 50px;"></div>
<div id="user-content-test" style="height: 2000px;"></div>
</div>
diff --git a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
index 65018fe1625..79b09654f00 100644
--- a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
@@ -122,12 +122,12 @@ describe('date_format_utility.js', () => {
describe('formatTimeAsSummary', () => {
it.each`
unit | value | result
- ${'months'} | ${1.5} | ${'1.5M'}
- ${'weeks'} | ${1.25} | ${'1.5w'}
- ${'days'} | ${2} | ${'2d'}
- ${'hours'} | ${10} | ${'10h'}
- ${'minutes'} | ${20} | ${'20m'}
- ${'seconds'} | ${10} | ${'<1m'}
+ ${'months'} | ${1.5} | ${'1.5 months'}
+ ${'weeks'} | ${1.25} | ${'1.5 weeks'}
+ ${'days'} | ${2} | ${'2 days'}
+ ${'hours'} | ${10} | ${'10 hours'}
+ ${'minutes'} | ${20} | ${'20 minutes'}
+ ${'seconds'} | ${10} | ${'<1 minute'}
${'seconds'} | ${0} | ${'-'}
`('will format $value $unit to $result', ({ unit, value, result }) => {
expect(utils.formatTimeAsSummary({ [unit]: value })).toBe(result);
diff --git a/spec/frontend/lib/utils/datetime/locale_dateformat_spec.js b/spec/frontend/lib/utils/datetime/locale_dateformat_spec.js
new file mode 100644
index 00000000000..3200f0cc7d7
--- /dev/null
+++ b/spec/frontend/lib/utils/datetime/locale_dateformat_spec.js
@@ -0,0 +1,177 @@
+import { DATE_TIME_FORMATS, localeDateFormat } from '~/lib/utils/datetime/locale_dateformat';
+import { setLanguage } from 'jest/__helpers__/locale_helper';
+import * as localeFns from '~/locale';
+
+describe('localeDateFormat (en-US)', () => {
+ const date = new Date('1983-07-09T14:15:23.123Z');
+ const sameDay = new Date('1983-07-09T18:27:09.198Z');
+ const sameMonth = new Date('1983-07-12T12:36:02.654Z');
+ const nextYear = new Date('1984-01-10T07:47:54.947Z');
+
+ beforeEach(() => {
+ setLanguage('en-US');
+ localeDateFormat.reset();
+ });
+
+ /*
+ Depending on the ICU/Intl version, formatted strings might contain
+ characters which aren't a normal space, e.g. U+2009 THIN SPACE in formatRange or
+ U+202F NARROW NO-BREAK SPACE between time and AM/PM.
+
+ In order for the specs to be more portable and easier to read, as git/gitlab aren't
+ great at rendering these other spaces, we replace them U+0020 SPACE
+ */
+ function expectDateString(str) {
+ // eslint-disable-next-line jest/valid-expect
+ return expect(str.replace(/[\s\u2009]+/g, ' '));
+ }
+
+ describe('#asDateTime', () => {
+ it('exposes a working date formatter', () => {
+ expectDateString(localeDateFormat.asDateTime.format(date)).toBe('Jul 9, 1983, 2:15 PM');
+ expectDateString(localeDateFormat.asDateTime.format(nextYear)).toBe('Jan 10, 1984, 7:47 AM');
+ });
+
+ it('exposes a working date range formatter', () => {
+ expectDateString(localeDateFormat.asDateTime.formatRange(date, nextYear)).toBe(
+ 'Jul 9, 1983, 2:15 PM – Jan 10, 1984, 7:47 AM',
+ );
+ expectDateString(localeDateFormat.asDateTime.formatRange(date, sameMonth)).toBe(
+ 'Jul 9, 1983, 2:15 PM – Jul 12, 1983, 12:36 PM',
+ );
+ expectDateString(localeDateFormat.asDateTime.formatRange(date, sameDay)).toBe(
+ 'Jul 9, 1983, 2:15 – 6:27 PM',
+ );
+ });
+
+ it.each([
+ ['automatic', 0, '2:15 PM'],
+ ['h12 preference', 1, '2:15 PM'],
+ ['h24 preference', 2, '14:15'],
+ ])("respects user's hourCycle preference: %s", (_, timeDisplayFormat, result) => {
+ window.gon.time_display_format = timeDisplayFormat;
+ expectDateString(localeDateFormat.asDateTime.format(date)).toContain(result);
+ expectDateString(localeDateFormat.asDateTime.formatRange(date, nextYear)).toContain(result);
+ });
+ });
+
+ describe('#asDateTimeFull', () => {
+ it('exposes a working date formatter', () => {
+ expectDateString(localeDateFormat.asDateTimeFull.format(date)).toBe(
+ 'July 9, 1983 at 2:15:23 PM GMT',
+ );
+ expectDateString(localeDateFormat.asDateTimeFull.format(nextYear)).toBe(
+ 'January 10, 1984 at 7:47:54 AM GMT',
+ );
+ });
+
+ it('exposes a working date range formatter', () => {
+ expectDateString(localeDateFormat.asDateTimeFull.formatRange(date, nextYear)).toBe(
+ 'July 9, 1983 at 2:15:23 PM GMT – January 10, 1984 at 7:47:54 AM GMT',
+ );
+ expectDateString(localeDateFormat.asDateTimeFull.formatRange(date, sameMonth)).toBe(
+ 'July 9, 1983 at 2:15:23 PM GMT – July 12, 1983 at 12:36:02 PM GMT',
+ );
+ expectDateString(localeDateFormat.asDateTimeFull.formatRange(date, sameDay)).toBe(
+ 'July 9, 1983, 2:15:23 PM GMT – 6:27:09 PM GMT',
+ );
+ });
+
+ it.each([
+ ['automatic', 0, '2:15:23 PM'],
+ ['h12 preference', 1, '2:15:23 PM'],
+ ['h24 preference', 2, '14:15:23'],
+ ])("respects user's hourCycle preference: %s", (_, timeDisplayFormat, result) => {
+ window.gon.time_display_format = timeDisplayFormat;
+ expectDateString(localeDateFormat.asDateTimeFull.format(date)).toContain(result);
+ expectDateString(localeDateFormat.asDateTimeFull.formatRange(date, nextYear)).toContain(
+ result,
+ );
+ });
+ });
+
+ describe('#asDate', () => {
+ it('exposes a working date formatter', () => {
+ expectDateString(localeDateFormat.asDate.format(date)).toBe('Jul 9, 1983');
+ expectDateString(localeDateFormat.asDate.format(nextYear)).toBe('Jan 10, 1984');
+ });
+
+ it('exposes a working date range formatter', () => {
+ expectDateString(localeDateFormat.asDate.formatRange(date, nextYear)).toBe(
+ 'Jul 9, 1983 – Jan 10, 1984',
+ );
+ expectDateString(localeDateFormat.asDate.formatRange(date, sameMonth)).toBe(
+ 'Jul 9 – 12, 1983',
+ );
+ expectDateString(localeDateFormat.asDate.formatRange(date, sameDay)).toBe('Jul 9, 1983');
+ });
+ });
+
+ describe('#asTime', () => {
+ it('exposes a working date formatter', () => {
+ expectDateString(localeDateFormat.asTime.format(date)).toBe('2:15 PM');
+ expectDateString(localeDateFormat.asTime.format(nextYear)).toBe('7:47 AM');
+ });
+
+ it('exposes a working date range formatter', () => {
+ expectDateString(localeDateFormat.asTime.formatRange(date, nextYear)).toBe(
+ '7/9/1983, 2:15 PM – 1/10/1984, 7:47 AM',
+ );
+ expectDateString(localeDateFormat.asTime.formatRange(date, sameMonth)).toBe(
+ '7/9/1983, 2:15 PM – 7/12/1983, 12:36 PM',
+ );
+ expectDateString(localeDateFormat.asTime.formatRange(date, sameDay)).toBe('2:15 – 6:27 PM');
+ });
+
+ it.each([
+ ['automatic', 0, '2:15 PM'],
+ ['h12 preference', 1, '2:15 PM'],
+ ['h24 preference', 2, '14:15'],
+ ])("respects user's hourCycle preference: %s", (_, timeDisplayFormat, result) => {
+ window.gon.time_display_format = timeDisplayFormat;
+ expectDateString(localeDateFormat.asTime.format(date)).toContain(result);
+ expectDateString(localeDateFormat.asTime.formatRange(date, nextYear)).toContain(result);
+ });
+ });
+
+ describe('#reset', () => {
+ it('removes the cached formatters', () => {
+ const spy = jest.spyOn(localeFns, 'createDateTimeFormat');
+
+ localeDateFormat.asDate.format(date);
+ localeDateFormat.asDate.format(date);
+ expect(spy).toHaveBeenCalledTimes(1);
+
+ localeDateFormat.reset();
+
+ localeDateFormat.asDate.format(date);
+ localeDateFormat.asDate.format(date);
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+ });
+
+ describe.each(DATE_TIME_FORMATS)('formatter for %p', (format) => {
+ it('is defined', () => {
+ expect(localeDateFormat[format]).toBeDefined();
+ expect(localeDateFormat[format].format(date)).toBeDefined();
+ expect(localeDateFormat[format].formatRange(date, nextYear)).toBeDefined();
+ });
+
+ it('getting the formatter multiple times, just calls the Intl API once', () => {
+ const spy = jest.spyOn(localeFns, 'createDateTimeFormat');
+
+ localeDateFormat[format].format(date);
+ localeDateFormat[format].format(date);
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ });
+
+ it('getting the formatter memoized the correct formatter', () => {
+ const spy = jest.spyOn(localeFns, 'createDateTimeFormat');
+
+ expect(localeDateFormat[format].format(date)).toBe(localeDateFormat[format].format(date));
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/datetime/timeago_utility_spec.js b/spec/frontend/lib/utils/datetime/timeago_utility_spec.js
index 44db4cf88a2..53ed524116e 100644
--- a/spec/frontend/lib/utils/datetime/timeago_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime/timeago_utility_spec.js
@@ -1,5 +1,6 @@
-import { DATE_ONLY_FORMAT } from '~/lib/utils/datetime/constants';
import { getTimeago, localTimeAgo, timeFor, duration } from '~/lib/utils/datetime/timeago_utility';
+import { DATE_ONLY_FORMAT, localeDateFormat } from '~/lib/utils/datetime/locale_dateformat';
+
import { s__ } from '~/locale';
import '~/commons/bootstrap';
@@ -143,7 +144,7 @@ describe('TimeAgo utils', () => {
it.each`
updateTooltip | title
${false} | ${'some time'}
- ${true} | ${'Feb 18, 2020 10:22pm UTC'}
+ ${true} | ${'February 18, 2020 at 10:22:32 PM GMT'}
`(
`has content: '${text}' and tooltip: '$title' with updateTooltip = $updateTooltip`,
({ updateTooltip, title }) => {
@@ -168,6 +169,7 @@ describe('TimeAgo utils', () => {
${1} | ${'12-hour'} | ${'Feb 18, 2020, 10:22 PM'}
${2} | ${'24-hour'} | ${'Feb 18, 2020, 22:22'}
`(`'$display' renders as '$text'`, ({ timeDisplayFormat, text }) => {
+ localeDateFormat.reset();
gon.time_display_relative = false;
gon.time_display_format = timeDisplayFormat;
diff --git a/spec/frontend/lib/utils/datetime_utility_spec.js b/spec/frontend/lib/utils/datetime_utility_spec.js
index 330bfca7029..73a4af2c85d 100644
--- a/spec/frontend/lib/utils/datetime_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime_utility_spec.js
@@ -800,6 +800,21 @@ describe('date addition/subtraction methods', () => {
);
});
+ describe('nYearsBefore', () => {
+ it.each`
+ date | numberOfYears | expected
+ ${'2020-07-06'} | ${4} | ${'2016-07-06'}
+ ${'2020-07-06'} | ${1} | ${'2019-07-06'}
+ `(
+ 'returns $expected for "$numberOfYears year(s) before $date"',
+ ({ date, numberOfYears, expected }) => {
+ expect(datetimeUtility.nYearsBefore(new Date(date), numberOfYears)).toEqual(
+ new Date(expected),
+ );
+ },
+ );
+ });
+
describe('nMonthsBefore', () => {
// The previous month (February) has 28 days
const march2019 = '2019-03-15T00:00:00.000Z';
diff --git a/spec/frontend/lib/utils/secret_detection_spec.js b/spec/frontend/lib/utils/secret_detection_spec.js
index 761062f0340..a8da6e8969f 100644
--- a/spec/frontend/lib/utils/secret_detection_spec.js
+++ b/spec/frontend/lib/utils/secret_detection_spec.js
@@ -31,6 +31,7 @@ describe('containsSensitiveToken', () => {
'token: gloas-a8cc74ccb0de004d09a968705ba49099229b288b3de43f26c473a9d8d7fb7693',
'https://example.com/feed?feed_token=123456789_abcdefghij',
'glpat-1234567890 and feed_token=ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'token: gldt-cgyKc1k_AsnEpmP-5fRL',
];
it.each(sensitiveMessages)('returns true for message: %s', (message) => {
diff --git a/spec/frontend/lib/utils/vuex_module_mappers_spec.js b/spec/frontend/lib/utils/vuex_module_mappers_spec.js
deleted file mode 100644
index 9070903728b..00000000000
--- a/spec/frontend/lib/utils/vuex_module_mappers_spec.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import { mount } from '@vue/test-utils';
-import Vue from 'vue';
-// eslint-disable-next-line no-restricted-imports
-import Vuex from 'vuex';
-import {
- mapVuexModuleActions,
- mapVuexModuleGetters,
- mapVuexModuleState,
- REQUIRE_STRING_ERROR_MESSAGE,
-} from '~/lib/utils/vuex_module_mappers';
-
-const TEST_MODULE_NAME = 'testModuleName';
-
-Vue.use(Vuex);
-
-// setup test component and store ----------------------------------------------
-//
-// These are used to indirectly test `vuex_module_mappers`.
-const TestComponent = {
- props: {
- vuexModule: {
- type: String,
- required: true,
- },
- },
- computed: {
- ...mapVuexModuleState((vm) => vm.vuexModule, { name: 'name', value: 'count' }),
- ...mapVuexModuleGetters((vm) => vm.vuexModule, ['hasValue', 'hasName']),
- stateJson() {
- return JSON.stringify({
- name: this.name,
- value: this.value,
- });
- },
- gettersJson() {
- return JSON.stringify({
- hasValue: this.hasValue,
- hasName: this.hasName,
- });
- },
- },
- methods: {
- ...mapVuexModuleActions((vm) => vm.vuexModule, ['increment']),
- },
- template: `
-<div>
- <pre data-testid="state">{{ stateJson }}</pre>
- <pre data-testid="getters">{{ gettersJson }}</pre>
-</div>`,
-};
-
-const createTestStore = () => {
- return new Vuex.Store({
- modules: {
- [TEST_MODULE_NAME]: {
- namespaced: true,
- state: {
- name: 'Lorem',
- count: 0,
- },
- mutations: {
- INCREMENT: (state, amount) => {
- state.count += amount;
- },
- },
- actions: {
- increment({ commit }, amount) {
- commit('INCREMENT', amount);
- },
- },
- getters: {
- hasValue: (state) => state.count > 0,
- hasName: (state) => Boolean(state.name.length),
- },
- },
- },
- });
-};
-
-describe('~/lib/utils/vuex_module_mappers', () => {
- let store;
- let wrapper;
-
- const getJsonInTemplate = (testId) =>
- JSON.parse(wrapper.find(`[data-testid="${testId}"]`).text());
- const getMappedState = () => getJsonInTemplate('state');
- const getMappedGetters = () => getJsonInTemplate('getters');
-
- beforeEach(() => {
- store = createTestStore();
-
- wrapper = mount(TestComponent, {
- propsData: {
- vuexModule: TEST_MODULE_NAME,
- },
- store,
- });
- });
-
- describe('from module defined by prop', () => {
- it('maps state', () => {
- expect(getMappedState()).toEqual({
- name: store.state[TEST_MODULE_NAME].name,
- value: store.state[TEST_MODULE_NAME].count,
- });
- });
-
- it('maps getters', () => {
- expect(getMappedGetters()).toEqual({
- hasName: true,
- hasValue: false,
- });
- });
-
- it('maps action', () => {
- jest.spyOn(store, 'dispatch');
-
- expect(store.dispatch).not.toHaveBeenCalled();
-
- wrapper.vm.increment(10);
-
- expect(store.dispatch).toHaveBeenCalledWith(`${TEST_MODULE_NAME}/increment`, 10);
- });
- });
-
- describe('with non-string object value', () => {
- it('throws helpful error', () => {
- expect(() => mapVuexModuleActions((vm) => vm.bogus, { foo: () => {} })).toThrow(
- REQUIRE_STRING_ERROR_MESSAGE,
- );
- });
- });
-});