Projet

Général

Profil

0004-agendas-is-an-agenda-available-for-desk-simple-manag.patch

Lauréline Guérin, 05 février 2021 10:19

Télécharger (10,3 ko)

Voir les différences:

Subject: [PATCH 04/11] agendas: is an agenda available for desk simple
 management (#48924)

 chrono/agendas/models.py |  47 +++++++++++
 tests/test_agendas.py    | 175 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 222 insertions(+)
chrono/agendas/models.py
560 560
                if e.desk_id == desk.pk or e.unavailability_calendar_id in uc_ids
561 561
            ]
562 562

  
563
    def is_available_for_simple_management(self):
564
        if self.kind != 'meetings':
565
            return False
566

  
567
        desks = self.desk_set.all()
568
        if len(desks) < 2:
569
            # no desk or just one, it's ok
570
            return True
571

  
572
        desk = desks[0]
573

  
574
        period_fields = ['weekday', 'start_time', 'end_time']
575
        exception_fields = ['label', 'start_datetime', 'end_datetime']
576
        source_fields = ['ics_filename', 'ics_url', 'settings_slug', 'enabled']
577
        desk_time_periods = set(desk.timeperiod_set.values_list(*period_fields))
578
        desk_exceptions = set(
579
            desk.timeperiodexception_set.filter(source__isnull=True).values_list(*exception_fields)
580
        )
581
        desk_sources = set(desk.timeperiodexceptionsource_set.values_list(*source_fields))
582
        desk_unavaibility_calendars = set(desk.unavailability_calendars.values_list('pk', flat=True))
583
        for other_desk in desks[1:]:
584
            # compare time periods
585
            other_desk_time_periods = set(other_desk.timeperiod_set.values_list(*period_fields))
586
            if desk_time_periods != other_desk_time_periods:
587
                return False
588

  
589
            # compare exceptions
590
            other_desk_exceptions = set(
591
                other_desk.timeperiodexception_set.filter(source__isnull=True).values_list(*exception_fields)
592
            )
593
            if desk_exceptions != other_desk_exceptions:
594
                return False
595

  
596
            # compare sources
597
            other_desk_sources = set(other_desk.timeperiodexceptionsource_set.values_list(*source_fields))
598
            if desk_sources != other_desk_sources:
599
                return False
600

  
601
            # compare unavailability calendars
602
            other_desk_unavaibility_calendars = set(
603
                other_desk.unavailability_calendars.values_list('pk', flat=True)
604
            )
605
            if desk_unavaibility_calendars != other_desk_unavaibility_calendars:
606
                return False
607

  
608
        return True
