Odoo18-Base/extra-addons/website_appointment/tests/test_appointment.py

182 lines
8.3 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import Counter
from datetime import datetime
from odoo.addons.appointment.tests.common import AppointmentCommon
from odoo.addons.website_appointment.controllers.appointment import WebsiteAppointment
from odoo.addons.website.tests.test_website_visitor import MockVisitor
from odoo.addons.website.tools import MockRequest
from odoo.exceptions import ValidationError
from odoo.tests import users, tagged
from unittest.mock import patch
class WebsiteAppointmentTest(AppointmentCommon, MockVisitor):
def test_apt_type_create_from_website(self):
""" Test that when creating an appointment type from the website, we use
the visitor's timezone as fallback for the user's timezone """
test_user = self.apt_manager
test_user.write({'tz': False})
visitor = self.env['website.visitor'].create({
"name": 'Test Visitor',
'access_token': test_user.partner_id.id,
"timezone": False,
})
AppointmentType = self.env['appointment.type']
with self.mock_visitor_from_request(force_visitor=visitor):
# Test appointment timezone when user and visitor both don't have timezone
AppointmentType.with_user(test_user).create_and_get_website_url(**{'name': 'Appointment UTC Timezone'})
self.assertEqual(
AppointmentType.search([
('name', '=', 'Appointment UTC Timezone')
]).appointment_tz, 'UTC'
)
# Test appointment timezone when user doesn't have timezone and visitor have timezone
visitor.timezone = 'Europe/Brussels'
AppointmentType.with_user(test_user).create_and_get_website_url(**{'name': 'Appointment Visitor Timezone'})
self.assertEqual(
AppointmentType.search([
('name', '=', 'Appointment Visitor Timezone')
]).appointment_tz, visitor.timezone
)
# Test appointment timezone when user has timezone
test_user.tz = 'Asia/Kolkata'
AppointmentType.with_user(test_user).create_and_get_website_url(**{'name': 'Appointment User Timezone'})
self.assertEqual(
AppointmentType.search([
('name', '=', 'Appointment User Timezone')
]).appointment_tz, test_user.tz
)
@users('apt_manager')
def test_apt_type_create_from_website_slots(self):
""" Test that when creating an appointment type from the website, defaults slots are set."""
pre_slots = self.env['appointment.slot'].search([])
# Necessary for appointment type as `create_and_get_website_url` does not return the record.
pre_appts = self.env['appointment.type'].search([])
self.env['appointment.type'].create_and_get_website_url(**{
'name': 'Test Appointment Type has slots',
'staff_user_ids': [self.staff_user_bxls.id]
})
new_appt = self.env['appointment.type'].search([]) - pre_appts
new_slots = self.env['appointment.slot'].search([]) - pre_slots
self.assertEqual(new_slots.appointment_type_id, new_appt)
expected_slots = {
(str(weekday), start_hour, end_hour) : 1
for weekday in range(1, 6)
for start_hour, end_hour in ((9., 12.), (14., 17.))
}
created_slots = Counter()
for slot in new_slots:
created_slots[(slot.weekday, slot.start_hour, slot.end_hour)] += 1
self.assertDictEqual(created_slots, expected_slots)
@users('admin')
def test_apt_type_is_published(self):
for category, default in [
('custom', False),
('punctual', False),
('recurring', False),
('anytime', False)
]:
appointment_type = self.env['appointment.type'].create({
'name': 'Custom Appointment',
'category': category,
'start_datetime': datetime(2023, 10, 3, 8, 0) if category == 'punctual' else False,
'end_datetime': datetime(2023, 10, 10, 8, 0) if category == 'punctual' else False,
})
self.assertEqual(appointment_type.is_published, default)
if category in ['custom', 'punctual', 'recurring']:
appointment_copied = appointment_type.copy()
self.assertFalse(appointment_copied.is_published, "When we copy an appointment type, the new one should not be published")
appointment_type.write({'is_published': False})
appointment_copied = appointment_type.copy()
self.assertFalse(appointment_copied.is_published)
else:
with self.assertRaises(ValidationError):
# A maximum of 1 anytime appointment per employee is allowed
appointment_type.copy()
@users('admin')
def test_apt_type_is_published_update(self):
appointment = self.env['appointment.type'].create({
'name': 'Recurring Appointment',
'category': 'recurring',
})
self.assertFalse(appointment.is_published, "A recurring appointment type should not be published at creation")
appointment.write({'category': 'custom'})
self.assertFalse(appointment.is_published, "Modifying an appointment type category should not modify the publish state")
appointment.write({'category': 'recurring'})
self.assertFalse(appointment.is_published, "Modifying an appointment type category should not modify the publish state")
appointment.write({'category': 'anytime'})
self.assertFalse(appointment.is_published, "Modifying an appointment type category should not modify the publish state")
appointment.write({
'category': 'punctual',
'start_datetime': datetime(2022, 2, 14, 8, 0, 0),
'end_datetime': datetime(2022, 2, 20, 20, 0, 0),
})
self.assertFalse(appointment.is_published, "Modifying an appointment type category should not modify the publish state")
def test_find_customer_country_from_visitor(self):
self.env.user.tz = "Europe/Brussels"
belgium = self.env.ref('base.be')
usa = self.env.ref('base.us')
current_website = self.env['website'].get_current_website()
appointments_belgium, appointment_usa = self.env['appointment.type'].create([
{
'name': 'Appointment for Belgium',
'country_ids': [(6, 0, [belgium.id])],
'website_id': current_website.id
}, {
'name': 'Appointment for the US',
'country_ids': [(6, 0, [usa.id])],
'website_id': current_website.id
},
])
visitor_from_the_us = self.env['website.visitor'].create({
"name": 'Visitor from the US',
'access_token': self.apt_manager.partner_id.id,
"country_id": usa.id,
'website_id': current_website.id
})
wa_controller = WebsiteAppointment()
self.env.user.country_id = False
class MockGeoIPWithCountryCode:
country_code = None
with MockRequest(self.env, website=current_website) as mock_request:
with self.mock_visitor_from_request(force_visitor=visitor_from_the_us), \
patch.object(mock_request, 'geoip', new=MockGeoIPWithCountryCode()):
# Make sure no country was identified before
self.assertFalse(mock_request.env.user.country_id)
self.assertFalse(mock_request.geoip.country_code)
domain = [
'|', ('end_datetime', '=', False), ('end_datetime', '>=', datetime.utcnow())
]
available_appointments = wa_controller._fetch_and_check_private_appointment_types(None, None, None, "", domain=wa_controller._appointments_base_domain(None, False, None, domain, True))
self.assertNotIn(appointments_belgium, available_appointments,
"US visitor should not have access to an Appointment Type restricted to Belgium.")
self.assertIn(appointment_usa, available_appointments,
"US visitor should have access to an Appointment Type restricted to the US.")