Unit tests
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
This commit is contained in:
parent
1576d29eff
commit
a6c64c7989
|
@ -1,7 +0,0 @@
|
|||
export function translate(app, str) {
|
||||
return 'TRANSLATED:' + str
|
||||
}
|
||||
|
||||
export function translatePlural(app, singularStr, pluralStr) {
|
||||
return 'TRANSLATED:' + pluralStr
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @returns {String}
|
||||
*/
|
||||
export function getLocale() {
|
||||
return 'en'
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String[]}
|
||||
*/
|
||||
export function getDayNames() {
|
||||
return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String[]}
|
||||
*/
|
||||
export function getDayNamesShort() {
|
||||
return ['Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.']
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String[]}
|
||||
*/
|
||||
export function getDayNamesMin() {
|
||||
return ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String[]}
|
||||
*/
|
||||
export function getMonthNames() {
|
||||
return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String[]}
|
||||
*/
|
||||
export function getMonthNamesShort() {
|
||||
return ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.']
|
||||
}
|
32
package.json
32
package.json
|
@ -56,7 +56,6 @@
|
|||
"jstz": "^2.1.1",
|
||||
"md5": "^2.2.1",
|
||||
"p-limit": "^2.2.1",
|
||||
"p-queue": "^6.2.1",
|
||||
"uuid": "^3.3.3",
|
||||
"v-autosize": "^1.0.3",
|
||||
"v-tooltip": "^2.0.2",
|
||||
|
@ -78,6 +77,7 @@
|
|||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "^7.7.1",
|
||||
"@vue/test-utils": "^1.0.0-beta.29",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
|
@ -99,6 +99,7 @@
|
|||
"jest-serializer-vue": "^2.0.2",
|
||||
"node-sass": "^4.13.0",
|
||||
"prettier-eslint": "^9.0.0",
|
||||
"regenerator-runtime": "^0.13.3",
|
||||
"sass-loader": "^7.3.1",
|
||||
"stylelint": "^11.1.1",
|
||||
"stylelint-bare-webpack-plugin": "^1.1.3",
|
||||
|
@ -124,17 +125,30 @@
|
|||
"^@/(.*)$": "<rootDir>/src/$1"
|
||||
},
|
||||
"transform": {
|
||||
"^.+\\.js$": "babel-jest",
|
||||
"^.+\\.vue$": "vue-jest"
|
||||
".*\\.js$": "<rootDir>/node_modules/babel-jest",
|
||||
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
|
||||
},
|
||||
"snapshotSerializers": [
|
||||
"<rootDir>/node_modules/jest-serializer-vue"
|
||||
],
|
||||
"globals": {
|
||||
"t": true,
|
||||
"n": true,
|
||||
"OC": true,
|
||||
"OCA": true
|
||||
}
|
||||
"coverageDirectory": "./coverage/",
|
||||
"collectCoverage": true,
|
||||
"collectCoverageFrom": [
|
||||
"<rootDir>/src/**/*.{js,vue}",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"coverageReporters": [
|
||||
"json",
|
||||
"text",
|
||||
"html",
|
||||
"lcov",
|
||||
"clover"
|
||||
],
|
||||
"transformIgnorePatterns": [
|
||||
"/node_modules/(?!calendar-js).+\\.js$"
|
||||
],
|
||||
"setupFilesAfterEnv": [
|
||||
"./tests/javascript/jest.setup.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
export default function getDefaultAlarms(allDay = false) {
|
||||
export function getDefaultAlarms(allDay = false) {
|
||||
if (allDay) {
|
||||
return [
|
||||
9 * 60 * 60, // On the day of the event at 9am
|
||||
|
@ -42,3 +42,5 @@ export default function getDefaultAlarms(allDay = false) {
|
|||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default getDefaultAlarms
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
||||
export default () => {
|
||||
export function getDefaultCategories() {
|
||||
// This list was taken from https://tools.ietf.org/html/rfc5545#section-5
|
||||
return [
|
||||
t('calendar', 'Anniversary'),
|
||||
|
@ -41,3 +41,5 @@ export default () => {
|
|||
t('calendar', 'Vacation'),
|
||||
]
|
||||
}
|
||||
|
||||
export default getDefaultCategories
|
||||
|
|
|
@ -24,22 +24,24 @@ import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
|||
import moment from '@nextcloud/moment'
|
||||
|
||||
/**
|
||||
* Formats an alarm
|
||||
*
|
||||
* @param {Object} alarm The alarm object to format
|
||||
* @param {Boolean} isAllDay Whether or not the event is all-day
|
||||
* @param {String} currentUserTimezone The current timezone of the user
|
||||
* @param {String} locale The locale to format it in
|
||||
* @returns {String}
|
||||
*/
|
||||
export default (alarm, isAllDay, currentUserTimezone) => {
|
||||
export default (alarm, isAllDay, currentUserTimezone, locale) => {
|
||||
if (alarm.relativeTrigger !== null) {
|
||||
// relative trigger
|
||||
const time = moment.duration(Math.abs(alarm.relativeTrigger), 'seconds').humanize()
|
||||
const time = moment.duration(Math.abs(alarm.relativeTrigger), 'seconds').locale(locale).humanize()
|
||||
|
||||
if (isAllDay && alarm.relativeIsRelatedToStart && alarm.relativeTrigger < 86400) {
|
||||
const date = new Date()
|
||||
date.setHours(alarm.relativeHoursAllDay)
|
||||
date.setMinutes(alarm.relativeMinutesAllDay)
|
||||
const formattedHourMinute = moment(date).format('LT')
|
||||
const formattedHourMinute = moment(date).locale(locale).format('LT')
|
||||
|
||||
if (alarm.relativeTrigger === 0) {
|
||||
return t('calendar', 'Midnight on the day the event starts')
|
||||
|
@ -93,11 +95,11 @@ export default (alarm, isAllDay, currentUserTimezone) => {
|
|||
// absolute trigger
|
||||
if (currentUserTimezone === alarm.absoluteTimezoneId) {
|
||||
return t('calendar', 'on {time}', {
|
||||
time: moment(alarm.absoluteDate).format('LLLL'),
|
||||
time: moment(alarm.absoluteDate).locale(locale).format('LLLL'),
|
||||
})
|
||||
} else {
|
||||
return t('calendar', 'on {time} {timezoneId}', {
|
||||
time: moment(alarm.absoluteDate).format('LLLL'),
|
||||
time: moment(alarm.absoluteDate).locale(locale).format('LLLL'),
|
||||
timezoneId: alarm.absoluteTimezoneId,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -26,15 +26,13 @@ import moment from '@nextcloud/moment'
|
|||
*
|
||||
* @param {Date} value The date object to format
|
||||
* @param {Boolean} isAllDay Whether or not to display only the date part
|
||||
* @param {String} locale The locale to format it in
|
||||
* @returns {string}
|
||||
*/
|
||||
export default (value, isAllDay) => {
|
||||
if (!value) {
|
||||
return ''
|
||||
}
|
||||
export default (value, isAllDay, locale) => {
|
||||
if (isAllDay) {
|
||||
return moment(value).format('ll')
|
||||
return moment(value).locale(locale).format('ll')
|
||||
} else {
|
||||
return moment(value).format('lll')
|
||||
return moment(value).locale(locale).format('lll')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,19 +22,27 @@
|
|||
import moment from '@nextcloud/moment'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
||||
export default (value, view) => {
|
||||
/**
|
||||
* Formats a date-range depending on the user's current view
|
||||
*
|
||||
* @param {String|Date} value The date to format
|
||||
* @param {String} view The current view of the user
|
||||
* @param {String} locale Which locale to format it in
|
||||
* @returns {string}
|
||||
*/
|
||||
export default (value, view, locale) => {
|
||||
switch (view) {
|
||||
case 'timeGridDay':
|
||||
return moment(value).format('ll')
|
||||
return moment(value).locale(locale).format('ll')
|
||||
|
||||
case 'timeGridWeek':
|
||||
return t('calendar', 'Week {number} of {year}', {
|
||||
number: moment(value).week(),
|
||||
year: moment(value).year(),
|
||||
number: moment(value).locale(locale).week(),
|
||||
year: moment(value).locale(locale).weekYear(),
|
||||
})
|
||||
|
||||
case 'dayGridMonth':
|
||||
default:
|
||||
return moment(value).format('MMMM YYYY')
|
||||
return moment(value).locale(locale).format('MMMM YYYY')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { translate as t, translatePlural as n, getDayNames, getMonthNames } from '@nextcloud/l10n'
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
/**
|
||||
* Formats a recurrence-rule
|
||||
*
|
||||
* @param {Object} recurrenceRule The recurrence-rule to format
|
||||
* @param {String} locale The locale to format it into
|
||||
* @returns {String}
|
||||
*/
|
||||
export default (recurrenceRule, locale) => {
|
||||
if (recurrenceRule.frequency === 'NONE') {
|
||||
return t('calendar', 'Does not repeat')
|
||||
}
|
||||
|
||||
let freqPart = ''
|
||||
if (recurrenceRule.interval === 1) {
|
||||
switch (recurrenceRule.frequency) {
|
||||
case 'DAILY':
|
||||
freqPart = t('calendar', 'Daily')
|
||||
break
|
||||
|
||||
case 'WEEKLY':
|
||||
freqPart = t('calendar', 'Weekly')
|
||||
break
|
||||
|
||||
case 'MONTHLY':
|
||||
freqPart = t('calendar', 'Monthly')
|
||||
break
|
||||
|
||||
case 'YEARLY':
|
||||
freqPart = t('calendar', 'Yearly')
|
||||
break
|
||||
}
|
||||
} else {
|
||||
switch (recurrenceRule.frequency) {
|
||||
case 'DAILY':
|
||||
freqPart = n('calendar', 'Every %n day', 'Every %n days', recurrenceRule.interval)
|
||||
break
|
||||
|
||||
case 'WEEKLY':
|
||||
freqPart = n('calendar', 'Every %n week', 'Every %n weeks', recurrenceRule.interval)
|
||||
break
|
||||
|
||||
case 'MONTHLY':
|
||||
freqPart = n('calendar', 'Every %n month', 'Every %n months', recurrenceRule.interval)
|
||||
break
|
||||
|
||||
case 'YEARLY':
|
||||
freqPart = n('calendar', 'Every %n year', 'Every %n years', recurrenceRule.interval)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let limitPart = ''
|
||||
if (recurrenceRule.frequency === 'WEEKLY' && recurrenceRule.byDay.length !== 0) {
|
||||
const formattedDays = getTranslatedByDaySet(recurrenceRule.byDay)
|
||||
|
||||
limitPart = n('calendar', 'on {weekday}', 'on {weekdays}', recurrenceRule.byDay.length, {
|
||||
weekday: formattedDays,
|
||||
weekdays: formattedDays,
|
||||
})
|
||||
} else if (recurrenceRule.frequency === 'MONTHLY') {
|
||||
if (recurrenceRule.byMonthDay.length !== 0) {
|
||||
const dayOfMonthList = recurrenceRule.byMonthDay.join(', ')
|
||||
|
||||
limitPart = n('calendar', 'on day {dayOfMonthList}', 'on days {dayOfMonthList}', recurrenceRule.byMonthDay.length, {
|
||||
dayOfMonthList,
|
||||
})
|
||||
} else {
|
||||
const ordinalNumber = getTranslatedOrdinalNumber(recurrenceRule.bySetPosition)
|
||||
const byDaySet = getTranslatedByDaySet(recurrenceRule.byDay)
|
||||
|
||||
limitPart = t('calendar', 'on the {ordinalNumber} {byDaySet}', {
|
||||
ordinalNumber,
|
||||
byDaySet,
|
||||
})
|
||||
}
|
||||
} else if (recurrenceRule.frequency === 'YEARLY') {
|
||||
const monthNames = getTranslatedMonths(recurrenceRule.byMonth)
|
||||
|
||||
if (recurrenceRule.byDay.length === 0) {
|
||||
limitPart = t('calendar', 'in {monthNames}', {
|
||||
monthNames,
|
||||
})
|
||||
} else {
|
||||
const ordinalNumber = getTranslatedOrdinalNumber(recurrenceRule.bySetPosition)
|
||||
const byDaySet = getTranslatedByDaySet(recurrenceRule.byDay)
|
||||
|
||||
limitPart = t('calendar', 'in {monthNames} on the {ordinalNumber} {byDaySet}', {
|
||||
monthNames,
|
||||
ordinalNumber,
|
||||
byDaySet,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let endPart = ''
|
||||
if (recurrenceRule.until !== null) {
|
||||
const untilDate = moment(recurrenceRule.until).locale(locale).format('L')
|
||||
|
||||
endPart = t('calendar', 'until {untilDate}', {
|
||||
untilDate,
|
||||
})
|
||||
} else if (recurrenceRule.count !== null) {
|
||||
endPart = n('calendar', '%n time', '%n times', recurrenceRule.count)
|
||||
}
|
||||
|
||||
return [
|
||||
freqPart,
|
||||
limitPart,
|
||||
endPart,
|
||||
].join(' ').replace(/\s{2,}/g, ' ').trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byDay list as formatted list of translated weekdays
|
||||
*
|
||||
* @param {string[]} byDayList The by-day-list to get formatted
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTranslatedByDaySet(byDayList) {
|
||||
const byDayNames = []
|
||||
const allByDayNames = getDayNames()
|
||||
|
||||
// TODO: This should be sorted by first day of week
|
||||
// TODO: This should summarise:
|
||||
// - SA, SU to weekend
|
||||
// - MO, TU, WE, TH, FR to weekday
|
||||
// - MO, TU, WE, TH, FR, SA, SU to day
|
||||
|
||||
if (byDayList.includes('MO')) {
|
||||
byDayNames.push(allByDayNames[1])
|
||||
}
|
||||
if (byDayList.includes('TU')) {
|
||||
byDayNames.push(allByDayNames[2])
|
||||
}
|
||||
if (byDayList.includes('WE')) {
|
||||
byDayNames.push(allByDayNames[3])
|
||||
}
|
||||
if (byDayList.includes('TH')) {
|
||||
byDayNames.push(allByDayNames[4])
|
||||
}
|
||||
if (byDayList.includes('FR')) {
|
||||
byDayNames.push(allByDayNames[5])
|
||||
}
|
||||
if (byDayList.includes('SA')) {
|
||||
byDayNames.push(allByDayNames[6])
|
||||
}
|
||||
if (byDayList.includes('SU')) {
|
||||
byDayNames.push(allByDayNames[0])
|
||||
}
|
||||
|
||||
return byDayNames.join(', ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byMonth list as formatted list of translated month-names
|
||||
*
|
||||
*
|
||||
* @param {string[]} byMonthList The by-month list to get formatted
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTranslatedMonths(byMonthList) {
|
||||
const sortedByMonth = byMonthList.slice().map((n) => parseInt(n, 10))
|
||||
sortedByMonth.sort((a, b) => a - b)
|
||||
|
||||
const monthNames = []
|
||||
const allMonthNames = getMonthNames()
|
||||
|
||||
for (const month of sortedByMonth) {
|
||||
monthNames.push(allMonthNames[month - 1])
|
||||
}
|
||||
|
||||
return monthNames.join(', ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translated ordinal number for by-set-position
|
||||
*
|
||||
* @param {Number} bySetPositionNum The by-set-position number to get the translation of
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTranslatedOrdinalNumber(bySetPositionNum) {
|
||||
switch (bySetPositionNum) {
|
||||
case 1:
|
||||
return t('calendar', 'first')
|
||||
|
||||
case 2:
|
||||
return t('calendar', 'second')
|
||||
|
||||
case 3:
|
||||
return t('calendar', 'third')
|
||||
|
||||
case 4:
|
||||
return t('calendar', 'fourth')
|
||||
|
||||
case 5:
|
||||
return t('calendar', 'fifth')
|
||||
|
||||
case -2:
|
||||
return t('calendar', 'second to last')
|
||||
|
||||
case -1:
|
||||
return t('calendar', 'last')
|
||||
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
|
@ -42,15 +42,15 @@ export default function(store, router, route, window) {
|
|||
}
|
||||
|
||||
const name = getPrefixedRoute(route.name, desiredRoute)
|
||||
const params = Object.assign({}, store.state.route.params, {
|
||||
const params = Object.assign({}, route.params, {
|
||||
object: event.extendedProps.objectId,
|
||||
recurrenceId: String(event.extendedProps.recurrenceId),
|
||||
})
|
||||
|
||||
// Don't push new route when day didn't change
|
||||
if (name === store.state.route.name
|
||||
&& params.object === store.state.route.params.object
|
||||
&& params.recurrenceId === store.state.route.params.recurrenceId) {
|
||||
if ((getPrefixedRoute(route.name, 'EditPopoverView') === route.name || getPrefixedRoute(route.name, 'EditSidebarView') === route.name)
|
||||
&& params.object === route.params.object
|
||||
&& params.recurrenceId === route.params.recurrenceId) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import getTimezoneManager from '../services/timezoneDataProviderService'
|
|||
* @returns {Function}
|
||||
*/
|
||||
export default function(store, fcAPI) {
|
||||
return async function({ event, oldEvent, delta, revert }) {
|
||||
return async function({ event, delta, revert }) {
|
||||
const deltaDuration = getDurationValueFromFullCalendarDuration(delta)
|
||||
const defaultAllDayDuration = getDurationValueFromFullCalendarDuration(fcAPI.getOption('defaultAllDayEventDuration'))
|
||||
const defaultTimedDuration = getDurationValueFromFullCalendarDuration(fcAPI.getOption('defaultTimedEventDuration'))
|
||||
|
@ -46,30 +46,44 @@ export default function(store, fcAPI) {
|
|||
const recurrenceId = event.extendedProps.recurrenceId
|
||||
const recurrenceIdDate = new Date(recurrenceId * 1000)
|
||||
|
||||
let calendarObject
|
||||
try {
|
||||
await store.dispatch('getEventByObjectId', { objectId })
|
||||
calendarObject = await store.dispatch('getEventByObjectId', { objectId })
|
||||
} catch (error) {
|
||||
console.debug(error)
|
||||
revert()
|
||||
return
|
||||
}
|
||||
|
||||
const calendarObject = store.getters.getCalendarObjectById(objectId)
|
||||
const eventComponent = calendarObject.getObjectAtRecurrenceId(recurrenceIdDate)
|
||||
|
||||
if (!eventComponent) {
|
||||
console.debug('Recurrence-id not found')
|
||||
revert()
|
||||
return
|
||||
}
|
||||
|
||||
eventComponent.shiftByDuration(deltaDuration, event.allDay, timezone, defaultAllDayDuration, defaultTimedDuration)
|
||||
try {
|
||||
// shiftByDuration may throw exceptions in certain cases
|
||||
eventComponent.shiftByDuration(deltaDuration, event.allDay, timezone, defaultAllDayDuration, defaultTimedDuration)
|
||||
} catch (error) {
|
||||
calendarObject.resetToDav()
|
||||
console.debug(error)
|
||||
revert()
|
||||
return
|
||||
}
|
||||
|
||||
if (eventComponent.canCreateRecurrenceExceptions()) {
|
||||
eventComponent.createRecurrenceException()
|
||||
}
|
||||
|
||||
await store.dispatch('updateCalendarObject', {
|
||||
calendarObject,
|
||||
})
|
||||
try {
|
||||
await store.dispatch('updateCalendarObject', {
|
||||
calendarObject,
|
||||
})
|
||||
} catch (error) {
|
||||
calendarObject.resetToDav()
|
||||
console.debug(error)
|
||||
revert()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Adds data to the html element representing the event in the fullcalendar grid.
|
||||
* This is used to later on position the popover
|
||||
*
|
||||
* @param {Object} data The destructuring object
|
||||
* @param {EventApi} event The fullcalendar event object
|
||||
|
|
|
@ -28,7 +28,7 @@ import { getDurationValueFromFullCalendarDuration } from './duration'
|
|||
* @returns {Function}
|
||||
*/
|
||||
export default function(store) {
|
||||
return async function({ event, prevEvent, startDelta, endDelta, revert }) {
|
||||
return async function({ event, startDelta, endDelta, revert }) {
|
||||
const startDeltaDuration = getDurationValueFromFullCalendarDuration(startDelta)
|
||||
const endDeltaDuration = getDurationValueFromFullCalendarDuration(endDelta)
|
||||
|
||||
|
@ -41,17 +41,16 @@ export default function(store) {
|
|||
const recurrenceId = event.extendedProps.recurrenceId
|
||||
const recurrenceIdDate = new Date(recurrenceId * 1000)
|
||||
|
||||
let calendarObject
|
||||
try {
|
||||
await store.dispatch('getEventByObjectId', { objectId })
|
||||
calendarObject = await store.dispatch('getEventByObjectId', { objectId })
|
||||
} catch (error) {
|
||||
console.debug(error)
|
||||
revert()
|
||||
return
|
||||
}
|
||||
|
||||
const calendarObject = store.getters.getCalendarObjectById(objectId)
|
||||
const eventComponent = calendarObject.getObjectAtRecurrenceId(recurrenceIdDate)
|
||||
|
||||
if (!eventComponent) {
|
||||
console.debug('Recurrence-id not found')
|
||||
revert()
|
||||
|
@ -69,8 +68,14 @@ export default function(store) {
|
|||
eventComponent.createRecurrenceException()
|
||||
}
|
||||
|
||||
await store.dispatch('updateCalendarObject', {
|
||||
calendarObject,
|
||||
})
|
||||
try {
|
||||
await store.dispatch('updateCalendarObject', {
|
||||
calendarObject,
|
||||
})
|
||||
} catch (error) {
|
||||
calendarObject.resetToDav()
|
||||
console.debug(error)
|
||||
revert()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,14 +45,19 @@ export default function(store) {
|
|||
const timezoneObject = getTimezoneManager().getTimezoneForId(timeZone)
|
||||
const timeRange = store.getters.getTimeRangeForCalendarCoveringRange(calendar.id, getUnixTimestampFromDate(start), getUnixTimestampFromDate(end))
|
||||
if (!timeRange) {
|
||||
await store.dispatch('getEventsFromCalendarInTimeRange', {
|
||||
calendar: calendar,
|
||||
from: start,
|
||||
to: end,
|
||||
})
|
||||
let timeRangeId
|
||||
try {
|
||||
timeRangeId = await store.dispatch('getEventsFromCalendarInTimeRange', {
|
||||
calendar: calendar,
|
||||
from: start,
|
||||
to: end,
|
||||
})
|
||||
} catch (error) {
|
||||
failureCallback(error)
|
||||
return
|
||||
}
|
||||
|
||||
const timeRange = store.getters.getTimeRangeForCalendarCoveringRange(calendar.id, getUnixTimestampFromDate(start), getUnixTimestampFromDate(end))
|
||||
const calendarObjects = store.getters.getCalendarObjectsByTimeRangeId(timeRange.id)
|
||||
const calendarObjects = store.getters.getCalendarObjectsByTimeRangeId(timeRangeId)
|
||||
successCallback(eventSourceFunction(calendarObjects, start, end, timezoneObject))
|
||||
} else {
|
||||
const calendarObjects = store.getters.getCalendarObjectsByTimeRangeId(timeRange.id)
|
||||
|
|
|
@ -19,10 +19,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import {
|
||||
generateTextColorForRGBString,
|
||||
} from '../utils/color.js'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import logger from '../utils/logger.js'
|
||||
|
||||
/**
|
||||
* convert an array of calendar-objects to events
|
||||
|
@ -36,7 +34,14 @@ import { translate as t } from '@nextcloud/l10n'
|
|||
export function eventSourceFunction(calendarObjects, start, end, timezone) {
|
||||
const fcEvents = []
|
||||
for (const calendarObject of calendarObjects) {
|
||||
const allObjectsInTimeRange = calendarObject.getAllObjectsInTimeRange(start, end)
|
||||
let allObjectsInTimeRange
|
||||
try {
|
||||
allObjectsInTimeRange = calendarObject.getAllObjectsInTimeRange(start, end)
|
||||
} catch (error) {
|
||||
logger.error(error.message)
|
||||
continue
|
||||
}
|
||||
|
||||
for (const object of allObjectsInTimeRange) {
|
||||
const classNames = []
|
||||
|
||||
|
@ -60,10 +65,10 @@ export function eventSourceFunction(calendarObjects, start, end, timezone) {
|
|||
},
|
||||
}
|
||||
|
||||
if (calendarObject.color) {
|
||||
fcEvent.backgroundColor = calendarObject.color
|
||||
fcEvent.textColor = generateTextColorForRGBString(calendarObject.color)
|
||||
}
|
||||
// if (object.color) {
|
||||
// fcEvent.backgroundColor = object.color
|
||||
// fcEvent.textColor = generateTextColorForRGBString(object.color)
|
||||
// }
|
||||
|
||||
fcEvents.push(fcEvent)
|
||||
}
|
||||
|
|
|
@ -27,10 +27,11 @@
|
|||
*
|
||||
* @param {Object} store The Vuex store
|
||||
* @param {Object} router The Vue router
|
||||
* @param {Object} route The Vue route
|
||||
* @param {Window} window The window object
|
||||
* @returns {Function}
|
||||
*/
|
||||
export default function(store, router, window) {
|
||||
export default function(store, router, route, window) {
|
||||
return function({ start, end, allDay }) {
|
||||
let name = store.state.settings.skipPopover
|
||||
? 'NewSidebarView'
|
||||
|
@ -40,17 +41,20 @@ export default function(store, router, window) {
|
|||
name = 'NewSidebarView'
|
||||
}
|
||||
|
||||
const params = Object.assign({}, store.state.route.params, {
|
||||
// If we are already in a new event view, don't change it
|
||||
if (['NewSidebarView', 'NewPopoverView'].includes(route.name)) {
|
||||
name = route.name
|
||||
}
|
||||
|
||||
const params = Object.assign({}, route.params, {
|
||||
allDay: allDay ? '1' : '0',
|
||||
dtstart: String(Math.floor(start.getTime() / 1000)),
|
||||
dtend: String(Math.floor(end.getTime() / 1000)),
|
||||
})
|
||||
|
||||
// Don't push new route when day didn't change
|
||||
if (name === store.state.route.name
|
||||
&& params.allDay === store.state.route.params.allDay
|
||||
&& params.dtstart === store.state.route.params.dtstart
|
||||
&& params.dtend === store.state.route.params.dtend) {
|
||||
if (name === route.name && params.allDay === route.params.allDay
|
||||
&& params.dtstart === route.params.dtstart && params.dtend === route.params.dtend) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ class VTimezoneNamedTimezone extends NamedTimeZoneImpl {
|
|||
/**
|
||||
* returns parameters for Date object in this timezone based on given timestamp
|
||||
*
|
||||
* @param {Number[]} ms Timestamp in milliseconds
|
||||
* @param {Number} ms Timestamp in milliseconds
|
||||
* @returns {Number[]}
|
||||
*/
|
||||
timestampToArray(ms) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import rfcProps from '../models/rfcProps'
|
||||
import { getRFCProperties } from '../models/rfcProps'
|
||||
import logger from '../utils/logger.js'
|
||||
import { getIllustrationForTitle } from '../utils/illustration.js'
|
||||
import { getPrefixedRoute } from '../utils/router.js'
|
||||
|
@ -301,7 +301,7 @@ export default {
|
|||
* @returns {{geo, color, timeTransparency, description, resources, location, categories, accessClass, priority, status}}
|
||||
*/
|
||||
rfcProps() {
|
||||
return rfcProps
|
||||
return getRFCProperties()
|
||||
},
|
||||
/**
|
||||
* Returns whether or not this event can be downloaded from the server
|
||||
|
|
|
@ -172,14 +172,12 @@ export function mapDavShareeToSharee(sharee) {
|
|||
let displayName
|
||||
if (sharee['common-name']) {
|
||||
displayName = sharee['common-name']
|
||||
} else if (sharee.href.startsWith('principal:principals/groups/')) {
|
||||
displayName = sharee.href.substr(28)
|
||||
} else if (sharee.href.startsWith('principal:principals/users/')) {
|
||||
displayName = sharee.href.substr(27)
|
||||
} else {
|
||||
if (sharee.href.startsWith('principal:principals/groups/')) {
|
||||
displayName = sharee.href.substr(28)
|
||||
} else if (sharee.href.startsWith('principal:principals/users/')) {
|
||||
displayName = sharee.href.substr(27)
|
||||
} else {
|
||||
displayName = sharee.href
|
||||
}
|
||||
displayName = sharee.href
|
||||
}
|
||||
|
||||
const writeable = sharee.access[0].endsWith('read-write')
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import PQueue from 'p-queue'
|
||||
import { getParserManager } from 'calendar-js'
|
||||
import DateTimeValue from 'calendar-js/src/values/dateTimeValue'
|
||||
import CalendarComponent from 'calendar-js/src/components/calendarComponent'
|
||||
|
||||
/**
|
||||
* This model represents exactly
|
||||
*
|
||||
* TODO: this should not be a class, but a simple object
|
||||
* TODO: all methods should be converted to vuex commits
|
||||
*/
|
||||
export default class CalendarObject {
|
||||
|
||||
|
@ -59,14 +61,6 @@ export default class CalendarObject {
|
|||
*/
|
||||
this.dav = dav
|
||||
|
||||
/**
|
||||
* A queue for sending updates to the server
|
||||
* aiming to prevent race-conditions
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
this.updateQueue = new PQueue({ concurrency: 1 })
|
||||
|
||||
/**
|
||||
* parsed calendar-js object
|
||||
* @type {CalendarComponent}
|
||||
|
|
|
@ -72,7 +72,7 @@ export const getDefaultCalendarObjectInstanceObject = (props = {}) => Object.ass
|
|||
organizer: {
|
||||
// name of the organizer
|
||||
name: null,
|
||||
// email of the organzier:
|
||||
// email of the organizer
|
||||
uri: null,
|
||||
},
|
||||
// Alarm of the event
|
||||
|
@ -81,7 +81,7 @@ export const getDefaultCalendarObjectInstanceObject = (props = {}) => Object.ass
|
|||
customColor: null,
|
||||
// Categories
|
||||
categories: [],
|
||||
// Wether or not the user is allowed to toggle the all-day checkbox
|
||||
// Whether or not the user is allowed to toggle the all-day checkbox
|
||||
canModifyAllDay: true,
|
||||
// The real event-component coming from calendar-js
|
||||
eventComponent: null,
|
||||
|
|
|
@ -20,89 +20,98 @@
|
|||
*
|
||||
*/
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import getDefaultCategories from '../defaults/defaultCategories.js'
|
||||
import { getDefaultCategories } from '../defaults/defaultCategories.js'
|
||||
|
||||
export default {
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.3
|
||||
*/
|
||||
accessClass: {
|
||||
readableName: t('calendar', 'When shared show'),
|
||||
icon: 'icon-eye',
|
||||
options: [
|
||||
{ value: 'PUBLIC', label: t('calendar', 'When shared show full event') },
|
||||
{ value: 'CONFIDENTIAL', label: t('calendar', 'When shared show only busy') },
|
||||
{ value: 'PRIVATE', label: t('calendar', 'When shared hide this event') },
|
||||
],
|
||||
multiple: false,
|
||||
info: t('calendar', 'The visibility of this event in shared calendars.'),
|
||||
defaultValue: 'PUBLIC',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.7
|
||||
*/
|
||||
location: {
|
||||
readableName: t('calendar', 'Location'),
|
||||
placeholder: t('calendar', 'Add a location'),
|
||||
icon: 'icon-address',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.5
|
||||
*/
|
||||
description: {
|
||||
readableName: t('calendar', 'Description'),
|
||||
placeholder: t('calendar', 'Add a description'),
|
||||
icon: 'icon-menu',
|
||||
defaultNumberOfRows: 2,
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.11
|
||||
*/
|
||||
status: {
|
||||
readableName: t('calendar', 'Status'),
|
||||
icon: 'icon-checkmark',
|
||||
options: [
|
||||
{ value: 'CONFIRMED', label: t('calendar', 'Confirmed') },
|
||||
{ value: 'TENTATIVE', label: t('calendar', 'Tentative') },
|
||||
{ value: 'CANCELLED', label: t('calendar', 'Cancelled') },
|
||||
],
|
||||
multiple: false,
|
||||
info: t('calendar', 'Confirmation about the overall status of the event.'),
|
||||
defaultValue: 'CONFIRMED',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.2.7
|
||||
*/
|
||||
timeTransparency: {
|
||||
readableName: t('calendar', 'Show as'),
|
||||
icon: 'icon-briefcase',
|
||||
multiple: false,
|
||||
info: t('calendar', 'Take this event into account when calculating free-busy information.'),
|
||||
options: [
|
||||
{ value: 'TRANSPARENT', label: t('calendar', 'Free') },
|
||||
{ value: 'OPAQUE', label: t('calendar', 'Busy') },
|
||||
],
|
||||
defaultValue: 'TRANSPARENT',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.2
|
||||
*/
|
||||
categories: {
|
||||
readableName: t('calendar', 'Categories'),
|
||||
icon: 'icon-tag',
|
||||
multiple: true,
|
||||
info: t('calendar', 'Categories help you to structure and organize your events.'),
|
||||
placeholder: t('calendar', 'Search or add categories'),
|
||||
tagPlaceholder: t('calendar', 'Add this as a new category'),
|
||||
options: getDefaultCategories(),
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc7986#section-5.9
|
||||
*/
|
||||
color: {
|
||||
readableName: t('calendar', 'Custom color'),
|
||||
icon: 'icon-color-picker',
|
||||
multiple: false,
|
||||
info: t('calendar', 'Special color of this event. Overrides the calendar-color.'),
|
||||
},
|
||||
/**
|
||||
* Gets all supported RFC properties
|
||||
*
|
||||
* @returns {{color: {readableName: *, icon: string, multiple: boolean, info: *}, timeTransparency: {readableName: *, defaultValue: string, icon: string, multiple: boolean, options: *[], info: *}, description: {readableName: *, icon: string, placeholder: *, defaultNumberOfRows: number}, location: {readableName: *, icon: string, placeholder: *}, categories: {readableName: *, icon: string, multiple: boolean, options: *, tagPlaceholder: *, placeholder: *, info: *}, accessClass: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, status: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}}}
|
||||
*/
|
||||
export function getRFCProperties() {
|
||||
return {
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.3
|
||||
*/
|
||||
accessClass: {
|
||||
readableName: t('calendar', 'When shared show'),
|
||||
icon: 'icon-eye',
|
||||
options: [
|
||||
{ value: 'PUBLIC', label: t('calendar', 'When shared show full event') },
|
||||
{ value: 'CONFIDENTIAL', label: t('calendar', 'When shared show only busy') },
|
||||
{ value: 'PRIVATE', label: t('calendar', 'When shared hide this event') },
|
||||
],
|
||||
multiple: false,
|
||||
info: t('calendar', 'The visibility of this event in shared calendars.'),
|
||||
defaultValue: 'PUBLIC',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.7
|
||||
*/
|
||||
location: {
|
||||
readableName: t('calendar', 'Location'),
|
||||
placeholder: t('calendar', 'Add a location'),
|
||||
icon: 'icon-address',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.5
|
||||
*/
|
||||
description: {
|
||||
readableName: t('calendar', 'Description'),
|
||||
placeholder: t('calendar', 'Add a description'),
|
||||
icon: 'icon-menu',
|
||||
defaultNumberOfRows: 2,
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.11
|
||||
*/
|
||||
status: {
|
||||
readableName: t('calendar', 'Status'),
|
||||
icon: 'icon-checkmark',
|
||||
options: [
|
||||
{ value: 'CONFIRMED', label: t('calendar', 'Confirmed') },
|
||||
{ value: 'TENTATIVE', label: t('calendar', 'Tentative') },
|
||||
{ value: 'CANCELLED', label: t('calendar', 'Cancelled') },
|
||||
],
|
||||
multiple: false,
|
||||
info: t('calendar', 'Confirmation about the overall status of the event.'),
|
||||
defaultValue: 'CONFIRMED',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.2.7
|
||||
*/
|
||||
timeTransparency: {
|
||||
readableName: t('calendar', 'Show as'),
|
||||
icon: 'icon-briefcase',
|
||||
multiple: false,
|
||||
info: t('calendar', 'Take this event into account when calculating free-busy information.'),
|
||||
options: [
|
||||
{ value: 'TRANSPARENT', label: t('calendar', 'Free') },
|
||||
{ value: 'OPAQUE', label: t('calendar', 'Busy') },
|
||||
],
|
||||
defaultValue: 'TRANSPARENT',
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc5545#section-3.8.1.2
|
||||
*/
|
||||
categories: {
|
||||
readableName: t('calendar', 'Categories'),
|
||||
icon: 'icon-tag',
|
||||
multiple: true,
|
||||
info: t('calendar', 'Categories help you to structure and organize your events.'),
|
||||
placeholder: t('calendar', 'Search or add categories'),
|
||||
tagPlaceholder: t('calendar', 'Add this as a new category'),
|
||||
options: getDefaultCategories(),
|
||||
},
|
||||
/**
|
||||
* https://tools.ietf.org/html/rfc7986#section-5.9
|
||||
*/
|
||||
color: {
|
||||
readableName: t('calendar', 'Custom color'),
|
||||
icon: 'icon-color-picker',
|
||||
multiple: false,
|
||||
info: t('calendar', 'Special color of this event. Overrides the calendar-color.'),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default getRFCProperties
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import 'core-js/stable';
|
||||
import 'regenerator-runtime/runtime';
|
|
@ -20,27 +20,54 @@
|
|||
*
|
||||
*/
|
||||
import defaultCategories from '../../../../src/defaults/defaultCategories.js'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
|
||||
jest.mock('@nextcloud/l10n')
|
||||
|
||||
describe('defaults/defaultCategories test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
translate.mockClear()
|
||||
})
|
||||
|
||||
it('should provide a default set of categories', () => {
|
||||
translate
|
||||
.mockImplementation((app, str) => str)
|
||||
|
||||
expect(defaultCategories()).toEqual([
|
||||
'TRANSLATED:Anniversary',
|
||||
'TRANSLATED:Appointment',
|
||||
'TRANSLATED:Business',
|
||||
'TRANSLATED:Education',
|
||||
'TRANSLATED:Holiday',
|
||||
'TRANSLATED:Meeting',
|
||||
'TRANSLATED:Miscellaneous',
|
||||
'TRANSLATED:Non-working hours',
|
||||
'TRANSLATED:Not in office',
|
||||
'TRANSLATED:Personal',
|
||||
'TRANSLATED:Phone call',
|
||||
'TRANSLATED:Sick day',
|
||||
'TRANSLATED:Special occasion',
|
||||
'TRANSLATED:Travel',
|
||||
'TRANSLATED:Vacation',
|
||||
'Anniversary',
|
||||
'Appointment',
|
||||
'Business',
|
||||
'Education',
|
||||
'Holiday',
|
||||
'Meeting',
|
||||
'Miscellaneous',
|
||||
'Non-working hours',
|
||||
'Not in office',
|
||||
'Personal',
|
||||
'Phone call',
|
||||
'Sick day',
|
||||
'Special occasion',
|
||||
'Travel',
|
||||
'Vacation',
|
||||
])
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(15)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Anniversary')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'Appointment')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'Business')
|
||||
expect(translate).toHaveBeenNthCalledWith(4, 'calendar', 'Education')
|
||||
expect(translate).toHaveBeenNthCalledWith(5, 'calendar', 'Holiday')
|
||||
expect(translate).toHaveBeenNthCalledWith(6, 'calendar', 'Meeting')
|
||||
expect(translate).toHaveBeenNthCalledWith(7, 'calendar', 'Miscellaneous')
|
||||
expect(translate).toHaveBeenNthCalledWith(8, 'calendar', 'Non-working hours')
|
||||
expect(translate).toHaveBeenNthCalledWith(9, 'calendar', 'Not in office')
|
||||
expect(translate).toHaveBeenNthCalledWith(10, 'calendar', 'Personal')
|
||||
expect(translate).toHaveBeenNthCalledWith(11, 'calendar', 'Phone call')
|
||||
expect(translate).toHaveBeenNthCalledWith(12, 'calendar', 'Sick day')
|
||||
expect(translate).toHaveBeenNthCalledWith(13, 'calendar', 'Special occasion')
|
||||
expect(translate).toHaveBeenNthCalledWith(14, 'calendar', 'Travel')
|
||||
expect(translate).toHaveBeenNthCalledWith(15, 'calendar', 'Vacation')
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('format/alarmFormat test suite', () => {
|
||||
|
||||
it('should format an alarm for an all-day event at midnight', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format an alarm for an all-day event days before', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format an alarm for an all-day event weeks weeks before', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format an alarm for an all-day event on the same day at a certain time', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format an alarm for an all-day event not supported in the default range', () => {
|
||||
// Bigger than one day or not related to start
|
||||
})
|
||||
|
||||
it('should format a relative trigger at the events start', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format a relative trigger at the events end', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format a relative trigger before the event starts', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format a relative trigger before the event ends', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format a relative trigger after the event starts', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format a relative trigger after the event ends', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format an absolute alarm in the user\'s timezone', () => {
|
||||
|
||||
})
|
||||
|
||||
it('should format an absolute alarm in a different timezone', () => {
|
||||
|
||||
})
|
||||
|
||||
})
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import dateFormat from "../../../../src/filters/dateFormat.js";
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
jest.mock('@nextcloud/moment')
|
||||
|
||||
describe('format/dateFormat test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
moment.mockClear()
|
||||
})
|
||||
|
||||
it('should format an all-day date', () => {
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const format = jest.fn()
|
||||
.mockReturnValue('formatted-allday-date')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ format })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(dateFormat(date, true, 'de')).toEqual('formatted-allday-date')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(1)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(locale).toHaveBeenCalledTimes(1)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(format).toHaveBeenCalledTimes(1)
|
||||
expect(format).toHaveBeenNthCalledWith(1, 'll')
|
||||
})
|
||||
|
||||
it('should format a timed date', () => {
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const format = jest.fn()
|
||||
.mockReturnValue('formatted-allday-date')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ format })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(dateFormat(date, false, 'de')).toEqual('formatted-allday-date')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(1)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(locale).toHaveBeenCalledTimes(1)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(format).toHaveBeenCalledTimes(1)
|
||||
expect(format).toHaveBeenNthCalledWith(1, 'lll')
|
||||
})
|
||||
|
||||
})
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import moment from '@nextcloud/moment'
|
||||
import dateRangeFormat from "../../../../src/filters/dateRangeFormat.js";
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
|
||||
jest.mock('@nextcloud/moment')
|
||||
jest.mock('@nextcloud/l10n')
|
||||
|
||||
describe('format/dateRangeFormat test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
moment.mockClear()
|
||||
translate.mockClear()
|
||||
})
|
||||
|
||||
it('should provide a format for day view', () => {
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const format = jest.fn()
|
||||
.mockReturnValue('formatted-allday-date')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ format })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(dateRangeFormat(date, 'timeGridDay', 'de')).toEqual('formatted-allday-date')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(1)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(locale).toHaveBeenCalledTimes(1)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(format).toHaveBeenCalledTimes(1)
|
||||
expect(format).toHaveBeenNthCalledWith(1, 'll')
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should provide a format for week view', () => {
|
||||
translate
|
||||
.mockImplementation((app, str) => str)
|
||||
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const week = jest.fn()
|
||||
.mockReturnValue('week-no')
|
||||
const weekYear = jest.fn()
|
||||
.mockReturnValue('week-year')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ week, weekYear })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(dateRangeFormat(date, 'timeGridWeek', 'de')).toEqual('Week {number} of {year}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(2)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(moment).toHaveBeenNthCalledWith(2, date)
|
||||
expect(locale).toHaveBeenCalledTimes(2)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(locale).toHaveBeenNthCalledWith(2, 'de')
|
||||
expect(week).toHaveBeenCalledTimes(1)
|
||||
expect(week).toHaveBeenNthCalledWith(1)
|
||||
expect(weekYear).toHaveBeenCalledTimes(1)
|
||||
expect(weekYear).toHaveBeenNthCalledWith(1)
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(1)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Week {number} of {year}', {
|
||||
number: 'week-no',
|
||||
year: 'week-year',
|
||||
})
|
||||
})
|
||||
|
||||
it('should provide a format for month view', () => {
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const format = jest.fn()
|
||||
.mockReturnValue('formatted-allday-month-year')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ format })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(dateRangeFormat(date, 'dayGridMonth', 'de')).toEqual('formatted-allday-month-year')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(1)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(locale).toHaveBeenCalledTimes(1)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(format).toHaveBeenCalledTimes(1)
|
||||
expect(format).toHaveBeenNthCalledWith(1, 'MMMM YYYY')
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should provide month as fallback for unknown view', () => {
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const format = jest.fn()
|
||||
.mockReturnValue('formatted-allday-month-year')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ format })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(dateRangeFormat(date, 'fooBarUnknownView', 'de')).toEqual('formatted-allday-month-year')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(1)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(locale).toHaveBeenCalledTimes(1)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(format).toHaveBeenCalledTimes(1)
|
||||
expect(format).toHaveBeenNthCalledWith(1, 'MMMM YYYY')
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
})
|
|
@ -0,0 +1,353 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import recurrenceRuleFormat from '../../../../src/filters/recurrenceRuleFormat.js'
|
||||
|
||||
import moment from '@nextcloud/moment'
|
||||
import { translate, translatePlural, getDayNames, getMonthNames } from '@nextcloud/l10n'
|
||||
|
||||
jest.mock('@nextcloud/moment')
|
||||
jest.mock('@nextcloud/l10n')
|
||||
|
||||
describe('format/recurrenceRuleFormat test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
moment.mockClear()
|
||||
translate.mockClear()
|
||||
translatePlural.mockClear()
|
||||
|
||||
translate
|
||||
.mockImplementation((app, str) => str)
|
||||
translatePlural
|
||||
.mockImplementation((app, sinStr, pluStr) => pluStr)
|
||||
getDayNames
|
||||
.mockReturnValue(['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'])
|
||||
getMonthNames
|
||||
.mockReturnValue(['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'])
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is non-recurring', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'NONE',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Does not repeat')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(1)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Does not repeat')
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every day', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'DAILY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Daily')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(1)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Daily')
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every week on Tuesday', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'WEEKLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: ['TU'],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Weekly on {weekdays}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(1)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Weekly')
|
||||
expect(translatePlural).toHaveBeenCalledTimes(1)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(1, 'calendar', 'on {weekday}', 'on {weekdays}', 1, {
|
||||
weekday: 'Tuesday',
|
||||
weekdays: 'Tuesday',
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every third week on Tuesday and Thursday', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'WEEKLY',
|
||||
interval: 3,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: ['TU', 'TH'],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Every %n weeks on {weekdays}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(0)
|
||||
expect(translatePlural).toHaveBeenCalledTimes(2)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(1, 'calendar', 'Every %n week', 'Every %n weeks', 3)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(2, 'calendar', 'on {weekday}', 'on {weekdays}', 2, {
|
||||
weekday: 'Tuesday, Thursday',
|
||||
weekdays: 'Tuesday, Thursday',
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every other month on 15th', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'MONTHLY',
|
||||
interval: 2,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: [],
|
||||
byMonthDay: ['15'],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Every %n months on days {dayOfMonthList}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(0)
|
||||
expect(translatePlural).toHaveBeenCalledTimes(2)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(1, 'calendar', 'Every %n month', 'Every %n months', 2)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(2, 'calendar', 'on day {dayOfMonthList}', 'on days {dayOfMonthList}', 1, {
|
||||
dayOfMonthList: '15',
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every month on 15th, 16th, 17th, 18th', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'MONTHLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: [],
|
||||
byMonthDay: ['15', '16', '17', '18'],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Monthly on days {dayOfMonthList}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(1)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Monthly')
|
||||
expect(translatePlural).toHaveBeenCalledTimes(1)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(1, 'calendar', 'on day {dayOfMonthList}', 'on days {dayOfMonthList}', 4, {
|
||||
dayOfMonthList: '15, 16, 17, 18',
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every month on last weekday', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'MONTHLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: ['MO', 'TU', 'WE', 'TH', 'FR'],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: -1,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Monthly on the {ordinalNumber} {byDaySet}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(3)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Monthly')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'last')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'on the {ordinalNumber} {byDaySet}', {
|
||||
ordinalNumber: 'last',
|
||||
byDaySet: 'Monday, Tuesday, Wednesday, Thursday, Friday',
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every month second Wednesday', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'MONTHLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: ['WE'],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: 2,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Monthly on the {ordinalNumber} {byDaySet}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(3)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Monthly')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'second')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'on the {ordinalNumber} {byDaySet}', {
|
||||
ordinalNumber: 'second',
|
||||
byDaySet: 'Wednesday',
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every year in May', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'YEARLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: ['5'],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Yearly in {monthNames}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(2)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Yearly')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'in {monthNames}', {
|
||||
monthNames: 'May'
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every year in May, July, October', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'YEARLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: ['5', '7', '10'],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Yearly in {monthNames}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(2)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Yearly')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'in {monthNames}', {
|
||||
monthNames: 'May, July, October'
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring infinitely every year in May, July, October on third Thursday', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'YEARLY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: null,
|
||||
byDay: ['TH'],
|
||||
byMonth: ['5', '7', '10'],
|
||||
byMonthDay: [],
|
||||
bySetPosition: 3,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Yearly in {monthNames} on the {ordinalNumber} {byDaySet}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(3)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Yearly')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'third')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'in {monthNames} on the {ordinalNumber} {byDaySet}', {
|
||||
monthNames: 'May, July, October',
|
||||
ordinalNumber: 'third',
|
||||
byDaySet: 'Thursday'
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring every day until a certain date', () => {
|
||||
const date = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
|
||||
const format = jest.fn()
|
||||
.mockReturnValue('formatted-allday-date')
|
||||
const locale = jest.fn()
|
||||
.mockReturnValue({ format })
|
||||
moment
|
||||
.mockReturnValue({ locale })
|
||||
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'DAILY',
|
||||
interval: 1,
|
||||
count: null,
|
||||
until: date,
|
||||
byDay: [],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Daily until {untilDate}')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(1)
|
||||
expect(moment).toHaveBeenNthCalledWith(1, date)
|
||||
expect(locale).toHaveBeenCalledTimes(1)
|
||||
expect(locale).toHaveBeenNthCalledWith(1, 'de')
|
||||
expect(format).toHaveBeenCalledTimes(1)
|
||||
expect(format).toHaveBeenNthCalledWith(1, 'L')
|
||||
expect(translate).toHaveBeenCalledTimes(2)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Daily')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'until {untilDate}', {
|
||||
untilDate: 'formatted-allday-date'
|
||||
})
|
||||
})
|
||||
|
||||
it('should format a recurrence-rule that is recurring every day exactly 10 times', () => {
|
||||
expect(recurrenceRuleFormat({
|
||||
frequency: 'DAILY',
|
||||
interval: 1,
|
||||
count: 42,
|
||||
until: null,
|
||||
byDay: [],
|
||||
byMonth: [],
|
||||
byMonthDay: [],
|
||||
bySetPosition: null,
|
||||
isUnsupported: false,
|
||||
recurrenceRuleValue: null,
|
||||
}, 'de')).toEqual('Daily %n times')
|
||||
|
||||
expect(moment).toHaveBeenCalledTimes(0)
|
||||
expect(translate).toHaveBeenCalledTimes(1)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Daily')
|
||||
expect(translatePlural).toHaveBeenCalledTimes(1)
|
||||
expect(translatePlural).toHaveBeenNthCalledWith(1, 'calendar', '%n time', '%n times', 42)
|
||||
})
|
||||
})
|
|
@ -19,11 +19,59 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { getDurationValueFromFullCalendarDuration, getFullCalendarDurationFromDurationValue } from '../../../../src/fullcalendar/duration.js'
|
||||
|
||||
describe('fullcalendar/duration test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
it('should get the calendar-js duration from a fullcalendar duration object - object', () => {
|
||||
expect(getDurationValueFromFullCalendarDuration({
|
||||
year: 99,
|
||||
days: 2,
|
||||
})).toEqual(null)
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration({
|
||||
days: 2,
|
||||
minutes: 50,
|
||||
seconds: 2
|
||||
}).totalSeconds).toEqual(175802)
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration({
|
||||
day: 2,
|
||||
minute: 50,
|
||||
second: 2
|
||||
}).totalSeconds).toEqual(175802)
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration({
|
||||
days: 1,
|
||||
day: 1,
|
||||
minutes: 25,
|
||||
minute: 25,
|
||||
seconds: 1,
|
||||
second: 1,
|
||||
milliseconds: 5555,
|
||||
millisecond: 6666,
|
||||
ms: 7777
|
||||
}).totalSeconds).toEqual(175820)
|
||||
})
|
||||
|
||||
it('should get the calendar-js duration from a fullcalendar duration object - string', () => {
|
||||
expect(getDurationValueFromFullCalendarDuration('05:00').totalSeconds).toEqual(18000)
|
||||
expect(getDurationValueFromFullCalendarDuration('05:21').totalSeconds).toEqual(19260)
|
||||
expect(getDurationValueFromFullCalendarDuration('05:21:50').totalSeconds).toEqual(19310)
|
||||
expect(getDurationValueFromFullCalendarDuration('05:21:23.678').totalSeconds).toEqual(19283)
|
||||
expect(getDurationValueFromFullCalendarDuration('FOO')).toEqual(null)
|
||||
})
|
||||
|
||||
it('should get the calendar-js duration from a fullcalendar duration object - number', () => {
|
||||
expect(getDurationValueFromFullCalendarDuration(5000).totalSeconds).toEqual(5)
|
||||
expect(getDurationValueFromFullCalendarDuration(5555).totalSeconds).toEqual(5)
|
||||
})
|
||||
|
||||
it('should get the calendar-js duration from a fullcalendar duration object - other', () => {
|
||||
expect(getDurationValueFromFullCalendarDuration(false)).toEqual(null)
|
||||
})
|
||||
|
||||
it('should get the fullcalendar duration from a calendar-js duration object', () => {
|
||||
expect(getFullCalendarDurationFromDurationValue({ totalSeconds: 500 })).toEqual({ seconds: 500 })
|
||||
})
|
||||
})
|
||||
|
|
|
@ -19,11 +19,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import eventAllow from "../../../../src/fullcalendar/eventAllow.js";
|
||||
|
||||
describe('fullcalendar/eventAllow test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
it('should always allow to drop an event that does allow modifying all-days', () => {
|
||||
expect(eventAllow({ allDay: true }, { allDay: true, extendedProps: { canModifyAllDay: true }})).toEqual(true)
|
||||
expect(eventAllow({ allDay: true }, { allDay: false, extendedProps: { canModifyAllDay: true }})).toEqual(true)
|
||||
expect(eventAllow({ allDay: false }, { allDay: true, extendedProps: { canModifyAllDay: true }})).toEqual(true)
|
||||
expect(eventAllow({ allDay: false }, { allDay: false, extendedProps: { canModifyAllDay: true }})).toEqual(true)
|
||||
})
|
||||
|
||||
it('should disallow changing the allday state when prohibited', () => {
|
||||
expect(eventAllow({ allDay: true }, { allDay: true, extendedProps: { canModifyAllDay: false }})).toEqual(true)
|
||||
expect(eventAllow({ allDay: true }, { allDay: false, extendedProps: { canModifyAllDay: false }})).toEqual(false)
|
||||
expect(eventAllow({ allDay: false }, { allDay: true, extendedProps: { canModifyAllDay: false }})).toEqual(false)
|
||||
expect(eventAllow({ allDay: false }, { allDay: false, extendedProps: { canModifyAllDay: false }})).toEqual(true)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -19,11 +19,250 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import eventClick from "../../../../src/fullcalendar/eventClick.js";
|
||||
import { getPrefixedRoute } from "../../../../src/utils/router.js";
|
||||
jest.mock("../../../../src/utils/router.js");
|
||||
|
||||
describe('fullcalendar/eventClick test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
beforeEach(() => {
|
||||
getPrefixedRoute.mockClear()
|
||||
})
|
||||
|
||||
it('should open the Popover on big screens', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'CalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'CalendarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'CalendarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'CalendarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(1)
|
||||
expect(router.push.mock.calls[0][0]).toEqual({
|
||||
name: 'EditPopoverView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should open the Sidebar on big screens if the user wishes so', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'CalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'CalendarView', 'EditSidebarView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'CalendarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'CalendarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(1)
|
||||
expect(router.push.mock.calls[0][0]).toEqual({
|
||||
name: 'EditSidebarView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should open the Sidebar on smaller screens', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'CalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 760 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'CalendarView', 'EditSidebarView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'CalendarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'CalendarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(1)
|
||||
expect(router.push.mock.calls[0][0]).toEqual({
|
||||
name: 'EditSidebarView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should keep the public prefix when viewed in public mode', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'PublicCalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('PublicEditSidebarView')
|
||||
.mockReturnValueOnce('PublicEditPopoverView')
|
||||
.mockReturnValueOnce('PublicEditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'PublicCalendarView', 'EditSidebarView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'PublicCalendarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'PublicCalendarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(1)
|
||||
expect(router.push.mock.calls[0][0]).toEqual({
|
||||
name: 'PublicEditSidebarView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should keep the embed prefix when viewed in embedded mode', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'EmbedCalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('EmbedEditSidebarView')
|
||||
.mockReturnValueOnce('EmbedEditPopoverView')
|
||||
.mockReturnValueOnce('EmbedEditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'EmbedCalendarView', 'EditSidebarView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'EmbedCalendarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'EmbedCalendarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(1)
|
||||
expect(router.push.mock.calls[0][0]).toEqual({
|
||||
name: 'EmbedEditSidebarView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should not update the route when the same event and same occurrence is already viewed - same route', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'EditSidebarView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'EditSidebarView', 'EditSidebarView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'EditSidebarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'EditSidebarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(0)
|
||||
})
|
||||
|
||||
it('should not update the route when the same event and same occurrence is already viewed - Sidebar Route', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'EditSidebarView',
|
||||
params: {
|
||||
object: 'object123',
|
||||
otherParam: '456',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
getPrefixedRoute
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditPopoverView')
|
||||
.mockReturnValueOnce('EditSidebarView')
|
||||
|
||||
const eventClickFunction = eventClick(store, router, route, window)
|
||||
eventClickFunction({ event: {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
}
|
||||
}})
|
||||
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(1, 'EditSidebarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(2, 'EditSidebarView', 'EditPopoverView')
|
||||
expect(getPrefixedRoute).toHaveBeenNthCalledWith(3, 'EditSidebarView', 'EditSidebarView')
|
||||
|
||||
expect(router.push.mock.calls.length).toEqual(0)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -19,11 +19,668 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import eventDrop from "../../../../src/fullcalendar/eventDrop.js";
|
||||
import { getDurationValueFromFullCalendarDuration} from "../../../../src/fullcalendar/duration.js";
|
||||
import getTimezoneManager from '../../../../src/services/timezoneDataProviderService.js'
|
||||
|
||||
jest.mock("../../../../src/fullcalendar/duration.js")
|
||||
jest.mock('../../../../src/services/timezoneDataProviderService.js')
|
||||
|
||||
describe('fullcalendar/eventDrop test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
beforeEach(() => {
|
||||
getDurationValueFromFullCalendarDuration.mockClear()
|
||||
getTimezoneManager.mockClear()
|
||||
})
|
||||
|
||||
it('should properly drop a non-recurring event', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(2)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'updateCalendarObject', { calendarObject })
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 }, false, { calendarJsTimezone: true, tzid: 'America/New_York' }, { calendarJsDurationValue: true, days: 1 }, { calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should properly drop a recurring event', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(true),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(2)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'updateCalendarObject', { calendarObject })
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 }, false, { calendarJsTimezone: true, tzid: 'America/New_York' }, { calendarJsDurationValue: true, days: 1 }, { calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenNthCalledWith(1)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should revert if delta duration could not be parsed', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert if default allday duration could not be parsed', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert if default timed duration could not be parsed', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce(false)
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when the object was not found', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockRejectedValueOnce({ message: 'error message' }) // getEventByObjectId
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when the recurrence was not found', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(null),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when shiftByDuration throws an exception', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn().mockImplementation(() => {
|
||||
throw new Error();
|
||||
}),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 }, false, { calendarJsTimezone: true, tzid: 'America/New_York' }, { calendarJsDurationValue: true, days: 1 }, { calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(1)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when there was an error updating the event', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const fcAPI = {
|
||||
getOption: jest.fn()
|
||||
.mockReturnValueOnce({ days: 1 })
|
||||
.mockReturnValueOnce({ hours: 2 })
|
||||
.mockReturnValueOnce('America/New_York'),
|
||||
}
|
||||
|
||||
const event = {
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const delta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, days: 1 })
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const eventComponent = {
|
||||
shiftByDuration: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
store.dispatch.mockImplementationOnce(() => {
|
||||
throw new Error()
|
||||
}) // updateCalendarObject
|
||||
|
||||
const eventDropFunction = eventDrop(store, fcAPI)
|
||||
await eventDropFunction({ event, delta, revert })
|
||||
|
||||
expect(fcAPI.getOption).toHaveBeenCalledTimes(3)
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(1, 'defaultAllDayEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(2, 'defaultTimedEventDuration')
|
||||
expect(fcAPI.getOption).toHaveBeenNthCalledWith(3, 'timeZone')
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(3)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, delta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, { days: 1})
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(3, { hours: 2 })
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(2)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'updateCalendarObject', { calendarObject })
|
||||
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.shiftByDuration).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 }, false, { calendarJsTimezone: true, tzid: 'America/New_York' }, { calendarJsDurationValue: true, days: 1 }, { calendarJsDurationValue: true, hours: 2 })
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(1)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -19,11 +19,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import eventRender from "../../../../src/fullcalendar/eventRender.js";
|
||||
|
||||
describe('services/illustrationProviderService test suite', () => {
|
||||
describe('fullcalendar/eventRender test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
it('should add extended properties from the event to the dataset of the dom element', () => {
|
||||
const el = document.createElement('div')
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: 'recurrence456',
|
||||
},
|
||||
}
|
||||
|
||||
eventRender({ event, el })
|
||||
|
||||
expect(el.dataset.objectId).toEqual('object123')
|
||||
expect(el.dataset.recurrenceId).toEqual('recurrence456')
|
||||
})
|
||||
|
||||
})
|
|
@ -19,11 +19,355 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import eventResize from "../../../../src/fullcalendar/eventResize.js";
|
||||
|
||||
import { getDurationValueFromFullCalendarDuration} from '../../../../src/fullcalendar/duration.js'
|
||||
jest.mock('../../../../src/fullcalendar/duration.js')
|
||||
|
||||
describe('fullcalendar/eventResize test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
beforeEach(() => {
|
||||
getDurationValueFromFullCalendarDuration.mockClear()
|
||||
})
|
||||
|
||||
it('should properly resize a non-recurring event', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const startDelta = {
|
||||
hours: 5
|
||||
}
|
||||
const endDelta = {}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce(false)
|
||||
|
||||
const eventComponent = {
|
||||
addDurationToStart: jest.fn(),
|
||||
addDurationToEnd: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch
|
||||
.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventResizeFunction = eventResize(store)
|
||||
await eventResizeFunction({ event, startDelta, endDelta, revert })
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(2)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, startDelta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, endDelta)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(2)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'updateCalendarObject', { calendarObject })
|
||||
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 })
|
||||
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should properly resize a recurring event', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const startDelta = {}
|
||||
const endDelta = {
|
||||
hours: 5
|
||||
}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
|
||||
const eventComponent = {
|
||||
addDurationToStart: jest.fn(),
|
||||
addDurationToEnd: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(true),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch
|
||||
.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventResizeFunction = eventResize(store)
|
||||
await eventResizeFunction({ event, startDelta, endDelta, revert })
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(2)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, startDelta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, endDelta)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(2)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'updateCalendarObject', { calendarObject })
|
||||
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 })
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should revert the action when neither a valid start nor end resize was given', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const startDelta = {}
|
||||
const endDelta = {}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValueOnce(false)
|
||||
|
||||
const eventComponent = {
|
||||
addDurationToStart: jest.fn(),
|
||||
addDurationToEnd: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(true),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch
|
||||
.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventResizeFunction = eventResize(store)
|
||||
await eventResizeFunction({ event, startDelta, endDelta, revert })
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(2)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, startDelta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, endDelta)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when the object was not found', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const startDelta = {
|
||||
hours: 5
|
||||
}
|
||||
const endDelta = {}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce(false)
|
||||
|
||||
const eventComponent = {
|
||||
addDurationToStart: jest.fn(),
|
||||
addDurationToEnd: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error()
|
||||
}) // getEventByObjectId
|
||||
.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventResizeFunction = eventResize(store)
|
||||
await eventResizeFunction({ event, startDelta, endDelta, revert })
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(2)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, startDelta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, endDelta)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when the recurrence was not found', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const startDelta = {
|
||||
hours: 5
|
||||
}
|
||||
const endDelta = {}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce(false)
|
||||
|
||||
const eventComponent = {
|
||||
addDurationToStart: jest.fn(),
|
||||
addDurationToEnd: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(null),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch
|
||||
.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
.mockResolvedValueOnce() // updateCalendarObject
|
||||
|
||||
const eventResizeFunction = eventResize(store)
|
||||
await eventResizeFunction({ event, startDelta, endDelta, revert })
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(2)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, startDelta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, endDelta)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(0)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(0)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should revert the action when there was an error updating the event', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
}
|
||||
const event = {
|
||||
extendedProps: {
|
||||
objectId: 'object123',
|
||||
recurrenceId: '1573554842'
|
||||
}
|
||||
}
|
||||
const startDelta = {
|
||||
hours: 5
|
||||
}
|
||||
const endDelta = {}
|
||||
const revert = jest.fn()
|
||||
|
||||
getDurationValueFromFullCalendarDuration
|
||||
.mockReturnValueOnce({ calendarJsDurationValue: true, hours: 5 })
|
||||
.mockReturnValueOnce(false)
|
||||
|
||||
const eventComponent = {
|
||||
addDurationToStart: jest.fn(),
|
||||
addDurationToEnd: jest.fn(),
|
||||
canCreateRecurrenceExceptions: jest.fn().mockReturnValue(false),
|
||||
createRecurrenceException: jest.fn(),
|
||||
}
|
||||
const calendarObject = {
|
||||
getObjectAtRecurrenceId: jest.fn().mockReturnValueOnce(eventComponent),
|
||||
resetToDav: jest.fn()
|
||||
}
|
||||
|
||||
store.dispatch
|
||||
.mockResolvedValueOnce(calendarObject) // getEventByObjectId
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error()
|
||||
}) // updateCalendarObject
|
||||
|
||||
const eventResizeFunction = eventResize(store)
|
||||
await eventResizeFunction({ event, startDelta, endDelta, revert })
|
||||
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenCalledTimes(2)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(1, startDelta)
|
||||
expect(getDurationValueFromFullCalendarDuration).toHaveBeenNthCalledWith(2, endDelta)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(2)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventByObjectId', { objectId: 'object123' })
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'updateCalendarObject', { calendarObject })
|
||||
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.addDurationToStart).toHaveBeenNthCalledWith(1, { calendarJsDurationValue: true, hours: 5 })
|
||||
|
||||
expect(eventComponent.addDurationToEnd).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(eventComponent.canCreateRecurrenceExceptions).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponent.createRecurrenceException).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(calendarObject.resetToDav).toHaveBeenCalledTimes(1)
|
||||
expect(revert).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -19,11 +19,272 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import eventSource from "../../../../src/fullcalendar/eventSource.js";
|
||||
|
||||
import { generateTextColorForRGBString } from '../../../../src/utils/color.js'
|
||||
import getTimezoneManager from '../../../../src/services/timezoneDataProviderService'
|
||||
import { getUnixTimestampFromDate } from '../../../../src/utils/date.js'
|
||||
import { eventSourceFunction } from '../../../../src/fullcalendar/eventSourceFunction.js'
|
||||
|
||||
jest.mock('../../../../src/utils/color.js')
|
||||
jest.mock('../../../../src/services/timezoneDataProviderService')
|
||||
jest.mock('../../../../src/utils/date.js')
|
||||
jest.mock('../../../../src/fullcalendar/eventSourceFunction.js')
|
||||
|
||||
describe('fullcalendar/eventSource test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
beforeEach(() => {
|
||||
generateTextColorForRGBString.mockClear()
|
||||
getTimezoneManager.mockClear()
|
||||
getUnixTimestampFromDate.mockClear()
|
||||
eventSourceFunction.mockClear()
|
||||
})
|
||||
|
||||
it('should provide an eventSource for a given calendar', () => {
|
||||
const store = {}
|
||||
const calendar = {
|
||||
id: 'calendar-id-123',
|
||||
color: '#ff00ff',
|
||||
isReadOnly: false
|
||||
}
|
||||
|
||||
generateTextColorForRGBString
|
||||
.mockReturnValue('#00ff00')
|
||||
|
||||
const eventSourceFunction = eventSource(store)
|
||||
expect(eventSourceFunction(calendar)).toEqual({
|
||||
id: 'calendar-id-123',
|
||||
backgroundColor: '#ff00ff',
|
||||
borderColor: '#ff00ff',
|
||||
textColor: '#00ff00',
|
||||
events: expect.any(Function)
|
||||
})
|
||||
|
||||
expect(generateTextColorForRGBString).toHaveBeenCalledTimes(1)
|
||||
expect(generateTextColorForRGBString).toHaveBeenNthCalledWith(1, '#ff00ff')
|
||||
})
|
||||
|
||||
it('should provide an eventSource for a given read-only calendar', () => {
|
||||
const store = {}
|
||||
const calendar = {
|
||||
id: 'calendar-id-123',
|
||||
color: '#ff00ff',
|
||||
isReadOnly: true
|
||||
}
|
||||
|
||||
generateTextColorForRGBString
|
||||
.mockReturnValue('#00ff00')
|
||||
|
||||
const eventSourceFunction = eventSource(store)
|
||||
expect(eventSourceFunction(calendar)).toEqual({
|
||||
id: 'calendar-id-123',
|
||||
backgroundColor: '#ff00ff',
|
||||
borderColor: '#ff00ff',
|
||||
textColor: '#00ff00',
|
||||
events: expect.any(Function),
|
||||
editable: false
|
||||
})
|
||||
|
||||
expect(generateTextColorForRGBString).toHaveBeenCalledTimes(1)
|
||||
expect(generateTextColorForRGBString).toHaveBeenNthCalledWith(1, '#ff00ff')
|
||||
})
|
||||
|
||||
it('should provide an eventSource function to provide events - fetch new timerange', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
.mockReturnValueOnce(42),
|
||||
getters: {
|
||||
getTimeRangeForCalendarCoveringRange: jest.fn()
|
||||
.mockReturnValueOnce(false),
|
||||
getCalendarObjectsByTimeRangeId: jest.fn()
|
||||
.mockReturnValueOnce([{ calendarObjectId: 1 }, { calendarObjectId: 2 }])
|
||||
}
|
||||
}
|
||||
|
||||
const calendar = {
|
||||
id: 'calendar-id-123',
|
||||
color: '#ff00ff',
|
||||
isReadOnly: true
|
||||
}
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
getUnixTimestampFromDate
|
||||
.mockReturnValueOnce(1234)
|
||||
.mockReturnValueOnce(5678)
|
||||
|
||||
generateTextColorForRGBString
|
||||
.mockReturnValue('#00ff00')
|
||||
|
||||
eventSourceFunction
|
||||
.mockReturnValueOnce([{ fcEventId: 1 }, { fcEventId: 2 }])
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 31, 59, 59, 59, 999))
|
||||
const timeZone = 'America/New_York'
|
||||
|
||||
const successCallback = jest.fn()
|
||||
const failureCallback = jest.fn()
|
||||
|
||||
const eventSourceFn = eventSource(store)
|
||||
const { events } = eventSourceFn(calendar)
|
||||
await events({ start, end, timeZone }, successCallback, failureCallback)
|
||||
|
||||
expect(store.getters.getTimeRangeForCalendarCoveringRange).toHaveBeenCalledTimes(1)
|
||||
expect(store.getters.getTimeRangeForCalendarCoveringRange).toHaveBeenNthCalledWith(1, 'calendar-id-123', 1234, 5678)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventsFromCalendarInTimeRange', {
|
||||
calendar,
|
||||
from: start,
|
||||
to: end
|
||||
})
|
||||
|
||||
expect(store.getters.getCalendarObjectsByTimeRangeId).toHaveBeenCalledTimes(1)
|
||||
expect(store.getters.getCalendarObjectsByTimeRangeId).toHaveBeenNthCalledWith(1, 42)
|
||||
|
||||
expect(eventSourceFunction).toHaveBeenCalledTimes(1)
|
||||
expect(eventSourceFunction).toHaveBeenNthCalledWith(1, [{ calendarObjectId: 1 }, { calendarObjectId: 2 }], start, end, { calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
|
||||
expect(successCallback).toHaveBeenCalledTimes(1)
|
||||
expect(successCallback).toHaveBeenNthCalledWith(1, [{ fcEventId: 1 }, { fcEventId: 2 }])
|
||||
|
||||
expect(failureCallback).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should provide an eventSource function to provide events - existing timerange', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
.mockReturnValueOnce(42),
|
||||
getters: {
|
||||
getTimeRangeForCalendarCoveringRange: jest.fn()
|
||||
.mockReturnValueOnce({
|
||||
id: 42
|
||||
}),
|
||||
getCalendarObjectsByTimeRangeId: jest.fn()
|
||||
.mockReturnValueOnce([{ calendarObjectId: 1 }, { calendarObjectId: 2 }])
|
||||
}
|
||||
}
|
||||
|
||||
const calendar = {
|
||||
id: 'calendar-id-123',
|
||||
color: '#ff00ff',
|
||||
isReadOnly: true
|
||||
}
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
getUnixTimestampFromDate
|
||||
.mockReturnValueOnce(1234)
|
||||
.mockReturnValueOnce(5678)
|
||||
|
||||
generateTextColorForRGBString
|
||||
.mockReturnValue('#00ff00')
|
||||
|
||||
eventSourceFunction
|
||||
.mockReturnValueOnce([{ fcEventId: 1 }, { fcEventId: 2 }])
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 31, 59, 59, 59, 999))
|
||||
const timeZone = 'America/New_York'
|
||||
|
||||
const successCallback = jest.fn()
|
||||
const failureCallback = jest.fn()
|
||||
|
||||
const eventSourceFn = eventSource(store)
|
||||
const { events } = eventSourceFn(calendar)
|
||||
await events({ start, end, timeZone }, successCallback, failureCallback)
|
||||
|
||||
expect(store.getters.getTimeRangeForCalendarCoveringRange).toHaveBeenCalledTimes(1)
|
||||
expect(store.getters.getTimeRangeForCalendarCoveringRange).toHaveBeenNthCalledWith(1, 'calendar-id-123', 1234, 5678)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(store.getters.getCalendarObjectsByTimeRangeId).toHaveBeenCalledTimes(1)
|
||||
expect(store.getters.getCalendarObjectsByTimeRangeId).toHaveBeenNthCalledWith(1, 42)
|
||||
|
||||
expect(eventSourceFunction).toHaveBeenCalledTimes(1)
|
||||
expect(eventSourceFunction).toHaveBeenNthCalledWith(1, [{ calendarObjectId: 1 }, { calendarObjectId: 2 }], start, end, { calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
|
||||
expect(successCallback).toHaveBeenCalledTimes(1)
|
||||
expect(successCallback).toHaveBeenNthCalledWith(1, [{ fcEventId: 1 }, { fcEventId: 2 }])
|
||||
|
||||
expect(failureCallback).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should provide an eventSource function that catches errors while fetching', async () => {
|
||||
const store = {
|
||||
dispatch: jest.fn()
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error()
|
||||
}),
|
||||
getters: {
|
||||
getTimeRangeForCalendarCoveringRange: jest.fn()
|
||||
.mockReturnValueOnce(false),
|
||||
getCalendarObjectsByTimeRangeId: jest.fn()
|
||||
.mockReturnValueOnce([{ calendarObjectId: 1 }, { calendarObjectId: 2 }])
|
||||
}
|
||||
}
|
||||
|
||||
const calendar = {
|
||||
id: 'calendar-id-123',
|
||||
color: '#ff00ff',
|
||||
isReadOnly: true
|
||||
}
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValueOnce({ calendarJsTimezone: true, tzid: 'America/New_York' })
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
getUnixTimestampFromDate
|
||||
.mockReturnValueOnce(1234)
|
||||
.mockReturnValueOnce(5678)
|
||||
|
||||
generateTextColorForRGBString
|
||||
.mockReturnValue('#00ff00')
|
||||
|
||||
eventSourceFunction
|
||||
.mockReturnValueOnce([{ fcEventId: 1 }, { fcEventId: 2 }])
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 31, 59, 59, 59, 999))
|
||||
const timeZone = 'America/New_York'
|
||||
|
||||
const successCallback = jest.fn()
|
||||
const failureCallback = jest.fn()
|
||||
|
||||
const eventSourceFn = eventSource(store)
|
||||
const { events } = eventSourceFn(calendar)
|
||||
await events({ start, end, timeZone }, successCallback, failureCallback)
|
||||
|
||||
expect(store.getters.getTimeRangeForCalendarCoveringRange).toHaveBeenCalledTimes(1)
|
||||
expect(store.getters.getTimeRangeForCalendarCoveringRange).toHaveBeenNthCalledWith(1, 'calendar-id-123', 1234, 5678)
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledTimes(1)
|
||||
expect(store.dispatch).toHaveBeenNthCalledWith(1, 'getEventsFromCalendarInTimeRange', {
|
||||
calendar,
|
||||
from: start,
|
||||
to: end
|
||||
})
|
||||
|
||||
expect(store.getters.getCalendarObjectsByTimeRangeId).toHaveBeenCalledTimes(0)
|
||||
expect(eventSourceFunction).toHaveBeenCalledTimes(0)
|
||||
expect(successCallback).toHaveBeenCalledTimes(0)
|
||||
|
||||
expect(failureCallback).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -19,11 +19,211 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { eventSourceFunction } from '../../../../src/fullcalendar/eventSourceFunction.js'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
jest.mock('@nextcloud/l10n')
|
||||
|
||||
describe('fullcalendar/eventSourceFunction test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
beforeEach(() => {
|
||||
translate.mockClear()
|
||||
})
|
||||
|
||||
it('should provide fc-events', () => {
|
||||
translate
|
||||
.mockImplementation((app, str) => str)
|
||||
|
||||
const eventComponentSet1 = [{
|
||||
id: '1-1',
|
||||
// To title on purpose
|
||||
isAllDay: jest.fn().mockReturnValue(false),
|
||||
getReferenceRecurrenceId: jest.fn().mockReturnValue({ unixTime: 123 }),
|
||||
canModifyAllDay: jest.fn().mockReturnValue(false),
|
||||
startDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-1-1-start'
|
||||
})
|
||||
},
|
||||
endDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-1-1-end'
|
||||
})
|
||||
},
|
||||
}, {
|
||||
id: '1-2',
|
||||
status: 'CANCELLED',
|
||||
isAllDay: jest.fn().mockReturnValue(false),
|
||||
getReferenceRecurrenceId: jest.fn().mockReturnValue({ unixTime: 456 }),
|
||||
canModifyAllDay: jest.fn().mockReturnValue(false),
|
||||
startDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-1-2-start'
|
||||
})
|
||||
},
|
||||
endDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-1-2-end'
|
||||
})
|
||||
},
|
||||
}, {
|
||||
id: '1-3',
|
||||
status: 'TENTATIVE',
|
||||
isAllDay: jest.fn().mockReturnValue(false),
|
||||
getReferenceRecurrenceId: jest.fn().mockReturnValue({ unixTime: 789 }),
|
||||
canModifyAllDay: jest.fn().mockReturnValue(false),
|
||||
startDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-1-3-start'
|
||||
})
|
||||
},
|
||||
endDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-1-3-end'
|
||||
})
|
||||
},
|
||||
}]
|
||||
const eventComponentSet2 = [{
|
||||
id: '2-1',
|
||||
status: 'CONFIRMED',
|
||||
isAllDay: jest.fn().mockReturnValue(true),
|
||||
getReferenceRecurrenceId: jest.fn().mockReturnValue({ unixTime: 101 }),
|
||||
canModifyAllDay: jest.fn().mockReturnValue(true),
|
||||
startDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-2-1-start'
|
||||
})
|
||||
},
|
||||
endDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-2-1-end'
|
||||
})
|
||||
},
|
||||
}]
|
||||
const eventComponentSet4 = [{
|
||||
id: '3-1',
|
||||
status: 'CONFIRMED',
|
||||
isAllDay: jest.fn().mockReturnValue(false),
|
||||
getReferenceRecurrenceId: jest.fn().mockReturnValue({ unixTime: 303 }),
|
||||
canModifyAllDay: jest.fn().mockReturnValue(true),
|
||||
startDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-3-1-start'
|
||||
})
|
||||
},
|
||||
endDate: {
|
||||
getInTimezone: jest.fn().mockReturnValue({
|
||||
jsDate: 'js-date-3-1-end'
|
||||
})
|
||||
},
|
||||
}]
|
||||
|
||||
const calendarObjects = [{
|
||||
calendarObject: true,
|
||||
id: '1',
|
||||
getAllObjectsInTimeRange: jest.fn()
|
||||
.mockReturnValueOnce(eventComponentSet1),
|
||||
}, {
|
||||
calendarObject: true,
|
||||
id: '2',
|
||||
getAllObjectsInTimeRange: jest.fn()
|
||||
.mockReturnValueOnce(eventComponentSet2),
|
||||
}, {
|
||||
calendarObject: true,
|
||||
id: '3',
|
||||
getAllObjectsInTimeRange: jest.fn()
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error('Error while getting all objects in time-range')
|
||||
})
|
||||
}, {
|
||||
calendarObject: true,
|
||||
id: '4',
|
||||
getAllObjectsInTimeRange: jest.fn()
|
||||
.mockReturnValueOnce(eventComponentSet4),
|
||||
}]
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 31, 59, 59, 59, 999))
|
||||
const timezone = { calendarJsTimezone: true, tzid: 'America/New_York' }
|
||||
const result = eventSourceFunction(calendarObjects, start, end, timezone)
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
id: '1###1-1',
|
||||
title: 'Untitled event',
|
||||
allDay: false,
|
||||
start: 'js-date-1-1-start',
|
||||
end: 'js-date-1-1-end',
|
||||
classNames: [],
|
||||
extendedProps: { objectId: '1', recurrenceId: 123, canModifyAllDay: false }
|
||||
},
|
||||
{
|
||||
id: '1###1-2',
|
||||
title: 'Untitled event',
|
||||
allDay: false,
|
||||
start: 'js-date-1-2-start',
|
||||
end: 'js-date-1-2-end',
|
||||
classNames: [ 'fc-event-nc-cancelled' ],
|
||||
extendedProps: { objectId: '1', recurrenceId: 456, canModifyAllDay: false }
|
||||
},
|
||||
{
|
||||
id: '1###1-3',
|
||||
title: 'Untitled event',
|
||||
allDay: false,
|
||||
start: 'js-date-1-3-start',
|
||||
end: 'js-date-1-3-end',
|
||||
classNames: [ 'fc-event-nc-tentative' ],
|
||||
extendedProps: { objectId: '1', recurrenceId: 789, canModifyAllDay: false }
|
||||
},
|
||||
{
|
||||
id: '2###2-1',
|
||||
title: 'Untitled event',
|
||||
allDay: true,
|
||||
start: 'js-date-2-1-start',
|
||||
end: 'js-date-2-1-end',
|
||||
classNames: [],
|
||||
extendedProps: { objectId: '2', recurrenceId: 101, canModifyAllDay: true }
|
||||
},
|
||||
{
|
||||
id: '4###3-1',
|
||||
title: 'Untitled event',
|
||||
allDay: false,
|
||||
start: 'js-date-3-1-start',
|
||||
end: 'js-date-3-1-end',
|
||||
classNames: [],
|
||||
extendedProps: { objectId: '4', recurrenceId: 303, canModifyAllDay: true }
|
||||
}
|
||||
])
|
||||
|
||||
expect(eventComponentSet1[0].startDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet1[0].startDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
expect(eventComponentSet1[0].endDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet1[0].endDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
|
||||
expect(eventComponentSet1[1].startDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet1[1].startDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
expect(eventComponentSet1[1].endDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet1[1].endDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
|
||||
expect(eventComponentSet1[2].startDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet1[2].startDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
expect(eventComponentSet1[2].endDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet1[2].endDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
|
||||
expect(eventComponentSet2[0].startDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet2[0].startDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
expect(eventComponentSet2[0].endDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet2[0].endDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
|
||||
expect(eventComponentSet4[0].startDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet4[0].startDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
expect(eventComponentSet4[0].endDate.getInTimezone).toHaveBeenCalledTimes(1)
|
||||
expect(eventComponentSet4[0].endDate.getInTimezone).toHaveBeenNthCalledWith(1, timezone)
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(5)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Untitled event')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'Untitled event')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'Untitled event')
|
||||
expect(translate).toHaveBeenNthCalledWith(4, 'calendar', 'Untitled event')
|
||||
expect(translate).toHaveBeenNthCalledWith(5, 'calendar', 'Untitled event')
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -19,11 +19,244 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import select from "../../../../src/fullcalendar/select.js";
|
||||
|
||||
describe('fullcalendar/select test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
it('should open the Popover on big screens', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'CalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(1)
|
||||
expect(router.push).toHaveBeenNthCalledWith(1, {
|
||||
name: 'NewPopoverView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should open the Sidebar on big screens if the user wishes so', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'CalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(1)
|
||||
expect(router.push).toHaveBeenNthCalledWith(1, {
|
||||
name: 'NewSidebarView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should open the Sidebar on smaller screens', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = { name: 'CalendarView', params: { otherParam: '456' } }
|
||||
const window = { innerWidth: 760 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(1)
|
||||
expect(router.push).toHaveBeenNthCalledWith(1, {
|
||||
name: 'NewSidebarView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should not update the route if the exact time-range is already open - Popover to Popover', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'NewPopoverView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should not update the route if the exact time-range is already open - Sidebar to Popover', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'NewSidebarView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should not update the route if the exact time-range is already open - Sidebar to Sidebar', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'NewSidebarView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should not update the route if the exact time-range is already open - Popover to Sidebar', () => {
|
||||
const store = { state: { settings: { skipPopover: true } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'NewPopoverView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 0, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 0, 2, 0, 0, 0, 0))
|
||||
const allDay = true
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should not the popover when a new event sidebar is already open - Popover', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'NewPopoverView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 3, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 3, 2, 0, 0, 0, 0))
|
||||
const allDay = false
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(1)
|
||||
expect(router.push).toHaveBeenNthCalledWith(1, {
|
||||
name: 'NewPopoverView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '0',
|
||||
dtstart: '1554076800',
|
||||
dtend: '1554163200',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should not the popover when a new event sidebar is already open - Sidebar', () => {
|
||||
const store = { state: { settings: { skipPopover: false } } }
|
||||
const router = { push: jest.fn() }
|
||||
const route = {
|
||||
name: 'NewSidebarView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '1',
|
||||
dtstart: '1546300800',
|
||||
dtend: '1546387200',
|
||||
},
|
||||
}
|
||||
const window = { innerWidth: 1920 }
|
||||
|
||||
const start = new Date(Date.UTC(2019, 3, 1, 0, 0, 0, 0))
|
||||
const end = new Date(Date.UTC(2019, 3, 2, 0, 0, 0, 0))
|
||||
const allDay = false
|
||||
|
||||
const selectFunction = select(store, router, route, window)
|
||||
selectFunction({ start, end, allDay })
|
||||
|
||||
expect(router.push).toHaveBeenCalledTimes(1)
|
||||
expect(router.push).toHaveBeenNthCalledWith(1, {
|
||||
name: 'NewSidebarView',
|
||||
params: {
|
||||
otherParam: '456',
|
||||
allDay: '0',
|
||||
dtstart: '1554076800',
|
||||
dtend: '1554163200',
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -20,10 +20,80 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import {
|
||||
createPlugin,
|
||||
} from '@fullcalendar/core'
|
||||
import getTimezoneManager from '../../../../src/services/timezoneDataProviderService.js'
|
||||
jest.mock('../../../../src/services/timezoneDataProviderService.js')
|
||||
jest.mock('@fullcalendar/core')
|
||||
|
||||
import vtimezoneNamedTimezoneImpl from "../../../../src/fullcalendar/vtimezoneNamedTimezoneImpl.js";
|
||||
|
||||
describe('fullcalendar/vtimezoneNamedTimezoneImpl test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
beforeEach(() => {
|
||||
getTimezoneManager.mockClear()
|
||||
})
|
||||
|
||||
it('should properly register a plugin for full-calendar', () => {
|
||||
expect(createPlugin).toHaveBeenCalledTimes(1)
|
||||
expect(createPlugin).toHaveBeenNthCalledWith(1, {
|
||||
namedTimeZonedImpl: expect.any(Function)
|
||||
})
|
||||
})
|
||||
|
||||
it('should properly implement the offsetForArray method', () => {
|
||||
const timezone = {
|
||||
calendarJsTimezone: true,
|
||||
tzid: 'America/New_York',
|
||||
offsetForArray: jest.fn().mockReturnValue(1337 * 60)
|
||||
}
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValue(timezone)
|
||||
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const VTimezoneNamedTimezone = createPlugin.mock.calls[0][0].namedTimeZonedImpl
|
||||
const instance = new VTimezoneNamedTimezone('America/New_York')
|
||||
|
||||
const result = instance.offsetForArray([2019, 0, 1, 14, 30, 0])
|
||||
|
||||
expect(result).toEqual(1337)
|
||||
|
||||
expect(getTimezoneForId).toHaveBeenCalledTimes(1)
|
||||
expect(timezone.offsetForArray).toHaveBeenCalledTimes(1)
|
||||
expect(timezone.offsetForArray).toHaveBeenNthCalledWith(1, 2019, 1, 1, 14, 30, 0)
|
||||
})
|
||||
|
||||
it('should properly implement the timestampToArray method', () => {
|
||||
const timezone = {
|
||||
calendarJsTimezone: true,
|
||||
tzid: 'America/New_York',
|
||||
timestampToArray: jest.fn().mockReturnValue([2019, 1, 1, 14, 30, 0])
|
||||
}
|
||||
|
||||
const getTimezoneForId = jest.fn()
|
||||
.mockReturnValue(timezone)
|
||||
|
||||
getTimezoneManager
|
||||
.mockReturnValue({
|
||||
getTimezoneForId
|
||||
})
|
||||
|
||||
const VTimezoneNamedTimezone = createPlugin.mock.calls[0][0].namedTimeZonedImpl
|
||||
const instance = new VTimezoneNamedTimezone('America/New_York')
|
||||
|
||||
const result = instance.timestampToArray(1337)
|
||||
|
||||
expect(result).toEqual([2019, 0, 1, 14, 30, 0])
|
||||
|
||||
expect(getTimezoneForId).toHaveBeenCalledTimes(1)
|
||||
expect(timezone.timestampToArray).toHaveBeenCalledTimes(1)
|
||||
expect(timezone.timestampToArray).toHaveBeenNthCalledWith(1, 1337)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
describe('services/datew test suite', () => {
|
||||
describe('models/calendarOje test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
|
@ -19,78 +19,120 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import rfcProps from '../../../../src/models/rfcProps.js'
|
||||
|
||||
import { getRFCProperties } from '../../../../src/models/rfcProps.js'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
import { getDefaultCategories } from '../../../../src/defaults/defaultCategories.js'
|
||||
jest.mock('@nextcloud/l10n')
|
||||
jest.mock('../../../../src/defaults/defaultCategories.js')
|
||||
|
||||
describe('models/rfcProps test suite', () => {
|
||||
|
||||
it('should provide property info for access class', () => {
|
||||
expect(rfcProps.accessClass).toEqual(expect.any(Object))
|
||||
beforeEach(() => {
|
||||
translate.mockClear()
|
||||
getDefaultCategories.mockClear()
|
||||
|
||||
expect(rfcProps.accessClass.readableName).toEqual('TRANSLATED:When shared show')
|
||||
translate
|
||||
.mockImplementation((app, str) => str)
|
||||
getDefaultCategories
|
||||
.mockReturnValue(['Category 1', 'Category 2', 'Category 3'])
|
||||
})
|
||||
|
||||
it('should provide property info for rfc properties', () => {
|
||||
const rfcProps = getRFCProperties()
|
||||
|
||||
expect(rfcProps.accessClass).toEqual(expect.any(Object))
|
||||
expect(rfcProps.accessClass.readableName).toEqual('When shared show')
|
||||
expect(rfcProps.accessClass.icon).toEqual('icon-eye')
|
||||
expect(rfcProps.accessClass.multiple).toEqual(false)
|
||||
expect(rfcProps.accessClass.info).toEqual('TRANSLATED:The visibility of this event in shared calendars.')
|
||||
expect(rfcProps.accessClass.info).toEqual('The visibility of this event in shared calendars.')
|
||||
expect(rfcProps.accessClass.defaultValue).toEqual('PUBLIC')
|
||||
})
|
||||
expect(rfcProps.accessClass.options).toEqual([
|
||||
{value: 'PUBLIC', label: 'When shared show full event'},
|
||||
{value: 'CONFIDENTIAL', label: 'When shared show only busy'},
|
||||
{value: 'PRIVATE', label: 'When shared hide this event'},
|
||||
])
|
||||
|
||||
it('should provide property info for location', () => {
|
||||
expect(rfcProps.location).toEqual(expect.any(Object))
|
||||
|
||||
expect(rfcProps.location.readableName).toEqual('TRANSLATED:Location')
|
||||
expect(rfcProps.location.placeholder).toEqual('TRANSLATED:Add a location')
|
||||
expect(rfcProps.location.readableName).toEqual('Location')
|
||||
expect(rfcProps.location.placeholder).toEqual('Add a location')
|
||||
expect(rfcProps.location.icon).toEqual('icon-address')
|
||||
expect(rfcProps.location.defaultNumberOfRows).toEqual(undefined)
|
||||
})
|
||||
|
||||
it('should provide property info for description', () => {
|
||||
expect(rfcProps.description).toEqual(expect.any(Object))
|
||||
|
||||
expect(rfcProps.description.readableName).toEqual('TRANSLATED:Description')
|
||||
expect(rfcProps.description.placeholder).toEqual('TRANSLATED:Add a description')
|
||||
expect(rfcProps.description.readableName).toEqual('Description')
|
||||
expect(rfcProps.description.placeholder).toEqual('Add a description')
|
||||
expect(rfcProps.description.icon).toEqual('icon-menu')
|
||||
expect(rfcProps.description.defaultNumberOfRows).toEqual(2)
|
||||
})
|
||||
|
||||
it('should provide property info for status', () => {
|
||||
expect(rfcProps.status).toEqual(expect.any(Object))
|
||||
|
||||
expect(rfcProps.status.readableName).toEqual('TRANSLATED:Status')
|
||||
expect(rfcProps.status.readableName).toEqual('Status')
|
||||
expect(rfcProps.status.icon).toEqual('icon-checkmark')
|
||||
expect(rfcProps.status.multiple).toEqual(false)
|
||||
expect(rfcProps.status.info).toEqual('TRANSLATED:Confirmation about the overall status of the event.')
|
||||
expect(rfcProps.status.info).toEqual('Confirmation about the overall status of the event.')
|
||||
expect(rfcProps.status.defaultValue).toEqual('CONFIRMED')
|
||||
})
|
||||
expect(rfcProps.status.options).toEqual([
|
||||
{ value: 'CONFIRMED', label: 'Confirmed' },
|
||||
{ value: 'TENTATIVE', label: 'Tentative' },
|
||||
{ value: 'CANCELLED', label: 'Cancelled' },
|
||||
])
|
||||
|
||||
it('should provide property info for timeTransparency', () => {
|
||||
expect(rfcProps.timeTransparency).toEqual(expect.any(Object))
|
||||
|
||||
expect(rfcProps.timeTransparency.readableName).toEqual('TRANSLATED:Show as')
|
||||
expect(rfcProps.timeTransparency.readableName).toEqual('Show as')
|
||||
expect(rfcProps.timeTransparency.icon).toEqual('icon-briefcase')
|
||||
expect(rfcProps.timeTransparency.multiple).toEqual(false)
|
||||
expect(rfcProps.timeTransparency.info).toEqual('TRANSLATED:Take this event into account when calculating free-busy information.')
|
||||
expect(rfcProps.timeTransparency.info).toEqual('Take this event into account when calculating free-busy information.')
|
||||
expect(rfcProps.timeTransparency.defaultValue).toEqual('TRANSPARENT')
|
||||
})
|
||||
expect(rfcProps.timeTransparency.options).toEqual([
|
||||
{ value: 'TRANSPARENT', label: 'Free' },
|
||||
{ value: 'OPAQUE', label: 'Busy' },
|
||||
])
|
||||
|
||||
it('should provide property info for categories', () => {
|
||||
expect(rfcProps.categories).toEqual(expect.any(Object))
|
||||
|
||||
expect(rfcProps.categories.readableName).toEqual('TRANSLATED:Categories')
|
||||
expect(rfcProps.categories.readableName).toEqual('Categories')
|
||||
expect(rfcProps.categories.icon).toEqual('icon-tag')
|
||||
expect(rfcProps.categories.multiple).toEqual(true)
|
||||
expect(rfcProps.categories.info).toEqual('TRANSLATED:Categories help you to structure and organize your events.')
|
||||
expect(rfcProps.categories.placeholder).toEqual('TRANSLATED:Search or add categories')
|
||||
expect(rfcProps.categories.tagPlaceholder).toEqual('TRANSLATED:Add this as a new category')
|
||||
})
|
||||
expect(rfcProps.categories.info).toEqual('Categories help you to structure and organize your events.')
|
||||
expect(rfcProps.categories.placeholder).toEqual('Search or add categories')
|
||||
expect(rfcProps.categories.tagPlaceholder).toEqual('Add this as a new category')
|
||||
expect(rfcProps.categories.options).toEqual(['Category 1', 'Category 2', 'Category 3'])
|
||||
|
||||
it('should provide property info for color', () => {
|
||||
expect(rfcProps.color).toEqual(expect.any(Object))
|
||||
|
||||
expect(rfcProps.color.readableName).toEqual('TRANSLATED:Custom color')
|
||||
expect(rfcProps.color.readableName).toEqual('Custom color')
|
||||
expect(rfcProps.color.multiple).toEqual(false)
|
||||
expect(rfcProps.color.icon).toEqual('icon-color-picker')
|
||||
expect(rfcProps.color.info).toEqual('TRANSLATED:Special color of this event. Overrides the calendar-color.')
|
||||
expect(rfcProps.color.info).toEqual('Special color of this event. Overrides the calendar-color.')
|
||||
|
||||
// expect(translate).toHaveBeenCalledTimes(10)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'When shared show')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'When shared show full event')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'When shared show only busy')
|
||||
expect(translate).toHaveBeenNthCalledWith(4, 'calendar', 'When shared hide this event')
|
||||
expect(translate).toHaveBeenNthCalledWith(5, 'calendar', 'The visibility of this event in shared calendars.')
|
||||
|
||||
expect(translate).toHaveBeenNthCalledWith(6, 'calendar', 'Location')
|
||||
expect(translate).toHaveBeenNthCalledWith(7, 'calendar', 'Add a location')
|
||||
|
||||
expect(translate).toHaveBeenNthCalledWith(8, 'calendar', 'Description')
|
||||
expect(translate).toHaveBeenNthCalledWith(9, 'calendar', 'Add a description')
|
||||
|
||||
expect(translate).toHaveBeenNthCalledWith(10, 'calendar', 'Status')
|
||||
expect(translate).toHaveBeenNthCalledWith(11, 'calendar', 'Confirmed')
|
||||
expect(translate).toHaveBeenNthCalledWith(12, 'calendar', 'Tentative')
|
||||
expect(translate).toHaveBeenNthCalledWith(13, 'calendar', 'Cancelled')
|
||||
expect(translate).toHaveBeenNthCalledWith(14, 'calendar', 'Confirmation about the overall status of the event.')
|
||||
|
||||
expect(translate).toHaveBeenNthCalledWith(15, 'calendar', 'Show as')
|
||||
expect(translate).toHaveBeenNthCalledWith(16, 'calendar', 'Take this event into account when calculating free-busy information.')
|
||||
expect(translate).toHaveBeenNthCalledWith(17, 'calendar', 'Free')
|
||||
expect(translate).toHaveBeenNthCalledWith(18, 'calendar', 'Busy')
|
||||
|
||||
expect(translate).toHaveBeenNthCalledWith(19, 'calendar', 'Categories')
|
||||
expect(translate).toHaveBeenNthCalledWith(20, 'calendar', 'Categories help you to structure and organize your events.')
|
||||
expect(translate).toHaveBeenNthCalledWith(21, 'calendar', 'Search or add categories')
|
||||
expect(translate).toHaveBeenNthCalledWith(22, 'calendar', 'Add this as a new category')
|
||||
|
||||
expect(translate).toHaveBeenNthCalledWith(23, 'calendar', 'Custom color')
|
||||
expect(translate).toHaveBeenNthCalledWith(24, 'calendar', 'Special color of this event. Overrides the calendar-color.')
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('services/colorService test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
})
|
||||
|
||||
})
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('services/defaultColor test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
})
|
||||
|
||||
})
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('services/loggerService test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
})
|
||||
|
||||
})
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('services/productInformationProvider test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
})
|
||||
|
||||
})
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2019 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('services/settingsService test suite', () => {
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
})
|
||||
|
||||
})
|
|
@ -20,14 +20,28 @@
|
|||
*
|
||||
*/
|
||||
import getIllustrationForTitle from "../../../../src/utils/illustration.js";
|
||||
import { imagePath } from '@nextcloud/router'
|
||||
jest.mock('@nextcloud/router')
|
||||
|
||||
describe('utils/illustration test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
imagePath.mockClear()
|
||||
})
|
||||
|
||||
it('should return a matching illustration', () => {
|
||||
imagePath.mockImplementation((app, image) => 'imagePath###' + app + '###' + image)
|
||||
|
||||
expect(getIllustrationForTitle('Watch movie with Jane')).toEqual('imagePath###calendar###illustrations/movie_night')
|
||||
expect(getIllustrationForTitle('Take time to relax')).toEqual('imagePath###calendar###illustrations/relaxation')
|
||||
expect(getIllustrationForTitle('Give presentation about calendar')).toEqual('imagePath###calendar###illustrations/presentation')
|
||||
|
||||
expect(getIllustrationForTitle('ABC', ['Watch', 'movie'])).toEqual('imagePath###calendar###illustrations/movie_night')
|
||||
|
||||
expect(imagePath).toHaveBeenCalledTimes(4)
|
||||
expect(imagePath).toHaveBeenNthCalledWith(1, 'calendar', 'illustrations/movie_night')
|
||||
expect(imagePath).toHaveBeenNthCalledWith(2, 'calendar', 'illustrations/relaxation')
|
||||
expect(imagePath).toHaveBeenNthCalledWith(3, 'calendar', 'illustrations/presentation')
|
||||
expect(imagePath).toHaveBeenNthCalledWith(4, 'calendar', 'illustrations/movie_night')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -19,15 +19,16 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import {
|
||||
getConfigValueFromHiddenInput,
|
||||
getLinkToConfig
|
||||
} from '../../../../src/utils/settings.js'
|
||||
|
||||
import { getConfigValueFromHiddenInput, getLinkToConfig } from '../../../../src/utils/settings.js'
|
||||
import { linkTo } from '@nextcloud/router'
|
||||
jest.mock('@nextcloud/router')
|
||||
|
||||
describe('utils/settings test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
linkTo.mockClear()
|
||||
})
|
||||
|
||||
it('should read a config value from DOM', () => {
|
||||
document.body.innerHTML = `
|
||||
<input id="config-first-day" value="1" />
|
||||
|
@ -40,7 +41,13 @@ describe('utils/settings test suite', () => {
|
|||
})
|
||||
|
||||
it('should generate a link to the config api', () => {
|
||||
expect(getLinkToConfig('view')).toEqual('linkTo###calendar###index.php/v1/config/view')
|
||||
expect(getLinkToConfig('weekends')).toEqual('linkTo###calendar###index.php/v1/config/weekends')
|
||||
linkTo.mockImplementation(() => 'baseurl:')
|
||||
|
||||
expect(getLinkToConfig('view')).toEqual('baseurl:/v1/config/view')
|
||||
expect(getLinkToConfig('weekends')).toEqual('baseurl:/v1/config/weekends')
|
||||
|
||||
expect(linkTo).toHaveBeenCalledTimes(2)
|
||||
expect(linkTo).toHaveBeenNthCalledWith(1, 'calendar', 'index.php')
|
||||
expect(linkTo).toHaveBeenNthCalledWith(2, 'calendar', 'index.php')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -23,12 +23,20 @@ import {
|
|||
getSortedTimezoneList,
|
||||
getReadableTimezoneName
|
||||
} from '../../../../src/utils/timezone.js'
|
||||
import { translate } from '@nextcloud/l10n'
|
||||
|
||||
jest.mock('@nextcloud/l10n')
|
||||
|
||||
describe('utils/timezone test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
translate.mockClear()
|
||||
})
|
||||
|
||||
it('should sort a timezone list', () => {
|
||||
translate
|
||||
.mockImplementation((app, str) => str)
|
||||
|
||||
const sorted = getSortedTimezoneList([
|
||||
'Europe/Berlin',
|
||||
'Europe/Amsterdam',
|
||||
|
@ -43,7 +51,7 @@ describe('utils/timezone test suite', () => {
|
|||
label: 'ABC',
|
||||
timezoneId: 'id123'
|
||||
}, {
|
||||
continent: 'TRANSLATED:Global',
|
||||
continent: 'Global',
|
||||
label: 'DEF',
|
||||
timezoneId: 'id456'
|
||||
}])
|
||||
|
@ -82,7 +90,7 @@ describe('utils/timezone test suite', () => {
|
|||
timezoneId: 'id123'
|
||||
}])
|
||||
|
||||
expect(sorted[3].continent).toEqual('TRANSLATED:Global')
|
||||
expect(sorted[3].continent).toEqual('Global')
|
||||
expect(sorted[3].regions).toEqual([{
|
||||
cities: [],
|
||||
label: 'DEF',
|
||||
|
@ -100,6 +108,11 @@ describe('utils/timezone test suite', () => {
|
|||
label: 'Z',
|
||||
timezoneId: 'Z'
|
||||
}])
|
||||
|
||||
expect(translate).toHaveBeenCalledTimes(3)
|
||||
expect(translate).toHaveBeenNthCalledWith(1, 'calendar', 'Global')
|
||||
expect(translate).toHaveBeenNthCalledWith(2, 'calendar', 'Global')
|
||||
expect(translate).toHaveBeenNthCalledWith(3, 'calendar', 'Global')
|
||||
})
|
||||
|
||||
it ('should get a readable timezone name', () => {
|
||||
|
|
|
@ -42,7 +42,7 @@ module.exports = {
|
|||
presets: ['@babel/preset-env']
|
||||
}
|
||||
},
|
||||
exclude: /node_modules\/(?!(p-limit|p-defer|p-queue|p-try|cdav-library))/
|
||||
exclude: /node_modules\/(?!(p-limit|p-defer|p-queue|p-try|cdav-library|calendar-js))/
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
|
|
Loading…
Reference in New Issue