From e8b9d0c2250911f125c664c8df3404d33bbf4eab Mon Sep 17 00:00:00 2001 From: giulianovarriale Date: Fri, 11 Nov 2016 10:57:51 -0200 Subject: [PATCH 01/11] Pass date as integer params on instantiate new Date in order to avoid time zone inconsistency --- app/assets/javascripts/due_date_select.js.es6 | 11 +++++-- .../javascripts/lib/utils/datetime_utility.js | 13 ++++++++ .../fix-timezone-due-date-picker.yml | 4 +++ spec/javascripts/datetime_utility_spec.js.es6 | 32 +++++++++++++++++++ spec/javascripts/due_date_select_spec.js.es6 | 25 +++++++++++++++ .../fixtures/due_date_select.html.haml | 29 +++++++++++++++++ 6 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 changelogs/unreleased/fix-timezone-due-date-picker.yml create mode 100644 spec/javascripts/due_date_select_spec.js.es6 create mode 100644 spec/javascripts/fixtures/due_date_select.html.haml diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6 index 2b7d57d86c6..f35c024e716 100644 --- a/app/assets/javascripts/due_date_select.js.es6 +++ b/app/assets/javascripts/due_date_select.js.es6 @@ -2,9 +2,10 @@ (function(global) { class DueDateSelect { - constructor({ $dropdown, $loading } = {}) { + constructor({ $dropdown, $loading, $context } = {}) { const $dropdownParent = $dropdown.closest('.dropdown'); const $block = $dropdown.closest('.block'); + this.$context = $context || $('body'); this.$loading = $loading; this.$dropdown = $dropdown; this.$dropdownParent = $dropdownParent; @@ -80,9 +81,12 @@ } parseSelectedDate() { - this.rawSelectedDate = $("input[name='" + this.fieldName + "']").val(); + this.rawSelectedDate = this.$context.find(`input[name='${this.fieldName}']`).val(); + if (this.rawSelectedDate.length) { - let dateObj = new Date(this.rawSelectedDate); + // Avoid time zone inconsistency using the utils.createDateObject + // method, instead of the native Date object. + const dateObj = gl.utils.createDateObject(this.rawSelectedDate); this.displayedDate = $.datepicker.formatDate('M d, yy', dateObj); } else { this.displayedDate = 'No due date'; @@ -176,5 +180,6 @@ } global.DueDateSelectors = DueDateSelectors; + global.DueDateSelect = DueDateSelect; })(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index e8e502694d6..7a136a355ec 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -16,6 +16,19 @@ } w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + // createDateObject must be used instead of using native Date object + // to create a new Date instance using string as param - '2016-11-10' or + // '2016/11/10' in order to avoid time zone inconsistency. + w.gl.utils.createDateObject = function(string) { + var dateSeparator = string.indexOf('-') > -1 ? '-' : '/'; + + var dateArray = string.split(dateSeparator).map(function(dateItem) { + return parseInt(dateItem, 10); + }); + + return new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); + } + w.gl.utils.formatDate = function(datetime) { return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z'); }; diff --git a/changelogs/unreleased/fix-timezone-due-date-picker.yml b/changelogs/unreleased/fix-timezone-due-date-picker.yml new file mode 100644 index 00000000000..02f5ed890c6 --- /dev/null +++ b/changelogs/unreleased/fix-timezone-due-date-picker.yml @@ -0,0 +1,4 @@ +--- +title: Fix date inconsistency on due date picker +merge_request: +author: Giuliano Varriale diff --git a/spec/javascripts/datetime_utility_spec.js.es6 b/spec/javascripts/datetime_utility_spec.js.es6 index 8ece24555c5..756c888cad7 100644 --- a/spec/javascripts/datetime_utility_spec.js.es6 +++ b/spec/javascripts/datetime_utility_spec.js.es6 @@ -2,6 +2,38 @@ (() => { describe('Date time utils', () => { + describe('create date object', () => { + describe('using dashes', () => { + it('should instantiate the date object using integer params', () => { + spyOn(window, 'Date') + gl.utils.createDateObject('2016-11-12'); + expect(window.Date).toHaveBeenCalledWith(2016, 10, 12); + }); + + it('should return the right date object ', () => { + const date = gl.utils.createDateObject('2016-11-12'); + expect(date.getDate()).toBe(12); + expect(date.getMonth()).toBe(10); + expect(date.getFullYear()).toBe(2016); + }); + }); + + describe('using slashes', () => { + it('should instantiate the date object using integer params', () => { + spyOn(window, 'Date') + gl.utils.createDateObject('2016/08/02'); + expect(window.Date).toHaveBeenCalledWith(2016, 7, 2); + }); + + it('should return the right date object', () => { + const date = gl.utils.createDateObject('2016/08/02'); + expect(date.getDate()).toBe(2); + expect(date.getMonth()).toBe(7); + expect(date.getFullYear()).toBe(2016); + }); + }); + }); + describe('get day name', () => { it('should return Sunday', () => { const day = gl.utils.getDayName(new Date('07/17/2016')); diff --git a/spec/javascripts/due_date_select_spec.js.es6 b/spec/javascripts/due_date_select_spec.js.es6 new file mode 100644 index 00000000000..d491c25b6fe --- /dev/null +++ b/spec/javascripts/due_date_select_spec.js.es6 @@ -0,0 +1,25 @@ +/* eslint-disable */ +//= require lib/utils/datetime_utility +//= require jquery +/*= require jquery-ui/datepicker */ +/*= require gl_dropdown */ +//= require due_date_select +(() => { + describe('Due Date Select', () => { + describe('parseSelectedDate()', () => { + it('call create date object', () => { + const $dom = $(fixture.preload('due_date_select.html')[0]); + + const dueDateSelect = new gl.DueDateSelect({ + $context: $dom, + $dropdown: $dom.find('.js-due-date-select'), + $loading: $dom.find('.block-loading') + }); + + spyOn(gl.utils, 'createDateObject'); + dueDateSelect.parseSelectedDate(); + expect(gl.utils.createDateObject).toHaveBeenCalledWith('2016-11-20'); + }); + }); + }); +})(); diff --git a/spec/javascripts/fixtures/due_date_select.html.haml b/spec/javascripts/fixtures/due_date_select.html.haml new file mode 100644 index 00000000000..ed7dcb0d658 --- /dev/null +++ b/spec/javascripts/fixtures/due_date_select.html.haml @@ -0,0 +1,29 @@ +.block.due_date + .sidebar-collapsed-icon + %i.fa.fa-calendar + %span.js-due-date-sidebar-value + Nov 20, 2016 + .title.hide-collapsed + Due date + %i.fa.fa-spinner.fa-spin.block-loading + %a.edit-link.pull-right{ href: "#"} Edit + .value.hide-collapsed + %span.value-content + %span.bold + Nov 20, 2016 + %span.no-value.js-remove-due-date-holder + %a.js-remove-due-date{ href: "#", role: "button" } + remove due date + .selectbox.hide-collapsed + %input{type: "hidden", name: "issue[due_date]", id: "issue[due_date]", value: "2016-11-20"} + .dropdown + %button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue", issue_update: "/h5bp/html5-boilerplate/issues/10.json" } } + %span.dropdown-toggle-text Due date + %i.fa.fa-chevron-down + .dropdown-menu.dropdown-menu-due-date + .dropdown-title + %span Due Date + %button.dropdown-title-button.dropdown-menu-close{ type: "button" } + %i.fa.fa-times.dropdown-menu-close-icon + .dropdown-content + .js-due-date-calendar From 35ce4b496c8bd1c160abe350ba8e6c722faa3989 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 13 Dec 2016 11:53:19 -0600 Subject: [PATCH 02/11] add MR number to changelog entry --- changelogs/unreleased/fix-timezone-due-date-picker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/unreleased/fix-timezone-due-date-picker.yml b/changelogs/unreleased/fix-timezone-due-date-picker.yml index 02f5ed890c6..2e6b71c70ca 100644 --- a/changelogs/unreleased/fix-timezone-due-date-picker.yml +++ b/changelogs/unreleased/fix-timezone-due-date-picker.yml @@ -1,4 +1,4 @@ --- title: Fix date inconsistency on due date picker -merge_request: +merge_request: 7422 author: Giuliano Varriale From 7d988e4483cfe13cccd797850ab6372c74c01d14 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 13 Dec 2016 15:37:59 -0600 Subject: [PATCH 03/11] fix eslint violations --- app/assets/javascripts/lib/utils/datetime_utility.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 7a136a355ec..76520f67a4d 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -1,4 +1,4 @@ -/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, padded-blocks, max-len */ +/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, prefer-arrow-callback, padded-blocks, max-len */ /* global timeago */ /* global dateFormat */ @@ -26,8 +26,8 @@ return parseInt(dateItem, 10); }); - return new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); - } + return new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); + }; w.gl.utils.formatDate = function(datetime) { return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z'); From 2951ee9e3683095579e651ad74df31d2f9bf6091 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 21 Dec 2016 16:06:57 -0600 Subject: [PATCH 04/11] use single sprockets require comment style and remove eslint-disable --- spec/javascripts/due_date_select_spec.js.es6 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/javascripts/due_date_select_spec.js.es6 b/spec/javascripts/due_date_select_spec.js.es6 index d491c25b6fe..202787edb19 100644 --- a/spec/javascripts/due_date_select_spec.js.es6 +++ b/spec/javascripts/due_date_select_spec.js.es6 @@ -1,9 +1,9 @@ -/* eslint-disable */ //= require lib/utils/datetime_utility //= require jquery -/*= require jquery-ui/datepicker */ -/*= require gl_dropdown */ +//= require jquery-ui/datepicker +//= require gl_dropdown //= require due_date_select + (() => { describe('Due Date Select', () => { describe('parseSelectedDate()', () => { @@ -13,7 +13,7 @@ const dueDateSelect = new gl.DueDateSelect({ $context: $dom, $dropdown: $dom.find('.js-due-date-select'), - $loading: $dom.find('.block-loading') + $loading: $dom.find('.block-loading'), }); spyOn(gl.utils, 'createDateObject'); From 3212d47c68c4608e7140b16a30f89e4d26267c46 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 22 Dec 2016 00:03:55 -0600 Subject: [PATCH 05/11] fix eslint complaints --- spec/javascripts/datetime_utility_spec.js.es6 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/javascripts/datetime_utility_spec.js.es6 b/spec/javascripts/datetime_utility_spec.js.es6 index 756c888cad7..a597e713f3e 100644 --- a/spec/javascripts/datetime_utility_spec.js.es6 +++ b/spec/javascripts/datetime_utility_spec.js.es6 @@ -5,7 +5,7 @@ describe('create date object', () => { describe('using dashes', () => { it('should instantiate the date object using integer params', () => { - spyOn(window, 'Date') + spyOn(window, 'Date'); gl.utils.createDateObject('2016-11-12'); expect(window.Date).toHaveBeenCalledWith(2016, 10, 12); }); @@ -19,8 +19,8 @@ }); describe('using slashes', () => { - it('should instantiate the date object using integer params', () => { - spyOn(window, 'Date') + it('should also instantiate the date object using integer params', () => { + spyOn(window, 'Date'); gl.utils.createDateObject('2016/08/02'); expect(window.Date).toHaveBeenCalledWith(2016, 7, 2); }); From 637dafde1dabfeb83a384fe48b845b2032b8a23a Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 2 Jan 2017 14:20:17 -0600 Subject: [PATCH 06/11] add rspec feature test --- spec/features/issues_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index b071fe480e6..39de8775c8a 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -619,14 +619,16 @@ describe 'Issues', feature: true do end it 'adds due date to issue' do + date = Date.today.at_beginning_of_month + 2.days + page.within '.due_date' do click_link 'Edit' page.within '.ui-datepicker-calendar' do - first('.ui-state-default').click + click_link date.day end - expect(page).to have_no_content 'None' + expect(find('.value').text).to have_content date.strftime('%b %-d, %Y') end end From 4d2fbe65cdcecf36c6c27553175b13b8f80abb73 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 2 Jan 2017 14:35:33 -0600 Subject: [PATCH 07/11] remove unnecessary fixtures and tests --- app/assets/javascripts/due_date_select.js.es6 | 6 ++-- spec/javascripts/datetime_utility_spec.js.es6 | 32 ------------------- spec/javascripts/due_date_select_spec.js.es6 | 25 --------------- .../fixtures/due_date_select.html.haml | 29 ----------------- 4 files changed, 2 insertions(+), 90 deletions(-) delete mode 100644 spec/javascripts/due_date_select_spec.js.es6 delete mode 100644 spec/javascripts/fixtures/due_date_select.html.haml diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6 index f35c024e716..cb92b8c7658 100644 --- a/app/assets/javascripts/due_date_select.js.es6 +++ b/app/assets/javascripts/due_date_select.js.es6 @@ -2,10 +2,9 @@ (function(global) { class DueDateSelect { - constructor({ $dropdown, $loading, $context } = {}) { + constructor({ $dropdown, $loading } = {}) { const $dropdownParent = $dropdown.closest('.dropdown'); const $block = $dropdown.closest('.block'); - this.$context = $context || $('body'); this.$loading = $loading; this.$dropdown = $dropdown; this.$dropdownParent = $dropdownParent; @@ -81,7 +80,7 @@ } parseSelectedDate() { - this.rawSelectedDate = this.$context.find(`input[name='${this.fieldName}']`).val(); + this.rawSelectedDate = $(`input[name='${this.fieldName}']`).val(); if (this.rawSelectedDate.length) { // Avoid time zone inconsistency using the utils.createDateObject @@ -180,6 +179,5 @@ } global.DueDateSelectors = DueDateSelectors; - global.DueDateSelect = DueDateSelect; })(window.gl || (window.gl = {})); diff --git a/spec/javascripts/datetime_utility_spec.js.es6 b/spec/javascripts/datetime_utility_spec.js.es6 index a597e713f3e..8ece24555c5 100644 --- a/spec/javascripts/datetime_utility_spec.js.es6 +++ b/spec/javascripts/datetime_utility_spec.js.es6 @@ -2,38 +2,6 @@ (() => { describe('Date time utils', () => { - describe('create date object', () => { - describe('using dashes', () => { - it('should instantiate the date object using integer params', () => { - spyOn(window, 'Date'); - gl.utils.createDateObject('2016-11-12'); - expect(window.Date).toHaveBeenCalledWith(2016, 10, 12); - }); - - it('should return the right date object ', () => { - const date = gl.utils.createDateObject('2016-11-12'); - expect(date.getDate()).toBe(12); - expect(date.getMonth()).toBe(10); - expect(date.getFullYear()).toBe(2016); - }); - }); - - describe('using slashes', () => { - it('should also instantiate the date object using integer params', () => { - spyOn(window, 'Date'); - gl.utils.createDateObject('2016/08/02'); - expect(window.Date).toHaveBeenCalledWith(2016, 7, 2); - }); - - it('should return the right date object', () => { - const date = gl.utils.createDateObject('2016/08/02'); - expect(date.getDate()).toBe(2); - expect(date.getMonth()).toBe(7); - expect(date.getFullYear()).toBe(2016); - }); - }); - }); - describe('get day name', () => { it('should return Sunday', () => { const day = gl.utils.getDayName(new Date('07/17/2016')); diff --git a/spec/javascripts/due_date_select_spec.js.es6 b/spec/javascripts/due_date_select_spec.js.es6 deleted file mode 100644 index 202787edb19..00000000000 --- a/spec/javascripts/due_date_select_spec.js.es6 +++ /dev/null @@ -1,25 +0,0 @@ -//= require lib/utils/datetime_utility -//= require jquery -//= require jquery-ui/datepicker -//= require gl_dropdown -//= require due_date_select - -(() => { - describe('Due Date Select', () => { - describe('parseSelectedDate()', () => { - it('call create date object', () => { - const $dom = $(fixture.preload('due_date_select.html')[0]); - - const dueDateSelect = new gl.DueDateSelect({ - $context: $dom, - $dropdown: $dom.find('.js-due-date-select'), - $loading: $dom.find('.block-loading'), - }); - - spyOn(gl.utils, 'createDateObject'); - dueDateSelect.parseSelectedDate(); - expect(gl.utils.createDateObject).toHaveBeenCalledWith('2016-11-20'); - }); - }); - }); -})(); diff --git a/spec/javascripts/fixtures/due_date_select.html.haml b/spec/javascripts/fixtures/due_date_select.html.haml deleted file mode 100644 index ed7dcb0d658..00000000000 --- a/spec/javascripts/fixtures/due_date_select.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -.block.due_date - .sidebar-collapsed-icon - %i.fa.fa-calendar - %span.js-due-date-sidebar-value - Nov 20, 2016 - .title.hide-collapsed - Due date - %i.fa.fa-spinner.fa-spin.block-loading - %a.edit-link.pull-right{ href: "#"} Edit - .value.hide-collapsed - %span.value-content - %span.bold - Nov 20, 2016 - %span.no-value.js-remove-due-date-holder - %a.js-remove-due-date{ href: "#", role: "button" } - remove due date - .selectbox.hide-collapsed - %input{type: "hidden", name: "issue[due_date]", id: "issue[due_date]", value: "2016-11-20"} - .dropdown - %button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue", issue_update: "/h5bp/html5-boilerplate/issues/10.json" } } - %span.dropdown-toggle-text Due date - %i.fa.fa-chevron-down - .dropdown-menu.dropdown-menu-due-date - .dropdown-title - %span Due Date - %button.dropdown-title-button.dropdown-menu-close{ type: "button" } - %i.fa.fa-times.dropdown-menu-close-icon - .dropdown-content - .js-due-date-calendar From e4883e7efce8ea578b32d89be089476f1fd26134 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 2 Jan 2017 14:48:58 -0600 Subject: [PATCH 08/11] remove unnecessary utility function --- app/assets/javascripts/due_date_select.js.es6 | 5 ++--- .../javascripts/lib/utils/datetime_utility.js | 15 +-------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6 index cb92b8c7658..6ea8adb7c7b 100644 --- a/app/assets/javascripts/due_date_select.js.es6 +++ b/app/assets/javascripts/due_date_select.js.es6 @@ -83,9 +83,8 @@ this.rawSelectedDate = $(`input[name='${this.fieldName}']`).val(); if (this.rawSelectedDate.length) { - // Avoid time zone inconsistency using the utils.createDateObject - // method, instead of the native Date object. - const dateObj = gl.utils.createDateObject(this.rawSelectedDate); + const dateArray = this.rawSelectedDate.split('-').map(v => parseInt(v, 10)); + const dateObj = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); this.displayedDate = $.datepicker.formatDate('M d, yy', dateObj); } else { this.displayedDate = 'No due date'; diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 76520f67a4d..e8e502694d6 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -1,4 +1,4 @@ -/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, prefer-arrow-callback, padded-blocks, max-len */ +/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, padded-blocks, max-len */ /* global timeago */ /* global dateFormat */ @@ -16,19 +16,6 @@ } w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; - // createDateObject must be used instead of using native Date object - // to create a new Date instance using string as param - '2016-11-10' or - // '2016/11/10' in order to avoid time zone inconsistency. - w.gl.utils.createDateObject = function(string) { - var dateSeparator = string.indexOf('-') > -1 ? '-' : '/'; - - var dateArray = string.split(dateSeparator).map(function(dateItem) { - return parseInt(dateItem, 10); - }); - - return new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); - }; - w.gl.utils.formatDate = function(datetime) { return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z'); }; From 49acf5d831b0699d60689b7d86528f4970091b49 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 2 Jan 2017 14:49:31 -0600 Subject: [PATCH 09/11] make expected due_date value format explicit --- app/views/shared/issuable/_sidebar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index bc57d48ae7c..5f199301364 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -97,7 +97,7 @@ remove due date - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) .selectbox.hide-collapsed - = f.hidden_field :due_date, value: issuable.due_date + = f.hidden_field :due_date, value: issuable.due_date.try(:strftime, 'yy-mm-dd') .dropdown %button.dropdown-menu-toggle.js-due-date-select{ type: 'button', data: { toggle: 'dropdown', field_name: "#{issuable.to_ability_name}[due_date]", ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable) } } %span.dropdown-toggle-text Due date From cf3c6a015f9ba644f1cec10319b247ef04114189 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 2 Jan 2017 15:03:16 -0600 Subject: [PATCH 10/11] add comment to explain why we are avoiding the dateString constructor option for our Date object --- app/assets/javascripts/due_date_select.js.es6 | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6 index 6ea8adb7c7b..201f9fdc3fe 100644 --- a/app/assets/javascripts/due_date_select.js.es6 +++ b/app/assets/javascripts/due_date_select.js.es6 @@ -83,6 +83,7 @@ this.rawSelectedDate = $(`input[name='${this.fieldName}']`).val(); if (this.rawSelectedDate.length) { + // Construct Date object manually to avoid buggy dateString support within Date constructor const dateArray = this.rawSelectedDate.split('-').map(v => parseInt(v, 10)); const dateObj = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]); this.displayedDate = $.datepicker.formatDate('M d, yy', dateObj); From 55fe57ebe6c69355b727108366e558b9ac5fd142 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Thu, 5 Jan 2017 17:40:42 -0500 Subject: [PATCH 11/11] Wait for ajax after clicking on a date --- spec/features/issues_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 39de8775c8a..394eb31aff8 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -628,6 +628,8 @@ describe 'Issues', feature: true do click_link date.day end + wait_for_ajax + expect(find('.value').text).to have_content date.strftime('%b %-d, %Y') end end @@ -640,6 +642,8 @@ describe 'Issues', feature: true do first('.ui-state-default').click end + wait_for_ajax + expect(page).to have_no_content 'No due date' click_link 'remove due date'