Merge ~r00ta/maas:refactor-pagination-tests into maas:master
- Git
- lp:~r00ta/maas
- refactor-pagination-tests
- Merge into master
Proposed by
Jacopo Rota
Status: | Merged |
---|---|
Approved by: | Jacopo Rota |
Approved revision: | c6440f28ad1b8fe75f9b9bd4f00f354ebc6cc8cb |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~r00ta/maas:refactor-pagination-tests |
Merge into: | maas:master |
Diff against target: |
712 lines (+291/-302) 4 files modified
src/tests/maasapiserver/v3/api/base.py (+145/-18) src/tests/maasapiserver/v3/api/test_machines.py (+39/-90) src/tests/maasapiserver/v3/api/test_resource_pools.py (+55/-98) src/tests/maasapiserver/v3/api/test_zones.py (+52/-96) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
MAAS Lander | Approve | ||
Jack Lloyd-Walters | Approve | ||
Review via email: mp+464426@code.launchpad.net |
Commit message
refactoring: move pagination tests to ApiCommonTests in order to reuse them
Description of the change
This MP aims to move the pagination tests to the common class for the API tests.
To post a comment you must log in.
- c6440f2... by Jacopo Rota
-
refactoring
Revision history for this message
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b refactor-
STATUS: FAILED
LOG: http://
COMMIT: c6440f28ad1b8fe
review:
Needs Fixing
Revision history for this message
Jack Lloyd-Walters (lloydwaltersj) wrote : | # |
Awesome! very nice way of solving this!
review:
Approve
Revision history for this message
Jacopo Rota (r00ta) wrote : | # |
jenkins: !test
Revision history for this message
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b refactor-
STATUS: SUCCESS
COMMIT: c6440f28ad1b8fe
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/tests/maasapiserver/v3/api/base.py b/src/tests/maasapiserver/v3/api/base.py |
2 | index aab1883..c692cf9 100644 |
3 | --- a/src/tests/maasapiserver/v3/api/base.py |
4 | +++ b/src/tests/maasapiserver/v3/api/base.py |
5 | @@ -1,53 +1,110 @@ |
6 | import abc |
7 | from dataclasses import dataclass |
8 | +from typing import Callable, Type, TypeVar |
9 | |
10 | from httpx import AsyncClient |
11 | import pytest |
12 | |
13 | +from maasapiserver.common.api.models.responses.errors import ErrorBodyResponse |
14 | +from maasapiserver.v3.api.models.responses.base import PaginatedResponse |
15 | +from maasapiserver.v3.auth.jwt import UserRole |
16 | +from tests.maasapiserver.fixtures.db import Fixture |
17 | |
18 | -@dataclass |
19 | -class EndpointDetails: |
20 | - method: str |
21 | - path: str |
22 | +T = TypeVar("T", bound=PaginatedResponse) |
23 | |
24 | |
25 | @dataclass |
26 | -class ApiEndpointsRoles: |
27 | - # endpoints that should be accessed without authentication |
28 | - unauthenticated_endpoints: list[EndpointDetails] |
29 | +class PaginatedEndpointTestConfig: |
30 | + response_type: Type[T] |
31 | + create_resources_routine: Callable |
32 | + assert_routine: Callable |
33 | + size_parameters: list[int] = range(0, 10) |
34 | |
35 | - # endpoints that can be accessed with user permissions |
36 | - user_endpoints: list[EndpointDetails] |
37 | |
38 | - # endpoints that can be accessed with admin permissions |
39 | - admin_endpoints: list[EndpointDetails] |
40 | +@dataclass |
41 | +class EndpointDetails: |
42 | + method: str |
43 | + path: str |
44 | + user_role: UserRole |
45 | + # None if the endpoint does not support pagination |
46 | + pagination_config: PaginatedEndpointTestConfig | None = None |
47 | |
48 | |
49 | @pytest.mark.usefixtures("ensuremaasdb") |
50 | @pytest.mark.asyncio |
51 | class ApiCommonTests(abc.ABC): |
52 | + INVALID_PAGINATION_TEST_DATA = [(1, 0), (0, 1), (-1, -1), (1, 1001)] |
53 | + |
54 | @abc.abstractmethod |
55 | - def get_endpoints_configuration(self) -> ApiEndpointsRoles: |
56 | - """Retrieve the configuration for testing authentication of the endpoints. |
57 | + def get_endpoints_configuration(self) -> list[EndpointDetails]: |
58 | + """Retrieve the configuration for testing authentication and pagination of the endpoints. |
59 | |
60 | This method should be overridden by every concrete test class to provide |
61 | the specific configuration required for testing authentication. |
62 | |
63 | Returns: |
64 | - ApiEndpointsRoles: The configuration containing roles and associated endpoints. |
65 | + list[EndpointDetails]: The list containing the endpoints configurations. |
66 | """ |
67 | pass |
68 | |
69 | def pytest_generate_tests(self, metafunc): |
70 | - if "user_endpoint" in metafunc.fixturenames: |
71 | + # generate dynamically the data for the parametrized tests |
72 | + if metafunc.definition.originalname == "test_user_endpoints_forbidden": |
73 | metafunc.parametrize( |
74 | "user_endpoint", |
75 | - self.get_endpoints_configuration().user_endpoints, |
76 | + list( |
77 | + filter( |
78 | + lambda endpoint: endpoint.user_role == UserRole.USER, |
79 | + self.get_endpoints_configuration(), |
80 | + ) |
81 | + ), |
82 | ) |
83 | - if "admin_endpoint" in metafunc.fixturenames: |
84 | + if ( |
85 | + metafunc.definition.originalname |
86 | + == "test_admin_endpoints_forbidden" |
87 | + ): |
88 | metafunc.parametrize( |
89 | "admin_endpoint", |
90 | - self.get_endpoints_configuration().admin_endpoints, |
91 | + list( |
92 | + filter( |
93 | + lambda endpoint: endpoint.user_role == UserRole.ADMIN, |
94 | + self.get_endpoints_configuration(), |
95 | + ) |
96 | + ), |
97 | + ) |
98 | + if ( |
99 | + metafunc.definition.originalname |
100 | + == "test_pagination_endpoint_with_invalid_data" |
101 | + ): |
102 | + paginated_endpoints = list( |
103 | + filter( |
104 | + lambda endpoint: endpoint.pagination_config, |
105 | + self.get_endpoints_configuration(), |
106 | + ) |
107 | + ) |
108 | + # for each endpoint |
109 | + metafunc.parametrize( |
110 | + "paginated_endpoint", |
111 | + paginated_endpoints, |
112 | + ) |
113 | + # for each test data |
114 | + metafunc.parametrize( |
115 | + "page,size", self.INVALID_PAGINATION_TEST_DATA |
116 | + ) |
117 | + if metafunc.definition.originalname == "test_pagination_parameters": |
118 | + paginated_endpoints = list( |
119 | + filter( |
120 | + lambda endpoint: endpoint.pagination_config, |
121 | + self.get_endpoints_configuration(), |
122 | + ) |
123 | + ) |
124 | + metafunc.parametrize( |
125 | + "paginated_endpoint,size", |
126 | + [ |
127 | + (endpoint, size) |
128 | + for endpoint in paginated_endpoints |
129 | + for size in endpoint.pagination_config.size_parameters |
130 | + ], |
131 | ) |
132 | |
133 | async def test_user_endpoints_forbidden( |
134 | @@ -73,3 +130,73 @@ class ApiCommonTests(abc.ABC): |
135 | admin_endpoint.method, admin_endpoint.path |
136 | ) |
137 | assert response.status_code == 403 |
138 | + |
139 | + async def test_pagination_endpoint_with_invalid_data( |
140 | + self, |
141 | + paginated_endpoint: EndpointDetails, |
142 | + page: int, |
143 | + size: int, |
144 | + authenticated_user_api_client_v3: AsyncClient, |
145 | + ) -> None: |
146 | + response = await authenticated_user_api_client_v3.request( |
147 | + paginated_endpoint.method, |
148 | + f"{paginated_endpoint.path}?page={page}&size={size}", |
149 | + ) |
150 | + assert response.status_code == 422 |
151 | + |
152 | + error_response = ErrorBodyResponse(**response.json()) |
153 | + assert error_response.kind == "Error" |
154 | + assert error_response.code == 422 |
155 | + |
156 | + async def test_pagination_parameters( |
157 | + self, |
158 | + paginated_endpoint: EndpointDetails, |
159 | + size: int, |
160 | + api_client: AsyncClient, |
161 | + authenticated_user_api_client_v3: AsyncClient, |
162 | + authenticated_admin_api_client_v3: AsyncClient, |
163 | + fixture: Fixture, |
164 | + ) -> None: |
165 | + # set the required client according to the endpoint requirements |
166 | + if paginated_endpoint.user_role == UserRole.USER: |
167 | + api_client = authenticated_user_api_client_v3 |
168 | + if paginated_endpoint.user_role == UserRole.ADMIN: |
169 | + api_client = authenticated_admin_api_client_v3 |
170 | + |
171 | + created_resources = await paginated_endpoint.pagination_config.create_resources_routine( |
172 | + fixture, size |
173 | + ) |
174 | + |
175 | + response = await api_client.request( |
176 | + paginated_endpoint.method, paginated_endpoint.path |
177 | + ) |
178 | + assert response.status_code == 200 |
179 | + |
180 | + typed_response = paginated_endpoint.pagination_config.response_type( |
181 | + **response.json() |
182 | + ) |
183 | + assert typed_response.total == size |
184 | + assert len(typed_response.items) == size |
185 | + |
186 | + for resource in created_resources: |
187 | + paginated_endpoint.pagination_config.assert_routine( |
188 | + resource, typed_response |
189 | + ) |
190 | + |
191 | + for page in range(1, size // 2): |
192 | + response = await api_client.request( |
193 | + paginated_endpoint.method, |
194 | + f"{paginated_endpoint.path}?page={page}&size=2", |
195 | + ) |
196 | + assert response.status_code == 200 |
197 | + typed_response = ( |
198 | + paginated_endpoint.pagination_config.response_type( |
199 | + **response.json() |
200 | + ) |
201 | + ) |
202 | + assert typed_response.total == size |
203 | + assert ( |
204 | + len(typed_response.items) == 2 |
205 | + if page != size // 2 |
206 | + else (size % 2 or 2) |
207 | + ) |
208 | diff --git a/src/tests/maasapiserver/v3/api/test_machines.py b/src/tests/maasapiserver/v3/api/test_machines.py |
209 | index 05538ff..2566aba 100644 |
210 | --- a/src/tests/maasapiserver/v3/api/test_machines.py |
211 | +++ b/src/tests/maasapiserver/v3/api/test_machines.py |
212 | @@ -1,8 +1,5 @@ |
213 | -from httpx import AsyncClient |
214 | -import pytest |
215 | - |
216 | -from maasapiserver.common.api.models.responses.errors import ErrorBodyResponse |
217 | from maasapiserver.v3.api.models.responses.machines import MachinesListResponse |
218 | +from maasapiserver.v3.auth.jwt import UserRole |
219 | from maasapiserver.v3.constants import EXTERNAL_V3_API_PREFIX |
220 | from maasapiserver.v3.models.machines import Machine |
221 | from tests.fixtures.factories.bmc import create_test_bmc |
222 | @@ -11,99 +8,51 @@ from tests.fixtures.factories.user import create_test_user |
223 | from tests.maasapiserver.fixtures.db import Fixture |
224 | from tests.maasapiserver.v3.api.base import ( |
225 | ApiCommonTests, |
226 | - ApiEndpointsRoles, |
227 | EndpointDetails, |
228 | + PaginatedEndpointTestConfig, |
229 | ) |
230 | |
231 | |
232 | -@pytest.mark.usefixtures("ensuremaasdb") |
233 | -@pytest.mark.asyncio |
234 | class TestMachinesApi(ApiCommonTests): |
235 | - def get_endpoints_configuration(self) -> ApiEndpointsRoles: |
236 | - return ApiEndpointsRoles( |
237 | - unauthenticated_endpoints=[], |
238 | - user_endpoints=[ |
239 | - EndpointDetails( |
240 | - method="GET", |
241 | - path="/api/v3/machines", |
242 | - ), |
243 | - ], |
244 | - admin_endpoints=[], |
245 | - ) |
246 | - |
247 | - def _assert_machine_in_list( |
248 | - self, machine: Machine, machines_response: MachinesListResponse |
249 | - ) -> None: |
250 | - machine_response = next( |
251 | - filter( |
252 | - lambda machine_response: machine.id == machine_response.id, |
253 | - machines_response.items, |
254 | - ) |
255 | - ) |
256 | - assert machine.id == machine_response.id |
257 | - assert ( |
258 | - machine.to_response(f"{EXTERNAL_V3_API_PREFIX}/machines") |
259 | - == machine_response |
260 | - ) |
261 | - |
262 | - @pytest.mark.parametrize("machines_size", range(0, 10)) |
263 | - async def test_list_parameters_200( |
264 | - self, |
265 | - authenticated_user_api_client_v3: AsyncClient, |
266 | - fixture: Fixture, |
267 | - machines_size: int, |
268 | - ) -> None: |
269 | - bmc = await create_test_bmc(fixture) |
270 | - user = await create_test_user(fixture) |
271 | - created_machines = [ |
272 | - ( |
273 | - await create_test_machine( |
274 | - fixture, description=str(i), bmc=bmc, user=user |
275 | + def get_endpoints_configuration(self) -> list[EndpointDetails]: |
276 | + def _assert_machine_in_list( |
277 | + machine: Machine, machines_response: MachinesListResponse |
278 | + ) -> None: |
279 | + machine_response = next( |
280 | + filter( |
281 | + lambda machine_response: machine.id == machine_response.id, |
282 | + machines_response.items, |
283 | ) |
284 | ) |
285 | - for i in range(0, machines_size) |
286 | - ] |
287 | - |
288 | - response = await authenticated_user_api_client_v3.get( |
289 | - "/api/v3/machines" |
290 | - ) |
291 | - assert response.status_code == 200 |
292 | - |
293 | - machines_response = MachinesListResponse(**response.json()) |
294 | - assert machines_response.kind == "MachinesList" |
295 | - assert machines_response.total == machines_size |
296 | - assert len(machines_response.items) == machines_size |
297 | - for machine in created_machines: |
298 | - self._assert_machine_in_list(machine, machines_response) |
299 | - |
300 | - for page in range(1, machines_size // 2): |
301 | - response = await authenticated_user_api_client_v3.get( |
302 | - f"/api/v3/machines?page={page}&size=2" |
303 | - ) |
304 | - assert response.status_code == 200 |
305 | - machines_response = MachinesListResponse(**response.json()) |
306 | - assert machines_response.kind == "MachinesList" |
307 | - assert machines_response.total == machines_size |
308 | + assert machine.id == machine_response.id |
309 | assert ( |
310 | - len(machines_response.items) == 2 |
311 | - if page != machines_size // 2 |
312 | - else (machines_size % 2 or 2) |
313 | + machine.to_response(f"{EXTERNAL_V3_API_PREFIX}/machines") |
314 | + == machine_response |
315 | ) |
316 | |
317 | - @pytest.mark.parametrize( |
318 | - "page,size", [(1, 0), (0, 1), (-1, -1), (1, 1001)] |
319 | - ) |
320 | - async def test_list_422( |
321 | - self, |
322 | - page: int, |
323 | - size: int, |
324 | - authenticated_user_api_client_v3: AsyncClient, |
325 | - ) -> None: |
326 | - response = await authenticated_user_api_client_v3.get( |
327 | - f"/api/v3/machines?page={page}&size={size}" |
328 | - ) |
329 | - assert response.status_code == 422 |
330 | - |
331 | - error_response = ErrorBodyResponse(**response.json()) |
332 | - assert error_response.kind == "Error" |
333 | - assert error_response.code == 422 |
334 | + async def create_pagination_test_resources( |
335 | + fixture: Fixture, size: int |
336 | + ) -> list[Machine]: |
337 | + bmc = await create_test_bmc(fixture) |
338 | + user = await create_test_user(fixture) |
339 | + return [ |
340 | + ( |
341 | + await create_test_machine( |
342 | + fixture, description=str(i), bmc=bmc, user=user |
343 | + ) |
344 | + ) |
345 | + for i in range(0, size) |
346 | + ] |
347 | + |
348 | + return [ |
349 | + EndpointDetails( |
350 | + method="GET", |
351 | + path="/api/v3/machines", |
352 | + user_role=UserRole.USER, |
353 | + pagination_config=PaginatedEndpointTestConfig( |
354 | + response_type=MachinesListResponse, |
355 | + assert_routine=_assert_machine_in_list, |
356 | + create_resources_routine=create_pagination_test_resources, |
357 | + ), |
358 | + ), |
359 | + ] |
360 | diff --git a/src/tests/maasapiserver/v3/api/test_resource_pools.py b/src/tests/maasapiserver/v3/api/test_resource_pools.py |
361 | index 95ff9f2..048fbda 100644 |
362 | --- a/src/tests/maasapiserver/v3/api/test_resource_pools.py |
363 | +++ b/src/tests/maasapiserver/v3/api/test_resource_pools.py |
364 | @@ -13,6 +13,7 @@ from maasapiserver.v3.api.models.responses.resource_pools import ( |
365 | ResourcePoolResponse, |
366 | ResourcePoolsListResponse, |
367 | ) |
368 | +from maasapiserver.v3.auth.jwt import UserRole |
369 | from maasapiserver.v3.constants import EXTERNAL_V3_API_PREFIX |
370 | from maasapiserver.v3.models.resource_pools import ResourcePool |
371 | from tests.fixtures.factories.resource_pools import ( |
372 | @@ -22,113 +23,69 @@ from tests.fixtures.factories.resource_pools import ( |
373 | from tests.maasapiserver.fixtures.db import Fixture |
374 | from tests.maasapiserver.v3.api.base import ( |
375 | ApiCommonTests, |
376 | - ApiEndpointsRoles, |
377 | EndpointDetails, |
378 | + PaginatedEndpointTestConfig, |
379 | ) |
380 | |
381 | |
382 | class TestResourcePoolApi(ApiCommonTests): |
383 | - def get_endpoints_configuration(self) -> ApiEndpointsRoles: |
384 | - return ApiEndpointsRoles( |
385 | - unauthenticated_endpoints=[], |
386 | - user_endpoints=[ |
387 | - EndpointDetails( |
388 | - method="GET", |
389 | - path="/api/v3/resource_pools", |
390 | - ), |
391 | - EndpointDetails( |
392 | - method="GET", |
393 | - path="/api/v3/resource_pools/1", |
394 | - ), |
395 | - ], |
396 | - admin_endpoints=[ |
397 | - EndpointDetails( |
398 | - method="POST", |
399 | - path="/api/v3/resource_pools", |
400 | - ), |
401 | - EndpointDetails( |
402 | - method="PATCH", path="/api/v3/resource_pools/1" |
403 | - ), |
404 | - ], |
405 | - ) |
406 | - |
407 | - def _assert_resource_pools_in_list( |
408 | - self, |
409 | - resource_pools: ResourcePool, |
410 | - resource_pools_response: ResourcePoolsListResponse, |
411 | - ) -> None: |
412 | - resource_pools_response = next( |
413 | - filter( |
414 | - lambda resource_pools_response: resource_pools.id |
415 | - == resource_pools_response.id, |
416 | - resource_pools_response.items, |
417 | + def get_endpoints_configuration(self) -> list[EndpointDetails]: |
418 | + def _assert_resource_pools_in_list( |
419 | + resource_pools: ResourcePool, |
420 | + resource_pools_response: ResourcePoolsListResponse, |
421 | + ) -> None: |
422 | + resource_pools_response = next( |
423 | + filter( |
424 | + lambda resource_pools_response: resource_pools.id |
425 | + == resource_pools_response.id, |
426 | + resource_pools_response.items, |
427 | + ) |
428 | ) |
429 | - ) |
430 | - assert resource_pools.id == resource_pools_response.id |
431 | - assert resource_pools.name == resource_pools_response.name |
432 | - assert ( |
433 | - resource_pools.description == resource_pools_response.description |
434 | - ) |
435 | - |
436 | - @pytest.mark.parametrize("resource_pools_size", range(1, 3)) |
437 | - async def test_list( |
438 | - self, |
439 | - resource_pools_size: int, |
440 | - authenticated_user_api_client_v3: AsyncClient, |
441 | - fixture: Fixture, |
442 | - ) -> None: |
443 | - created_resource_pools = await create_n_test_resource_pools( |
444 | - fixture, size=resource_pools_size |
445 | - ) |
446 | - response = await authenticated_user_api_client_v3.get( |
447 | - "/api/v3/resource_pools" |
448 | - ) |
449 | - assert response.status_code == 200 |
450 | - |
451 | - resource_pools_response = ResourcePoolsListResponse(**response.json()) |
452 | - assert resource_pools_response.kind == "ResourcePoolList" |
453 | - # Increment as the default resource pool is included in the count. |
454 | - assert resource_pools_response.total == resource_pools_size + 1 |
455 | - assert len(resource_pools_response.items) == resource_pools_size + 1 |
456 | - for resource_pools in created_resource_pools: |
457 | - self._assert_resource_pools_in_list( |
458 | - resource_pools, resource_pools_response |
459 | + assert resource_pools.id == resource_pools_response.id |
460 | + assert resource_pools.name == resource_pools_response.name |
461 | + assert ( |
462 | + resource_pools.description |
463 | + == resource_pools_response.description |
464 | ) |
465 | |
466 | - async def test_parametrised_list( |
467 | - self, authenticated_user_api_client_v3: AsyncClient, fixture: Fixture |
468 | - ) -> None: |
469 | - await create_n_test_resource_pools(fixture, size=9) |
470 | - |
471 | - for page in range(1, 6): |
472 | - response = await authenticated_user_api_client_v3.get( |
473 | - f"/api/v3/resource_pools?page={page}&size=2" |
474 | - ) |
475 | - assert response.status_code == 200 |
476 | - resource_pools_response = ResourcePoolsListResponse( |
477 | - **response.json() |
478 | - ) |
479 | - assert resource_pools_response.kind == "ResourcePoolList" |
480 | - assert resource_pools_response.total == 10 |
481 | - assert len(resource_pools_response.items) == 2 |
482 | - |
483 | - @pytest.mark.parametrize( |
484 | - "page,size", [(1, 0), (0, 1), (-1, -1), (1, 1001)] |
485 | - ) |
486 | - async def test_invalid_list( |
487 | - self, |
488 | - page: int, |
489 | - size: int, |
490 | - authenticated_user_api_client_v3: AsyncClient, |
491 | - ) -> None: |
492 | - response = await authenticated_user_api_client_v3.get( |
493 | - f"/api/v3/resource_pools?page={page}&size={size}" |
494 | - ) |
495 | - assert response.status_code == 422 |
496 | + async def create_pagination_test_resources( |
497 | + fixture: Fixture, size: int |
498 | + ) -> list[ResourcePool]: |
499 | + if size > 1: |
500 | + # remove one because we have to consider the default resource pool |
501 | + return await create_n_test_resource_pools( |
502 | + fixture, size=size - 1 |
503 | + ) |
504 | + return [] |
505 | |
506 | - error_response = ErrorBodyResponse(**response.json()) |
507 | - assert error_response.kind == "Error" |
508 | - assert error_response.code == 422 |
509 | + return [ |
510 | + EndpointDetails( |
511 | + method="GET", |
512 | + path="/api/v3/resource_pools", |
513 | + user_role=UserRole.USER, |
514 | + pagination_config=PaginatedEndpointTestConfig( |
515 | + response_type=ResourcePoolsListResponse, |
516 | + assert_routine=_assert_resource_pools_in_list, |
517 | + create_resources_routine=create_pagination_test_resources, |
518 | + size_parameters=list(range(1, 10)), |
519 | + ), |
520 | + ), |
521 | + EndpointDetails( |
522 | + method="GET", |
523 | + path="/api/v3/resource_pools/1", |
524 | + user_role=UserRole.USER, |
525 | + ), |
526 | + EndpointDetails( |
527 | + method="POST", |
528 | + path="/api/v3/resource_pools", |
529 | + user_role=UserRole.ADMIN, |
530 | + ), |
531 | + EndpointDetails( |
532 | + method="PATCH", |
533 | + path="/api/v3/resource_pools/1", |
534 | + user_role=UserRole.ADMIN, |
535 | + ), |
536 | + ] |
537 | |
538 | async def test_get( |
539 | self, authenticated_user_api_client_v3: AsyncClient, fixture: Fixture |
540 | diff --git a/src/tests/maasapiserver/v3/api/test_zones.py b/src/tests/maasapiserver/v3/api/test_zones.py |
541 | index 63c3342..827d8bf 100644 |
542 | --- a/src/tests/maasapiserver/v3/api/test_zones.py |
543 | +++ b/src/tests/maasapiserver/v3/api/test_zones.py |
544 | @@ -14,116 +14,72 @@ from maasapiserver.v3.api.models.responses.zones import ( |
545 | ZoneResponse, |
546 | ZonesListResponse, |
547 | ) |
548 | +from maasapiserver.v3.auth.jwt import UserRole |
549 | from maasapiserver.v3.constants import EXTERNAL_V3_API_PREFIX |
550 | from maasapiserver.v3.models.zones import Zone |
551 | from tests.fixtures.factories.zone import create_test_zone |
552 | from tests.maasapiserver.fixtures.db import Fixture |
553 | from tests.maasapiserver.v3.api.base import ( |
554 | ApiCommonTests, |
555 | - ApiEndpointsRoles, |
556 | EndpointDetails, |
557 | + PaginatedEndpointTestConfig, |
558 | ) |
559 | |
560 | |
561 | -@pytest.mark.usefixtures("ensuremaasdb") |
562 | -@pytest.mark.asyncio |
563 | class TestZonesApi(ApiCommonTests): |
564 | - def get_endpoints_configuration(self) -> ApiEndpointsRoles: |
565 | - return ApiEndpointsRoles( |
566 | - unauthenticated_endpoints=[], |
567 | - user_endpoints=[ |
568 | - EndpointDetails( |
569 | - method="GET", |
570 | - path="/api/v3/zones", |
571 | - ), |
572 | - EndpointDetails( |
573 | - method="GET", |
574 | - path="/api/v3/zones/1", |
575 | - ), |
576 | - ], |
577 | - admin_endpoints=[ |
578 | - EndpointDetails( |
579 | - method="POST", |
580 | - path="/api/v3/zones", |
581 | - ), |
582 | - EndpointDetails(method="DELETE", path="/api/v3/zones/1"), |
583 | - ], |
584 | - ) |
585 | - |
586 | - def _assert_zone_in_list( |
587 | - self, zone: Zone, zones_response: ZonesListResponse |
588 | - ) -> None: |
589 | - zone_response = next( |
590 | - filter( |
591 | - lambda zone_response: zone.id == zone_response.id, |
592 | - zones_response.items, |
593 | - ) |
594 | - ) |
595 | - assert zone.id == zone_response.id |
596 | - assert zone.name == zone_response.name |
597 | - assert zone.description == zone_response.description |
598 | - |
599 | - # GET /zones |
600 | - # We don't have a test that checks for empty list because it's impossible: there is always at least one "default" zone |
601 | - # created at startup by the migration scripts. |
602 | - @pytest.mark.parametrize("zones_size", range(1, 3)) |
603 | - async def test_list_default_200( |
604 | - self, |
605 | - zones_size: int, |
606 | - authenticated_user_api_client_v3: AsyncClient, |
607 | - fixture: Fixture, |
608 | - ) -> None: |
609 | - # The "default" zone with id=1 is created at startup with the migrations. By consequence, we create zones_size-1 zones |
610 | - # here. |
611 | - created_zones = [ |
612 | - (await create_test_zone(fixture, name=str(i), description=str(i))) |
613 | - for i in range(0, zones_size - 1) |
614 | - ] |
615 | - response = await authenticated_user_api_client_v3.get("/api/v3/zones") |
616 | - assert response.status_code == 200 |
617 | - |
618 | - zones_response = ZonesListResponse(**response.json()) |
619 | - assert zones_response.kind == "ZonesList" |
620 | - assert zones_response.total == zones_size |
621 | - assert len(zones_response.items) == zones_size |
622 | - for zone in created_zones: |
623 | - self._assert_zone_in_list(zone, zones_response) |
624 | - |
625 | - async def test_list_parameters_200( |
626 | - self, authenticated_user_api_client_v3: AsyncClient, fixture: Fixture |
627 | - ) -> None: |
628 | - # The "default" zone with id=1 is created at startup with the migrations. By consequence, we create zones_size-1 zones |
629 | - # here. |
630 | - for i in range(0, 9): |
631 | - await create_test_zone(fixture, name=str(i), description=str(i)) |
632 | - |
633 | - for page in range(1, 6): |
634 | - response = await authenticated_user_api_client_v3.get( |
635 | - f"/api/v3/zones?page={page}&size=2" |
636 | + def get_endpoints_configuration(self) -> list[EndpointDetails]: |
637 | + def _assert_zone_in_list( |
638 | + zone: Zone, zones_response: ZonesListResponse |
639 | + ) -> None: |
640 | + zone_response = next( |
641 | + filter( |
642 | + lambda zone_response: zone.id == zone_response.id, |
643 | + zones_response.items, |
644 | + ) |
645 | ) |
646 | - assert response.status_code == 200 |
647 | - zones_response = ZonesListResponse(**response.json()) |
648 | - assert zones_response.kind == "ZonesList" |
649 | - assert zones_response.total == 10 |
650 | - assert len(zones_response.items) == 2 |
651 | + assert zone.id == zone_response.id |
652 | + assert zone.name == zone_response.name |
653 | + assert zone.description == zone_response.description |
654 | |
655 | - @pytest.mark.parametrize( |
656 | - "page,size", [(1, 0), (0, 1), (-1, -1), (1, 1001)] |
657 | - ) |
658 | - async def test_list_422( |
659 | - self, |
660 | - page: int, |
661 | - size: int, |
662 | - authenticated_user_api_client_v3: AsyncClient, |
663 | - ) -> None: |
664 | - response = await authenticated_user_api_client_v3.get( |
665 | - f"/api/v3/zones?page={page}&size={size}" |
666 | - ) |
667 | - assert response.status_code == 422 |
668 | + async def create_pagination_test_resources( |
669 | + fixture: Fixture, size: int |
670 | + ) -> list[Zone]: |
671 | + if size > 1: |
672 | + # remove one because we have to consider the default zone |
673 | + return [ |
674 | + ( |
675 | + await create_test_zone( |
676 | + fixture, name=str(i), description=str(i) |
677 | + ) |
678 | + ) |
679 | + for i in range(0, size - 1) |
680 | + ] |
681 | + return [] |
682 | |
683 | - error_response = ErrorBodyResponse(**response.json()) |
684 | - assert error_response.kind == "Error" |
685 | - assert error_response.code == 422 |
686 | + return [ |
687 | + EndpointDetails( |
688 | + method="GET", |
689 | + path="/api/v3/zones", |
690 | + user_role=UserRole.USER, |
691 | + pagination_config=PaginatedEndpointTestConfig( |
692 | + response_type=ZonesListResponse, |
693 | + assert_routine=_assert_zone_in_list, |
694 | + create_resources_routine=create_pagination_test_resources, |
695 | + size_parameters=list(range(1, 10)), |
696 | + ), |
697 | + ), |
698 | + EndpointDetails( |
699 | + method="GET", path="/api/v3/zones/1", user_role=UserRole.USER |
700 | + ), |
701 | + EndpointDetails( |
702 | + method="POST", path="/api/v3/zones", user_role=UserRole.ADMIN |
703 | + ), |
704 | + EndpointDetails( |
705 | + method="DELETE", |
706 | + path="/api/v3/zones/1", |
707 | + user_role=UserRole.ADMIN, |
708 | + ), |
709 | + ] |
710 | |
711 | # GET /zones/{zone_id} |
712 | async def test_get_default( |
UNIT TESTS pagination- tests lp:~r00ta/maas/+git/maas into -b master lp:~maas-committers/maas
-b refactor-
STATUS: FAILED maas-ci. internal: 8080/job/ maas-tester/ 5296/console 3f2efe63436929a 704cb7042f
LOG: http://
COMMIT: 4023501e6d37c69