mirror of
https://github.com/bringout/oca-ocb-technical.git
synced 2026-04-23 06:32:02 +02:00
19.0 vanilla
This commit is contained in:
parent
5faf7397c5
commit
2696f14ed7
721 changed files with 220375 additions and 91221 deletions
|
|
@ -1,12 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
import pytz
|
||||
from datetime import datetime, date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tests import Form, TransactionCase
|
||||
from freezegun import freeze_time
|
||||
|
||||
|
||||
|
|
@ -22,8 +21,7 @@ class TestRecurrentEvents(TransactionCase):
|
|||
events = events.sorted('start')
|
||||
self.assertEqual(len(events), len(dates), "Wrong number of events in the recurrence")
|
||||
self.assertTrue(all(events.mapped('active')), "All events should be active")
|
||||
for event, dates in zip(events, dates):
|
||||
start, stop = dates
|
||||
for event, (start, stop) in zip(events, dates):
|
||||
self.assertEqual(event.start, start)
|
||||
self.assertEqual(event.stop, stop)
|
||||
|
||||
|
|
@ -353,6 +351,60 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
|
|||
(datetime(2023, 4, 27, 7, 00), datetime(2023, 4, 27, 8, 00)),
|
||||
])
|
||||
|
||||
def test_all_day_date(self):
|
||||
recurrence = self.env['calendar.event'].with_context(
|
||||
default_start=datetime(2019, 10, 22),
|
||||
default_stop=datetime(2019, 10, 22),
|
||||
default_start_date=date(2019, 10, 22),
|
||||
default_stop_date=date(2019, 10, 22),
|
||||
).create({
|
||||
'name': 'Recurrent Event',
|
||||
'start': datetime(2019, 10, 22, 8, 0),
|
||||
'stop': datetime(2019, 10, 22, 18, 0),
|
||||
'start_date': date(2019, 10, 22),
|
||||
'stop_date': date(2019, 10, 22),
|
||||
'recurrency': True,
|
||||
'rrule_type': 'weekly',
|
||||
'tue': True,
|
||||
'interval': 1,
|
||||
'count': 2,
|
||||
'event_tz': 'UTC',
|
||||
'allday': True,
|
||||
}).recurrence_id
|
||||
events = recurrence.calendar_event_ids
|
||||
self.assertEqual(events[0].start_date, date(2019, 10, 22), "The first event has the initial start date")
|
||||
self.assertEqual(events[1].start_date, date(2019, 10, 29), "The start date of the second event is one week later")
|
||||
|
||||
def test_recurrency_with_this_event(self):
|
||||
"""
|
||||
1) Create an event with a recurrence set on it
|
||||
2) Try updating the event with a different recurrence without specifying 'recurrence_update'
|
||||
3) Update the recurrence of one of the events, this time using the 'recurrence_update' as future_events
|
||||
4) Finally, check that the updated event correctly reflects the recurrence
|
||||
"""
|
||||
event = self.env['calendar.event'].create({
|
||||
'name': "Test Event",
|
||||
'allday': False,
|
||||
'rrule': u'FREQ=DAILY;INTERVAL=1;COUNT=10',
|
||||
'recurrency': True,
|
||||
'start': datetime(2023, 7, 28, 1, 0),
|
||||
'stop': datetime(2023, 7, 29, 18, 0),
|
||||
})
|
||||
events = self.env['calendar.recurrence'].search([('base_event_id', '=', event.id)]).calendar_event_ids
|
||||
self.assertEqual(len(events), 10, "It should have 10 events in the recurrence")
|
||||
|
||||
# Update the recurrence without without specifying 'recurrence_update'
|
||||
with self.assertRaises(UserError):
|
||||
event.write({'rrule': u'FREQ=DAILY;INTERVAL=2;COUNT=5'})
|
||||
# Update the recurrence of the earlier event
|
||||
events[5].write({
|
||||
'recurrence_update': 'future_events',
|
||||
'count': 2,
|
||||
})
|
||||
updated_events = self.env['calendar.recurrence'].search([('base_event_id', '=', events[5].id)]).calendar_event_ids
|
||||
self.assertEqual(len(updated_events), 2, "It should have 2 events in the recurrence")
|
||||
self.assertTrue(updated_events[1].recurrency, "It should have recurrency in the updated events")
|
||||
|
||||
class TestUpdateRecurrentEvents(TestRecurrentEvents):
|
||||
|
||||
@classmethod
|
||||
|
|
@ -443,7 +495,7 @@ class TestUpdateRecurrentEvents(TestRecurrentEvents):
|
|||
'start': event.start + relativedelta(days=4),
|
||||
'stop': event.stop + relativedelta(days=5),
|
||||
})
|
||||
recurrence = self.env['calendar.recurrence'].search([])
|
||||
recurrence = self.env['calendar.recurrence'].search([], limit=1)
|
||||
self.assertEventDates(recurrence.calendar_event_ids, [
|
||||
(datetime(2019, 10, 26, 1, 0), datetime(2019, 10, 29, 18, 0)),
|
||||
(datetime(2019, 11, 2, 1, 0), datetime(2019, 11, 5, 18, 0)),
|
||||
|
|
@ -489,7 +541,7 @@ class TestUpdateRecurrentEvents(TestRecurrentEvents):
|
|||
'start': event.start + relativedelta(days=4),
|
||||
'stop': event.stop + relativedelta(days=5),
|
||||
})
|
||||
self.assertFalse(self.recurrence.calendar_event_ids, "Inactive event should not create recurrent events")
|
||||
self.assertFalse(self.recurrence.exists(), "Inactive event should not create recurrent events")
|
||||
|
||||
def test_shift_all_with_outlier(self):
|
||||
outlier = self.events[1]
|
||||
|
|
@ -571,7 +623,7 @@ class TestUpdateRecurrentEvents(TestRecurrentEvents):
|
|||
'recurrence_update': 'all_events',
|
||||
'mon': True, # recurrence is now Tuesday AND Monday
|
||||
})
|
||||
recurrence = self.env['calendar.recurrence'].search([])
|
||||
recurrence = self.env['calendar.recurrence'].search([], limit=1)
|
||||
self.assertEventDates(recurrence.calendar_event_ids, [
|
||||
(datetime(2019, 10, 22, 1, 0), datetime(2019, 10, 24, 18, 0)),
|
||||
(datetime(2019, 10, 28, 1, 0), datetime(2019, 10, 30, 18, 0)),
|
||||
|
|
@ -692,6 +744,60 @@ class TestUpdateRecurrentEvents(TestRecurrentEvents):
|
|||
self.assertTrue(self.recurrence)
|
||||
self.assertEqual(self.events.exists(), self.events[0])
|
||||
|
||||
def test_unlink_recurrence_wizard_next(self):
|
||||
""" Test unlinking the next recurrent event using the delete wizard. """
|
||||
# Retrieve the recurring event to delete the next event occurrence.
|
||||
event = self.events[1]
|
||||
|
||||
# Step 1: Use the popover delete wizard to delete the next occurrence of the event.
|
||||
wizard = self.env['calendar.popover.delete.wizard'].with_context(
|
||||
form_view_ref='calendar.calendar_popover_delete_view').create({'calendar_event_id': event.id})
|
||||
form = Form(wizard)
|
||||
form.delete = 'next'
|
||||
form.save()
|
||||
wizard.close()
|
||||
|
||||
# Step 2: Use another delete wizard to handle the deletion of the next occurrence.
|
||||
wizard_delete = self.env['calendar.popover.delete.wizard'].with_context(
|
||||
form_view_ref='calendar.view_event_delete_wizard_form',
|
||||
default_recurrence='next'
|
||||
).create({'calendar_event_id': event.id})
|
||||
form_delete = Form(wizard_delete)
|
||||
form_delete.save()
|
||||
|
||||
# Step 3: Send cancellation notifications and delete the next occurrence.
|
||||
# Ensure that the recurrence still exists but the next event occurrence is deleted.
|
||||
wizard_delete.action_send_mail_and_delete()
|
||||
self.assertTrue(self.recurrence)
|
||||
self.assertEqual(self.events.exists(), self.events[0])
|
||||
|
||||
def test_unlink_recurrence_wizard_all(self):
|
||||
""" Test unlinking all recurrences using the delete wizard. """
|
||||
# Step 0: Retrieve the recurring event to be deleted.
|
||||
event = self.events[1]
|
||||
|
||||
# Step 1: Use the popover delete wizard to delete all occurrences of the event.
|
||||
wizard = self.env['calendar.popover.delete.wizard'].with_context(
|
||||
form_view_ref='calendar.calendar_popover_delete_view').create({'calendar_event_id': event.id})
|
||||
form = Form(wizard)
|
||||
form.delete = 'all'
|
||||
form.save()
|
||||
wizard.close()
|
||||
|
||||
# Step 2: Use another delete wizard to handle the deletion of the event recurrence.
|
||||
wizard_delete = self.env['calendar.popover.delete.wizard'].with_context(
|
||||
form_view_ref='calendar.view_event_delete_wizard_form',
|
||||
default_recurrence='all'
|
||||
).create({'calendar_event_id': event.id})
|
||||
form_delete = Form(wizard_delete)
|
||||
form_delete.save()
|
||||
|
||||
# Step 3: Send cancellation notifications and delete all recurrences.
|
||||
# Ensure that the recurrence and all related events have been deleted.
|
||||
wizard_delete.action_send_mail_and_delete()
|
||||
self.assertFalse(self.recurrence.exists())
|
||||
self.assertFalse(self.events.exists())
|
||||
|
||||
def test_recurrence_update_all_first_archived(self):
|
||||
"""Test to check the flow when a calendar event is
|
||||
created from a day that does not belong to the recurrence.
|
||||
|
|
@ -734,7 +840,6 @@ class TestUpdateRecurrentEvents(TestRecurrentEvents):
|
|||
(datetime(2019, 11, 6, 1, 0), datetime(2019, 11, 6, 2, 0)),
|
||||
])
|
||||
|
||||
|
||||
class TestUpdateMultiDayWeeklyRecurrentEvents(TestRecurrentEvents):
|
||||
|
||||
@classmethod
|
||||
|
|
@ -769,7 +874,7 @@ class TestUpdateMultiDayWeeklyRecurrentEvents(TestRecurrentEvents):
|
|||
'start': event.start + relativedelta(days=2),
|
||||
'stop': event.stop + relativedelta(days=2),
|
||||
})
|
||||
recurrence = self.env['calendar.recurrence'].search([])
|
||||
recurrence = self.env['calendar.recurrence'].search([], limit=1)
|
||||
# We don't try to do magic tricks. First event is moved, other remain
|
||||
self.assertEventDates(recurrence.calendar_event_ids, [
|
||||
(datetime(2019, 10, 24, 1, 0), datetime(2019, 10, 26, 18, 0)),
|
||||
|
|
@ -787,7 +892,7 @@ class TestUpdateMultiDayWeeklyRecurrentEvents(TestRecurrentEvents):
|
|||
'start': event.start + relativedelta(days=2),
|
||||
'stop': event.stop + relativedelta(days=3),
|
||||
})
|
||||
recurrence = self.env['calendar.recurrence'].search([])
|
||||
recurrence = self.env['calendar.recurrence'].search([], limit=1)
|
||||
self.assertEventDates(recurrence.calendar_event_ids, [
|
||||
(datetime(2019, 10, 24, 1, 0), datetime(2019, 10, 27, 18, 0)),
|
||||
(datetime(2019, 10, 31, 1, 0), datetime(2019, 11, 3, 18, 0)),
|
||||
|
|
@ -840,7 +945,7 @@ class TestUpdateMonthlyByDay(TestRecurrentEvents):
|
|||
'start': event.start + relativedelta(hours=5),
|
||||
'stop': event.stop + relativedelta(hours=5),
|
||||
})
|
||||
recurrence = self.env['calendar.recurrence'].search([])
|
||||
recurrence = self.env['calendar.recurrence'].search([], limit=1)
|
||||
self.assertEventDates(recurrence.calendar_event_ids, [
|
||||
(datetime(2019, 10, 15, 6, 0), datetime(2019, 10, 16, 23, 0)),
|
||||
(datetime(2019, 11, 19, 6, 0), datetime(2019, 11, 20, 23, 0)),
|
||||
|
|
@ -898,3 +1003,116 @@ class TestUpdateMonthlyByDate(TestRecurrentEvents):
|
|||
(datetime(2019, 11, 25, 1, 0), datetime(2019, 11, 27, 18, 0)),
|
||||
(datetime(2019, 12, 25, 1, 0), datetime(2019, 12, 27, 18, 0)),
|
||||
])
|
||||
|
||||
def test_recurring_ui_options_daily(self):
|
||||
with Form(self.env['calendar.event']) as calendar_form:
|
||||
calendar_form.name = 'test recurrence daily'
|
||||
calendar_form.recurrency = True
|
||||
calendar_form.rrule_type_ui = 'daily'
|
||||
calendar_form.count = 2
|
||||
calendar_form.start = datetime(2019, 6, 23, 16)
|
||||
calendar_form.stop = datetime(2019, 6, 23, 17)
|
||||
event = calendar_form.save()
|
||||
self.assertEventDates(event.recurrence_id.calendar_event_ids, [
|
||||
(datetime(2019, 6, 23, 16), datetime(2019, 6, 23, 17)),
|
||||
(datetime(2019, 6, 24, 16, 0), datetime(2019, 6, 24, 17)),
|
||||
])
|
||||
self.assertEqual(event.rrule_type_ui, 'daily')
|
||||
self.assertEqual(event.count, 2)
|
||||
|
||||
def test_recurring_ui_options_monthly(self):
|
||||
with Form(self.env['calendar.event']) as calendar_form:
|
||||
calendar_form.name = 'test recurrence monthly'
|
||||
calendar_form.recurrency = True
|
||||
calendar_form.rrule_type_ui = 'monthly'
|
||||
calendar_form.count = 2
|
||||
calendar_form.start = datetime(2019, 6, 11, 16)
|
||||
calendar_form.stop = datetime(2019, 6, 11, 17)
|
||||
calendar_form.day = 11
|
||||
event = calendar_form.save()
|
||||
self.assertEventDates(event.recurrence_id.calendar_event_ids, [
|
||||
(datetime(2019, 6, 11, 16), datetime(2019, 6, 11, 17)),
|
||||
(datetime(2019, 7, 11, 16), datetime(2019, 7, 11, 17)),
|
||||
])
|
||||
self.assertEqual(event.rrule_type_ui, 'monthly')
|
||||
self.assertEqual(event.count, 2)
|
||||
|
||||
def test_recurring_ui_options_yearly(self):
|
||||
with Form(self.env['calendar.event']) as calendar_form:
|
||||
calendar_form.name = 'test recurrence yearly'
|
||||
calendar_form.recurrency = True
|
||||
calendar_form.rrule_type_ui = 'yearly'
|
||||
calendar_form.count = 2
|
||||
calendar_form.start = datetime(2019, 6, 11, 16)
|
||||
calendar_form.stop = datetime(2019, 6, 11, 17)
|
||||
event = calendar_form.save()
|
||||
self.assertEventDates(event.recurrence_id.calendar_event_ids, [
|
||||
(datetime(2019, 6, 11, 16), datetime(2019, 6, 11, 17)),
|
||||
(datetime(2020, 6, 11, 16), datetime(2020, 6, 11, 17)),
|
||||
])
|
||||
# set to custom because a yearly recurrence, becomes a monthly recurrence every 12 months
|
||||
self.assertEqual(event.rrule_type_ui, 'yearly')
|
||||
self.assertEqual(event.count, 2)
|
||||
self.assertEqual(event.interval, 1)
|
||||
self.assertEqual(event.rrule_type, 'yearly')
|
||||
|
||||
def test_attendees_state_after_update(self):
|
||||
""" Ensure that after the organizer updates a recurrence, the attendees state will be pending and current user accepted. """
|
||||
# Create events with organizer and attendee state set as accepted.
|
||||
organizer = self.env.ref('base.user_admin')
|
||||
attendee_partner = self.env['res.partner'].create({'name': "attendee", "email": 'attendee@email.com'})
|
||||
first_event = self.env['calendar.event'].with_user(organizer).create({
|
||||
'name': "Recurrence",
|
||||
'start': datetime(2023, 10, 18, 8, 0),
|
||||
'stop': datetime(2023, 10, 18, 10, 0),
|
||||
'rrule': u'FREQ=WEEKLY;COUNT=5;BYDAY=WE',
|
||||
'recurrency': True,
|
||||
'partner_ids': [(4, organizer.partner_id.id), (4, attendee_partner.id)],
|
||||
})
|
||||
recurrence_id = first_event.recurrence_id.id
|
||||
|
||||
# Accept all events for all attendees and ensure their acceptance.
|
||||
for event in first_event.recurrence_id.calendar_event_ids:
|
||||
for attendee in event.attendee_ids:
|
||||
attendee.state = 'accepted'
|
||||
|
||||
# Change time fields of the recurrence by organizer in "all_events" mode. Events must reset attendee status to 'needsAction'.
|
||||
first_event.with_user(organizer).write({
|
||||
'start': first_event.start + relativedelta(hours=2),
|
||||
'stop': first_event.stop + relativedelta(hours=2),
|
||||
'recurrence_update': 'all_events',
|
||||
})
|
||||
first_event = self.env['calendar.recurrence'].search([('id', '>', recurrence_id)]).base_event_id
|
||||
recurrence_id = first_event.recurrence_id.id
|
||||
|
||||
# Ensure that attendee status is pending after organizer (current user) update time values.
|
||||
for event in first_event.recurrence_id.calendar_event_ids:
|
||||
for attendee in event.attendee_ids:
|
||||
if attendee.partner_id == organizer.partner_id:
|
||||
self.assertEqual(attendee.state, "accepted", "Organizer must remain accepted after time values update.")
|
||||
else:
|
||||
self.assertEqual(attendee.state, "needsAction", "Attendees state except organizer must be pending after update.")
|
||||
|
||||
# Accept all events again for all attendes.
|
||||
for event in first_event.recurrence_id.calendar_event_ids:
|
||||
for attendee in event.attendee_ids:
|
||||
attendee.state = 'accepted'
|
||||
|
||||
# Change time fields of the recurrence by organizer in "future_events" mode. Events must reset attendee status to 'needsAction'.
|
||||
second_event = first_event.recurrence_id.calendar_event_ids.sorted('start')[1]
|
||||
second_event.with_user(organizer).write({
|
||||
'start': second_event.start + relativedelta(hours=2),
|
||||
'stop': second_event.stop + relativedelta(hours=2),
|
||||
'recurrence_update': 'future_events',
|
||||
})
|
||||
second_event = self.env['calendar.recurrence'].search([('id', '>', recurrence_id)]).base_event_id
|
||||
|
||||
# Ensure that first event is accepted for everyone and also from the second event on, the state in pending for attendees except organizer.
|
||||
self.assertTrue(first_event.active, "Event from previous recurrence must remain active after the second event got updated.")
|
||||
self.assertTrue(all(attendee.state == 'accepted' for attendee in first_event.attendee_ids), "Attendees state from previous event must remain accepted.")
|
||||
for event in second_event.recurrence_id.calendar_event_ids:
|
||||
for attendee in event.attendee_ids:
|
||||
if attendee.partner_id == organizer.partner_id:
|
||||
self.assertEqual(attendee.state, "accepted", "Current user must remain accepted after time values update.")
|
||||
else:
|
||||
self.assertEqual(attendee.state, "needsAction", "Attendees state except current user must be pending after update.")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue