From 3855cfccb6876e613771a4a53b65e2c95a13fa73 Mon Sep 17 00:00:00 2001 From: Emmanuel Cazenave Date: Thu, 6 Apr 2023 10:58:43 +0200 Subject: [PATCH] agendas: do not use minimal_booking_time in min_booking_datetime computation (#76303) --- chrono/agendas/models.py | 4 +- tests/api/datetimes/test_all.py | 36 +++++++++++++ tests/api/datetimes/test_meetings.py | 32 ++++++++++++ tests/api/test_agenda.py | 4 +- tests/test_agendas.py | 78 ++++++++++++++-------------- 5 files changed, 111 insertions(+), 43 deletions(-) diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index d854e0df..9f348882 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -684,9 +684,7 @@ class Agenda(models.Model): else: t += datetime.timedelta(days=self.minimal_booking_delay) - # replace time if needed - if self.minimal_booking_time: - t = datetime.datetime.combine(t.date(), self.minimal_booking_time, tzinfo=t.tzinfo) + t = t.replace(hour=0, minute=0, second=0, microsecond=0) # t could not exist, recompute it as an existing datetime by converting to UTC then to localtime return localtime(t.astimezone(utc)) diff --git a/tests/api/datetimes/test_all.py b/tests/api/datetimes/test_all.py index 72b71aee..313af7fe 100644 --- a/tests/api/datetimes/test_all.py +++ b/tests/api/datetimes/test_all.py @@ -1363,3 +1363,39 @@ def test_past_datetimes_recurring_event(app, user): ) data = resp.json['data'] assert len(data) == 7 + + +@pytest.mark.freeze_time('2023-04-03') +def test_events_datetimes_min_booking_datetime_with_minimal_booking_time(app): + agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0) + Event.objects.create( + slug='event-slug', + start_datetime=make_aware(datetime.datetime(year=2023, month=4, day=3, hour=9)), + places=5, + agenda=agenda, + ) + Event.objects.create( + slug='event-slug-2', + start_datetime=make_aware(datetime.datetime(year=2023, month=4, day=3, hour=11)), + places=5, + agenda=agenda, + ) + + api_url = '/api/agenda/%s/datetimes/' % agenda.slug + resp = app.get(api_url) + assert resp.json['data'][0]['datetime'] == '2023-04-03 09:00:00' + assert resp.json['data'][1]['datetime'] == '2023-04-03 11:00:00' + + # set a minimal minimal_booking_time and check that it has no impact + agenda.minimal_booking_time = datetime.time(10, 0, 0) + agenda.save() + resp = app.get(api_url) + assert resp.json['data'][0]['datetime'] == '2023-04-03 09:00:00' + assert resp.json['data'][1]['datetime'] == '2023-04-03 11:00:00' + + # set a minimal minimal_booking_time to None check that it has no impact + agenda.minimal_booking_time = None + agenda.save() + resp = app.get(api_url) + assert resp.json['data'][0]['datetime'] == '2023-04-03 09:00:00' + assert resp.json['data'][1]['datetime'] == '2023-04-03 11:00:00' diff --git a/tests/api/datetimes/test_meetings.py b/tests/api/datetimes/test_meetings.py index c3738081..7d1db0a5 100644 --- a/tests/api/datetimes/test_meetings.py +++ b/tests/api/datetimes/test_meetings.py @@ -2660,3 +2660,35 @@ def test_datetimes_api_meetings_agenda_filter_minutes(app): assert datetime_from_str(resp.json['data'][1]['datetime']).minute == 30 assert datetime_from_str(resp.json['data'][2]['datetime']).minute == 0 assert datetime_from_str(resp.json['data'][3]['datetime']).minute == 30 + + +@pytest.mark.freeze_time('2023-04-03') +def test_datetimes_api_meetings_min_booking_datetime_with_minimal_booking_time(app): + agenda = Agenda.objects.create( + label='Agenda', kind='meetings', minimal_booking_delay=0, maximal_booking_delay=3 + ) + desk = Desk.objects.create(agenda=agenda, slug='desk') + meeting_type = MeetingType.objects.create(agenda=agenda, slug='foo', duration=30) + for weekday in [0, 1, 2]: # monday, tuesday, wednesday + TimePeriod.objects.create( + weekday=weekday, + start_time=datetime.time(9, 0), + end_time=datetime.time(10, 00), + desk=desk, + ) + + api_url = '/api/agenda/%s/meetings/%s/datetimes/' % (agenda.slug, meeting_type.slug) + resp = app.get(api_url) + assert resp.json['data'][0]['datetime'] == '2023-04-03 09:00:00' + + # set a minimal minimal_booking_time and check that it has no impact + agenda.minimal_booking_time = datetime.time(10, 0, 0) + agenda.save() + resp = app.get(api_url) + assert resp.json['data'][0]['datetime'] == '2023-04-03 09:00:00' + + # set a minimal minimal_booking_time to None check that it has no impact + agenda.minimal_booking_time = None + agenda.save() + resp = app.get(api_url) + assert resp.json['data'][0]['datetime'] == '2023-04-03 09:00:00' diff --git a/tests/api/test_agenda.py b/tests/api/test_agenda.py index de6bc777..d2c1609b 100644 --- a/tests/api/test_agenda.py +++ b/tests/api/test_agenda.py @@ -613,7 +613,9 @@ def test_add_agenda(app, user, settings): agenda = Agenda.objects.get(slug='foo-events') assert agenda.edit_role == edit_group assert agenda.view_role == view_group - assert agenda.min_booking_datetime == localtime(now()).replace(day=12) + assert agenda.min_booking_datetime == localtime(now()).replace( + day=12, hour=0, minute=0, second=0, microsecond=0 + ) assert agenda.minimal_booking_time is None assert agenda.category == category_a assert agenda.events_type == events_type diff --git a/tests/test_agendas.py b/tests/test_agendas.py index 5f5d45d8..6136d288 100644 --- a/tests/test_agendas.py +++ b/tests/test_agendas.py @@ -277,22 +277,22 @@ def delay_parameter_to_label(argvalue): @pytest.mark.parametrize( 'current_time,min_booking_datetime', [ - ('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 8)), - ('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 7)), + ('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 0, 0)), + ('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 0, 0)), # summer DST change on sunday 28th - ('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 29, 1, 30)), - ('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 2, 30)), - ('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 3, 30)), - ('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 1, 30)), - ('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 3, 30)), + ('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 29, 0, 0)), + ('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 0, 0)), + ('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 0, 0)), + ('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 0, 0)), + ('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 0, 0)), # winter DST change on sunday 31th - ('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 1, 30)), - ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 2, 30)), - ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 2, 30)), - ('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 1, 30)), - ('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 2, 30)), - ('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 2, 30)), - ('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 3, 30)), + ('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 0, 0)), + ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 0, 0)), + ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 0, 0)), + ('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 0, 0)), + ('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 0, 0)), + ('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 0, 0)), + ('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 0, 0)), ], ids=delay_parameter_to_label, ) @@ -305,22 +305,22 @@ def test_agenda_minimal_booking_delay_no_minimal_booking_time(freezer, current_t @pytest.mark.parametrize( 'current_time,min_booking_datetime', [ - ('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 16, 8)), - ('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 24, 7)), + ('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 16, 0, 0)), + ('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 24, 0, 0)), # summer DST change on sunday 28th - ('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 31, 1, 30)), - ('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 31, 2, 30)), - ('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 31, 3, 30)), - ('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 1, 30)), - ('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 3, 30)), + ('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 31, 0, 0)), + ('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 31, 0, 0)), + ('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 31, 0, 0)), + ('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 0, 0)), + ('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 0, 0)), # winter DST change on sunday 31th - ('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 5, 1, 30)), - ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 5, 2, 30)), - ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 5, 2, 30)), - ('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 5, 1, 30)), - ('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 5, 2, 30)), - ('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 5, 2, 30)), - ('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 5, 3, 30)), + ('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 5, 0, 0)), + ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 5, 0, 0)), + ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 5, 0, 0)), + ('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 5, 0, 0)), + ('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 5, 0, 0)), + ('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 5, 0, 0)), + ('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 5, 0, 0)), ], ids=delay_parameter_to_label, ) @@ -341,19 +341,19 @@ def test_agenda_minimal_booking_delay_in_working_days_no_minimal_booking_time( @pytest.mark.parametrize( 'current_time,min_booking_datetime', [ - ('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 8)), - ('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 8)), + ('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 0, 0)), + ('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 0, 0)), # summer DST change on sunday - ('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 8)), - ('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 8)), + ('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 0, 0)), + ('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 0, 0)), # winter DST change on sunday - ('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 8)), - ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 8)), - ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 8)), - ('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 8)), - ('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 8)), - ('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 8)), - ('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 8)), + ('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 0, 0)), + ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 0, 0)), + ('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 0, 0)), + ('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 0, 0)), + ('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 0, 0)), + ('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 0, 0)), + ('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 0, 0)), ], ids=delay_parameter_to_label, )