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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-07-17 21:09:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-17 21:09:20 +0300
commitec72da1833d94bb1556af94193ccf2a93c9cb939 (patch)
tree6227669a11aaf8370186a7aa6591d5fa9d853bb0 /spec/frontend/deploy_freeze
parent283fb71e02992b6687e3264d53bbc718b7567109 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/deploy_freeze')
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js91
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js43
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js69
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_timezone_dropdown_spec.js88
-rw-r--r--spec/frontend/deploy_freeze/mock_data.js186
-rw-r--r--spec/frontend/deploy_freeze/store/actions_spec.js122
-rw-r--r--spec/frontend/deploy_freeze/store/mutations_spec.js62
7 files changed, 661 insertions, 0 deletions
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js
new file mode 100644
index 00000000000..7f41cc87a6b
--- /dev/null
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js
@@ -0,0 +1,91 @@
+import Vuex from 'vuex';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { GlButton, GlModal } from '@gitlab/ui';
+import DeployFreezeModal from '~/deploy_freeze/components/deploy_freeze_modal.vue';
+import DeployFreezeTimezoneDropdown from '~/deploy_freeze/components/deploy_freeze_timezone_dropdown.vue';
+import createStore from '~/deploy_freeze/store';
+import { mockDeployFreezePayload, mockTimezoneData } from '../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Deploy freeze modal', () => {
+ let wrapper;
+ let store;
+
+ beforeEach(() => {
+ store = createStore({
+ projectId: '8',
+ timezoneData: mockTimezoneData,
+ });
+ wrapper = shallowMount(DeployFreezeModal, {
+ attachToDocument: true,
+ stubs: {
+ GlModal,
+ },
+ localVue,
+ store,
+ });
+ });
+
+ const findModal = () => wrapper.find(GlModal);
+ const addDeployFreezeButton = () =>
+ findModal()
+ .findAll(GlButton)
+ .at(1);
+
+ const setInput = (freezeStartCron, freezeEndCron, selectedTimezone) => {
+ store.state.freezeStartCron = freezeStartCron;
+ store.state.freezeEndCron = freezeEndCron;
+ store.state.selectedTimezone = selectedTimezone;
+
+ wrapper.find('#deploy-freeze-start').trigger('input');
+ wrapper.find('#deploy-freeze-end').trigger('input');
+ wrapper.find(DeployFreezeTimezoneDropdown).trigger('input');
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('Basic interactions', () => {
+ it('button is disabled when freeze period is invalid', () => {
+ expect(addDeployFreezeButton().attributes('disabled')).toBeTruthy();
+ });
+ });
+
+ describe('Adding a new deploy freeze', () => {
+ beforeEach(() => {
+ const { freeze_start, freeze_end, cron_timezone } = mockDeployFreezePayload;
+ setInput(freeze_start, freeze_end, cron_timezone);
+ });
+
+ it('button is enabled when valid freeze period settings are present', () => {
+ expect(addDeployFreezeButton().attributes('disabled')).toBeUndefined();
+ });
+ });
+
+ describe('Validations', () => {
+ describe('when the cron state is invalid', () => {
+ beforeEach(() => {
+ setInput('invalid cron', 'invalid cron', 'invalid timezone');
+ });
+
+ it('disables the add deploy freeze button', () => {
+ expect(addDeployFreezeButton().attributes('disabled')).toBeTruthy();
+ });
+ });
+
+ describe('when the cron state is valid', () => {
+ beforeEach(() => {
+ const { freeze_start, freeze_end, cron_timezone } = mockDeployFreezePayload;
+ setInput(freeze_start, freeze_end, cron_timezone);
+ });
+
+ it('does not disable the submit button', () => {
+ expect(addDeployFreezeButton().attributes('disabled')).toBeFalsy();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js
new file mode 100644
index 00000000000..0c0f3401811
--- /dev/null
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js
@@ -0,0 +1,43 @@
+import Vuex from 'vuex';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import DeployFreezeSettings from '~/deploy_freeze/components/deploy_freeze_settings.vue';
+import DeployFreezeTable from '~/deploy_freeze/components/deploy_freeze_table.vue';
+import DeployFreezeModal from '~/deploy_freeze/components/deploy_freeze_modal.vue';
+
+import createStore from '~/deploy_freeze/store';
+import { mockTimezoneData } from '../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Deploy freeze settings', () => {
+ let wrapper;
+ let store;
+
+ beforeEach(() => {
+ store = createStore({
+ projectId: '8',
+ timezoneData: mockTimezoneData,
+ });
+ jest.spyOn(store, 'dispatch').mockImplementation();
+ wrapper = shallowMount(DeployFreezeSettings, {
+ localVue,
+ store,
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('Deploy freeze table contains components', () => {
+ it('contains deploy freeze table', () => {
+ expect(wrapper.find(DeployFreezeTable).exists()).toBe(true);
+ });
+
+ it('contains deploy freeze modal', () => {
+ expect(wrapper.find(DeployFreezeModal).exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
new file mode 100644
index 00000000000..9a07224ec63
--- /dev/null
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
@@ -0,0 +1,69 @@
+import Vuex from 'vuex';
+import { createLocalVue, mount } from '@vue/test-utils';
+import DeployFreezeTable from '~/deploy_freeze/components/deploy_freeze_table.vue';
+import createStore from '~/deploy_freeze/store';
+import { mockFreezePeriods, mockTimezoneData } from '../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Deploy freeze table', () => {
+ let wrapper;
+ let store;
+
+ const createComponent = () => {
+ store = createStore({
+ projectId: '8',
+ timezoneData: mockTimezoneData,
+ });
+ jest.spyOn(store, 'dispatch').mockImplementation();
+ wrapper = mount(DeployFreezeTable, {
+ attachToDocument: true,
+ localVue,
+ store,
+ });
+ };
+
+ const findEmptyFreezePeriods = () => wrapper.find('[data-testid="empty-freeze-periods"]');
+ const findAddDeployFreezeButton = () => wrapper.find('[data-testid="add-deploy-freeze"]');
+ const findDeployFreezeTable = () => wrapper.find('[data-testid="deploy-freeze-table"]');
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('dispatches fetchFreezePeriods when mounted', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('fetchFreezePeriods');
+ });
+
+ describe('Renders correct data', () => {
+ it('displays empty', () => {
+ expect(findEmptyFreezePeriods().exists()).toBe(true);
+ expect(findEmptyFreezePeriods().text()).toBe(
+ 'No deploy freezes exist for this project. To add one, click Add deploy freeze',
+ );
+ });
+
+ it('displays data', () => {
+ store.state.freezePeriods = mockFreezePeriods;
+
+ return wrapper.vm.$nextTick(() => {
+ const tableRows = findDeployFreezeTable().findAll('tbody tr');
+ expect(tableRows.length).toBe(mockFreezePeriods.length);
+ expect(findEmptyFreezePeriods().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('Table click actions', () => {
+ it('displays add deploy freeze button', () => {
+ expect(findAddDeployFreezeButton().exists()).toBe(true);
+ expect(findAddDeployFreezeButton().text()).toBe('Add deploy freeze');
+ });
+ });
+});
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_timezone_dropdown_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_timezone_dropdown_spec.js
new file mode 100644
index 00000000000..9563de4b920
--- /dev/null
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_timezone_dropdown_spec.js
@@ -0,0 +1,88 @@
+import Vuex from 'vuex';
+import DeployFreezeTimezoneDropdown from '~/deploy_freeze/components/deploy_freeze_timezone_dropdown.vue';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import createStore from '~/deploy_freeze/store';
+import { mockTimezoneData } from '../mock_data';
+
+import { GlDropdownItem } from '@gitlab/ui';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Deploy freeze timezone dropdown', () => {
+ let wrapper;
+ let store;
+
+ const createComponent = term => {
+ store = createStore({
+ projectId: '8',
+ timezoneData: mockTimezoneData,
+ });
+ store.state.timezoneData = mockTimezoneData;
+ wrapper = shallowMount(DeployFreezeTimezoneDropdown, {
+ store,
+ localVue,
+ propsData: {
+ value: term,
+ timezoneData: mockTimezoneData,
+ },
+ });
+ };
+
+ const findAllDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findDropdownItemByIndex = index => wrapper.findAll(GlDropdownItem).at(index);
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('No enviroments found', () => {
+ beforeEach(() => {
+ createComponent('UTC timezone');
+ });
+
+ it('renders empty results message', () => {
+ expect(findDropdownItemByIndex(0).text()).toBe('No matching results');
+ });
+ });
+
+ describe('Search term is empty', () => {
+ beforeEach(() => {
+ createComponent('');
+ });
+
+ it('renders all timezones when search term is empty', () => {
+ expect(findAllDropdownItems()).toHaveLength(mockTimezoneData.length);
+ });
+ });
+
+ describe('Time zones found', () => {
+ beforeEach(() => {
+ createComponent('Alaska');
+ });
+
+ it('renders only the time zone searched for', () => {
+ expect(findAllDropdownItems()).toHaveLength(1);
+ expect(findDropdownItemByIndex(0).text()).toBe('[UTC -8] Alaska');
+ });
+
+ it('should not display empty results message', () => {
+ expect(wrapper.find({ ref: 'noMatchingResults' }).exists()).toBe(false);
+ });
+
+ describe('Custom events', () => {
+ it('should emit selectTimezone if an environment is clicked', () => {
+ findDropdownItemByIndex(0).vm.$emit('click');
+ expect(wrapper.emitted('selectTimezone')).toEqual([
+ [
+ {
+ formattedTimezone: '[UTC -8] Alaska',
+ identifier: 'America/Juneau',
+ },
+ ],
+ ]);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/deploy_freeze/mock_data.js b/spec/frontend/deploy_freeze/mock_data.js
new file mode 100644
index 00000000000..56230388cda
--- /dev/null
+++ b/spec/frontend/deploy_freeze/mock_data.js
@@ -0,0 +1,186 @@
+export const mockDeployFreezePayload = {
+ freeze_start: '0 12 * * 1-5',
+ freeze_end: '0 12 * * 6',
+ cron_timezone: 'Etc/UTC',
+};
+
+export const mockFreezePeriods = [
+ {
+ id: 3,
+ freeze_start: '5 4 * * *',
+ freeze_end: '5 9 * 8 *',
+ cron_timezone: 'Eastern Time (US & Canada)',
+ created_at: '2020-07-10T05:10:35.122Z',
+ updated_at: '2020-07-10T05:10:35.122Z',
+ },
+ {
+ id: 8,
+ freeze_start: '0 12 * * 1-5',
+ freeze_end: '0 1 5 * *',
+ cron_timezone: 'Mountain Time (US & Canada)',
+ created_at: '2020-07-10T19:27:57.378Z',
+ updated_at: '2020-07-10T19:27:57.378Z',
+ },
+ {
+ id: 9,
+ freeze_start: '0 12 * * 1-5',
+ freeze_end: '0 16 * * 6',
+ cron_timezone: 'Central Time (US & Canada)',
+ created_at: '2020-07-10T19:29:15.240Z',
+ updated_at: '2020-07-10T19:29:15.240Z',
+ },
+];
+
+export const mockTimezoneData = [
+ { name: 'International Date Line West', offset: -43200, identifier: 'Etc/GMT+12' },
+ { name: 'American Samoa', offset: -39600, identifier: 'Pacific/Pago_Pago' },
+ { name: 'Midway Island', offset: -39600, identifier: 'Pacific/Midway' },
+ { name: 'Hawaii', offset: -36000, identifier: 'Pacific/Honolulu' },
+ { name: 'Alaska', offset: -28800, identifier: 'America/Juneau' },
+ { name: 'Pacific Time (US & Canada)', offset: -25200, identifier: 'America/Los_Angeles' },
+ { name: 'Tijuana', offset: -25200, identifier: 'America/Tijuana' },
+ { name: 'Arizona', offset: -25200, identifier: 'America/Phoenix' },
+ { name: 'Chihuahua', offset: -21600, identifier: 'America/Chihuahua' },
+ { name: 'Mazatlan', offset: -21600, identifier: 'America/Mazatlan' },
+ { name: 'Mountain Time (US & Canada)', offset: -21600, identifier: 'America/Denver' },
+ { name: 'Central America', offset: -21600, identifier: 'America/Guatemala' },
+ { name: 'Central Time (US & Canada)', offset: -18000, identifier: 'America/Chicago' },
+ { name: 'Guadalajara', offset: -18000, identifier: 'America/Mexico_City' },
+ { name: 'Mexico City', offset: -18000, identifier: 'America/Mexico_City' },
+ { name: 'Monterrey', offset: -18000, identifier: 'America/Monterrey' },
+ { name: 'Saskatchewan', offset: -21600, identifier: 'America/Regina' },
+ { name: 'Bogota', offset: -18000, identifier: 'America/Bogota' },
+ { name: 'Eastern Time (US & Canada)', offset: -14400, identifier: 'America/New_York' },
+ { name: 'Indiana (East)', offset: -14400, identifier: 'America/Indiana/Indianapolis' },
+ { name: 'Lima', offset: -18000, identifier: 'America/Lima' },
+ { name: 'Quito', offset: -18000, identifier: 'America/Lima' },
+ { name: 'Atlantic Time (Canada)', offset: -10800, identifier: 'America/Halifax' },
+ { name: 'Caracas', offset: -14400, identifier: 'America/Caracas' },
+ { name: 'Georgetown', offset: -14400, identifier: 'America/Guyana' },
+ { name: 'La Paz', offset: -14400, identifier: 'America/La_Paz' },
+ { name: 'Puerto Rico', offset: -14400, identifier: 'America/Puerto_Rico' },
+ { name: 'Santiago', offset: -14400, identifier: 'America/Santiago' },
+ { name: 'Newfoundland', offset: -9000, identifier: 'America/St_Johns' },
+ { name: 'Brasilia', offset: -10800, identifier: 'America/Sao_Paulo' },
+ { name: 'Buenos Aires', offset: -10800, identifier: 'America/Argentina/Buenos_Aires' },
+ { name: 'Greenland', offset: -7200, identifier: 'America/Godthab' },
+ { name: 'Montevideo', offset: -10800, identifier: 'America/Montevideo' },
+ { name: 'Mid-Atlantic', offset: -7200, identifier: 'Atlantic/South_Georgia' },
+ { name: 'Azores', offset: 0, identifier: 'Atlantic/Azores' },
+ { name: 'Cape Verde Is.', offset: -3600, identifier: 'Atlantic/Cape_Verde' },
+ { name: 'Casablanca', offset: 3600, identifier: 'Africa/Casablanca' },
+ { name: 'Dublin', offset: 3600, identifier: 'Europe/Dublin' },
+ { name: 'Edinburgh', offset: 3600, identifier: 'Europe/London' },
+ { name: 'Lisbon', offset: 3600, identifier: 'Europe/Lisbon' },
+ { name: 'London', offset: 3600, identifier: 'Europe/London' },
+ { name: 'Monrovia', offset: 0, identifier: 'Africa/Monrovia' },
+ { name: 'UTC', offset: 0, identifier: 'Etc/UTC' },
+ { name: 'Amsterdam', offset: 7200, identifier: 'Europe/Amsterdam' },
+ { name: 'Belgrade', offset: 7200, identifier: 'Europe/Belgrade' },
+ { name: 'Berlin', offset: 7200, identifier: 'Europe/Berlin' },
+ { name: 'Bern', offset: 7200, identifier: 'Europe/Zurich' },
+ { name: 'Bratislava', offset: 7200, identifier: 'Europe/Bratislava' },
+ { name: 'Brussels', offset: 7200, identifier: 'Europe/Brussels' },
+ { name: 'Budapest', offset: 7200, identifier: 'Europe/Budapest' },
+ { name: 'Copenhagen', offset: 7200, identifier: 'Europe/Copenhagen' },
+ { name: 'Ljubljana', offset: 7200, identifier: 'Europe/Ljubljana' },
+ { name: 'Madrid', offset: 7200, identifier: 'Europe/Madrid' },
+ { name: 'Paris', offset: 7200, identifier: 'Europe/Paris' },
+ { name: 'Prague', offset: 7200, identifier: 'Europe/Prague' },
+ { name: 'Rome', offset: 7200, identifier: 'Europe/Rome' },
+ { name: 'Sarajevo', offset: 7200, identifier: 'Europe/Sarajevo' },
+ { name: 'Skopje', offset: 7200, identifier: 'Europe/Skopje' },
+ { name: 'Stockholm', offset: 7200, identifier: 'Europe/Stockholm' },
+ { name: 'Vienna', offset: 7200, identifier: 'Europe/Vienna' },
+ { name: 'Warsaw', offset: 7200, identifier: 'Europe/Warsaw' },
+ { name: 'West Central Africa', offset: 3600, identifier: 'Africa/Algiers' },
+ { name: 'Zagreb', offset: 7200, identifier: 'Europe/Zagreb' },
+ { name: 'Zurich', offset: 7200, identifier: 'Europe/Zurich' },
+ { name: 'Athens', offset: 10800, identifier: 'Europe/Athens' },
+ { name: 'Bucharest', offset: 10800, identifier: 'Europe/Bucharest' },
+ { name: 'Cairo', offset: 7200, identifier: 'Africa/Cairo' },
+ { name: 'Harare', offset: 7200, identifier: 'Africa/Harare' },
+ { name: 'Helsinki', offset: 10800, identifier: 'Europe/Helsinki' },
+ { name: 'Jerusalem', offset: 10800, identifier: 'Asia/Jerusalem' },
+ { name: 'Kaliningrad', offset: 7200, identifier: 'Europe/Kaliningrad' },
+ { name: 'Kyiv', offset: 10800, identifier: 'Europe/Kiev' },
+ { name: 'Pretoria', offset: 7200, identifier: 'Africa/Johannesburg' },
+ { name: 'Riga', offset: 10800, identifier: 'Europe/Riga' },
+ { name: 'Sofia', offset: 10800, identifier: 'Europe/Sofia' },
+ { name: 'Tallinn', offset: 10800, identifier: 'Europe/Tallinn' },
+ { name: 'Vilnius', offset: 10800, identifier: 'Europe/Vilnius' },
+ { name: 'Baghdad', offset: 10800, identifier: 'Asia/Baghdad' },
+ { name: 'Istanbul', offset: 10800, identifier: 'Europe/Istanbul' },
+ { name: 'Kuwait', offset: 10800, identifier: 'Asia/Kuwait' },
+ { name: 'Minsk', offset: 10800, identifier: 'Europe/Minsk' },
+ { name: 'Moscow', offset: 10800, identifier: 'Europe/Moscow' },
+ { name: 'Nairobi', offset: 10800, identifier: 'Africa/Nairobi' },
+ { name: 'Riyadh', offset: 10800, identifier: 'Asia/Riyadh' },
+ { name: 'St. Petersburg', offset: 10800, identifier: 'Europe/Moscow' },
+ { name: 'Tehran', offset: 16200, identifier: 'Asia/Tehran' },
+ { name: 'Abu Dhabi', offset: 14400, identifier: 'Asia/Muscat' },
+ { name: 'Baku', offset: 14400, identifier: 'Asia/Baku' },
+ { name: 'Muscat', offset: 14400, identifier: 'Asia/Muscat' },
+ { name: 'Samara', offset: 14400, identifier: 'Europe/Samara' },
+ { name: 'Tbilisi', offset: 14400, identifier: 'Asia/Tbilisi' },
+ { name: 'Volgograd', offset: 14400, identifier: 'Europe/Volgograd' },
+ { name: 'Yerevan', offset: 14400, identifier: 'Asia/Yerevan' },
+ { name: 'Kabul', offset: 16200, identifier: 'Asia/Kabul' },
+ { name: 'Ekaterinburg', offset: 18000, identifier: 'Asia/Yekaterinburg' },
+ { name: 'Islamabad', offset: 18000, identifier: 'Asia/Karachi' },
+ { name: 'Karachi', offset: 18000, identifier: 'Asia/Karachi' },
+ { name: 'Tashkent', offset: 18000, identifier: 'Asia/Tashkent' },
+ { name: 'Chennai', offset: 19800, identifier: 'Asia/Kolkata' },
+ { name: 'Kolkata', offset: 19800, identifier: 'Asia/Kolkata' },
+ { name: 'Mumbai', offset: 19800, identifier: 'Asia/Kolkata' },
+ { name: 'New Delhi', offset: 19800, identifier: 'Asia/Kolkata' },
+ { name: 'Sri Jayawardenepura', offset: 19800, identifier: 'Asia/Colombo' },
+ { name: 'Kathmandu', offset: 20700, identifier: 'Asia/Kathmandu' },
+ { name: 'Almaty', offset: 21600, identifier: 'Asia/Almaty' },
+ { name: 'Astana', offset: 21600, identifier: 'Asia/Dhaka' },
+ { name: 'Dhaka', offset: 21600, identifier: 'Asia/Dhaka' },
+ { name: 'Urumqi', offset: 21600, identifier: 'Asia/Urumqi' },
+ { name: 'Rangoon', offset: 23400, identifier: 'Asia/Rangoon' },
+ { name: 'Bangkok', offset: 25200, identifier: 'Asia/Bangkok' },
+ { name: 'Hanoi', offset: 25200, identifier: 'Asia/Bangkok' },
+ { name: 'Jakarta', offset: 25200, identifier: 'Asia/Jakarta' },
+ { name: 'Krasnoyarsk', offset: 25200, identifier: 'Asia/Krasnoyarsk' },
+ { name: 'Novosibirsk', offset: 25200, identifier: 'Asia/Novosibirsk' },
+ { name: 'Beijing', offset: 28800, identifier: 'Asia/Shanghai' },
+ { name: 'Chongqing', offset: 28800, identifier: 'Asia/Chongqing' },
+ { name: 'Hong Kong', offset: 28800, identifier: 'Asia/Hong_Kong' },
+ { name: 'Irkutsk', offset: 28800, identifier: 'Asia/Irkutsk' },
+ { name: 'Kuala Lumpur', offset: 28800, identifier: 'Asia/Kuala_Lumpur' },
+ { name: 'Perth', offset: 28800, identifier: 'Australia/Perth' },
+ { name: 'Singapore', offset: 28800, identifier: 'Asia/Singapore' },
+ { name: 'Taipei', offset: 28800, identifier: 'Asia/Taipei' },
+ { name: 'Ulaanbaatar', offset: 28800, identifier: 'Asia/Ulaanbaatar' },
+ { name: 'Osaka', offset: 32400, identifier: 'Asia/Tokyo' },
+ { name: 'Sapporo', offset: 32400, identifier: 'Asia/Tokyo' },
+ { name: 'Seoul', offset: 32400, identifier: 'Asia/Seoul' },
+ { name: 'Tokyo', offset: 32400, identifier: 'Asia/Tokyo' },
+ { name: 'Yakutsk', offset: 32400, identifier: 'Asia/Yakutsk' },
+ { name: 'Adelaide', offset: 34200, identifier: 'Australia/Adelaide' },
+ { name: 'Darwin', offset: 34200, identifier: 'Australia/Darwin' },
+ { name: 'Brisbane', offset: 36000, identifier: 'Australia/Brisbane' },
+ { name: 'Canberra', offset: 36000, identifier: 'Australia/Melbourne' },
+ { name: 'Guam', offset: 36000, identifier: 'Pacific/Guam' },
+ { name: 'Hobart', offset: 36000, identifier: 'Australia/Hobart' },
+ { name: 'Melbourne', offset: 36000, identifier: 'Australia/Melbourne' },
+ { name: 'Port Moresby', offset: 36000, identifier: 'Pacific/Port_Moresby' },
+ { name: 'Sydney', offset: 36000, identifier: 'Australia/Sydney' },
+ { name: 'Vladivostok', offset: 36000, identifier: 'Asia/Vladivostok' },
+ { name: 'Magadan', offset: 39600, identifier: 'Asia/Magadan' },
+ { name: 'New Caledonia', offset: 39600, identifier: 'Pacific/Noumea' },
+ { name: 'Solomon Is.', offset: 39600, identifier: 'Pacific/Guadalcanal' },
+ { name: 'Srednekolymsk', offset: 39600, identifier: 'Asia/Srednekolymsk' },
+ { name: 'Auckland', offset: 43200, identifier: 'Pacific/Auckland' },
+ { name: 'Fiji', offset: 43200, identifier: 'Pacific/Fiji' },
+ { name: 'Kamchatka', offset: 43200, identifier: 'Asia/Kamchatka' },
+ { name: 'Marshall Is.', offset: 43200, identifier: 'Pacific/Majuro' },
+ { name: 'Wellington', offset: 43200, identifier: 'Pacific/Auckland' },
+ { name: 'Chatham Is.', offset: 45900, identifier: 'Pacific/Chatham' },
+ { name: "Nuku'alofa", offset: 46800, identifier: 'Pacific/Tongatapu' },
+ { name: 'Samoa', offset: 46800, identifier: 'Pacific/Apia' },
+ { name: 'Tokelau Is.', offset: 46800, identifier: 'Pacific/Fakaofo' },
+];
diff --git a/spec/frontend/deploy_freeze/store/actions_spec.js b/spec/frontend/deploy_freeze/store/actions_spec.js
new file mode 100644
index 00000000000..ad33dfee39f
--- /dev/null
+++ b/spec/frontend/deploy_freeze/store/actions_spec.js
@@ -0,0 +1,122 @@
+import Api from '~/api';
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import axios from '~/lib/utils/axios_utils';
+import createFlash from '~/flash';
+import getInitialState from '~/deploy_freeze/store/state';
+import * as actions from '~/deploy_freeze/store/actions';
+import * as types from '~/deploy_freeze/store/mutation_types';
+import { mockTimezoneData, mockFreezePeriods } from '../mock_data';
+
+jest.mock('~/api.js');
+jest.mock('~/flash.js');
+
+describe('deploy freeze store actions', () => {
+ let mock;
+ let state;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ state = getInitialState({
+ projectId: '8',
+ timezoneData: mockTimezoneData,
+ });
+ Api.freezePeriods.mockResolvedValue({ data: mockFreezePeriods });
+ Api.createFreezePeriod.mockResolvedValue();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('setSelectedTimezone', () => {
+ it('commits SET_SELECTED_TIMEZONE mutation', () => {
+ testAction(actions.setSelectedTimezone, {}, {}, [
+ {
+ payload: {},
+ type: types.SET_SELECTED_TIMEZONE,
+ },
+ ]);
+ });
+ });
+
+ describe('setFreezeStartCron', () => {
+ it('commits SET_FREEZE_START_CRON mutation', () => {
+ testAction(actions.setFreezeStartCron, {}, {}, [
+ {
+ type: types.SET_FREEZE_START_CRON,
+ },
+ ]);
+ });
+ });
+
+ describe('setFreezeEndCron', () => {
+ it('commits SET_FREEZE_END_CRON mutation', () => {
+ testAction(actions.setFreezeEndCron, {}, {}, [
+ {
+ type: types.SET_FREEZE_END_CRON,
+ },
+ ]);
+ });
+ });
+
+ describe('addFreezePeriod', () => {
+ it('dispatch correct actions on adding a freeze period', () => {
+ testAction(
+ actions.addFreezePeriod,
+ {},
+ state,
+ [{ type: 'RESET_MODAL' }],
+ [
+ { type: 'requestAddFreezePeriod' },
+ { type: 'receiveAddFreezePeriodSuccess' },
+ { type: 'fetchFreezePeriods' },
+ ],
+ );
+ });
+
+ it('should show flash error and set error in state on add failure', () => {
+ Api.createFreezePeriod.mockRejectedValue();
+
+ testAction(
+ actions.addFreezePeriod,
+ {},
+ state,
+ [],
+ [{ type: 'requestAddFreezePeriod' }, { type: 'receiveAddFreezePeriodError' }],
+ () => expect(createFlash).toHaveBeenCalled(),
+ );
+ });
+ });
+
+ describe('fetchFreezePeriods', () => {
+ it('dispatch correct actions on fetchFreezePeriods', () => {
+ testAction(
+ actions.fetchFreezePeriods,
+ {},
+ state,
+ [],
+ [
+ { type: 'requestFreezePeriods' },
+ { type: 'receiveFreezePeriodsSuccess', payload: mockFreezePeriods },
+ ],
+ );
+ });
+
+ it('should show flash error and set error in state on fetch variables failure', () => {
+ Api.freezePeriods.mockRejectedValue();
+
+ testAction(
+ actions.fetchFreezePeriods,
+ {},
+ state,
+ [],
+ [{ type: 'requestFreezePeriods' }],
+ () =>
+ expect(createFlash).toHaveBeenCalledWith(
+ 'There was an error fetching the deploy freezes.',
+ ),
+ );
+ });
+ });
+});
diff --git a/spec/frontend/deploy_freeze/store/mutations_spec.js b/spec/frontend/deploy_freeze/store/mutations_spec.js
new file mode 100644
index 00000000000..85ed0a84156
--- /dev/null
+++ b/spec/frontend/deploy_freeze/store/mutations_spec.js
@@ -0,0 +1,62 @@
+import state from '~/deploy_freeze/store/state';
+import mutations from '~/deploy_freeze/store/mutations';
+import * as types from '~/deploy_freeze/store/mutation_types';
+import { mockFreezePeriods, mockTimezoneData } from '../mock_data';
+
+describe('CI variable list mutations', () => {
+ let stateCopy;
+ beforeEach(() => {
+ stateCopy = state({
+ projectId: '8',
+ timezoneData: mockTimezoneData,
+ });
+ });
+
+ describe('RESET_MODAL', () => {
+ it('should reset modal state', () => {
+ mutations[types.RESET_MODAL](stateCopy);
+
+ expect(stateCopy.freezeStartCron).toBe('');
+ expect(stateCopy.freezeEndCron).toBe('');
+ expect(stateCopy.selectedTimezone).toBe('');
+ expect(stateCopy.selectedTimezoneIdentifier).toBe('');
+ });
+ });
+
+ describe('RECEIVE_FREEZE_PERIODS_SUCCESS', () => {
+ it('should set environments', () => {
+ mutations[types.RECEIVE_FREEZE_PERIODS_SUCCESS](stateCopy, mockFreezePeriods);
+
+ expect(stateCopy.freezePeriods).toEqual(mockFreezePeriods);
+ });
+ });
+
+ describe('SET_SELECTED_TIMEZONE', () => {
+ it('should set the cron timezone', () => {
+ const timezone = {
+ formattedTimezone: '[UTC -7] Pacific Time (US & Canada)',
+ identifier: 'America/Los_Angeles',
+ };
+ mutations[types.SET_SELECTED_TIMEZONE](stateCopy, timezone);
+
+ expect(stateCopy.selectedTimezone).toEqual(timezone.formattedTimezone);
+ expect(stateCopy.selectedTimezoneIdentifier).toEqual(timezone.identifier);
+ });
+ });
+
+ describe('SET_FREEZE_START_CRON', () => {
+ it('should set freezeStartCron', () => {
+ mutations[types.SET_FREEZE_START_CRON](stateCopy, '5 0 * 8 *');
+
+ expect(stateCopy.freezeStartCron).toBe('5 0 * 8 *');
+ });
+ });
+
+ describe('SET_FREEZE_ENDT_CRON', () => {
+ it('should set freezeEndCron', () => {
+ mutations[types.SET_FREEZE_END_CRON](stateCopy, '5 0 * 8 *');
+
+ expect(stateCopy.freezeEndCron).toBe('5 0 * 8 *');
+ });
+ });
+});