mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 04:52:04 +02:00
263 lines
9.5 KiB
Python
263 lines
9.5 KiB
Python
# Copyright 2017 Akretion (http://www.akretion.com).
|
|
# Copyright 2020 ACSONE SA/NV
|
|
# @author Sébastien BEAU <sebastien.beau@akretion.com>
|
|
# @author Laurent Mignon <laurent.mignon@acsone.eu>
|
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
|
|
|
import copy
|
|
|
|
from odoo import http
|
|
from odoo.tests.common import TransactionCase, get_db_name
|
|
|
|
from odoo.addons.component.core import (
|
|
WorkContext,
|
|
_component_databases,
|
|
_get_addon_name,
|
|
)
|
|
from odoo.addons.component.tests.common import (
|
|
ComponentRegistryCase,
|
|
TransactionComponentCase,
|
|
new_rollbacked_env,
|
|
)
|
|
|
|
from ..controllers.main import RestController, _PseudoCollection
|
|
from ..core import (
|
|
RestServicesRegistry,
|
|
_rest_controllers_per_module,
|
|
_rest_services_databases,
|
|
)
|
|
from ..tools import ROUTING_DECORATOR_ATTR, _inspect_methods
|
|
|
|
|
|
class RegistryMixin(object):
|
|
@classmethod
|
|
def setUpRegistry(cls):
|
|
with new_rollbacked_env() as env:
|
|
service_registration = env["rest.service.registration"]
|
|
# build the registry of every installed addons
|
|
services_registry = service_registration._init_global_registry()
|
|
cls._services_registry = services_registry
|
|
# ensure that we load only the services of the 'installed'
|
|
# modules, not 'to install', which means we load only the
|
|
# dependencies of the tested addons, not the siblings or
|
|
# children addons
|
|
service_registration.build_registry(
|
|
services_registry, states=("installed",)
|
|
)
|
|
# build the services of the current tested addon
|
|
current_addon = _get_addon_name(cls.__module__)
|
|
service_registration.load_services(current_addon, services_registry)
|
|
env["rest.service.registration"]._build_controllers_routes(
|
|
services_registry
|
|
)
|
|
|
|
|
|
class RestServiceRegistryCase(ComponentRegistryCase):
|
|
|
|
# pylint: disable=W8106
|
|
@staticmethod
|
|
def _setup_registry(class_or_instance):
|
|
ComponentRegistryCase._setup_registry(class_or_instance)
|
|
|
|
class_or_instance._service_registry = RestServicesRegistry()
|
|
# take a copy of registered controllers
|
|
class_or_instance._controller_children_classes = copy.deepcopy(
|
|
http.Controller.children_classes
|
|
)
|
|
class_or_instance._original_addon_rest_controllers_per_module = copy.deepcopy(
|
|
_rest_controllers_per_module[_get_addon_name(class_or_instance.__module__)]
|
|
)
|
|
db_name = get_db_name()
|
|
|
|
# makes the test component registry available for the db name
|
|
class_or_instance._original_component_databases = _component_databases.get(
|
|
db_name
|
|
)
|
|
_component_databases[db_name] = class_or_instance.comp_registry
|
|
|
|
# makes the test service registry available for the db name
|
|
class_or_instance._original_services_registry = _rest_services_databases.get(
|
|
db_name, {}
|
|
)
|
|
_rest_services_databases[db_name] = class_or_instance._service_registry
|
|
|
|
# build the services and controller of every installed addons
|
|
# but the current addon (when running with pytest/nosetest, we
|
|
# simulate the --test-enable behavior by excluding the current addon
|
|
# which is in 'to install' / 'to upgrade' with --test-enable).
|
|
current_addon = _get_addon_name(class_or_instance.__module__)
|
|
|
|
with new_rollbacked_env() as env:
|
|
RestServiceRegistration = env["rest.service.registration"]
|
|
RestServiceRegistration.build_registry(
|
|
class_or_instance._service_registry,
|
|
states=("installed",),
|
|
exclude_addons=[current_addon],
|
|
)
|
|
RestServiceRegistration._build_controllers_routes(
|
|
class_or_instance._service_registry
|
|
)
|
|
|
|
# register our components
|
|
class_or_instance.comp_registry.load_components("base_rest")
|
|
|
|
# Define a base test controller here to avoid to have this controller
|
|
# registered outside tests
|
|
class_or_instance._collection_name = "base.rest.test"
|
|
|
|
BaseTestController = class_or_instance._get_test_controller(class_or_instance)
|
|
|
|
class_or_instance._BaseTestController = BaseTestController
|
|
class_or_instance._controller_route_method_names = {
|
|
"my_controller_route_without",
|
|
"my_controller_route_with",
|
|
"my_controller_route_without_auth_2",
|
|
}
|
|
|
|
@staticmethod
|
|
def _get_test_controller(class_or_instance, root_path="/test_controller/"):
|
|
class BaseTestController(RestController):
|
|
_root_path = root_path
|
|
_collection_name = class_or_instance._collection_name
|
|
_default_auth = "public"
|
|
|
|
@http.route("/my_controller_route_without")
|
|
def my_controller_route_without(self):
|
|
return {}
|
|
|
|
@http.route(
|
|
"/my_controller_route_with",
|
|
auth="public",
|
|
cors="http://with_cors",
|
|
csrf="False",
|
|
save_session="False",
|
|
)
|
|
def my_controller_route_with(self):
|
|
return {}
|
|
|
|
@http.route("/my_controller_route_without_auth_2", auth=None)
|
|
def my_controller_route_without_auth_2(self):
|
|
return {}
|
|
|
|
return BaseTestController
|
|
|
|
@staticmethod
|
|
def _teardown_registry(class_or_instance):
|
|
ComponentRegistryCase._teardown_registry(class_or_instance)
|
|
http.Controller.children_classes = (
|
|
class_or_instance._controller_children_classes
|
|
)
|
|
db_name = get_db_name()
|
|
_component_databases[db_name] = class_or_instance._original_component_databases
|
|
_rest_services_databases[
|
|
db_name
|
|
] = class_or_instance._original_services_registry
|
|
class_or_instance._service_registry = {}
|
|
_rest_controllers_per_module[
|
|
_get_addon_name(class_or_instance.__module__)
|
|
] = class_or_instance._original_addon_rest_controllers_per_module
|
|
|
|
@staticmethod
|
|
def _build_services(class_or_instance, *classes):
|
|
class_or_instance._build_components(*classes)
|
|
with new_rollbacked_env() as env:
|
|
RestServiceRegistration = env["rest.service.registration"]
|
|
current_addon = _get_addon_name(class_or_instance.__module__)
|
|
RestServiceRegistration.load_services(
|
|
current_addon, class_or_instance._service_registry
|
|
)
|
|
RestServiceRegistration._build_controllers_routes(
|
|
class_or_instance._service_registry
|
|
)
|
|
|
|
@staticmethod
|
|
def _get_controller_for(service, addon="base_rest"):
|
|
identifier = "{}_{}_{}".format(
|
|
get_db_name(),
|
|
service._collection.replace(".", "_"),
|
|
service._usage.replace(".", "_"),
|
|
)
|
|
controllers = [
|
|
controller
|
|
for controller in http.Controller.children_classes.get(addon, [])
|
|
if getattr(controller, "_identifier", None) == identifier
|
|
]
|
|
if not controllers:
|
|
return
|
|
return controllers[-1]
|
|
|
|
@staticmethod
|
|
def _get_controller_route_methods(controller):
|
|
methods = {}
|
|
for name, method in _inspect_methods(controller):
|
|
if hasattr(method, ROUTING_DECORATOR_ATTR):
|
|
methods[name] = method
|
|
return methods
|
|
|
|
@staticmethod
|
|
def _get_service_component(class_or_instance, usage, collection=None):
|
|
collection = collection or _PseudoCollection(
|
|
class_or_instance._collection_name, class_or_instance.env
|
|
)
|
|
work = WorkContext(
|
|
model_name="rest.service.registration",
|
|
collection=collection,
|
|
components_registry=class_or_instance.comp_registry,
|
|
)
|
|
return work.component(usage=usage)
|
|
|
|
|
|
class TransactionRestServiceRegistryCase(TransactionCase, RestServiceRegistryCase):
|
|
"""Adds Odoo Transaction to inherited from ComponentRegistryCase.
|
|
|
|
This class doesn't set up the registry for you.
|
|
You're supposed to explicitly call `_setup_registry` and `_teardown_registry`
|
|
when you need it, either on setUpClass and tearDownClass or setUp and tearDown.
|
|
|
|
class MyTestCase(TransactionRestServiceRegistryCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self._setup_registry(self)
|
|
|
|
def tearDown(self):
|
|
self._teardown_registry(self)
|
|
super().tearDown()
|
|
|
|
class MyTestCase(TransactionRestServiceRegistryCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls._setup_registry(cls)
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
cls._teardown_registry(cls)
|
|
super().tearDownClass()
|
|
"""
|
|
|
|
# pylint: disable=W8106
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
# resolve an inheritance issue (common.TransactionCase does not use
|
|
# super)
|
|
TransactionCase.setUpClass()
|
|
cls.base_url = cls.env["ir.config_parameter"].get_param("web.base.url")
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
TransactionCase.tearDownClass()
|
|
|
|
|
|
class BaseRestCase(TransactionComponentCase, RegistryMixin):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.setUpRegistry()
|
|
cls.base_url = cls.env["ir.config_parameter"].get_param("web.base.url")
|
|
cls.registry.enter_test_mode(cls.env.cr)
|
|
|
|
# pylint: disable=W8110
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
cls.registry.leave_test_mode()
|
|
super().tearDownClass()
|