Merge pull request #580 from dod-ccpo/date-field-component-tests
Add in VUE date picker component
This commit is contained in:
187
js/components/__tests__/date_selector.test.js
Normal file
187
js/components/__tests__/date_selector.test.js
Normal file
@@ -0,0 +1,187 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
import DateSelector from '../date_selector'
|
||||
|
||||
describe('DateSelector', () => {
|
||||
const component = new Vue(DateSelector).$mount()
|
||||
|
||||
describe('isDateValid', () => {
|
||||
it('returns true when a valid date', () => {
|
||||
component.day = 4
|
||||
component.month = 8
|
||||
component.year = 1776
|
||||
|
||||
expect(component.isDateValid).toEqual(true)
|
||||
})
|
||||
|
||||
it('returns false when an invalid date', () => {
|
||||
component.day = 32
|
||||
component.month = 13
|
||||
component.year = 2019
|
||||
|
||||
expect(component.isDateValid).toEqual(false)
|
||||
})
|
||||
|
||||
it('returns false when parts of the date are missing', () => {
|
||||
component.day = 31
|
||||
component.year = 2019
|
||||
|
||||
expect(component.isDateValid).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('daysMaxCalculation', () => {
|
||||
it('calculates correctly for each month', () => {
|
||||
component.year = null
|
||||
|
||||
let months = {
|
||||
'1': 31,
|
||||
'2': 29,
|
||||
'3': 31,
|
||||
'4': 30,
|
||||
'5': 31,
|
||||
'6': 30,
|
||||
'7': 31,
|
||||
'8': 31,
|
||||
'9': 30,
|
||||
'10': 31,
|
||||
'11': 30,
|
||||
'12': 31,
|
||||
}
|
||||
|
||||
for (var month in months) {
|
||||
component.month = parseInt(month)
|
||||
expect(component.daysMaxCalculation).toEqual(months[month])
|
||||
}
|
||||
})
|
||||
|
||||
it('takes year or lack of year into account and calculates leap years', () => {
|
||||
component.month = 2
|
||||
|
||||
component.year = null
|
||||
expect(component.daysMaxCalculation).toEqual(29)
|
||||
|
||||
component.year = 2019
|
||||
expect(component.daysMaxCalculation).toEqual(28)
|
||||
|
||||
component.year = 2016
|
||||
expect(component.daysMaxCalculation).toEqual(29)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isMonthValid', () => {
|
||||
it('returns false when over 12', () => {
|
||||
component.month = 13
|
||||
expect(component.isMonthValid).toEqual(false)
|
||||
})
|
||||
|
||||
it('returns true when between 1 and 12', () => {
|
||||
component.month = 3
|
||||
expect(component.isMonthValid).toEqual(true)
|
||||
})
|
||||
|
||||
it('returns false when null', () => {
|
||||
component.month = null
|
||||
expect(component.isMonthValid).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isDayValid', () => {
|
||||
it('returns true when 31 and no month', () => {
|
||||
component.day = 31
|
||||
component.month = null
|
||||
expect(component.isDayValid).toEqual(true)
|
||||
})
|
||||
|
||||
it('returns false when 31 and in February', () => {
|
||||
component.day = 31
|
||||
component.month = 2
|
||||
expect(component.isDayValid).toEqual(false)
|
||||
})
|
||||
|
||||
it('returns false when 32 and no month', () => {
|
||||
component.day = 32
|
||||
component.month = null
|
||||
expect(component.isDayValid).toEqual(false)
|
||||
})
|
||||
|
||||
it('returns false when null', () => {
|
||||
component.day = null
|
||||
expect(component.isDayValid).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isWithinDateRange', () => {
|
||||
beforeEach(() => {
|
||||
component.day = 24
|
||||
component.month = 1
|
||||
component.year = 2019
|
||||
})
|
||||
|
||||
it('always returns true when no mindate or maxdate', () => {
|
||||
expect(component.isWithinDateRange).toEqual(true)
|
||||
})
|
||||
|
||||
it('handles mindate only', () => {
|
||||
component.mindate = '2019-01-25'
|
||||
expect(component.isWithinDateRange).toEqual(false)
|
||||
|
||||
component.mindate = '2014-01-25'
|
||||
expect(component.isWithinDateRange).toEqual(true)
|
||||
})
|
||||
|
||||
it('handles maxdate only', () => {
|
||||
component.maxdate = '2019-01-25'
|
||||
expect(component.isWithinDateRange).toEqual(true)
|
||||
|
||||
component.maxdate = '2014-01-25'
|
||||
expect(component.isWithinDateRange).toEqual(false)
|
||||
})
|
||||
|
||||
it('handles mindate and maxdate', () => {
|
||||
component.mindate = '2019-01-25'
|
||||
component.maxdate = '2019-02-28'
|
||||
expect(component.isWithinDateRange).toEqual(false)
|
||||
|
||||
component.mindate = '2013-01-25'
|
||||
component.maxdate = '2016-02-28'
|
||||
expect(component.isWithinDateRange).toEqual(false)
|
||||
|
||||
component.mindate = '2014-01-25'
|
||||
component.maxdate = '2020-02-28'
|
||||
expect(component.isWithinDateRange).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isYearValid', () => {
|
||||
it('returns false if year is null', () => {
|
||||
component.year = null
|
||||
expect(component.isYearValid).toEqual(false)
|
||||
})
|
||||
|
||||
it('returns true if year is present', () => {
|
||||
component.year = new Date().getFullYear()
|
||||
expect(component.isYearValid).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('formattedDate', () => {
|
||||
it('returns null if not all parts are present', () => {
|
||||
component.day = null
|
||||
component.month = 1
|
||||
component.year = 1988
|
||||
|
||||
expect(component.formattedDate).toBeNull()
|
||||
})
|
||||
|
||||
it('joins date components into a JS date', () => {
|
||||
component.mindate = null
|
||||
component.maxdate = null
|
||||
component.day = 22
|
||||
component.month = 1
|
||||
component.year = 1988
|
||||
|
||||
expect(component.formattedDate).toEqual('01/22/1988')
|
||||
})
|
||||
})
|
||||
})
|
106
js/components/date_selector.js
Normal file
106
js/components/date_selector.js
Normal file
@@ -0,0 +1,106 @@
|
||||
import Vue from 'vue'
|
||||
import { getDaysInMonth } from 'date-fns'
|
||||
|
||||
var paddedNumber = function(number) {
|
||||
if ((number + '').length === 1) {
|
||||
return `0${number}`
|
||||
} else {
|
||||
return number
|
||||
}
|
||||
}
|
||||
|
||||
export default Vue.component('date-selector', {
|
||||
props: ['initialday', 'initialmonth', 'initialyear', 'mindate', 'maxdate'],
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
day: this.initialday,
|
||||
month: this.initialmonth,
|
||||
year: this.initialyear,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
formattedDate: function() {
|
||||
if (!this.isDateValid) {
|
||||
return null
|
||||
}
|
||||
|
||||
let day = paddedNumber(this.day)
|
||||
let month = paddedNumber(this.month)
|
||||
|
||||
return `${month}/${day}/${this.year}`
|
||||
},
|
||||
|
||||
isMonthValid: function() {
|
||||
var _month = parseInt(this.month)
|
||||
|
||||
return _month >= 0 && _month <= 12
|
||||
},
|
||||
|
||||
isDayValid: function() {
|
||||
var _day = parseInt(this.day)
|
||||
|
||||
return _day >= 0 && _day <= this.daysMaxCalculation
|
||||
},
|
||||
|
||||
isYearValid: function() {
|
||||
return parseInt(this.year) >= 1
|
||||
},
|
||||
|
||||
isWithinDateRange: function() {
|
||||
let _mindate = this.mindate ? Date.parse(this.mindate) : null
|
||||
let _maxdate = this.maxdate ? Date.parse(this.maxdate) : null
|
||||
let _dateTimestamp = Date.UTC(this.year, this.month - 1, this.day)
|
||||
|
||||
if (_mindate !== null && _mindate >= _dateTimestamp) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (_maxdate !== null && _maxdate <= _dateTimestamp) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
|
||||
isDateValid: function() {
|
||||
return (
|
||||
this.day &&
|
||||
this.month &&
|
||||
this.year &&
|
||||
this.isDayValid &&
|
||||
this.isMonthValid &&
|
||||
this.isYearValid &&
|
||||
this.isWithinDateRange
|
||||
)
|
||||
},
|
||||
|
||||
daysMaxCalculation: function() {
|
||||
switch (parseInt(this.month)) {
|
||||
case 2: // February
|
||||
if (this.year) {
|
||||
return getDaysInMonth(new Date(this.year, this.month - 1))
|
||||
} else {
|
||||
return 29
|
||||
}
|
||||
break
|
||||
|
||||
case 4: // April
|
||||
case 6: // June
|
||||
case 9: // September
|
||||
case 11: // November
|
||||
return 30
|
||||
break
|
||||
|
||||
default:
|
||||
// All other months, or null, go with 31
|
||||
return 31
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render: function(createElement) {
|
||||
return createElement('p', 'Please implement inline-template')
|
||||
},
|
||||
})
|
Reference in New Issue
Block a user