diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-17 21:09:20 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-17 21:09:20 +0300 |
commit | ec72da1833d94bb1556af94193ccf2a93c9cb939 (patch) | |
tree | 6227669a11aaf8370186a7aa6591d5fa9d853bb0 /spec/frontend/deploy_freeze | |
parent | 283fb71e02992b6687e3264d53bbc718b7567109 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/deploy_freeze')
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 *'); + }); + }); +}); |