diff --git a/doc/changelog.rst b/doc/changelog.rst index 9a0460f..9adac30 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,6 +7,7 @@ Changelog Fixed ^^^^^ - Fix :attr:`~SearchRequest.start_index` and :attr:`~SearchRequest.count` limits. :issue:`84` +- :attr:`~ListResponse.total_resuls` is required. [0.3.0] - 2024-12-11 -------------------- diff --git a/scim2_models/rfc7644/list_response.py b/scim2_models/rfc7644/list_response.py index 099bee8..af55ec6 100644 --- a/scim2_models/rfc7644/list_response.py +++ b/scim2_models/rfc7644/list_response.py @@ -104,7 +104,13 @@ class ListResponse(Message, Generic[AnyResource], metaclass=ListResponseMetaclas def check_results_number( cls, value: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo ) -> Self: - """:rfc:`RFC7644 §3.4.2 <7644#section-3.4.2.4>` indicates that 'resources' must be set if 'totalResults' is non-zero.""" + """Validate result numbers. + + :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2.4>` indicates that: + + - 'totalResults' is required + - 'resources' must be set if 'totalResults' is non-zero. + """ obj = handler(value) if ( @@ -114,6 +120,12 @@ def check_results_number( ): return obj + if obj.total_results is None: + raise PydanticCustomError( + "required_error", + "Field 'total_results' is required but value is missing or null", + ) + if obj.total_results > 0 and not obj.resources: raise PydanticCustomError( "no_resource_error", diff --git a/tests/test_list_response.py b/tests/test_list_response.py index 071cb5d..cf9419e 100644 --- a/tests/test_list_response.py +++ b/tests/test_list_response.py @@ -217,3 +217,26 @@ def test_list_response_schema_ordering(): ], } ListResponse[Union[User[EnterpriseUser], Group]].model_validate(payload) + + +def test_total_results_required(): + """ListResponse.total_results is required.""" + payload = { + "Resources": [ + { + "schemas": [ + "urn:ietf:params:scim:schemas:core:2.0:User", + ], + "userName": "bjensen@example.com", + "id": "foobar", + } + ], + } + + with pytest.raises( + ValidationError, + match="Field 'total_results' is required but value is missing or null", + ): + ListResponse[User].model_validate( + payload, scim_ctx=Context.RESOURCE_QUERY_RESPONSE + )