diff options
Diffstat (limited to 'spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js')
-rw-r--r-- | spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js b/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js new file mode 100644 index 00000000000..08fa6ca9057 --- /dev/null +++ b/spec/javascripts/pipeline_schedules/interval_pattern_input_spec.js @@ -0,0 +1,217 @@ +import Vue from 'vue'; +import IntervalPatternInput from '~/pipeline_schedules/components/interval_pattern_input'; + +const IntervalPatternInputComponent = Vue.extend(IntervalPatternInput); +const inputNameAttribute = 'schedule[cron]'; + +const cronIntervalPresets = { + everyDay: '0 4 * * *', + everyWeek: '0 4 * * 0', + everyMonth: '0 4 1 * *', +}; + +window.gl = window.gl || {}; + +window.gl.pipelineScheduleFieldErrors = { + updateFormValidityState: () => {}, +}; + +describe('Interval Pattern Input Component', function () { + describe('when prop initialCronInterval is passed (edit)', function () { + describe('when prop initialCronInterval is custom', function () { + beforeEach(function () { + this.initialCronInterval = '1 2 3 4 5'; + this.intervalPatternComponent = new IntervalPatternInputComponent({ + propsData: { + initialCronInterval: this.initialCronInterval, + }, + }).$mount(); + }); + + it('is initialized as a Vue component', function () { + expect(this.intervalPatternComponent).toBeDefined(); + }); + + it('prop initialCronInterval is set', function () { + expect(this.intervalPatternComponent.initialCronInterval).toBe(this.initialCronInterval); + }); + + it('sets showUnsetWarning to false', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.showUnsetWarning).toBe(false); + done(); + }); + }); + + it('does not render showUnsetWarning', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.$el.outerHTML).not.toContain('Schedule not yet set'); + done(); + }); + }); + + it('sets isEditable to true', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.isEditable).toBe(true); + done(); + }); + }); + }); + + describe('when prop initialCronInterval is preset', function () { + beforeEach(function () { + this.intervalPatternComponent = new IntervalPatternInputComponent({ + propsData: { + inputNameAttribute, + initialCronInterval: '0 4 * * *', + }, + }).$mount(); + }); + + it('is initialized as a Vue component', function () { + expect(this.intervalPatternComponent).toBeDefined(); + }); + + it('sets showUnsetWarning to false', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.showUnsetWarning).toBe(false); + done(); + }); + }); + + it('does not render showUnsetWarning', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.$el.outerHTML).not.toContain('Schedule not yet set'); + done(); + }); + }); + + it('sets isEditable to false', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.isEditable).toBe(false); + done(); + }); + }); + }); + }); + + describe('when prop initialCronInterval is not passed (new)', function () { + beforeEach(function () { + this.intervalPatternComponent = new IntervalPatternInputComponent({ + propsData: { + inputNameAttribute, + }, + }).$mount(); + }); + + it('is initialized as a Vue component', function () { + expect(this.intervalPatternComponent).toBeDefined(); + }); + + it('prop initialCronInterval is set', function () { + const defaultInitialCronInterval = ''; + expect(this.intervalPatternComponent.initialCronInterval).toBe(defaultInitialCronInterval); + }); + + it('sets showUnsetWarning to true', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.showUnsetWarning).toBe(true); + done(); + }); + }); + + it('renders showUnsetWarning to true', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.$el.outerHTML).toContain('Schedule not yet set'); + done(); + }); + }); + + it('sets isEditable to true', function (done) { + Vue.nextTick(() => { + expect(this.intervalPatternComponent.isEditable).toBe(true); + done(); + }); + }); + }); + + describe('User Actions', function () { + beforeEach(function () { + // For an unknown reason, Phantom.js doesn't trigger click events + // on radio buttons in a way Vue can register. So, we have to mount + // to a fixture. + setFixtures('<div id="my-mount"></div>'); + + this.initialCronInterval = '1 2 3 4 5'; + this.intervalPatternComponent = new IntervalPatternInputComponent({ + propsData: { + initialCronInterval: this.initialCronInterval, + }, + }).$mount('#my-mount'); + }); + + it('cronInterval is updated when everyday preset interval is selected', function (done) { + this.intervalPatternComponent.$el.querySelector('#every-day').click(); + + Vue.nextTick(() => { + expect(this.intervalPatternComponent.cronInterval).toBe(cronIntervalPresets.everyDay); + expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(cronIntervalPresets.everyDay); + done(); + }); + }); + + it('cronInterval is updated when everyweek preset interval is selected', function (done) { + this.intervalPatternComponent.$el.querySelector('#every-week').click(); + + Vue.nextTick(() => { + expect(this.intervalPatternComponent.cronInterval).toBe(cronIntervalPresets.everyWeek); + expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(cronIntervalPresets.everyWeek); + + done(); + }); + }); + + it('cronInterval is updated when everymonth preset interval is selected', function (done) { + this.intervalPatternComponent.$el.querySelector('#every-month').click(); + + Vue.nextTick(() => { + expect(this.intervalPatternComponent.cronInterval).toBe(cronIntervalPresets.everyMonth); + expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(cronIntervalPresets.everyMonth); + done(); + }); + }); + + it('only a space is added to cronInterval (trimmed later) when custom radio is selected', function (done) { + this.intervalPatternComponent.$el.querySelector('#every-month').click(); + this.intervalPatternComponent.$el.querySelector('#custom').click(); + + Vue.nextTick(() => { + const intervalWithSpaceAppended = `${cronIntervalPresets.everyMonth} `; + expect(this.intervalPatternComponent.cronInterval).toBe(intervalWithSpaceAppended); + expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(intervalWithSpaceAppended); + done(); + }); + }); + + it('text input is disabled when preset interval is selected', function (done) { + this.intervalPatternComponent.$el.querySelector('#every-month').click(); + + Vue.nextTick(() => { + expect(this.intervalPatternComponent.isEditable).toBe(false); + expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').disabled).toBe(true); + done(); + }); + }); + + it('text input is enabled when custom is selected', function (done) { + this.intervalPatternComponent.$el.querySelector('#every-month').click(); + this.intervalPatternComponent.$el.querySelector('#custom').click(); + + Vue.nextTick(() => { + expect(this.intervalPatternComponent.isEditable).toBe(true); + expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').disabled).toBe(false); + done(); + }); + }); + }); +}); |