Skip to content

Commit a77023e

Browse files
[MIG] base_rest: Migration to 19.0
1 parent d6b2add commit a77023e

12 files changed

Lines changed: 165 additions & 24 deletions

base_rest/__manifest__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@
1212
"author": "ACSONE SA/NV, Odoo Community Association (OCA)",
1313
"maintainers": [],
1414
"website": "https://github.com/OCA/rest-framework",
15-
"depends": ["component", "web"],
15+
"depends": ["bus", "component", "web", "web_tour"],
1616
"data": [
1717
"views/openapi_template.xml",
1818
"views/base_rest_view.xml",
1919
],
2020
"assets": {
2121
"web.assets_frontend": [
2222
"base_rest/static/src/scss/base_rest.scss",
23-
"base_rest/static/src/js/swagger_ui.js",
24-
"base_rest/static/src/js/swagger.js",
23+
],
24+
"web.assets_tests": [
25+
"base_rest/static/tests/tours/**/*.js",
2526
],
2627
},
2728
"external_dependencies": {
@@ -33,5 +34,4 @@
3334
"apispec",
3435
]
3536
},
36-
"installable": True,
3737
}

base_rest/controllers/api_docs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def index(self, **params):
3030
self._get_api_urls()
3131
primary_name = params.get("urls.primaryName")
3232
swagger_settings = {
33-
"urls": self._get_api_urls(),
33+
"urls": self._get_api_urls() or None,
3434
"urls.primaryName": primary_name,
3535
}
3636
values = {"swagger_settings": swagger_settings}

base_rest/http.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
ValidationError,
3030
)
3131
from odoo.http import (
32-
CSRF_FREE_METHODS,
3332
MISSING_CSRF_WARNING,
33+
SAFE_HTTP_METHODS,
3434
Dispatcher,
3535
SessionExpiredException,
3636
request,
@@ -162,7 +162,7 @@ def dispatch(self, endpoint, args):
162162

163163
# Check for CSRF token for relevant requests
164164
if (
165-
self.request.httprequest.method not in CSRF_FREE_METHODS
165+
self.request.httprequest.method not in SAFE_HTTP_METHODS
166166
and endpoint.routing.get("csrf", True)
167167
):
168168
token = params.pop("csrf_token", None)

base_rest/models/rest_service_registration.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ def build_registry(self, services_registry, states=None, exclude_addons=None):
189189
# dependencies to ensure that controllers defined in a more
190190
# specialized addon and overriding more generic one takes precedences
191191
# on the generic one into the registry
192-
graph = odoo.modules.graph.Graph()
193-
graph.add_module(self.env.cr, "base")
192+
graph = odoo.modules.module_graph.ModuleGraph(self.env.cr)
193+
graph.extend(["base"])
194194

195195
query = "SELECT name FROM ir_module_module WHERE state IN %s "
196196
params = [tuple(states)]
@@ -200,7 +200,7 @@ def build_registry(self, services_registry, states=None, exclude_addons=None):
200200
self.env.cr.execute(query, params)
201201

202202
module_list = [name for (name,) in self.env.cr.fetchall() if name not in graph]
203-
graph.add_modules(self.env.cr, module_list)
203+
graph.extend(module_list)
204204

205205
for module in graph:
206206
self.load_services(module.name, services_registry)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {registry} from "@web/core/registry";
2+
3+
registry
4+
.category("web_tour.tours")
5+
.add("base_rest.tour_api_docs_no_content_validation", {
6+
steps: () => [
7+
{
8+
trigger: "h4:contains('No API definition provided.')",
9+
},
10+
],
11+
});
12+
13+
registry.category("web_tour.tours").add("base_rest.tour_api_docs_simple_api_endpoint", {
14+
steps: () => [
15+
{
16+
trigger: "span:contains('pod_bay_doors')",
17+
},
18+
{
19+
trigger:
20+
"span.opblock-summary-path[data-path='/control-panel/pod_bay_doors/open']",
21+
run: "click",
22+
},
23+
{
24+
trigger: "button.try-out__btn",
25+
run: "click",
26+
},
27+
{
28+
trigger: "button.execute",
29+
run: "click",
30+
},
31+
{
32+
trigger: "pre.microlight:contains('I'm sorry, Dave.')",
33+
},
34+
],
35+
});

base_rest/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from . import common
2+
from . import test_api_docs
23
from . import test_cerberus_list_validator
34
from . import test_cerberus_validator
45
from . import test_controller_builder

base_rest/tests/common.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def _setup_registry(class_or_instance):
9595
)
9696

9797
# register our components
98+
class_or_instance.comp_registry.load_components("component")
9899
class_or_instance.comp_registry.load_components("base_rest")
99100

100101
# Define a base test controller here to avoid to have this controller
@@ -239,15 +240,15 @@ def setUpClass(cls):
239240

240241

241242
class BaseRestCase(TransactionComponentCase, RegistryMixin):
242-
@classmethod
243-
def setUpClass(cls):
244-
super().setUpClass()
245-
cls.setUpRegistry()
246-
cls.base_url = cls.env["ir.config_parameter"].get_param("web.base.url")
247-
cls.registry.enter_test_mode(cls.env.cr)
243+
# pylint: disable=W8106
244+
def setUp(self):
245+
super().setUp()
246+
self.setUpRegistry()
247+
self.base_url = self.env["ir.config_parameter"].get_param("web.base.url")
248+
self.registry_enter_test_mode(register_cleanup=False)
248249

