|
| 1 | +from unittest.mock import patch |
| 2 | + |
1 | 3 | import pytest |
2 | 4 |
|
3 | 5 | from infrahub.core import registry |
4 | 6 | from infrahub.core.branch import Branch |
5 | 7 | from infrahub.core.node import Node |
6 | 8 | from infrahub.core.node.constraints.grouped_uniqueness import NodeGroupedUniquenessConstraint |
| 9 | +from infrahub.core.validators.uniqueness.query import NodeUniqueAttributeConstraintQuery |
7 | 10 | from infrahub.database import InfrahubDatabase |
8 | 11 | from infrahub.exceptions import ValidationError |
9 | 12 |
|
@@ -197,6 +200,86 @@ async def test_uniqueness_constraint_no_conflict_relationship_and_attribute( |
197 | 200 |
|
198 | 201 | await self.__call_system_under_test(db=db, branch=default_branch, node=car_node) |
199 | 202 |
|
| 203 | + @pytest.mark.parametrize( |
| 204 | + ["node_constraints", "parent_constraints", "node_query_should_run"], |
| 205 | + [ |
| 206 | + ( |
| 207 | + [ |
| 208 | + ["nbr_seats__value", "name__value"], |
| 209 | + ["previous_owner", "nbr_seats__value"], |
| 210 | + ], |
| 211 | + [ |
| 212 | + ["nbr_seats__value", "name__value"], |
| 213 | + ["previous_owner", "nbr_seats__value"], |
| 214 | + ], |
| 215 | + False, |
| 216 | + ), |
| 217 | + ( |
| 218 | + [ |
| 219 | + ["nbr_seats__value", "name__value"], |
| 220 | + ], |
| 221 | + [ |
| 222 | + ["nbr_seats__value", "name__value"], |
| 223 | + ["previous_owner", "nbr_seats__value"], |
| 224 | + ], |
| 225 | + False, |
| 226 | + ), |
| 227 | + ( |
| 228 | + [ |
| 229 | + ["previous_owner", "name__value"], |
| 230 | + ], |
| 231 | + [ |
| 232 | + ["nbr_seats__value", "name__value"], |
| 233 | + ["previous_owner", "nbr_seats__value"], |
| 234 | + ], |
| 235 | + True, |
| 236 | + ), |
| 237 | + ( |
| 238 | + [ |
| 239 | + ["nbr_seats__value", "name__value"], |
| 240 | + ["previous_owner", "nbr_seats__value", "color__value"], |
| 241 | + ], |
| 242 | + [ |
| 243 | + ["nbr_seats__value", "name__value"], |
| 244 | + ["previous_owner", "nbr_seats__value"], |
| 245 | + ], |
| 246 | + True, |
| 247 | + ), |
| 248 | + ], |
| 249 | + ) |
| 250 | + async def test_uniqueness_constraint_skips_overlapping_constraints( |
| 251 | + self, |
| 252 | + db: InfrahubDatabase, |
| 253 | + default_branch: Branch, |
| 254 | + car_person_generics_data_simple, |
| 255 | + node_constraints: list[list[str]], |
| 256 | + parent_constraints: list[list[str]], |
| 257 | + node_query_should_run: bool, |
| 258 | + ): |
| 259 | + car_node: Node = car_person_generics_data_simple["c1"] |
| 260 | + car_schema = car_node.get_schema() |
| 261 | + schema_branch = registry.schema.get_schema_branch(name=default_branch.name) |
| 262 | + parent_kind = car_schema.inherit_from[0] |
| 263 | + parent_schema = schema_branch.get(name=parent_kind, duplicate=False) |
| 264 | + car_schema.uniqueness_constraints = node_constraints |
| 265 | + parent_schema.uniqueness_constraints = parent_constraints |
| 266 | + |
| 267 | + # make sure we only use this query once if the constraints overlap |
| 268 | + with patch( |
| 269 | + "infrahub.core.node.constraints.grouped_uniqueness.NodeUniqueAttributeConstraintQuery", |
| 270 | + wraps=NodeUniqueAttributeConstraintQuery, |
| 271 | + ) as wrapped_query: |
| 272 | + await self.__call_system_under_test(db=db, branch=default_branch, node=car_node) |
| 273 | + if node_query_should_run: |
| 274 | + assert len(wrapped_query.init.call_args_list) == 2 |
| 275 | + else: |
| 276 | + assert len(wrapped_query.init.call_args_list) == 1 |
| 277 | + query_kinds = {init_call[1]["query_request"].kind for init_call in wrapped_query.init.call_args_list} |
| 278 | + if node_query_should_run: |
| 279 | + assert query_kinds == {car_schema.kind, parent_kind} |
| 280 | + else: |
| 281 | + assert query_kinds == {parent_kind} |
| 282 | + |
200 | 283 | async def test_uniqueness_constraint_conflict_relationship_and_attribute( |
201 | 284 | self, db: InfrahubDatabase, default_branch: Branch, car_person_generics_data_simple |
202 | 285 | ): |
|
0 commit comments