609

  
563 610

  
564 611
class VirtualMember(models.Model):
565 612
    """Trough model to link virtual agendas to their real agendas.
tests/test_agendas.py
177 177
    assert category.slug == 'foo-baz-2'
178 178

  
179 179

  
180
def test_agenda_is_available_for_simple_management(settings):
181
    settings.EXCEPTIONS_SOURCES = {
182
        'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},
183
    }
184

  
185
    agenda = Agenda.objects.create(label='Agenda', kind='meetings')
186
    # no desks
187
    assert agenda.is_available_for_simple_management() is True
188

  
189
    # check kind
190
    agenda.kind = 'events'
191
    agenda.save()
192
    assert agenda.is_available_for_simple_management() is False
193
    agenda.kind = 'virtual'
194
    agenda.save()
195
    assert agenda.is_available_for_simple_management() is False
196

  
197
    # only one desk
198
    agenda.kind = 'meetings'
199
    agenda.save()
200
    desk = Desk.objects.create(label='Desk', agenda=agenda)
201
    assert agenda.is_available_for_simple_management() is True
202

  
203
    # create some related data for this desk
204
    time_period = TimePeriod.objects.create(
205
        weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
206
    )
207
    desk.import_timeperiod_exceptions_from_settings(enable=True)
208
    source1 = desk.timeperiodexceptionsource_set.get(settings_slug='holidays')
209
    source2 = TimePeriodExceptionSource.objects.create(desk=desk, ics_url='http://example.com/sample.ics')
210
    source3 = TimePeriodExceptionSource.objects.create(
211
        desk=desk,
212
        ics_filename='sample.ics',
213
        ics_file=ContentFile(ICS_SAMPLE_WITH_DURATION, name='sample.ics'),
214
    )
215
    date_now = now()
216
    exception = TimePeriodException.objects.create(
217
        label='Exception',
218
        desk=desk,
219
        start_datetime=date_now + datetime.timedelta(days=1),
220
        end_datetime=date_now + datetime.timedelta(days=2),
221
    )
222
    unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar')
223
    unavailability_calendar.desks.add(desk)
224
    unavailability_calendar2 = UnavailabilityCalendar.objects.create(label='Calendar 2')
225

  
226
    # still ok
227
    assert agenda.is_available_for_simple_management() is True
228

  
229
    # duplicate the desk twice
230
    desk2 = desk.duplicate()
231
    desk.duplicate()
232

  
233
    # still ok
234
    assert agenda.is_available_for_simple_management() is True
235

  
236
    # changes on time periods
237
    for _desk in [desk, desk2]:
238
        time_period2 = TimePeriod.objects.create(
239
            weekday=2, desk=_desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
240
        )
241
        assert agenda.is_available_for_simple_management() is False
242
        time_period2.delete()
243
        assert agenda.is_available_for_simple_management() is True
244
    time_period.weekday = 2
245
    time_period.save()
246
    assert agenda.is_available_for_simple_management() is False
247
    time_period.weekday = 1
248
    time_period.start_time = datetime.time(10, 1)
249
    time_period.save()
250
    assert agenda.is_available_for_simple_management() is False
251
    time_period.start_time = datetime.time(10, 0)
252
    time_period.end_time = datetime.time(12, 1)
253
    time_period.save()
254
    assert agenda.is_available_for_simple_management() is False
255
    time_period.end_time = datetime.time(12, 0)
256
    time_period.save()
257
    assert agenda.is_available_for_simple_management() is True
258

  
259
    # changes on exceptions
260
    for _desk in [desk, desk2]:
261
        exception2 = TimePeriodException.objects.create(
262
            label='Exception',
263
            desk=_desk,
264
            start_datetime=date_now + datetime.timedelta(days=3),
265
            end_datetime=date_now + datetime.timedelta(days=4),
266
        )
267
        assert agenda.is_available_for_simple_management() is False
268
        exception2.delete()
269
        assert agenda.is_available_for_simple_management() is True
270
    exception.label = 'Exception blah'
271
    exception.save()
272
    assert agenda.is_available_for_simple_management() is False
273
    exception.label = 'Exception'
274
    exception.start_datetime = date_now + datetime.timedelta(days=3)
275
    exception.save()
276
    assert agenda.is_available_for_simple_management() is False
277
    exception.start_datetime = date_now + datetime.timedelta(days=1)
278
    exception.end_datetime = date_now + datetime.timedelta(days=1)
279
    exception.save()
280
    assert agenda.is_available_for_simple_management() is False
281
    exception.end_datetime = date_now + datetime.timedelta(days=2)
282
    exception.save()
283
    assert agenda.is_available_for_simple_management() is True
284
    # exceptions from source are not checked
285
    exception3 = TimePeriodException.objects.create(
286
        label='Exception',
287
        desk=desk,
288
        start_datetime=date_now + datetime.timedelta(days=3),
289
        end_datetime=date_now + datetime.timedelta(days=4),
290
        source=source2,
291
    )
292
    assert agenda.is_available_for_simple_management() is True
293
    exception3.delete()
294

  
295
    # changes on sources - from settings
296
    for _desk in [desk, desk2]:
297
        source = TimePeriodExceptionSource.objects.create(
298
            desk=_desk, settings_slug='holidays-bis', enabled=True
299
        )
300
        assert agenda.is_available_for_simple_management() is False
301
        source.delete()
302
        assert agenda.is_available_for_simple_management() is True
303
    source1.enabled = False
304
    source1.save()
305
    assert agenda.is_available_for_simple_management() is False
306
    source1.enabled = True
307
    source1.settings_slug = 'holidays-bis'
308
    source1.save()
309
    assert agenda.is_available_for_simple_management() is False
310
    source1.settings_slug = 'holidays'
311
    source1.save()
312
    assert agenda.is_available_for_simple_management() is True
313

  
314
    # changes on sources - from url
315
    for _desk in [desk, desk2]:
316
        source = TimePeriodExceptionSource.objects.create(
317
            desk=_desk, ics_url='http://example.com/sample-bis.ics'
318
        )
319
        assert agenda.is_available_for_simple_management() is False
320
        source.delete()
321
        assert agenda.is_available_for_simple_management() is True
322
    source2.ics_url = 'http://example.com/sample-bis.ics'
323
    source2.save()
324
    assert agenda.is_available_for_simple_management() is False
325
    source2.ics_url = 'http://example.com/sample.ics'
326
    source2.save()
327
    assert agenda.is_available_for_simple_management() is True
328

  
329
    # changes on sources - from file
330
    for _desk in [desk, desk2]:
331
        source = TimePeriodExceptionSource.objects.create(
332
            desk=_desk,
333
            ics_filename='sample-bis.ics',
334
            ics_file=ContentFile(ICS_SAMPLE, name='sample-bis.ics'),
335
        )
336
        assert agenda.is_available_for_simple_management() is False
337
        source.delete()
338
        assert agenda.is_available_for_simple_management() is True
339
    source3.ics_filename = 'sample-bis.ics'
340
    source3.save()
341
    assert agenda.is_available_for_simple_management() is False
342
    source3.ics_filename = 'sample.ics'
343
    source3.save()
344
    assert agenda.is_available_for_simple_management() is True
345
    # ics_file content is not checked
346

  
347
    # changes on unavailability calendars
348
    for _desk in [desk, desk2]:
349
        unavailability_calendar2.desks.add(_desk)
350
        assert agenda.is_available_for_simple_management() is False
351
        unavailability_calendar2.desks.remove(_desk)
352
        assert agenda.is_available_for_simple_management() is True
353

  
354

  
180 355
def test_event_slug():
181 356
    other_agenda = Agenda.objects.create(label='Foo bar')
182 357
    Event.objects.create(agenda=other_agenda, places=42, start_datetime=now(), slug='foo-bar')
183
-