249250
# pylint: disable=W8110
250251
@classmethod
251252
def tearDownClass(cls):
252-
cls.registry.leave_test_mode()
253+
cls.registry_leave_test_mode()
253254
super().tearDownClass()

base_rest/tests/test_api_docs.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from odoo.tests import HttpCase, tagged
2+
3+
from odoo.addons.component.core import Component
4+
5+
from .. import restapi
6+
from .common import TransactionRestServiceRegistryCase
7+
8+
9+
@tagged("post_install", "-at_install")
10+
class TestAPIDocs(TransactionRestServiceRegistryCase, HttpCase):
11+
@classmethod
12+
def setUpClass(cls):
13+
"""
14+
Avoids shadowing of "base_url" from RegistyCase class.
15+
"""
16+
super().setUpClass()
17+
cls.base_url = lambda _self: cls.env["ir.config_parameter"].get_param(
18+
"web.base.url"
19+
)
20+
21+
def setUp(self):
22+
super().setUp()
23+
24+
self._setup_registry(self)
25+
26+
def tearDown(self):
27+
self._teardown_registry(self)
28+
29+
super().tearDown()
30+
31+
def test_00_api_docs_no_data(self):
32+
"""
33+
Makes sure the API Swagger page doesn't crash when we have no active endpoints.
34+
"""
35+
self.authenticate("admin", "admin")
36+
response = self.url_open("/api-docs")
37+
38+
self.assertEqual(response.status_code, 200)
39+
40+
# Verify the content through a tour.
41+
self.start_tour(
42+
"/api-docs",
43+
"base_rest.tour_api_docs_no_content_validation",
44+
login="admin",
45+
)
46+
47+
def test_01_api_docs_simple_request(self):
48+
"""
49+
Adding a few controllers to the API, the Swagger interface should be fully
50+
functional. We won't test it itself, only that Odoo is sending the
51+
correct information.
52+
"""
53+
54+
class SimpleAPIEndpoint(Component):
55+
_inherit = "base.rest.service"
56+
_name = "simple.api.endpoint"
57+
_usage = "api"
58+
_collection = self._collection_name
59+
_description = "Simple API Endpoint"
60+
61+
@restapi.method(
62+
[("/control-panel/pod_bay_doors/open", "POST")],
63+
auth="public",
64+
output_param=restapi.CerberusValidator(
65+
{"result": {"type": "string", "required": True}}
66+
),
67+
)
68+
def open_pod_bay_doors(self):
69+
return {"result": "I'm sorry, Dave. I'm afraid I can't do that."}
70+
71+
self._build_services(self, SimpleAPIEndpoint)
72+
73+
self.authenticate("admin", "admin")
74+
75+
self.start_tour(
76+
"/api-docs",
77+
"base_rest.tour_api_docs_simple_api_endpoint",
78+
login="admin",
79+
)

base_rest/tests/test_openapi_generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
33

44
from odoo.addons.component.core import Component
5-
from odoo.addons.website.tools import MockRequest
5+
from odoo.addons.http_routing.tests.common import MockRequest
66

77
from .. import restapi
88
from .common import TransactionRestServiceRegistryCase

base_rest/tests/test_service_context_provider.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright 2021 ACSONE SA/NV
22
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
33
from odoo.addons.component.core import Component
4-
from odoo.addons.website.tools import MockRequest
4+
from odoo.addons.http_routing.tests.common import MockRequest
55

66
from .. import restapi
77
from .common import BaseRestCase, TransactionRestServiceRegistryCase
@@ -79,25 +79,37 @@ class TestServiceNewApi(Component):
7979
_collection = self._collection_name
8080
_description = "test"
8181

82+
def _get_partner_schema(self):
83+
return {"name": {"type": "string", "required": True}}
84+
8285
@restapi.method(
8386
[(["/<int:id>/get", "/<int:id>"], "GET")],
8487
output_param=restapi.CerberusValidator("_get_partner_schema"),
8588
auth="public",
8689
)
8790
def get(self, _id):
88-
return {"name": self.env["res.partner"].browse(_id).name}
91+
return {"name": self.env["res.partner"].browse(_id).exists().name}
8992

9093
self._build_components(TestComponentContextprovider)
9194
self._build_services(self, TestServiceNewApi)
9295
controller = self._get_controller_for(TestServiceNewApi)
93-
service_component = controller().service_component
96+
controller_instance = controller()
97+
service_component = controller_instance.service_component
9498
with (
95-
MockRequest(self.env),
99+
self.with_user("admin"),
100+
MockRequest(self.env) as request,
96101
service_component(service_name="partner") as service,
97102
):
103+
# Required for logging REST methods.
104+
request.httprequest.headers = {}
98105
self.assertEqual(
99106
service.work.authenticated_partner_id, self.env.user.partner_id.id
100107
)
108+
# Actually testing if the rules are computed correctly by calling
109+
# the controller method itself.
110+
controller_instance._process_method(
111+
"partner", "get", self.env.user.company_id.partner_id.id
112+
)
101113

102114
def test_03(self):
103115
"""Test authenticated_partner_id
@@ -147,4 +159,4 @@ def get(self, _id):
147159
class CommonCase(BaseRestCase):
148160
# dummy test method to pass codecov
149161
def test_04(self):
150-
self.assertEqual(self.registry.test_cr, self.cr)
162+
self.assertEqual(self.registry.db_name, self.cr.dbname)

0 commit comments

Comments
 (0)