This commit is contained in:
parent
9331b06e04
commit
176d23aa4b
|
@ -46,7 +46,7 @@ from django.utils.functional import cached_property
|
|||
from django.utils.html import format_html
|
||||
from django.utils.safestring import SafeString
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ngettext
|
||||
from django.utils.translation import ngettext, pgettext
|
||||
from django.views.generic import (
|
||||
CreateView,
|
||||
DayArchiveView,
|
||||
|
@ -740,6 +740,11 @@ class ResourceAddView(CreateView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-resource-view', kwargs={'pk': self.object.id})
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request, comment=pgettext('snapshot', 'created'))
|
||||
return response
|
||||
|
||||
|
||||
resource_add = ResourceAddView.as_view()
|
||||
|
||||
|
@ -757,6 +762,11 @@ class ResourceEditView(UpdateView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-resource-view', kwargs={'pk': self.object.id})
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request)
|
||||
return response
|
||||
|
||||
|
||||
resource_edit = ResourceEditView.as_view()
|
||||
|
||||
|
@ -773,6 +783,10 @@ class ResourceDeleteView(DeleteView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-resource-list')
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
self.get_object().take_snapshot(request=self.request, deletion=True)
|
||||
return super().post(*args, **kwargs)
|
||||
|
||||
|
||||
resource_delete = ResourceDeleteView.as_view()
|
||||
|
||||
|
@ -811,6 +825,11 @@ class CategoryAddView(CreateView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-category-list')
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request, comment=pgettext('snapshot', 'created'))
|
||||
return response
|
||||
|
||||
|
||||
category_add = CategoryAddView.as_view()
|
||||
|
||||
|
@ -828,6 +847,11 @@ class CategoryEditView(UpdateView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-category-list')
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request)
|
||||
return response
|
||||
|
||||
|
||||
category_edit = CategoryEditView.as_view()
|
||||
|
||||
|
@ -844,6 +868,10 @@ class CategoryDeleteView(DeleteView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-category-list')
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
self.get_object().take_snapshot(request=self.request, deletion=True)
|
||||
return super().post(*args, **kwargs)
|
||||
|
||||
|
||||
category_delete = CategoryDeleteView.as_view()
|
||||
|
||||
|
@ -882,6 +910,11 @@ class EventsTypeAddView(CreateView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-events-type-list')
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request, comment=pgettext('snapshot', 'created'))
|
||||
return response
|
||||
|
||||
|
||||
events_type_add = EventsTypeAddView.as_view()
|
||||
|
||||
|
@ -926,6 +959,7 @@ class EventsTypeEditView(UpdateView):
|
|||
continue
|
||||
self.object.custom_fields.append(sub_data)
|
||||
self.object.save()
|
||||
self.object.take_snapshot(request=self.request)
|
||||
return response
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
@ -975,6 +1009,7 @@ class EventsTypeDeleteView(DeleteView):
|
|||
|
||||
def post(self, *args, **kwargs):
|
||||
if self.can_be_deleted():
|
||||
self.get_object().take_snapshot(request=self.request, deletion=True)
|
||||
return super().post(*args, **kwargs)
|
||||
raise PermissionDenied()
|
||||
|
||||
|
@ -1003,6 +1038,7 @@ class AgendaAddView(CreateView):
|
|||
if self.object.kind == 'events':
|
||||
desk = Desk.objects.create(agenda=self.object, slug='_exceptions_holder')
|
||||
desk.import_timeperiod_exceptions_from_settings()
|
||||
self.object.take_snapshot(request=self.request, comment=pgettext('snapshot', 'created'))
|
||||
return result
|
||||
|
||||
|
||||
|
@ -1110,6 +1146,8 @@ class AgendasImportView(FormView):
|
|||
|
||||
global_noop = True
|
||||
for obj_name, obj_results in results.items():
|
||||
for obj in obj_results['all']:
|
||||
obj.take_snapshot(request=self.request, comment=_('imported'))
|
||||
if obj_results['all']:
|
||||
global_noop = False
|
||||
count = len(obj_results['created'])
|
||||
|
@ -1205,12 +1243,18 @@ class AgendaEditView(ManagedAgendaMixin, UpdateView):
|
|||
title = _('Edit Agenda')
|
||||
model = Agenda
|
||||
form_class = AgendaEditForm
|
||||
comment = None
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['title'] = self.title
|
||||
return context
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.agenda.take_snapshot(request=self.request, comment=self.comment)
|
||||
return response
|
||||
|
||||
|
||||
agenda_edit = AgendaEditView.as_view()
|
||||
|
||||
|
@ -1219,6 +1263,7 @@ class AgendaBookingDelaysView(AgendaEditView):
|
|||
form_class = AgendaBookingDelaysForm
|
||||
title = _('Configure booking delays')
|
||||
tab_anchor = 'delays'
|
||||
comment = _('changed booking delays')
|
||||
|
||||
|
||||
agenda_booking_delays = AgendaBookingDelaysView.as_view()
|
||||
|
@ -1228,6 +1273,7 @@ class AgendaRolesView(AgendaEditView):
|
|||
form_class = AgendaRolesForm
|
||||
title = _('Configure roles')
|
||||
tab_anchor = 'permissions'
|
||||
comment = _('changed roles')
|
||||
|
||||
|
||||
agenda_roles = AgendaRolesView.as_view()
|
||||
|
@ -1237,6 +1283,7 @@ class AgendaDisplaySettingsView(AgendaEditView):
|
|||
form_class = AgendaDisplaySettingsForm
|
||||
title = _('Configure display options')
|
||||
tab_anchor = 'display-options'
|
||||
comment = _('changed display options')
|
||||
|
||||
def set_agenda(self, **kwargs):
|
||||
self.agenda = get_object_or_404(Agenda.objects.exclude(kind='virtual'), pk=kwargs.get('pk'))
|
||||
|
@ -1252,6 +1299,7 @@ class AgendaBookingCheckSettingsView(AgendaEditView):
|
|||
form_class = AgendaBookingCheckSettingsForm
|
||||
title = _('Configure booking check options')
|
||||
tab_anchor = 'booking-check-options'
|
||||
comment = _('changed booking check options')
|
||||
|
||||
def set_agenda(self, **kwargs):
|
||||
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events')
|
||||
|
@ -1264,6 +1312,7 @@ class AgendaInvoicingSettingsView(AgendaEditView):
|
|||
form_class = AgendaInvoicingSettingsForm
|
||||
title = _('Configure invoicing options')
|
||||
tab_anchor = 'invoicing-options'
|
||||
comment = _('changed invoicing options')
|
||||
|
||||
def set_agenda(self, **kwargs):
|
||||
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events', partial_bookings=True)
|
||||
|
@ -1297,6 +1346,7 @@ class AgendaDeleteView(DeleteView):
|
|||
context = self.get_context_data()
|
||||
if context['cannot_delete']:
|
||||
raise PermissionDenied()
|
||||
self.object.take_snapshot(request=self.request, deletion=True)
|
||||
return super().delete(request, *args, **kwargs)
|
||||
|
||||
|
||||
|
@ -2453,6 +2503,7 @@ class AgendaDuplicate(FormView):
|
|||
|
||||
def form_valid(self, form):
|
||||
self.new_agenda = self.agenda.duplicate(label=form.cleaned_data['label'])
|
||||
self.new_agenda.take_snapshot(request=self.request, comment=pgettext('snapshot', 'created'))
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -2469,6 +2520,11 @@ class AgendaAddEventView(ManagedAgendaMixin, CreateView):
|
|||
model = Event
|
||||
form_class = NewEventForm
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('added event (%s)') % self.object)
|
||||
return response
|
||||
|
||||
|
||||
agenda_add_event = AgendaAddEventView.as_view()
|
||||
|
||||
|
@ -2485,7 +2541,9 @@ class AgendaEventDuplicateView(ManagedAgendaMixin, UpdateView):
|
|||
|
||||
def form_valid(self, form):
|
||||
messages.success(self.request, _('Event successfully duplicated.'))
|
||||
return super().form_valid(form)
|
||||
response = super().form_valid(form)
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('added event (%s)') % self.object)
|
||||
return response
|
||||
|
||||
|
||||
event_duplicate = AgendaEventDuplicateView.as_view()
|
||||
|
@ -2533,7 +2591,10 @@ class AgendaImportEventsView(ManagedAgendaMixin, FormView):
|
|||
_('Event "%s" start date has changed. Do not forget to notify the registrants.')
|
||||
% (event.label or event.slug),
|
||||
)
|
||||
return super().form_valid(form)
|
||||
response = super().form_valid(form)
|
||||
if form.events:
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('imported events'))
|
||||
return response
|
||||
|
||||
|
||||
agenda_import_events = AgendaImportEventsView.as_view()
|
||||
|
@ -2613,6 +2674,10 @@ class AgendaDeskManagementToggleView(ManagedAgendaMixin, View):
|
|||
message = _('Desk global management enabled.')
|
||||
if message:
|
||||
messages.info(self.request, message)
|
||||
if self.agenda.desk_simple_management:
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('enabled individual management'))
|
||||
else:
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('enabled global management'))
|
||||
return HttpResponseRedirect(reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.pk}))
|
||||
|
||||
|
||||
|
@ -2638,6 +2703,11 @@ class AgendaNotificationsSettingsView(ManagedAgendaMixin, UpdateView):
|
|||
self.agenda.event_set.filter(**filter_kwargs).update(**update_kwargs)
|
||||
return AgendaNotificationsSettings.objects.create(agenda=self.agenda)
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('changed notification settings'))
|
||||
return response
|
||||
|
||||
|
||||
agenda_notifications_settings = AgendaNotificationsSettingsView.as_view()
|
||||
|
||||
|
@ -2647,6 +2717,7 @@ class AgendaReminderSettingsView(AgendaEditView):
|
|||
model = AgendaReminderSettings
|
||||
form_class = AgendaReminderForm
|
||||
tab_anchor = 'reminders'
|
||||
comment = _('changed reminder settings')
|
||||
|
||||
def get_object(self):
|
||||
try:
|
||||
|
@ -2958,6 +3029,11 @@ class EventEditView(ManagedAgendaMixin, UpdateView):
|
|||
return reverse('chrono-manager-agenda-settings', kwargs={'pk': self.agenda.id})
|
||||
return reverse('chrono-manager-event-view', kwargs={'pk': self.agenda.id, 'event_pk': self.object.id})
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('changed event (%s)') % self.object)
|
||||
return response
|
||||
|
||||
|
||||
event_edit = EventEditView.as_view()
|
||||
|
||||
|
@ -2981,7 +3057,9 @@ class EventDeleteView(ManagedAgendaMixin, DeleteView):
|
|||
context = self.get_context_data()
|
||||
if context['cannot_delete']:
|
||||
raise PermissionDenied()
|
||||
return super().delete(request, *args, **kwargs)
|
||||
response = super().delete(request, *args, **kwargs)
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('removed event (%s)') % self.object)
|
||||
return response
|
||||
|
||||
def get_success_url(self):
|
||||
if self.request.GET.get('next') == 'settings' or self.request.POST.get('next') == 'settings':
|
||||
|
@ -3175,7 +3253,11 @@ class AgendaAddResourceView(ManagedAgendaMixin, FormView):
|
|||
|
||||
def form_valid(self, form):
|
||||
self.agenda.resources.add(form.cleaned_data['resource'])
|
||||
return super().form_valid(form)
|
||||
response = super().form_valid(form)
|
||||
self.agenda.take_snapshot(
|
||||
request=self.request, comment=_('added resource (%s)') % form.cleaned_data['resource']
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
agenda_add_resource = AgendaAddResourceView.as_view()
|
||||
|
@ -3193,6 +3275,7 @@ class AgendaResourceDeleteView(ManagedAgendaMixin, DeleteView):
|
|||
def delete(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
self.agenda.resources.remove(self.object)
|
||||
self.agenda.take_snapshot(request=request, comment=_('removed resource (%s)') % self.object)
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
|
||||
|
@ -3245,6 +3328,15 @@ class UnavailabilityCalendarToggleView(ManagedDeskMixin, DetailView):
|
|||
message = _('One or several bookings overlap with exceptions.')
|
||||
messages.warning(self.request, message)
|
||||
break
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request,
|
||||
comment=_('enabled unavailability calendar (%s)') % unavailability_calendar,
|
||||
)
|
||||
else:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request,
|
||||
comment=_('disabled unavailability calendar (%s)') % unavailability_calendar,
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(
|
||||
'%s#open:time-periods'
|
||||
|
@ -3261,6 +3353,13 @@ class AgendaAddMeetingTypeView(ManagedAgendaMixin, CreateView):
|
|||
form_class = NewMeetingTypeForm
|
||||
tab_anchor = 'meeting-types'
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.agenda.take_snapshot(
|
||||
request=self.request, comment=_('added meeting type (%s)') % self.object
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
agenda_add_meeting_type = AgendaAddMeetingTypeView.as_view()
|
||||
|
||||
|
@ -3274,7 +3373,11 @@ class MeetingTypeEditView(ManagedAgendaSubobjectMixin, UpdateView):
|
|||
def form_valid(self, form):
|
||||
try:
|
||||
with transaction.atomic():
|
||||
return super().form_valid(form)
|
||||
response = super().form_valid(form)
|
||||
self.object.agenda.take_snapshot(
|
||||
request=self.request, comment=_('changed meeting type (%s)') % self.object
|
||||
)
|
||||
return response
|
||||
except IntegrityError as e:
|
||||
if 'tstzrange_constraint' in str(e):
|
||||
form.add_error(
|
||||
|
@ -3327,6 +3430,9 @@ class MeetingTypeDeleteView(ManagedAgendaSubobjectMixin, DeleteView):
|
|||
self.object.deleted = True
|
||||
self.object.slug += '__deleted__' + str(uuid.uuid4())
|
||||
self.object.save()
|
||||
self.object.agenda.take_snapshot(
|
||||
request=self.request, comment=_('removed meeting type (%s)') % self.object
|
||||
)
|
||||
return HttpResponseRedirect(success_url)
|
||||
|
||||
|
||||
|
@ -3363,6 +3469,7 @@ class AgendaAddTimePeriodView(ManagedDeskMixin, FormView):
|
|||
process_time_period_add_form(form, desk=desk)
|
||||
else:
|
||||
process_time_period_add_form(form, desk=self.desk)
|
||||
self.desk.agenda.take_snapshot(request=self.request, comment=_('added repeating period'))
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
@ -3379,6 +3486,7 @@ class VirtualAgendaAddTimePeriodView(ManagedAgendaMixin, FormView):
|
|||
|
||||
def form_valid(self, form):
|
||||
process_time_period_add_form(form, agenda=self.agenda)
|
||||
self.agenda.take_snapshot(request=self.request, comment=_('added excluded period'))
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
@ -3401,6 +3509,23 @@ class TimePeriodEditView(ManagedTimePeriodMixin, UpdateView):
|
|||
else:
|
||||
return ['chrono/manager_date_time_period_form.html']
|
||||
|
||||
def form_valid(self, form):
|
||||
response = super().form_valid(form)
|
||||
if self.object.desk:
|
||||
if self.object.date:
|
||||
self.object.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('changed unique period (%s)') % self.object
|
||||
)
|
||||
else:
|
||||
self.object.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('changed repeating period (%s)') % self.object
|
||||
)
|
||||
else:
|
||||
self.object.agenda.take_snapshot(
|
||||
request=self.request, comment=_('changed excluded period (%s)') % self.object
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
time_period_edit = TimePeriodEditView.as_view()
|
||||
|
||||
|
@ -3410,14 +3535,31 @@ class TimePeriodDeleteView(ManagedTimePeriodMixin, DeleteView):
|
|||
model = TimePeriod
|
||||
tab_anchor = 'time-periods'
|
||||
|
||||
def take_snapshot(self, time_period):
|
||||
if self.object.desk:
|
||||
if time_period.date:
|
||||
self.time_period.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('removed unique period (%s)') % time_period
|
||||
)
|
||||
else:
|
||||
self.time_period.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('removed repeating period (%s)') % time_period
|
||||
)
|
||||
else:
|
||||
self.object.agenda.take_snapshot(
|
||||
request=self.request, comment=_('removed excluded period (%s)') % self.object
|
||||
)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
time_period = self.get_object()
|
||||
response = super().delete(request, *args, **kwargs)
|
||||
|
||||
if not time_period.desk:
|
||||
self.take_snapshot(time_period)
|
||||
return response
|
||||
|
||||
if not time_period.desk.agenda.desk_simple_management:
|
||||
self.take_snapshot(time_period)
|
||||
return response
|
||||
|
||||
for desk in time_period.desk.agenda.desk_set.exclude(pk=time_period.desk.pk):
|
||||
|
@ -3430,6 +3572,7 @@ class TimePeriodDeleteView(ManagedTimePeriodMixin, DeleteView):
|
|||
if tp is not None:
|
||||
tp.delete()
|
||||
|
||||
self.take_snapshot(time_period)
|
||||
return response
|
||||
|
||||
|
||||
|
@ -3451,9 +3594,12 @@ class AgendaAddDateTimePeriodView(ManagedDeskMixin, FormView):
|
|||
|
||||
if self.desk.agenda.desk_simple_management:
|
||||
for desk in self.desk.agenda.desk_set.all():
|
||||
TimePeriod.objects.create(desk=desk, **create_kwargs)
|
||||
time_period = TimePeriod.objects.create(desk=desk, **create_kwargs)
|
||||
else:
|
||||
TimePeriod.objects.create(desk=self.desk, **create_kwargs)
|
||||
time_period = TimePeriod.objects.create(desk=self.desk, **create_kwargs)
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('added unique period (%s)') % time_period
|
||||
)
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
|
@ -3490,6 +3636,11 @@ class AgendaAddDesk(AgendaDeskMixin, ManagedAgendaMixin, CreateView):
|
|||
def set_agenda(self, **kwargs):
|
||||
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='meetings')
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.agenda.take_snapshot(request=self.request, comment=_('added desk (%s)') % self.object)
|
||||
return response
|
||||
|
||||
|
||||
agenda_add_desk = AgendaAddDesk.as_view()
|
||||
|
||||
|
@ -3503,6 +3654,11 @@ class DeskEditView(AgendaDeskMixin, ManagedAgendaSubobjectMixin, UpdateView):
|
|||
def get_queryset(self):
|
||||
return super().get_queryset().filter(agenda__kind='meetings')
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.agenda.take_snapshot(request=self.request, comment=_('changed desk (%s)') % self.object)
|
||||
return response
|
||||
|
||||
|
||||
desk_edit = DeskEditView.as_view()
|
||||
|
||||
|
@ -3534,7 +3690,9 @@ class DeskDeleteView(AgendaDeskMixin, ManagedAgendaSubobjectMixin, DeleteView):
|
|||
context = self.get_context_data()
|
||||
if context['cannot_delete']:
|
||||
raise PermissionDenied()
|
||||
return super().delete(request, *args, **kwargs)
|
||||
response = super().delete(request, *args, **kwargs)
|
||||
self.object.agenda.take_snapshot(request=self.request, comment=_('removed desk (%s)' % self.object))
|
||||
return response
|
||||
|
||||
|
||||
desk_delete = DeskDeleteView.as_view()
|
||||
|
@ -3550,6 +3708,13 @@ class VirtualMemberAddView(ManagedAgendaMixin, CreateView):
|
|||
kwargs['instance'] = VirtualMember(virtual_agenda=self.agenda)
|
||||
return kwargs
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.agenda.take_snapshot(
|
||||
request=self.request, comment=_('added agenda (%s)') % self.object.real_agenda
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
agenda_add_virtual_member = VirtualMemberAddView.as_view()
|
||||
|
||||
|
@ -3601,6 +3766,7 @@ class AgendaAddTimePeriodExceptionView(ManagedDeskMixin, CreateView):
|
|||
if exception.has_booking_within_time_slot():
|
||||
messages.warning(self.request, _('One or several bookings exists within this time slot.'))
|
||||
break
|
||||
self.desk.agenda.take_snapshot(request=self.request, comment=_('added exception (%s)') % self.object)
|
||||
return result
|
||||
|
||||
|
||||
|
@ -3615,6 +3781,14 @@ class TimePeriodExceptionEditView(ManagedTimePeriodExceptionMixin, UpdateView):
|
|||
|
||||
def form_valid(self, form):
|
||||
result = super().form_valid(form)
|
||||
if not self.desk:
|
||||
self.unavailability_calendar.take_snapshot(
|
||||
request=self.request, comment=_('changed unavailability (%s)') % self.object
|
||||
)
|
||||
else:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('changed exception (%s)') % self.object
|
||||
)
|
||||
messages.info(self.request, _('Exception updated.'))
|
||||
for exception in form.exceptions:
|
||||
if exception.has_booking_within_time_slot():
|
||||
|
@ -3674,6 +3848,14 @@ class TimePeriodExceptionDeleteView(ManagedTimePeriodExceptionMixin, DeleteView)
|
|||
def delete(self, request, *args, **kwargs):
|
||||
exception = self.get_object()
|
||||
response = super().delete(request, *args, **kwargs)
|
||||
if not self.desk:
|
||||
self.unavailability_calendar.take_snapshot(
|
||||
request=self.request, comment=_('removed unavailability (%s)') % self.object
|
||||
)
|
||||
else:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('removed exception (%s)') % self.object
|
||||
)
|
||||
|
||||
if not exception.desk_id:
|
||||
return response
|
||||
|
@ -3754,6 +3936,7 @@ class DeskImportTimePeriodExceptionsView(ManagedAgendaSubobjectMixin, UpdateView
|
|||
return self.form_invalid(form)
|
||||
|
||||
messages.info(self.request, _('Exceptions will be imported in a few minutes.'))
|
||||
desk.agenda.take_snapshot(request=self.request, comment=_('imported exceptions (%s)') % sources[0])
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
@ -3769,7 +3952,15 @@ class TimePeriodExceptionSourceDeleteView(ManagedTimePeriodExceptionMixin, Delet
|
|||
source = self.get_object()
|
||||
response = super().delete(request, *args, **kwargs)
|
||||
|
||||
if not source.desk or not source.desk.agenda.desk_simple_management:
|
||||
if not source.desk:
|
||||
self.unavailability_calendar.take_snapshot(
|
||||
request=self.request, comment=_('removed exceptions %s') % source
|
||||
)
|
||||
return response
|
||||
if not source.desk.agenda.desk_simple_management:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('removed exceptions (%s)') % source
|
||||
)
|
||||
return response
|
||||
|
||||
for desk in source.desk.agenda.desk_set.exclude(pk=source.desk_id):
|
||||
|
@ -3781,6 +3972,7 @@ class TimePeriodExceptionSourceDeleteView(ManagedTimePeriodExceptionMixin, Delet
|
|||
if _source is not None:
|
||||
_source.delete()
|
||||
|
||||
self.desk.agenda.take_snapshot(request=self.request, comment=_('removed exceptions (%s)') % source)
|
||||
return response
|
||||
|
||||
|
||||
|
@ -3814,7 +4006,16 @@ class TimePeriodExceptionSourceReplaceView(ManagedTimePeriodExceptionMixin, Upda
|
|||
return self.form_invalid(form)
|
||||
|
||||
messages.info(self.request, _('Exceptions will be synchronized in a few minutes.'))
|
||||
return super().form_valid(form)
|
||||
response = super().form_valid(form)
|
||||
if self.desk:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('imported exceptions (%s)') % self.object
|
||||
)
|
||||
else:
|
||||
self.unavailability_calendar.take_snapshot(
|
||||
request=self.request, comment=_('imported exceptions (%s)') % self.object
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
time_period_exception_source_replace = TimePeriodExceptionSourceReplaceView.as_view()
|
||||
|
@ -4199,6 +4400,14 @@ class TimePeriodExceptionSourceToggleView(ManagedTimePeriodExceptionMixin, Detai
|
|||
_source.disable()
|
||||
message = _('Exception source %(source)s has been disabled.')
|
||||
|
||||
if was_enabled:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('disabled exceptions (%s)') % source
|
||||
)
|
||||
else:
|
||||
self.desk.agenda.take_snapshot(
|
||||
request=self.request, comment=_('enabled exceptions (%s)') % source
|
||||
)
|
||||
messages.info(self.request, message % {'source': source, 'desk': source.desk})
|
||||
return HttpResponseRedirect(
|
||||
'%s#open:time-periods'
|
||||
|
@ -4279,6 +4488,11 @@ class UnavailabilityCalendarAddView(CreateView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-unavailability-calendar-settings', kwargs={'pk': self.object.id})
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request, comment=pgettext('snapshot', 'created'))
|
||||
return response
|
||||
|
||||
|
||||
unavailability_calendar_add = UnavailabilityCalendarAddView.as_view()
|
||||
|
||||
|
@ -4303,6 +4517,11 @@ class UnavailabilityCalendarEditView(ManagedUnavailabilityCalendarMixin, UpdateV
|
|||
model = UnavailabilityCalendar
|
||||
form_class = UnavailabilityCalendarEditForm
|
||||
|
||||
def form_valid(self, *args, **kwargs):
|
||||
response = super().form_valid(*args, **kwargs)
|
||||
self.object.take_snapshot(request=self.request)
|
||||
return response
|
||||
|
||||
|
||||
unavailability_calendar_edit = UnavailabilityCalendarEditView.as_view()
|
||||
|
||||
|
@ -4319,12 +4538,14 @@ class UnavailabilityCalendarDeleteView(DeleteView):
|
|||
def get_success_url(self):
|
||||
return reverse('chrono-manager-unavailability-calendar-list')
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
def post(self, *args, **kwargs):
|
||||
self.get_object().take_snapshot(request=self.request, deletion=True)
|
||||
try:
|
||||
return super().delete(request, *args, **kwargs)
|
||||
return super().post(*args, **kwargs)
|
||||
except ProtectedError:
|
||||
messages.warning(
|
||||
request, _('This calendar cannot be deleted because it is used by shared custody agendas.')
|
||||
self.request,
|
||||
_('This calendar cannot be deleted because it is used by shared custody agendas.'),
|
||||
)
|
||||
return HttpResponseRedirect(self.get_object().get_absolute_url())
|
||||
|
||||
|
@ -4385,6 +4606,9 @@ class UnavailabilityCalendarAddUnavailabilityView(ManagedUnavailabilityCalendarM
|
|||
|
||||
def form_valid(self, form):
|
||||
result = super().form_valid(form)
|
||||
self.unavailability_calendar.take_snapshot(
|
||||
request=self.request, comment=_('added unavailability (%s)') % self.object
|
||||
)
|
||||
messages.info(self.request, _('Unavailability added.'))
|
||||
if self.object.has_booking_within_time_slot():
|
||||
messages.warning(self.request, _('One or several bookings exists within this time slot.'))
|
||||
|
@ -4437,7 +4661,9 @@ class UnavailabilityCalendarImportUnavailabilitiesView(ManagedUnavailabilityCale
|
|||
return self.form_invalid(form)
|
||||
|
||||
messages.info(self.request, _('Exceptions will be imported in a few minutes.'))
|
||||
return super().form_valid(form)
|
||||
response = super().form_valid(form)
|
||||
self.object.take_snapshot(request=self.request, comment=_('imported exceptions (%s)') % source)
|
||||
return response
|
||||
|
||||
|
||||
unavailability_calendar_import_unavailabilities = UnavailabilityCalendarImportUnavailabilitiesView.as_view()
|
||||
|
|
|
@ -24,6 +24,7 @@ from chrono.agendas.models import (
|
|||
UnavailabilityCalendar,
|
||||
VirtualMember,
|
||||
)
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot
|
||||
from chrono.utils.signature import check_query
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from tests.utils import login
|
||||
|
@ -422,6 +423,7 @@ def test_add_agenda(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
|
||||
agenda = Agenda.objects.get(label='Foo bar')
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
|
||||
resp = resp.follow()
|
||||
assert 'Foo bar' in resp.text
|
||||
|
@ -465,6 +467,7 @@ def test_add_agenda_and_set_role(app, admin_user, manager_user):
|
|||
resp.form['label'] = 'Foo bar'
|
||||
resp.form['kind'] = 'meetings'
|
||||
resp = resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
agenda = Agenda.objects.get(label='Foo bar')
|
||||
assert agenda.desk_set.count() == 1
|
||||
|
@ -474,6 +477,7 @@ def test_add_agenda_and_set_role(app, admin_user, manager_user):
|
|||
resp.form['edit_role'] = manager_user.groups.all()[0].pk
|
||||
resp = resp.form.submit().follow()
|
||||
assert 'Edit Role: Managers' in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
# still only one desk
|
||||
assert agenda.desk_set.count() == 1
|
||||
|
@ -527,6 +531,7 @@ def test_options_agenda(app, admin_user):
|
|||
assert '<h2>Settings' in resp.text
|
||||
agenda_events.refresh_from_db()
|
||||
assert agenda_events.anonymize_delay == 365
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = app.get('/manage/agendas/%s/edit' % agenda_meetings.pk)
|
||||
assert 'default_view' in resp.context['form'].fields
|
||||
|
@ -550,6 +555,7 @@ def test_options_agenda(app, admin_user):
|
|||
|
||||
def test_options_events_agenda_events_type(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/agendas/%s/edit' % agenda.pk)
|
||||
|
@ -577,6 +583,7 @@ def test_options_events_agenda_events_type(app, admin_user):
|
|||
def test_options_events_agenda_delays(settings, app, admin_user):
|
||||
settings.WORKING_DAY_CALENDAR = None
|
||||
agenda = Agenda.objects.create(label='Foo bar')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
assert agenda.minimal_booking_delay == 1
|
||||
app = login(app)
|
||||
url = '/manage/agendas/%s/booking-delays' % agenda.pk
|
||||
|
@ -593,6 +600,7 @@ def test_options_events_agenda_delays(settings, app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.minimal_booking_delay_in_working_days is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_options_events_agenda_lingo_link(settings, app, admin_user):
|
||||
|
@ -624,6 +632,7 @@ def test_options_virtual_agenda_delays(app, admin_user):
|
|||
|
||||
def test_options_agenda_booking_display_options(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
|
||||
app = login(app)
|
||||
|
||||
|
@ -641,6 +650,7 @@ def test_options_agenda_booking_display_options(app, admin_user):
|
|||
agenda.refresh_from_db()
|
||||
assert agenda.booking_user_block_template == '{{ booking.user_name }} Foo Bar'
|
||||
assert agenda.get_booking_user_block_template() == '{{ booking.user_name }} Foo Bar'
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = app.get(url)
|
||||
resp.form['booking_user_block_template'] = ''
|
||||
|
@ -686,6 +696,7 @@ def test_options_agenda_booking_display_options(app, admin_user):
|
|||
|
||||
def test_options_agenda_booking_check_options(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
|
||||
app = login(app)
|
||||
|
||||
|
@ -700,6 +711,7 @@ def test_options_agenda_booking_check_options(app, admin_user):
|
|||
agenda.refresh_from_db()
|
||||
assert agenda.booking_check_filters == 'foo,bar,baz'
|
||||
assert agenda.get_booking_check_filters() == ['foo', 'bar', 'baz']
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# check auto checked
|
||||
assert agenda.mark_event_checked_auto is False
|
||||
|
@ -820,6 +832,7 @@ def test_agenda_options_desk_simple_management(available_mock, app, admin_user):
|
|||
agenda.refresh_from_db()
|
||||
# was changed
|
||||
assert agenda.desk_simple_management is not old_value
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
available_mock.return_value = False
|
||||
for old_value in [True, False]:
|
||||
|
@ -855,6 +868,7 @@ def test_delete_agenda(app, admin_user):
|
|||
assert resp.location.endswith('/manage/')
|
||||
resp = resp.follow()
|
||||
assert 'Foo bar' not in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_delete_busy_agenda(app, admin_user):
|
||||
|
@ -2499,6 +2513,7 @@ def test_agenda_view_event(app, manager_user):
|
|||
def test_agenda_view_edit_event(app, manager_user):
|
||||
test_agenda_view_event(app, manager_user)
|
||||
agenda = Agenda.objects.first()
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
resp = app.get('/manage/agendas/%s/month/2019/12/01/' % agenda.id, status=200)
|
||||
resp = resp.click('xyz')
|
||||
assert 'Options' not in resp.text
|
||||
|
@ -2514,10 +2529,12 @@ def test_agenda_view_edit_event(app, manager_user):
|
|||
resp.form['start_datetime_1'] = agenda.event_set.first().start_datetime.strftime('%H:%M')
|
||||
resp = resp.form.submit(status=302).follow()
|
||||
assert event_url == resp.request.url
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = resp.click('Delete')
|
||||
resp = resp.form.submit()
|
||||
assert Event.objects.count() == 0
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
|
||||
def test_virtual_agenda_add(app, admin_user):
|
||||
|
@ -2531,6 +2548,7 @@ def test_virtual_agenda_add(app, admin_user):
|
|||
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
|
||||
assert agenda.minimal_booking_delay is None
|
||||
assert agenda.maximal_booking_delay is None
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_virtual_agenda_day_view(app, admin_user, manager_user):
|
||||
|
@ -3001,6 +3019,7 @@ def test_virtual_agenda_settings_include(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
|
||||
assert VirtualMember.objects.get(virtual_agenda=agenda, real_agenda=meeting_agenda_1)
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = resp.follow()
|
||||
resp = resp.click('Include Agenda')
|
||||
|
@ -3028,6 +3047,7 @@ def test_virtual_agenda_settings_add_excluded_period(app, admin_user):
|
|||
assert tp.start_time.minute == 0
|
||||
assert tp.end_time.hour == 17
|
||||
assert tp.end_time.minute == 0
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = resp.follow()
|
||||
assert 'Monday / 10 a.m. → 5 p.m.' in resp.text
|
||||
|
@ -3054,6 +3074,7 @@ def test_virtual_agenda_settings_edit_excluded_period(app, admin_user):
|
|||
assert tp.start_time.minute == 0
|
||||
assert tp.end_time.hour == 18
|
||||
assert tp.end_time.minute == 0
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_virtual_agenda_settings_delete_excluded_period(app, admin_user):
|
||||
|
@ -3068,6 +3089,7 @@ def test_virtual_agenda_settings_delete_excluded_period(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
|
||||
assert TimePeriod.objects.count() == 0
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_virtual_agenda_settings_include_incompatible_agenda(app, admin_user):
|
||||
|
@ -3252,6 +3274,7 @@ def test_duplicate_agenda(app, admin_user):
|
|||
resp = resp.click('Duplicate')
|
||||
resp = resp.form.submit()
|
||||
assert Agenda.objects.count() == 2
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
new_agenda = Agenda.objects.exclude(pk=agenda.pk).first()
|
||||
assert resp.location == '/manage/agendas/%s/settings' % new_agenda.pk
|
||||
|
@ -3443,6 +3466,7 @@ def test_agenda_notifications(app, admin_user, managers_group):
|
|||
resp.form['cancelled_event'] = 'use-email-field'
|
||||
resp = resp.form.submit().follow()
|
||||
assert 'Notifications are disabled' in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
agenda.view_role = managers_group
|
||||
agenda.save()
|
||||
|
@ -3519,6 +3543,7 @@ def test_manager_reminders(app, admin_user):
|
|||
resp.form['days_before_email'] = 3
|
||||
resp.form['email_extra_info'] = 'test'
|
||||
resp = resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
assert 'Users will be reminded of their booking by email, 3 days in advance.' in resp.text
|
||||
assert 'reminded of their booking by SMS' not in resp.text
|
||||
|
@ -3757,6 +3782,7 @@ def test_manager_agenda_booking_delays(app, admin_user):
|
|||
assert '42 days' in resp.text
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.maximal_booking_delay == 42
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from chrono.agendas.models import Agenda, Category
|
||||
from chrono.apps.snapshot.models import CategorySnapshot
|
||||
from tests.utils import login
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
@ -28,6 +29,7 @@ def test_add_category(app, admin_user):
|
|||
assert resp.location.endswith('/manage/categories/')
|
||||
assert category.label == 'Foo bar'
|
||||
assert category.slug == 'foo-bar'
|
||||
assert CategorySnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_add_category_as_manager(app, manager_user):
|
||||
|
@ -51,6 +53,7 @@ def test_edit_category(app, admin_user):
|
|||
category.refresh_from_db()
|
||||
assert category.label == 'Foo bar baz'
|
||||
assert category.slug == 'baz'
|
||||
assert CategorySnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_edit_category_as_manager(app, manager_user):
|
||||
|
@ -71,6 +74,7 @@ def test_delete_category(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/categories/')
|
||||
assert Category.objects.exists() is False
|
||||
assert CategorySnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_delete_category_as_manager(app, manager_user):
|
||||
|
|
|
@ -12,6 +12,7 @@ from django.test.utils import CaptureQueriesContext
|
|||
from webtest import Upload
|
||||
|
||||
from chrono.agendas.models import Agenda, Booking, Desk, Event, EventsType, Lease, Subscription
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot
|
||||
from chrono.utils.lingo import CheckType
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from tests.utils import login
|
||||
|
@ -36,6 +37,7 @@ def test_add_event(app, admin_user):
|
|||
resp.form['places'] = 10
|
||||
resp = resp.form.submit()
|
||||
resp = resp.follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
event = Event.objects.get(places=10)
|
||||
assert event.publication_datetime is None
|
||||
assert "This agenda doesn't have any event yet." not in resp.text
|
||||
|
@ -81,6 +83,7 @@ def test_add_recurring_event(app, admin_user):
|
|||
resp.form['frequency'] = 'unique' # not a recurring event
|
||||
resp.form['recurrence_days'] = [2]
|
||||
resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
event = Event.objects.get()
|
||||
assert event.recurrence_days is None
|
||||
|
@ -89,6 +92,7 @@ def test_add_recurring_event(app, admin_user):
|
|||
# add recurring event
|
||||
resp.form['frequency'] = 'recurring'
|
||||
resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
event = Event.objects.get(primary_event__isnull=True)
|
||||
assert event.recurrence_days == [2]
|
||||
|
@ -173,6 +177,7 @@ def test_add_event_third_millennium(app, admin_user):
|
|||
def test_edit_event(settings, app, admin_user):
|
||||
settings.LANGUAGE_CODE = 'fr-fr' # check date initial value format
|
||||
agenda = Agenda.objects.create(label='Foo bar')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
event = Event.objects.create(
|
||||
label='Foo',
|
||||
start_datetime=make_aware(datetime.datetime(2016, 2, 15, 17, 0)),
|
||||
|
@ -214,6 +219,7 @@ def test_edit_event(settings, app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
settings.LANGUAGE_CODE = 'en'
|
||||
resp = resp.follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
assert '/manage/agendas/%s/events/%s/edit' % (agenda.id, event.id) in resp.text
|
||||
assert 'Feb. 16, 2016, 5 p.m.' in resp.text
|
||||
event.refresh_from_db()
|
||||
|
@ -295,6 +301,7 @@ def test_edit_event_with_custom_fields(app, admin_user):
|
|||
],
|
||||
)
|
||||
agenda = Agenda.objects.create(label='Foo', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
|
||||
|
||||
app = login(app)
|
||||
|
@ -376,6 +383,7 @@ def test_edit_recurring_event(settings, app, admin_user, freezer):
|
|||
resp.form['frequency'] = 'recurring'
|
||||
resp.form['recurrence_days'] = [localtime().isoweekday()]
|
||||
resp = resp.form.submit()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# no end date, events are created for the year to come
|
||||
assert Event.objects.count() == 54
|
||||
|
@ -482,6 +490,7 @@ def test_edit_recurring_event(settings, app, admin_user, freezer):
|
|||
def test_edit_recurring_event_with_end_date(settings, app, admin_user, freezer):
|
||||
freezer.move_to('2021-01-12 12:10')
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
event = Event.objects.create(
|
||||
start_datetime=now(), places=10, recurrence_days=list(range(1, 8)), agenda=agenda
|
||||
)
|
||||
|
@ -632,6 +641,7 @@ def test_delete_event(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
|
||||
assert Event.objects.count() == 0
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_delete_busy_event(app, admin_user):
|
||||
|
@ -729,6 +739,7 @@ def test_delete_event_as_manager(app, manager_user):
|
|||
|
||||
def test_export_events(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='Foo bar')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/agendas/%s/export-events' % agenda.id)
|
||||
|
@ -794,6 +805,7 @@ def test_import_events(app, admin_user):
|
|||
resp = resp.form.submit(status=302)
|
||||
assert Event.objects.count() == 1
|
||||
Event.objects.all().delete()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = app.get('/manage/agendas/%s/import-events' % agenda.id, status=200)
|
||||
resp.form['events_csv_file'] = Upload('t.csv', b'xx', 'text/csv')
|
||||
|
@ -1014,7 +1026,7 @@ def test_import_events(app, admin_user):
|
|||
)
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
resp = resp.form.submit(status=302)
|
||||
assert len(ctx.captured_queries) == 22
|
||||
assert len(ctx.captured_queries) == 32
|
||||
assert Event.objects.count() == 5
|
||||
assert set(Event.objects.values_list('slug', flat=True)) == {
|
||||
'labelb',
|
||||
|
@ -1033,8 +1045,8 @@ def test_import_events(app, admin_user):
|
|||
|
||||
|
||||
def test_import_event_nested_quotes(app, admin_user):
|
||||
agenda = Agenda(label='Foo bar')
|
||||
agenda.save()
|
||||
agenda = Agenda.objects.create(label='Foo bar')
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
app = login(app)
|
||||
|
||||
resp = app.get('/manage/agendas/%s/import-events' % agenda.id, status=200)
|
||||
|
@ -3337,6 +3349,7 @@ def test_duplicate_event(app, admin_user):
|
|||
resp = resp.form.submit().follow()
|
||||
|
||||
assert Event.objects.count() == 2
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
duplicate = Event.objects.latest('pk')
|
||||
|
||||
|
@ -3375,6 +3388,7 @@ def test_duplicate_event_creates_recurrences(app, admin_user):
|
|||
resp = resp.form.submit().follow()
|
||||
|
||||
duplicate = Event.objects.filter(primary_event__isnull=True).latest('pk')
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
assert duplicate != recurring_event
|
||||
assert duplicate.recurrences.count() == 6
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from chrono.agendas.models import Agenda, EventsType
|
||||
from chrono.apps.snapshot.models import EventsTypeSnapshot
|
||||
from tests.utils import login
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
@ -29,6 +30,7 @@ def test_add_events_type(app, admin_user):
|
|||
assert events_type.label == 'Foo bar'
|
||||
assert events_type.slug == 'foo-bar'
|
||||
assert events_type.custom_fields == []
|
||||
assert EventsTypeSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_add_events_type_as_manager(app, manager_user):
|
||||
|
@ -58,6 +60,7 @@ def test_edit_events_type(app, admin_user):
|
|||
assert events_type.label == 'Foo bar baz'
|
||||
assert events_type.slug == 'baz2'
|
||||
assert events_type.custom_fields == []
|
||||
assert EventsTypeSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_edit_events_type_custom_fields(app, admin_user):
|
||||
|
@ -160,6 +163,7 @@ def test_delete_events_type(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/events-types/')
|
||||
assert EventsType.objects.exists() is False
|
||||
assert EventsTypeSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_delete_referenced_events_type(app):
|
||||
|
|
|
@ -23,6 +23,7 @@ from chrono.agendas.models import (
|
|||
TimePeriodExceptionSource,
|
||||
UnavailabilityCalendar,
|
||||
)
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot
|
||||
from chrono.manager.forms import TimePeriodExceptionForm
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from tests.utils import login
|
||||
|
@ -42,6 +43,7 @@ def test_add_agenda_exceptions_from_settings(app, admin_user):
|
|||
resp.form['label'] = 'Foo bar'
|
||||
resp.form['kind'] = 'meetings'
|
||||
resp = resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
agenda = Agenda.objects.get(label='Foo bar')
|
||||
assert agenda.desk_set.count() == 1
|
||||
|
@ -58,6 +60,7 @@ def test_add_agenda_exceptions_from_settings(app, admin_user):
|
|||
resp = app.get('/manage/agendas/%s/add-desk' % agenda.pk)
|
||||
resp.form['label'] = 'Desk A'
|
||||
resp = resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
desk = Desk.objects.get(slug='desk-a')
|
||||
assert desk.timeperiodexception_set.exists()
|
||||
|
@ -93,6 +96,7 @@ def test_meetings_agenda_add_time_period_exception(app, admin_user):
|
|||
assert localtime(time_period_exception.end_datetime).strftime(dt_format) == tomorrow.replace(
|
||||
hour=16
|
||||
).strftime(dt_format)
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
# add an exception beyond 2 weeks and make sure it isn't listed
|
||||
resp = resp.click('Add a time period exception', index=0)
|
||||
future = tomorrow + datetime.timedelta(days=15)
|
||||
|
@ -184,6 +188,7 @@ def test_meetings_agenda_add_time_period_exception_all_desks(app, admin_user):
|
|||
assert TimePeriodException.objects.count() == 2
|
||||
assert 'Exceptions added.' in resp.text
|
||||
assert 'One or several bookings exists within this time slot.' in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
exception = TimePeriodException.objects.first()
|
||||
resp = app.get('/manage/time-period-exceptions/%s/edit' % exception.pk)
|
||||
|
@ -267,6 +272,7 @@ def test_meetings_agenda_add_time_period_exception_desk_simple_management(app, a
|
|||
assert 'One or several bookings exists within this time slot.' in resp.text
|
||||
assert TimePeriodException.objects.count() == 2
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_meetings_agenda_edit_time_period_exception(app, admin_user):
|
||||
|
@ -289,6 +295,7 @@ def test_meetings_agenda_edit_time_period_exception(app, admin_user):
|
|||
assert exception.start_datetime == make_aware(datetime.datetime(2018, 12, 16, 8, 0))
|
||||
exception2.refresh_from_db()
|
||||
assert exception2.start_datetime == make_aware(datetime.datetime(2018, 12, 16, 5, 0))
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_meetings_agenda_edit_time_period_exception_overlaps(app, admin_user):
|
||||
|
@ -370,6 +377,7 @@ def test_meetings_agenda_edit_time_period_exception_desk_simple_management(app,
|
|||
assert exception2.start_datetime == make_aware(datetime.datetime(2017, 5, 22, 8, 0))
|
||||
assert exception2.end_datetime == make_aware(datetime.datetime(2017, 5, 22, 17, 30))
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# should not happen: corresponding exception does not exist
|
||||
exception2.delete()
|
||||
|
@ -441,6 +449,7 @@ def test_meetings_agenda_delete_time_period_exception(app, admin_user):
|
|||
resp = resp.form.submit().follow()
|
||||
assert TimePeriodException.objects.count() == 1
|
||||
assert resp.request.url.endswith('/manage/agendas/%d/settings' % agenda.pk)
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# stay on exception list
|
||||
time_period_exception = TimePeriodException.objects.create(
|
||||
|
@ -475,6 +484,7 @@ def test_meetings_agenda_delete_time_period_exception_desk_simple_management(app
|
|||
resp.form.submit()
|
||||
assert TimePeriodException.objects.count() == 0
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# should not happen: corresponding exception does not exist
|
||||
exception = TimePeriodException.objects.create(
|
||||
|
@ -639,6 +649,7 @@ END:VCALENDAR"""
|
|||
assert source.ics_url is None
|
||||
resp = resp.follow()
|
||||
assert 'Exceptions will be imported in a few minutes.' in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2017-12-01')
|
||||
|
@ -698,6 +709,7 @@ END:VCALENDAR"""
|
|||
assert source.ics_filename is None
|
||||
assert source.ics_file.name == ''
|
||||
assert source.ics_url == 'http://example.com/foo.ics'
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
@mock.patch('chrono.agendas.models.requests.get')
|
||||
|
@ -866,6 +878,7 @@ END:VCALENDAR"""
|
|||
desk = Desk.objects.create(agenda=agenda, label='New Desk')
|
||||
desk.duplicate()
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_agenda_import_time_period_exception_file_desk_all_desks(app, admin_user):
|
||||
|
@ -901,6 +914,7 @@ END:VCALENDAR"""
|
|||
desk = Desk.objects.create(agenda=agenda, label='New Desk')
|
||||
desk.duplicate()
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
@mock.patch('chrono.agendas.models.requests.get')
|
||||
|
@ -928,6 +942,7 @@ END:VCALENDAR"""
|
|||
resp = resp.form.submit(status=302)
|
||||
assert TimePeriodException.objects.count() == 2
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_agenda_import_time_period_exception_file_desk_simple_management(app, admin_user):
|
||||
|
@ -952,6 +967,7 @@ END:VCALENDAR"""
|
|||
resp = resp.form.submit(status=302)
|
||||
assert TimePeriodException.objects.count() == 2
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_meetings_agenda_delete_time_period_exception_source(app, admin_user):
|
||||
|
@ -982,6 +998,7 @@ def test_meetings_agenda_delete_time_period_exception_source(app, admin_user):
|
|||
assert TimePeriodExceptionSource.objects.count() == 3
|
||||
assert source1.timeperiodexception_set.count() == 1
|
||||
assert TimePeriodExceptionSource.objects.filter(pk=source2.pk).exists() is False
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_meetings_agenda_delete_time_period_exception_source_desk_simple_management(app, admin_user):
|
||||
|
@ -997,6 +1014,7 @@ def test_meetings_agenda_delete_time_period_exception_source_desk_simple_managem
|
|||
resp.form.submit()
|
||||
assert TimePeriodExceptionSource.objects.count() == 0
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# should not happen: corresponding source does not exist
|
||||
source = TimePeriodExceptionSource.objects.create(desk=desk, ics_url='https://example.com/test.ics')
|
||||
|
@ -1031,6 +1049,7 @@ END:VCALENDAR"""
|
|||
assert source.timeperiodexception_set.count() == 2
|
||||
exceptions = list(source.timeperiodexception_set.order_by('pk'))
|
||||
old_ics_file_path = source.ics_file.path
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
desk2 = desk.duplicate()
|
||||
source2 = desk2.timeperiodexceptionsource_set.get()
|
||||
|
@ -1057,6 +1076,7 @@ END:VCALENDAR"""
|
|||
new_exceptions2 = list(source2.timeperiodexception_set.order_by('pk'))
|
||||
assert exceptions2[0].pk == new_exceptions2[0].pk
|
||||
assert exceptions2[1].pk == new_exceptions2[1].pk
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
|
||||
def test_meetings_agenda_replace_time_period_exception_source_desk_simple_management(app, admin_user):
|
||||
|
@ -1102,6 +1122,7 @@ END:VCALENDAR"""
|
|||
assert source2.ics_filename == 'exceptions-bis.ics'
|
||||
assert os.path.exists(old_ics_file_path2) is False
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# should not happen: corresponding source does not exist
|
||||
source2.delete()
|
||||
|
@ -1265,6 +1286,7 @@ def test_meetings_agenda_time_period_exception_source_from_settings_toggle_desk_
|
|||
assert not desk.timeperiodexception_set.exists()
|
||||
assert not desk2.timeperiodexception_set.exists()
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
app.get('/manage/time-period-exceptions-source/%s/toggle' % source.pk)
|
||||
source.refresh_from_db()
|
||||
|
|
|
@ -12,10 +12,19 @@ from chrono.agendas.models import (
|
|||
Category,
|
||||
Desk,
|
||||
Event,
|
||||
EventsType,
|
||||
MeetingType,
|
||||
Resource,
|
||||
SharedCustodySettings,
|
||||
UnavailabilityCalendar,
|
||||
)
|
||||
from chrono.apps.snapshot.models import (
|
||||
AgendaSnapshot,
|
||||
CategorySnapshot,
|
||||
EventsTypeSnapshot,
|
||||
ResourceSnapshot,
|
||||
UnavailabilityCalendarSnapshot,
|
||||
)
|
||||
from chrono.utils.timezone import now
|
||||
from tests.utils import login
|
||||
|
||||
|
@ -68,6 +77,29 @@ def test_export_site(app, admin_user):
|
|||
assert 'resources' not in site_json
|
||||
assert 'categories' not in site_json
|
||||
|
||||
Category.objects.create(label='cat')
|
||||
Resource.objects.create(label='resource')
|
||||
EventsType.objects.create(label='events-type')
|
||||
resp = app.get('/manage/agendas/export/')
|
||||
resp = resp.form.submit()
|
||||
|
||||
site_text = resp.text
|
||||
site_json = json.loads(site_text)
|
||||
assert len(site_json['agendas']) == 1
|
||||
assert len(site_json['unavailability_calendars']) == 1
|
||||
assert len(site_json['events_types']) == 1
|
||||
assert len(site_json['resources']) == 1
|
||||
assert len(site_json['categories']) == 1
|
||||
resp = app.get('/manage/agendas/import/')
|
||||
resp.form['agendas_json'] = Upload('export.json', site_text.encode('utf-8'), 'application/json')
|
||||
resp = resp.form.submit().follow()
|
||||
assert UnavailabilityCalendar.objects.count() == 1
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
assert CategorySnapshot.objects.count() == 1
|
||||
assert EventsTypeSnapshot.objects.count() == 1
|
||||
assert ResourceSnapshot.objects.count() == 1
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_import_agenda_as_manager(app, manager_user):
|
||||
# open /manage/ access to manager_user, and check agenda import is not
|
||||
|
|
|
@ -16,6 +16,7 @@ from chrono.agendas.models import (
|
|||
TimePeriodExceptionSource,
|
||||
UnavailabilityCalendar,
|
||||
)
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot
|
||||
from chrono.utils.timezone import localtime, now
|
||||
from tests.utils import login
|
||||
|
||||
|
@ -133,6 +134,7 @@ def test_meetings_agenda_add_meeting_type(app, admin_user):
|
|||
assert meeting_type.deleted is False
|
||||
resp = resp.follow()
|
||||
assert 'Blah' in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_meetings_agenda_edit_meeting_type(app, admin_user):
|
||||
|
@ -154,6 +156,7 @@ def test_meetings_agenda_edit_meeting_type(app, admin_user):
|
|||
assert meeting_type.slug == other_meeting_type.slug
|
||||
assert meeting_type.duration == 120
|
||||
assert meeting_type.deleted is False
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# check slug edition
|
||||
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
|
||||
|
@ -211,6 +214,7 @@ def test_meetings_agenda_delete_meeting_type(app, admin_user):
|
|||
meeting_type.refresh_from_db()
|
||||
assert meeting_type.deleted is True
|
||||
assert '__deleted__' in meeting_type.slug
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# meeting type not showing up anymore
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
|
||||
|
@ -233,11 +237,13 @@ def test_meetings_agenda_add_desk(app, admin_user):
|
|||
agenda = Agenda.objects.get(slug='foo-bar')
|
||||
agenda.desk_simple_management = False
|
||||
agenda.save()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
|
||||
resp = resp.click('New Desk')
|
||||
resp.form['label'] = 'Desk A'
|
||||
resp = resp.form.submit().follow()
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
assert Desk.objects.count() == 2
|
||||
desk = Desk.objects.latest('pk')
|
||||
TimePeriod.objects.create(
|
||||
|
@ -291,6 +297,7 @@ def test_meetings_agenda_add_desk_from_another(app, admin_user):
|
|||
assert (
|
||||
new_desk.timeperiodexceptionsource_set.count() == 0
|
||||
) # holidays not automatically added via duplication
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
@override_settings(
|
||||
|
@ -319,6 +326,7 @@ def test_meetings_agenda_add_desk_simple_management(app, admin_user):
|
|||
assert (
|
||||
new_desk.timeperiodexceptionsource_set.count() == 0
|
||||
) # holidays not automatically added via duplication
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# ok if no desks (should not happen)
|
||||
Desk.objects.all().delete()
|
||||
|
@ -350,6 +358,7 @@ def test_meetings_agenda_edit_desk(app, admin_user):
|
|||
desk.refresh_from_db()
|
||||
assert desk.label == 'Desk C'
|
||||
assert desk.slug == other_desk.slug
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# check slug edition
|
||||
resp = app.get('/manage/desks/%s/edit' % desk.pk)
|
||||
|
@ -382,6 +391,7 @@ def test_meetings_agenda_delete_desk(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.pk)
|
||||
assert Desk.objects.count() == 1
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# only one desk
|
||||
app.get('/manage/desks/%s/delete' % desk_b.pk, status=404)
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.db import connection
|
|||
from django.test.utils import CaptureQueriesContext
|
||||
|
||||
from chrono.agendas.models import Agenda, Booking, Desk, Event, MeetingType, Resource, TimePeriod
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot, ResourceSnapshot
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from tests.utils import login
|
||||
|
||||
|
@ -34,6 +35,7 @@ def test_add_resource(app, admin_user):
|
|||
assert resp.location.endswith('/manage/resource/%s/' % resource.pk)
|
||||
assert resource.label == 'Foo bar'
|
||||
assert resource.slug == 'foo-bar'
|
||||
assert ResourceSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_add_resource_as_manager(app, manager_user):
|
||||
|
@ -881,6 +883,7 @@ def test_edit_resource(app, admin_user):
|
|||
resource.refresh_from_db()
|
||||
assert resource.label == 'Foo bar baz'
|
||||
assert resource.slug == 'baz'
|
||||
assert ResourceSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_edit_resource_as_manager(app, manager_user):
|
||||
|
@ -901,6 +904,7 @@ def test_delete_resource(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/resources/')
|
||||
assert Resource.objects.exists() is False
|
||||
assert ResourceSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_delete_resource_as_manager(app, manager_user):
|
||||
|
@ -941,6 +945,7 @@ def test_meetings_agenda_resources(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings#open:resources' % agenda.pk)
|
||||
assert list(agenda.resources.all()) == [resource]
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
resp = resp.follow()
|
||||
assert '/manage/resource/%s/' % resource.pk in resp.text
|
||||
assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) in resp.text
|
||||
|
@ -951,6 +956,7 @@ def test_meetings_agenda_resources(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings#open:resources' % agenda.pk)
|
||||
assert list(agenda.resources.all()) == []
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
resp = resp.follow()
|
||||
assert '/manage/resource/%s/' % resource.pk not in resp.text
|
||||
assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) not in resp.text
|
||||
|
|
|
@ -3,6 +3,7 @@ import datetime
|
|||
import pytest
|
||||
|
||||
from chrono.agendas.models import Agenda, Desk, MeetingType, TimePeriod
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot
|
||||
from tests.utils import login
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
@ -28,6 +29,7 @@ def test_meetings_agenda_add_time_period(app, admin_user):
|
|||
assert TimePeriod.objects.get(desk=desk).weekday_indexes is None
|
||||
assert desk2.timeperiod_set.exists() is False
|
||||
resp = resp.follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# add a second time period
|
||||
resp = resp.click('Add repeating periods', index=0)
|
||||
|
@ -72,6 +74,7 @@ def test_meetings_agenda_add_time_period_desk_simple_management(app, admin_user)
|
|||
resp.form['start_time'] = '10:00'
|
||||
resp.form['end_time'] = '13:00'
|
||||
resp.form.submit()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
assert TimePeriod.objects.filter(desk=desk).count() == 1
|
||||
assert TimePeriod.objects.filter(desk=desk2).count() == 1
|
||||
|
@ -136,6 +139,7 @@ def test_meetings_agenda_edit_time_period(app, admin_user):
|
|||
assert time_period.start_time.hour == 10
|
||||
time_period2.refresh_from_db()
|
||||
assert time_period2.start_time.hour == 9
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = resp.click('Monday / 10 a.m. → noon')
|
||||
resp.form['repeat'] = 'custom'
|
||||
|
@ -182,6 +186,7 @@ def test_meetings_agenda_edit_time_period_desk_simple_management(app, admin_user
|
|||
assert time_period2.start_time.hour == 10
|
||||
assert time_period2.end_time.hour == 11
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# should not happen: corresponding time period does not exist
|
||||
time_period2.delete()
|
||||
|
@ -213,6 +218,7 @@ def test_meetings_agenda_delete_time_period(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
|
||||
assert TimePeriod.objects.count() == 1
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_meetings_agenda_delete_time_period_desk_simple_management(app, admin_user):
|
||||
|
@ -230,6 +236,7 @@ def test_meetings_agenda_delete_time_period_desk_simple_management(app, admin_us
|
|||
resp.form.submit()
|
||||
assert TimePeriod.objects.count() == 0
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# should not happen: corresponding time period does not exist
|
||||
time_period = TimePeriod.objects.create(
|
||||
|
@ -262,6 +269,7 @@ def test_meetings_agenda_date_time_period(app, admin_user):
|
|||
assert TimePeriod.objects.get(desk=desk).end_time.minute == 0
|
||||
assert desk2.timeperiod_set.exists() is False
|
||||
resp = resp.follow()
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# invert start and end
|
||||
resp = resp.click('Add a unique period', index=0)
|
||||
|
@ -301,6 +309,7 @@ def test_meetings_agenda_date_time_period_desk_simple_management(app, admin_user
|
|||
|
||||
assert TimePeriod.objects.filter(desk=desk).count() == 1
|
||||
assert TimePeriod.objects.filter(desk=desk2).count() == 1
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
# edit
|
||||
resp = resp.click('Monday 24')
|
||||
|
|
|
@ -15,6 +15,7 @@ from chrono.agendas.models import (
|
|||
TimePeriodExceptionSource,
|
||||
UnavailabilityCalendar,
|
||||
)
|
||||
from chrono.apps.snapshot.models import AgendaSnapshot, UnavailabilityCalendarSnapshot
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from tests.utils import login
|
||||
|
||||
|
@ -51,6 +52,7 @@ def test_add_unavailability_calendar(app, admin_user):
|
|||
resp = app.get('/manage/unavailability-calendars/')
|
||||
assert 'Foo bar' in resp.text
|
||||
assert 'foo-bar' in resp.text
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_used_unavailability_calendar(app, admin_user):
|
||||
|
@ -83,6 +85,7 @@ def test_edit_unavailability_calendar(app, admin_user):
|
|||
assert 'Bar' in resp.text
|
||||
unavailability_calendar.refresh_from_db()
|
||||
assert unavailability_calendar.label == 'Bar'
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_delete_unavailability_calendar(app, admin_user):
|
||||
|
@ -95,6 +98,7 @@ def test_delete_unavailability_calendar(app, admin_user):
|
|||
resp = resp.follow()
|
||||
assert 'Foo' not in resp.text
|
||||
assert UnavailabilityCalendar.objects.count() == 0
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_unavailability_calendar_add_time_period_exceptions(app, admin_user):
|
||||
|
@ -117,6 +121,7 @@ def test_unavailability_calendar_add_time_period_exceptions(app, admin_user):
|
|||
assert 'Unavailability added.' in resp.text
|
||||
assert 'One or several bookings exists within this time slot.' not in resp.text
|
||||
assert TimePeriodException.objects.count() == 1
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
time_period_exception = TimePeriodException.objects.first()
|
||||
assert time_period_exception.unavailability_calendar == unavailability_calendar
|
||||
|
@ -170,6 +175,7 @@ def test_unavailability_calendar_edit_time_period_exceptions(app, admin_user):
|
|||
assert 'Exception foo' in resp.text
|
||||
time_period_exception.refresh_from_db()
|
||||
assert time_period_exception.label == 'Exception foo'
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
# with an error
|
||||
resp = app.get('/manage/time-period-exceptions/%s/edit' % time_period_exception.pk)
|
||||
|
@ -195,6 +201,7 @@ def test_unavailability_calendar_delete_time_period_exceptions(app, admin_user):
|
|||
resp = resp.form.submit().follow()
|
||||
assert 'Exception foo' not in resp.text
|
||||
assert unavailability_calendar.timeperiodexception_set.count() == 0
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_unavailability_calendar_import_time_period_exception_from_ics(app, admin_user):
|
||||
|
@ -234,6 +241,7 @@ END:VCALENDAR"""
|
|||
assert source.ics_url is None
|
||||
resp = resp.follow()
|
||||
assert 'Exceptions will be imported in a few minutes.' in resp.text
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
@mock.patch('chrono.agendas.models.requests.get')
|
||||
|
@ -295,6 +303,7 @@ def test_unavailability_calendar_delete_time_period_exception_source(app, admin_
|
|||
assert TimePeriodExceptionSource.objects.count() == 1
|
||||
assert source1.timeperiodexception_set.count() == 1
|
||||
assert TimePeriodExceptionSource.objects.filter(pk=source2.pk).exists() is False
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
|
||||
def test_unavailability_calendar_replace_time_period_exception_source(app, admin_user, freezer):
|
||||
|
@ -321,6 +330,7 @@ END:VCALENDAR"""
|
|||
assert source.timeperiodexception_set.count() == 2
|
||||
exceptions = list(source.timeperiodexception_set.order_by('pk'))
|
||||
old_ics_file_path = source.ics_file.path
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 1
|
||||
|
||||
# replace the source
|
||||
resp = app.get('/manage/time-period-exceptions-source/%d/replace' % source.pk)
|
||||
|
@ -335,6 +345,7 @@ END:VCALENDAR"""
|
|||
new_exceptions = list(source.timeperiodexception_set.order_by('pk'))
|
||||
assert exceptions[0].pk != new_exceptions[0].pk
|
||||
assert exceptions[1].pk != new_exceptions[1].pk
|
||||
assert UnavailabilityCalendarSnapshot.objects.count() == 2
|
||||
|
||||
|
||||
@mock.patch('chrono.agendas.models.requests.get')
|
||||
|
@ -402,6 +413,7 @@ def test_unavailability_calendar_in_desk(app, admin_user):
|
|||
resp = app.get(settings_url)
|
||||
assert 'what' in resp.text
|
||||
assert 'One or several bookings overlap with exceptions.' not in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
resp = app.get(exceptions_url)
|
||||
assert 'calendar' in resp.text
|
||||
|
@ -418,6 +430,7 @@ def test_unavailability_calendar_in_desk(app, admin_user):
|
|||
assert 'calendar' in resp.text
|
||||
assert 'enable' in resp.text
|
||||
assert not desk.unavailability_calendars.exists()
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
# info message if some exceptions overlaps with a booking
|
||||
meeting_type = MeetingType.objects.create(label='Meeting Type', agenda=agenda)
|
||||
|
@ -477,11 +490,13 @@ def test_unavailability_calendar_in_desk_desk_simple_management(app, admin_user)
|
|||
assert agenda.is_available_for_simple_management() is True
|
||||
resp = resp.follow()
|
||||
assert 'One or several bookings overlap with exceptions.' in resp.text
|
||||
assert AgendaSnapshot.objects.count() == 1
|
||||
|
||||
app.get('/manage/desk/%s/unavailability-calendar/%s/toggle/' % (desk.pk, unavailability_calendar.pk))
|
||||
assert not desk.unavailability_calendars.exists()
|
||||
assert not desk2.unavailability_calendars.exists()
|
||||
assert agenda.is_available_for_simple_management() is True
|
||||
assert AgendaSnapshot.objects.count() == 2
|
||||
|
||||
# should not happen: unavailability_calendar is not in the correct state
|
||||
desk2.unavailability_calendars.add(unavailability_calendar)
|
||||
|
|
Loading…
Reference in New Issue