Merge pull request #3001 from tchernobog/feature/default-reminder-setting

Allow user to set default reminder duration for new events
This commit is contained in:
Christoph Wurst 2021-05-07 17:24:53 +02:00 committed by GitHub
commit ead3fac8aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 270 additions and 5 deletions

View File

@ -55,9 +55,24 @@
} }
&--slotDuration, &--slotDuration,
&--defaultReminder {
display: table;
label {
display: table-cell;
min-width: 50%;
vertical-align: middle;
}
.multiselect {
display: table-cell;
width: 50%;
}
}
&--timezone { &--timezone {
width: 100%; width: 100%;
.multiselect { .multiselect {
width: 100%; width: 100%;
} }

View File

@ -120,6 +120,7 @@ class PublicViewController extends Controller {
$defaultSkipPopover = $this->config->getAppValue($this->appName, 'skipPopover', 'yes'); $defaultSkipPopover = $this->config->getAppValue($this->appName, 'skipPopover', 'yes');
$defaultTimezone = $this->config->getAppValue($this->appName, 'timezone', 'automatic'); $defaultTimezone = $this->config->getAppValue($this->appName, 'timezone', 'automatic');
$defaultSlotDuration = $this->config->getAppValue($this->appName, 'slotDuration', '00:30:00'); $defaultSlotDuration = $this->config->getAppValue($this->appName, 'slotDuration', '00:30:00');
$defaultDefaultReminder = $this->config->getAppValue($this->appName, 'defaultReminder', 'none');
$defaultShowTasks = $this->config->getAppValue($this->appName, 'showTasks', 'yes'); $defaultShowTasks = $this->config->getAppValue($this->appName, 'showTasks', 'yes');
$appVersion = $this->config->getAppValue($this->appName, 'installed_version', null); $appVersion = $this->config->getAppValue($this->appName, 'installed_version', null);
@ -134,6 +135,7 @@ class PublicViewController extends Controller {
$this->initialStateService->provideInitialState($this->appName, 'talk_enabled', false); $this->initialStateService->provideInitialState($this->appName, 'talk_enabled', false);
$this->initialStateService->provideInitialState($this->appName, 'timezone', $defaultTimezone); $this->initialStateService->provideInitialState($this->appName, 'timezone', $defaultTimezone);
$this->initialStateService->provideInitialState($this->appName, 'slot_duration', $defaultSlotDuration); $this->initialStateService->provideInitialState($this->appName, 'slot_duration', $defaultSlotDuration);
$this->initialStateService->provideInitialState($this->appName, 'default_reminder', $defaultDefaultReminder);
$this->initialStateService->provideInitialState($this->appName, 'show_tasks', $defaultShowTasks === 'yes'); $this->initialStateService->provideInitialState($this->appName, 'show_tasks', $defaultShowTasks === 'yes');
$this->initialStateService->provideInitialState($this->appName, 'tasks_enabled', false); $this->initialStateService->provideInitialState($this->appName, 'tasks_enabled', false);

View File

@ -87,6 +87,8 @@ class SettingsController extends Controller {
return $this->setEventLimit($value); return $this->setEventLimit($value);
case 'slotDuration': case 'slotDuration':
return $this->setSlotDuration($value); return $this->setSlotDuration($value);
case 'defaultReminder':
return $this->setDefaultReminder($value);
case 'showTasks': case 'showTasks':
return $this->setShowTasks($value); return $this->setShowTasks($value);
default: default:
@ -310,4 +312,31 @@ class SettingsController extends Controller {
return new JSONResponse(); return new JSONResponse();
} }
/**
* sets defaultReminder for user
*
* @param string $value User-selected option for default_reminder in agenda view
* @return JSONResponse
*/
private function setDefaultReminder(string $value):JSONResponse {
if ($value !== 'none' &&
filter_var($value, FILTER_VALIDATE_INT,
['options' => ['max_range' => 0]]) === false) {
return new JSONResponse([], Http::STATUS_UNPROCESSABLE_ENTITY);
}
try {
$this->config->setUserValue(
$this->userId,
$this->appName,
'defaultReminder',
$value
);
} catch (\Exception $e) {
return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
}
return new JSONResponse();
}
} }

View File

@ -94,6 +94,7 @@ class ViewController extends Controller {
$defaultSkipPopover = $this->config->getAppValue($this->appName, 'skipPopover', 'no'); $defaultSkipPopover = $this->config->getAppValue($this->appName, 'skipPopover', 'no');
$defaultTimezone = $this->config->getAppValue($this->appName, 'timezone', 'automatic'); $defaultTimezone = $this->config->getAppValue($this->appName, 'timezone', 'automatic');
$defaultSlotDuration = $this->config->getAppValue($this->appName, 'slotDuration', '00:30:00'); $defaultSlotDuration = $this->config->getAppValue($this->appName, 'slotDuration', '00:30:00');
$defaultDefaultReminder = $this->config->getAppValue($this->appName, 'defaultReminder', 'none');
$defaultShowTasks = $this->config->getAppValue($this->appName, 'showTasks', 'yes'); $defaultShowTasks = $this->config->getAppValue($this->appName, 'showTasks', 'yes');
$appVersion = $this->config->getAppValue($this->appName, 'installed_version', null); $appVersion = $this->config->getAppValue($this->appName, 'installed_version', null);
@ -105,6 +106,7 @@ class ViewController extends Controller {
$skipPopover = $this->config->getUserValue($this->userId, $this->appName, 'skipPopover', $defaultSkipPopover) === 'yes'; $skipPopover = $this->config->getUserValue($this->userId, $this->appName, 'skipPopover', $defaultSkipPopover) === 'yes';
$timezone = $this->config->getUserValue($this->userId, $this->appName, 'timezone', $defaultTimezone); $timezone = $this->config->getUserValue($this->userId, $this->appName, 'timezone', $defaultTimezone);
$slotDuration = $this->config->getUserValue($this->userId, $this->appName, 'slotDuration', $defaultSlotDuration); $slotDuration = $this->config->getUserValue($this->userId, $this->appName, 'slotDuration', $defaultSlotDuration);
$defaultReminder = $this->config->getUserValue($this->userId, $this->appName, 'defaultReminder', $defaultDefaultReminder);
$showTasks = $this->config->getUserValue($this->userId, $this->appName, 'showTasks', $defaultShowTasks) === 'yes'; $showTasks = $this->config->getUserValue($this->userId, $this->appName, 'showTasks', $defaultShowTasks) === 'yes';
$talkEnabled = $this->appManager->isEnabledForUser('spreed'); $talkEnabled = $this->appManager->isEnabledForUser('spreed');
@ -120,6 +122,7 @@ class ViewController extends Controller {
$this->initialStateService->provideInitialState($this->appName, 'talk_enabled', $talkEnabled); $this->initialStateService->provideInitialState($this->appName, 'talk_enabled', $talkEnabled);
$this->initialStateService->provideInitialState($this->appName, 'timezone', $timezone); $this->initialStateService->provideInitialState($this->appName, 'timezone', $timezone);
$this->initialStateService->provideInitialState($this->appName, 'slot_duration', $slotDuration); $this->initialStateService->provideInitialState($this->appName, 'slot_duration', $slotDuration);
$this->initialStateService->provideInitialState($this->appName, 'default_reminder', $defaultReminder);
$this->initialStateService->provideInitialState($this->appName, 'show_tasks', $showTasks); $this->initialStateService->provideInitialState($this->appName, 'show_tasks', $showTasks);
$this->initialStateService->provideInitialState($this->appName, 'tasks_enabled', $tasksEnabled); $this->initialStateService->provideInitialState($this->appName, 'tasks_enabled', $tasksEnabled);

View File

@ -66,7 +66,9 @@
{{ $t('calendar', 'Show week numbers') }} {{ $t('calendar', 'Show week numbers') }}
</ActionCheckbox> </ActionCheckbox>
<li class="settings-fieldset-interior-item settings-fieldset-interior-item--slotDuration"> <li class="settings-fieldset-interior-item settings-fieldset-interior-item--slotDuration">
<label for="slotDuration">{{ $t('calendar', 'Time increments') }}</label>
<Multiselect <Multiselect
:id="slotDuration"
:allow-empty="false" :allow-empty="false"
:options="slotDurationOptions" :options="slotDurationOptions"
:value="selectedDurationOption" :value="selectedDurationOption"
@ -75,6 +77,18 @@
label="label" label="label"
@select="changeSlotDuration" /> @select="changeSlotDuration" />
</li> </li>
<li class="settings-fieldset-interior-item settings-fieldset-interior-item--defaultReminder">
<label for="defaultReminder">{{ $t('calendar', 'Default reminder') }}</label>
<Multiselect
:id="defaultReminder"
:allow-empty="false"
:options="defaultReminderOptions"
:value="selectedDefaultReminderOption"
:disabled="savingDefaultReminder"
track-by="value"
label="label"
@select="changeDefaultReminder" />
</li>
<SettingsTimezoneSelect :is-disabled="loadingCalendars" /> <SettingsTimezoneSelect :is-disabled="loadingCalendars" />
<ActionButton class="settings-fieldset-interior-item" icon="icon-clippy" @click.prevent.stop="copyPrimaryCalDAV"> <ActionButton class="settings-fieldset-interior-item" icon="icon-clippy" @click.prevent.stop="copyPrimaryCalDAV">
{{ $t('calendar', 'Copy primary CalDAV address') }} {{ $t('calendar', 'Copy primary CalDAV address') }}
@ -124,6 +138,8 @@ import {
IMPORT_STAGE_PROCESSING, IMPORT_STAGE_PROCESSING,
} from '../../models/consts.js' } from '../../models/consts.js'
import { getDefaultAlarms } from '../../defaults/defaultAlarmProvider.js'
export default { export default {
name: 'Settings', name: 'Settings',
components: { components: {
@ -148,6 +164,7 @@ export default {
savingTasks: false, savingTasks: false,
savingPopover: false, savingPopover: false,
savingSlotDuration: false, savingSlotDuration: false,
savingDefaultReminder: false,
savingWeekend: false, savingWeekend: false,
savingWeekNumber: false, savingWeekNumber: false,
displayKeyboardShortcuts: false, displayKeyboardShortcuts: false,
@ -164,6 +181,7 @@ export default {
showWeekends: state => state.settings.showWeekends, showWeekends: state => state.settings.showWeekends,
showWeekNumbers: state => state.settings.showWeekNumbers, showWeekNumbers: state => state.settings.showWeekNumbers,
slotDuration: state => state.settings.slotDuration, slotDuration: state => state.settings.slotDuration,
defaultReminder: state => state.settings.defaultReminder,
timezone: state => state.settings.timezone, timezone: state => state.settings.timezone,
locale: (state) => state.settings.momentLocale, locale: (state) => state.settings.momentLocale,
}), }),
@ -209,6 +227,22 @@ export default {
selectedDurationOption() { selectedDurationOption() {
return this.slotDurationOptions.find(o => o.value === this.slotDuration) return this.slotDurationOptions.find(o => o.value === this.slotDuration)
}, },
defaultReminderOptions() {
const defaultAlarms = getDefaultAlarms().map(seconds => {
return {
label: moment.duration(Math.abs(seconds) * 1000).locale(this.locale).humanize(),
value: seconds.toString(),
}
})
return [{
label: this.$t('calendar', 'No reminder'),
value: 'none',
}].concat(defaultAlarms)
},
selectedDefaultReminderOption() {
return this.defaultReminderOptions.find(o => o.value === this.defaultReminder)
},
}, },
methods: { methods: {
async toggleBirthdayEnabled() { async toggleBirthdayEnabled() {
@ -310,6 +344,30 @@ export default {
this.savingSlotDuration = false this.savingSlotDuration = false
} }
}, },
/**
* Updates the setting for the default reminder
*
* @param {Object} option The new selected value
*/
async changeDefaultReminder(option) {
if (!option) {
return
}
// change to loading status
this.savingDefaultReminder = true
try {
await this.$store.dispatch('setDefaultReminder', {
defaultReminder: option.value,
})
this.savingDefaultReminder = false
} catch (error) {
console.error(error)
showError(this.$t('calendar', 'New setting was not saved successfully.'))
this.savingDefaultReminder = false
}
},
/** /**
* Copies the primary CalDAV url to the user's clipboard. * Copies the primary CalDAV url to the user's clipboard.
*/ */

View File

@ -45,6 +45,8 @@ import {
} from '../utils/color.js' } from '../utils/color.js'
import { mapAlarmComponentToAlarmObject } from '../models/alarm.js' import { mapAlarmComponentToAlarmObject } from '../models/alarm.js'
import { getObjectAtRecurrenceId } from '../utils/calendarObject.js' import { getObjectAtRecurrenceId } from '../utils/calendarObject.js'
import logger from '../utils/logger.js'
import settings from './settings.js'
const state = { const state = {
isNew: null, isNew: null,
@ -1430,6 +1432,18 @@ const actions = {
const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate) const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate)
const calendarObjectInstance = mapEventComponentToEventObject(eventComponent) const calendarObjectInstance = mapEventComponentToEventObject(eventComponent)
// Add an alarm if the user set a default one in the settings. If
// not, defaultReminder will not be a number (rather the string "none").
const defaultReminder = parseInt(settings.state.defaultReminder)
if (!isNaN(defaultReminder)) {
commit('addAlarmToCalendarObjectInstance', {
calendarObjectInstance: calendarObjectInstance,
type: 'DISPLAY',
totalSeconds: defaultReminder,
})
logger.debug(`Added defaultReminder (${defaultReminder}s) to newly created event`)
}
commit('setCalendarObjectInstanceForNewEvent', { commit('setCalendarObjectInstanceForNewEvent', {
calendarObject, calendarObject,
calendarObjectInstance, calendarObjectInstance,

View File

@ -38,6 +38,7 @@ const state = {
showWeekNumbers: null, showWeekNumbers: null,
skipPopover: null, skipPopover: null,
slotDuration: null, slotDuration: null,
defaultReminder: null,
tasksEnabled: false, tasksEnabled: false,
timezone: 'automatic', timezone: 'automatic',
// user-defined Nextcloud settings // user-defined Nextcloud settings
@ -102,6 +103,17 @@ const mutations = {
state.slotDuration = slotDuration state.slotDuration = slotDuration
}, },
/**
* Updates the user's preferred defaultReminder
*
* @param {Object} state The Vuex state
* @param {Object} data The destructuring object
* @param {String} data.defaultReminder The new default reminder length
*/
setDefaultReminder(state, { defaultReminder }) {
state.defaultReminder = defaultReminder
},
/** /**
* Updates the user's timezone * Updates the user's timezone
* *
@ -126,11 +138,12 @@ const mutations = {
* @param {Boolean} data.showWeekends Whether or not to display weekends * @param {Boolean} data.showWeekends Whether or not to display weekends
* @param {Boolean} data.skipPopover Whether or not to skip the simple event popover * @param {Boolean} data.skipPopover Whether or not to skip the simple event popover
* @param {String} data.slotDuration The duration of one slot in the agendaView * @param {String} data.slotDuration The duration of one slot in the agendaView
* @param {String} data.defaultReminder The default reminder to set on newly created events
* @param {Boolean} data.talkEnabled Whether or not the talk app is enabled * @param {Boolean} data.talkEnabled Whether or not the talk app is enabled
* @param {Boolean} data.tasksEnabled Whether ot not the tasks app is enabled * @param {Boolean} data.tasksEnabled Whether ot not the tasks app is enabled
* @param {String} data.timezone The timezone to view the calendar in. Either an Olsen timezone or "automatic" * @param {String} data.timezone The timezone to view the calendar in. Either an Olsen timezone or "automatic"
*/ */
loadSettingsFromServer(state, { appVersion, eventLimit, firstRun, showWeekNumbers, showTasks, showWeekends, skipPopover, slotDuration, talkEnabled, tasksEnabled, timezone }) { loadSettingsFromServer(state, { appVersion, eventLimit, firstRun, showWeekNumbers, showTasks, showWeekends, skipPopover, slotDuration, defaultReminder, talkEnabled, tasksEnabled, timezone }) {
logInfo(` logInfo(`
Initial settings: Initial settings:
- AppVersion: ${appVersion} - AppVersion: ${appVersion}
@ -141,6 +154,7 @@ Initial settings:
- ShowWeekends: ${showWeekends} - ShowWeekends: ${showWeekends}
- SkipPopover: ${skipPopover} - SkipPopover: ${skipPopover}
- SlotDuration: ${slotDuration} - SlotDuration: ${slotDuration}
- DefaultReminder: ${defaultReminder}
- TalkEnabled: ${talkEnabled} - TalkEnabled: ${talkEnabled}
- TasksEnabled: ${tasksEnabled} - TasksEnabled: ${tasksEnabled}
- Timezone: ${timezone} - Timezone: ${timezone}
@ -154,6 +168,7 @@ Initial settings:
state.showWeekends = showWeekends state.showWeekends = showWeekends
state.skipPopover = skipPopover state.skipPopover = skipPopover
state.slotDuration = slotDuration state.slotDuration = slotDuration
state.defaultReminder = defaultReminder
state.talkEnabled = talkEnabled state.talkEnabled = talkEnabled
state.tasksEnabled = tasksEnabled state.tasksEnabled = tasksEnabled
state.timezone = timezone state.timezone = timezone
@ -319,6 +334,24 @@ const actions = {
commit('setSlotDuration', { slotDuration }) commit('setSlotDuration', { slotDuration })
}, },
/**
* Updates the user's preferred defaultReminder
*
* @param {Object} vuex The Vuex destructuring object
* @param {Object} vuex.state The Vuex state
* @param {Function} vuex.commit The Vuex commit Function
* @param {Object} data The destructuring object
* @param {String} data.defaultReminder The new default reminder
*/
async setDefaultReminder({ state, commit }, { defaultReminder }) {
if (state.defaultReminder === defaultReminder) {
return
}
await setConfig('defaultReminder', defaultReminder)
commit('setDefaultReminder', { defaultReminder })
},
/** /**
* Updates the user's timezone * Updates the user's timezone
* *

View File

@ -124,6 +124,7 @@ export default {
showWeekends: state => state.settings.showWeekends, showWeekends: state => state.settings.showWeekends,
showWeekNumbers: state => state.settings.showWeekNumbers, showWeekNumbers: state => state.settings.showWeekNumbers,
slotDuration: state => state.settings.slotDuration, slotDuration: state => state.settings.slotDuration,
defaultReminder: state => state.settings.defaultReminder,
showTasks: state => state.settings.showTasks, showTasks: state => state.settings.showTasks,
timezone: state => state.settings.timezone, timezone: state => state.settings.timezone,
modificationCount: state => state.calendarObjects.modificationCount, modificationCount: state => state.calendarObjects.modificationCount,
@ -191,6 +192,7 @@ export default {
showWeekNumbers: loadState('calendar', 'show_week_numbers'), showWeekNumbers: loadState('calendar', 'show_week_numbers'),
skipPopover: loadState('calendar', 'skip_popover'), skipPopover: loadState('calendar', 'skip_popover'),
slotDuration: loadState('calendar', 'slot_duration'), slotDuration: loadState('calendar', 'slot_duration'),
defaultReminder: loadState('calendar', 'default_reminder'),
talkEnabled: loadState('calendar', 'talk_enabled'), talkEnabled: loadState('calendar', 'talk_enabled'),
tasksEnabled: loadState('calendar', 'tasks_enabled'), tasksEnabled: loadState('calendar', 'tasks_enabled'),
timezone: loadState('calendar', 'timezone'), timezone: loadState('calendar', 'timezone'),

View File

@ -56,6 +56,7 @@ describe('store/settings test suite', () => {
showWeekNumbers: null, showWeekNumbers: null,
skipPopover: null, skipPopover: null,
slotDuration: null, slotDuration: null,
defaultReminder: null,
tasksEnabled: false, tasksEnabled: false,
timezone: 'automatic', timezone: 'automatic',
momentLocale: 'en', momentLocale: 'en',
@ -131,6 +132,15 @@ describe('store/settings test suite', () => {
expect(state.slotDuration).toEqual('00:30:00') expect(state.slotDuration).toEqual('00:30:00')
}) })
it('should provide a mutation to set the default reminder duration setting', () => {
const state = {
defaultReminder: 'previousValue',
}
settingsStore.mutations.setDefaultReminder(state, { defaultReminder: '-300' })
expect(state.defaultReminder).toEqual('-300')
})
it('should provide a mutation to set the timezone setting', () => { it('should provide a mutation to set the timezone setting', () => {
const state = { const state = {
timezone: 'previousValue', timezone: 'previousValue',
@ -151,6 +161,7 @@ describe('store/settings test suite', () => {
showWeekNumbers: null, showWeekNumbers: null,
skipPopover: null, skipPopover: null,
slotDuration: null, slotDuration: null,
defaultReminder: null,
tasksEnabled: false, tasksEnabled: false,
timezone: 'automatic', timezone: 'automatic',
momentLocale: 'en', momentLocale: 'en',
@ -166,6 +177,7 @@ describe('store/settings test suite', () => {
showWeekends: true, showWeekends: true,
skipPopover: true, skipPopover: true,
slotDuration: '00:30:00', slotDuration: '00:30:00',
defaultReminder: '-600',
talkEnabled: false, talkEnabled: false,
tasksEnabled: true, tasksEnabled: true,
timezone: 'Europe/Berlin', timezone: 'Europe/Berlin',
@ -185,6 +197,7 @@ Initial settings:
- ShowWeekends: true - ShowWeekends: true
- SkipPopover: true - SkipPopover: true
- SlotDuration: 00:30:00 - SlotDuration: 00:30:00
- DefaultReminder: -600
- TalkEnabled: false - TalkEnabled: false
- TasksEnabled: true - TasksEnabled: true
- Timezone: Europe/Berlin - Timezone: Europe/Berlin
@ -198,6 +211,7 @@ Initial settings:
showWeekends: true, showWeekends: true,
skipPopover: true, skipPopover: true,
slotDuration: '00:30:00', slotDuration: '00:30:00',
defaultReminder: '-600',
talkEnabled: false, talkEnabled: false,
tasksEnabled: true, tasksEnabled: true,
timezone: 'Europe/Berlin', timezone: 'Europe/Berlin',
@ -535,6 +549,38 @@ Initial settings:
expect(commit).toHaveBeenNthCalledWith(1, 'setSlotDuration', { slotDuration: '00:30:00' }) expect(commit).toHaveBeenNthCalledWith(1, 'setSlotDuration', { slotDuration: '00:30:00' })
}) })
it('should provide an action to set the default reminder setting - same value', async () => {
expect.assertions(2)
const state = {
defaultReminder: 'none'
}
const commit = jest.fn()
await settingsStore.actions.setDefaultReminder({ state, commit }, { defaultReminder: 'none' })
expect(setConfig).toHaveBeenCalledTimes(0)
expect(commit).toHaveBeenCalledTimes(0)
})
it('should provide an action to set the default reminder setting - different value', async () => {
expect.assertions(4)
const state = {
defaultReminder: 'none'
}
const commit = jest.fn()
setConfig.mockResolvedValueOnce()
await settingsStore.actions.setDefaultReminder({ state, commit }, { defaultReminder: '00:10:00' })
expect(setConfig).toHaveBeenCalledTimes(1)
expect(setConfig).toHaveBeenNthCalledWith(1, 'defaultReminder', '00:10:00')
expect(commit).toHaveBeenCalledTimes(1)
expect(commit).toHaveBeenNthCalledWith(1, 'setDefaultReminder', { defaultReminder: '00:10:00' })
})
it('should provide an action to set the timezone setting - same value', async () => { it('should provide an action to set the timezone setting - same value', async () => {
expect.assertions(2) expect.assertions(2)

View File

@ -63,7 +63,7 @@ class PublicViewControllerTest extends TestCase {
} }
public function testPublicIndexWithBranding():void { public function testPublicIndexWithBranding():void {
$this->config->expects(self::exactly(9)) $this->config->expects(self::exactly(10))
->method('getAppValue') ->method('getAppValue')
->willReturnMap([ ->willReturnMap([
['calendar', 'eventLimit', 'yes', 'no'], ['calendar', 'eventLimit', 'yes', 'no'],
@ -73,6 +73,7 @@ class PublicViewControllerTest extends TestCase {
['calendar', 'skipPopover', 'yes', 'yes'], ['calendar', 'skipPopover', 'yes', 'yes'],
['calendar', 'timezone', 'automatic', 'defaultTimezone'], ['calendar', 'timezone', 'automatic', 'defaultTimezone'],
['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'], ['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'],
['calendar', 'defaultReminder', 'none', 'defaultDefaultReminder'],
['calendar', 'showTasks', 'yes', 'yes'], ['calendar', 'showTasks', 'yes', 'yes'],
['calendar', 'installed_version', null, '1.0.0'] ['calendar', 'installed_version', null, '1.0.0']
]); ]);
@ -99,7 +100,7 @@ class PublicViewControllerTest extends TestCase {
->with('imagePath456') ->with('imagePath456')
->willReturn('absoluteImagePath456'); ->willReturn('absoluteImagePath456');
$this->initialStateService->expects(self::exactly(12)) $this->initialStateService->expects(self::exactly(13))
->method('provideInitialState') ->method('provideInitialState')
->withConsecutive( ->withConsecutive(
['calendar', 'app_version', '1.0.0'], ['calendar', 'app_version', '1.0.0'],
@ -112,6 +113,7 @@ class PublicViewControllerTest extends TestCase {
['calendar', 'talk_enabled', false], ['calendar', 'talk_enabled', false],
['calendar', 'timezone', 'defaultTimezone'], ['calendar', 'timezone', 'defaultTimezone'],
['calendar', 'slot_duration', 'defaultSlotDuration'], ['calendar', 'slot_duration', 'defaultSlotDuration'],
['calendar', 'default_reminder', 'defaultDefaultReminder'],
['calendar', 'show_tasks', true], ['calendar', 'show_tasks', true],
['calendar', 'tasks_enabled', false] ['calendar', 'tasks_enabled', false]
); );
@ -138,6 +140,7 @@ class PublicViewControllerTest extends TestCase {
['calendar', 'skipPopover', 'yes', 'yes'], ['calendar', 'skipPopover', 'yes', 'yes'],
['calendar', 'timezone', 'automatic', 'defaultTimezone'], ['calendar', 'timezone', 'automatic', 'defaultTimezone'],
['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'], ['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'],
['calendar', 'defaultReminder', 'none', 'defaultDefaultReminder'],
['calendar', 'showTasks', 'yes', 'defaultShowTasks'], ['calendar', 'showTasks', 'yes', 'defaultShowTasks'],
['calendar', 'installed_version', null, '1.0.0'] ['calendar', 'installed_version', null, '1.0.0']
]); ]);
@ -163,7 +166,7 @@ class PublicViewControllerTest extends TestCase {
->with('imagePath456') ->with('imagePath456')
->willReturn('absoluteImagePath456'); ->willReturn('absoluteImagePath456');
$this->initialStateService->expects(self::exactly(12)) $this->initialStateService->expects(self::exactly(13))
->method('provideInitialState') ->method('provideInitialState')
->withConsecutive( ->withConsecutive(
['calendar', 'app_version', '1.0.0'], ['calendar', 'app_version', '1.0.0'],
@ -176,6 +179,7 @@ class PublicViewControllerTest extends TestCase {
['calendar', 'talk_enabled', false], ['calendar', 'talk_enabled', false],
['calendar', 'timezone', 'defaultTimezone'], ['calendar', 'timezone', 'defaultTimezone'],
['calendar', 'slot_duration', 'defaultSlotDuration'], ['calendar', 'slot_duration', 'defaultSlotDuration'],
['calendar', 'default_reminder', 'defaultDefaultReminder'],
['calendar', 'show_tasks', false], ['calendar', 'show_tasks', false],
['calendar', 'tasks_enabled', false] ['calendar', 'tasks_enabled', false]
); );

View File

@ -370,6 +370,59 @@ class SettingsControllerTest extends TestCase {
$this->assertEquals(500, $actual->getStatus()); $this->assertEquals(500, $actual->getStatus());
} }
/**
* @param string $value
* @param int $expectedStatusCode
*
* @dataProvider setDefaultReminderWithAllowedValueDataProvider
*/
public function testSetDefaultReminderWithAllowedValue(string $value,
int $expectedStatusCode):void {
if ($expectedStatusCode === 200) {
$this->config->expects($this->once())
->method('setUserValue')
->with('user123', $this->appName, 'defaultReminder', $value);
}
$actual = $this->controller->setConfig('defaultReminder', $value);
$this->assertInstanceOf('OCP\AppFramework\Http\JSONResponse', $actual);
$this->assertEquals([], $actual->getData());
$this->assertEquals($expectedStatusCode, $actual->getStatus());
}
public function setDefaultReminderWithAllowedValueDataProvider():array {
return [
['none', 200],
['-0', 200],
['0', 200],
['-300', 200],
['-600', 200],
['-900', 200],
['-1200', 200],
['-2400', 200],
['-2400', 200],
['not-none', 422],
['NaN', 422],
['0.1', 422],
['1', 422],
['300', 422],
];
}
public function testSetDefaultReminderWithException():void {
$this->config->expects($this->once())
->method('setUserValue')
->with('user123', $this->appName, 'defaultReminder', 'none')
->will($this->throwException(new \Exception));
$actual = $this->controller->setConfig('defaultReminder', 'none');
$this->assertInstanceOf('OCP\AppFramework\Http\JSONResponse', $actual);
$this->assertEquals([], $actual->getData());
$this->assertEquals(500, $actual->getStatus());
}
public function testSetNotExistingConfig():void { public function testSetNotExistingConfig():void {
$actual = $this->controller->setConfig('foo', 'bar'); $actual = $this->controller->setConfig('foo', 'bar');

View File

@ -78,6 +78,7 @@ class ViewControllerTest extends TestCase {
['calendar', 'skipPopover', 'no', 'defaultSkipPopover'], ['calendar', 'skipPopover', 'no', 'defaultSkipPopover'],
['calendar', 'timezone', 'automatic', 'defaultTimezone'], ['calendar', 'timezone', 'automatic', 'defaultTimezone'],
['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'], ['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'],
['calendar', 'defaultReminder', 'none', 'defaultDefaultReminder'],
['calendar', 'showTasks', 'yes', 'defaultShowTasks'], ['calendar', 'showTasks', 'yes', 'defaultShowTasks'],
['calendar', 'installed_version', null, '1.0.0'], ['calendar', 'installed_version', null, '1.0.0'],
]); ]);
@ -92,6 +93,7 @@ class ViewControllerTest extends TestCase {
['user123', 'calendar', 'skipPopover', 'defaultSkipPopover', 'yes'], ['user123', 'calendar', 'skipPopover', 'defaultSkipPopover', 'yes'],
['user123', 'calendar', 'timezone', 'defaultTimezone', 'Europe/Berlin'], ['user123', 'calendar', 'timezone', 'defaultTimezone', 'Europe/Berlin'],
['user123', 'calendar', 'slotDuration', 'defaultSlotDuration', '00:15:00'], ['user123', 'calendar', 'slotDuration', 'defaultSlotDuration', '00:15:00'],
['user123', 'calendar', 'defaultReminder', 'defaultDefaultReminder', '00:10:00'],
['user123', 'calendar', 'showTasks', 'defaultShowTasks', '00:15:00'], ['user123', 'calendar', 'showTasks', 'defaultShowTasks', '00:15:00'],
]); ]);
$this->appManager $this->appManager
@ -114,6 +116,7 @@ class ViewControllerTest extends TestCase {
['calendar', 'talk_enabled', true], ['calendar', 'talk_enabled', true],
['calendar', 'timezone', 'Europe/Berlin'], ['calendar', 'timezone', 'Europe/Berlin'],
['calendar', 'slot_duration', '00:15:00'], ['calendar', 'slot_duration', '00:15:00'],
['calendar', 'default_reminder', '00:10:00'],
['calendar', 'show_tasks', false], ['calendar', 'show_tasks', false],
['calendar', 'tasks_enabled', true] ['calendar', 'tasks_enabled', true]
); );
@ -143,6 +146,7 @@ class ViewControllerTest extends TestCase {
['calendar', 'skipPopover', 'no', 'defaultSkipPopover'], ['calendar', 'skipPopover', 'no', 'defaultSkipPopover'],
['calendar', 'timezone', 'automatic', 'defaultTimezone'], ['calendar', 'timezone', 'automatic', 'defaultTimezone'],
['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'], ['calendar', 'slotDuration', '00:30:00', 'defaultSlotDuration'],
['calendar', 'defaultReminder', 'none', 'defaultDefaultReminder'],
['calendar', 'showTasks', 'yes', 'defaultShowTasks'], ['calendar', 'showTasks', 'yes', 'defaultShowTasks'],
['calendar', 'installed_version', null, '1.0.0'], ['calendar', 'installed_version', null, '1.0.0'],
]); ]);
@ -157,6 +161,7 @@ class ViewControllerTest extends TestCase {
['user123', 'calendar', 'skipPopover', 'defaultSkipPopover', 'yes'], ['user123', 'calendar', 'skipPopover', 'defaultSkipPopover', 'yes'],
['user123', 'calendar', 'timezone', 'defaultTimezone', 'Europe/Berlin'], ['user123', 'calendar', 'timezone', 'defaultTimezone', 'Europe/Berlin'],
['user123', 'calendar', 'slotDuration', 'defaultSlotDuration', '00:15:00'], ['user123', 'calendar', 'slotDuration', 'defaultSlotDuration', '00:15:00'],
['user123', 'calendar', 'defaultReminder', 'defaultDefaultReminder', '00:10:00'],
['user123', 'calendar', 'showTasks', 'defaultShowTasks', '00:15:00'], ['user123', 'calendar', 'showTasks', 'defaultShowTasks', '00:15:00'],
]); ]);
$this->appManager $this->appManager
@ -179,6 +184,7 @@ class ViewControllerTest extends TestCase {
['calendar', 'talk_enabled', true], ['calendar', 'talk_enabled', true],
['calendar', 'timezone', 'Europe/Berlin'], ['calendar', 'timezone', 'Europe/Berlin'],
['calendar', 'slot_duration', '00:15:00'], ['calendar', 'slot_duration', '00:15:00'],
['calendar', 'default_reminder', '00:10:00'],
['calendar', 'show_tasks', false], ['calendar', 'show_tasks', false],
['calendar', 'tasks_enabled', false] ['calendar', 'tasks_enabled', false]
); );