Skip to content

Commit d2e7f62

Browse files
committed
feat: support loading configuration object in ListResponses
1 parent 3cc0ebe commit d2e7f62

File tree

3 files changed

+130
-53
lines changed

3 files changed

+130
-53
lines changed

doc/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Changelog
77
Added
88
^^^^^
99
- Display server discovery step network connections.
10+
- Support loading server configuration objects in :class:`~scim2_models.ListResponses`.
1011

1112
[0.2.0] - 2024-12-03
1213
--------------------

scim2_cli/__init__.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from scim2_client import SCIMClientError
1010
from scim2_client.engines.httpx import SyncSCIMClient
1111
from scim2_models import Group
12+
from scim2_models import ListResponse
1213
from scim2_models import Resource
1314
from scim2_models import ResourceType
1415
from scim2_models import Schema
@@ -53,17 +54,27 @@ def load_config_files(
5354
]:
5455
if schemas_fd:
5556
schemas_payload = json.load(schemas_fd)
56-
schemas_obj = [Schema.model_validate(schema) for schema in schemas_payload]
57+
if isinstance(schemas_payload, dict):
58+
schemas_obj = ListResponse[Schema].model_validate(schemas_payload).resources
59+
else:
60+
schemas_obj = [Schema.model_validate(schema) for schema in schemas_payload]
5761
resource_models = [Resource.from_schema(schema) for schema in schemas_obj]
5862

5963
else:
6064
resource_models = [User, Group]
6165

6266
if resource_types_fd:
6367
resource_types_payload = json.load(resource_types_fd)
64-
resource_types = [
65-
ResourceType.model_validate(item) for item in resource_types_payload
66-
]
68+
if isinstance(schemas_payload, dict):
69+
resource_types = (
70+
ListResponse[ResourceType]
71+
.model_validate(resource_types_payload)
72+
.resources
73+
)
74+
else:
75+
resource_types = [
76+
ResourceType.model_validate(item) for item in resource_types_payload
77+
]
6778
else:
6879
resource_types = None
6980

tests/test_cli.py

Lines changed: 114 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import json
22
import os
33

4+
import pytest
45
from scim2_models import AuthenticationScheme
56
from scim2_models import Bulk
67
from scim2_models import ChangePassword
78
from scim2_models import ETag
89
from scim2_models import Filter
10+
from scim2_models import ListResponse
911
from scim2_models import Patch
1012
from scim2_models import ResourceType
13+
from scim2_models import Schema
1114
from scim2_models import ServiceProviderConfig
1215
from scim2_models import Sort
1316
from scim2_models import User
@@ -112,11 +115,9 @@ def test_env_vars(runner, httpserver, simple_user_payload):
112115
del os.environ["SCIM_CLI_HEADERS"]
113116

114117

115-
def test_custom_configuration_by_parameter(
116-
runner, httpserver, simple_user_payload, tmp_path
117-
):
118-
"""Test passing custom .JSON configuration files to the command."""
119-
spc = ServiceProviderConfig(
118+
@pytest.fixture
119+
def service_provider_configuration():
120+
return ServiceProviderConfig(
120121
documentation_uri="https://scim.test",
121122
patch=Patch(supported=False),
122123
bulk=Bulk(supported=False, max_operations=0, max_payload_size=0),
@@ -134,29 +135,48 @@ def test_custom_configuration_by_parameter(
134135
primary=True,
135136
),
136137
],
137-
).model_dump()
138+
)
138139

139-
spc_path = tmp_path / "service_provider_configuration.json"
140-
with open(spc_path, "w") as fd:
141-
json.dump(spc, fd)
142140

143-
schemas = [User.to_schema().model_dump()]
144-
schemas_path = tmp_path / "schemas.json"
145-
with open(schemas_path, "w") as fd:
146-
json.dump(schemas, fd)
141+
@pytest.fixture
142+
def schemas():
143+
return [User.to_schema()]
144+
147145

148-
resource_types = [
146+
@pytest.fixture
147+
def resource_types():
148+
return [
149149
ResourceType(
150150
id="User",
151151
name="User",
152152
endpoint="/somewhere-different",
153153
description="User accounts",
154154
schema_="urn:ietf:params:scim:schemas:core:2.0:User",
155-
).model_dump()
155+
)
156156
]
157+
158+
159+
def test_custom_configuration_by_parameter(
160+
runner,
161+
httpserver,
162+
simple_user_payload,
163+
tmp_path,
164+
service_provider_configuration,
165+
schemas,
166+
resource_types,
167+
):
168+
"""Test passing custom .JSON configuration files to the command."""
169+
spc_path = tmp_path / "service_provider_configuration.json"
170+
with open(spc_path, "w") as fd:
171+
json.dump(service_provider_configuration.model_dump(), fd)
172+
173+
schemas_path = tmp_path / "schemas.json"
174+
with open(schemas_path, "w") as fd:
175+
json.dump([schema.model_dump() for schema in schemas], fd)
176+
157177
resource_types_path = tmp_path / "resource_types.json"
158178
with open(resource_types_path, "w") as fd:
159-
json.dump(resource_types, fd)
179+
json.dump([resource_type.model_dump() for resource_type in resource_types], fd)
160180

161181
httpserver.expect_request(
162182
"/somewhere-different/foobar",
@@ -187,49 +207,94 @@ def test_custom_configuration_by_parameter(
187207
assert result.exit_code == 0
188208

189209

190-
def test_custom_configuration_by_env(runner, httpserver, simple_user_payload, tmp_path):
191-
"""Test passing custom .JSON configuration files to the command."""
192-
spc = ServiceProviderConfig(
193-
documentation_uri="https://scim.test",
194-
patch=Patch(supported=False),
195-
bulk=Bulk(supported=False, max_operations=0, max_payload_size=0),
196-
change_password=ChangePassword(supported=True),
197-
filter=Filter(supported=False, max_results=0),
198-
sort=Sort(supported=False),
199-
etag=ETag(supported=False),
200-
authentication_schemes=[
201-
AuthenticationScheme(
202-
name="OAuth Bearer Token",
203-
description="Authentication scheme using the OAuth Bearer Token Standard",
204-
spec_uri="http://www.rfc-editor.org/info/rfc6750",
205-
documentation_uri="https://scim.test",
206-
type="oauthbearertoken",
207-
primary=True,
208-
),
210+
def test_custom_configuration_in_list_response(
211+
runner,
212+
httpserver,
213+
simple_user_payload,
214+
tmp_path,
215+
service_provider_configuration,
216+
schemas,
217+
resource_types,
218+
):
219+
"""Test that ListResponse format is supported."""
220+
spc_path = tmp_path / "service_provider_configuration.json"
221+
with open(spc_path, "w") as fd:
222+
json.dump(service_provider_configuration.model_dump(), fd)
223+
224+
schemas_path = tmp_path / "schemas.json"
225+
with open(schemas_path, "w") as fd:
226+
json.dump(
227+
ListResponse[Schema](
228+
total_results=len(schemas),
229+
start_index=1,
230+
items_per_page=len(schemas),
231+
resources=schemas,
232+
).model_dump(),
233+
fd,
234+
)
235+
236+
resource_types_path = tmp_path / "resource_types.json"
237+
with open(resource_types_path, "w") as fd:
238+
json.dump(
239+
ListResponse[ResourceType](
240+
total_results=len(resource_types),
241+
start_index=1,
242+
items_per_page=len(resource_types),
243+
resources=resource_types,
244+
).model_dump(),
245+
fd,
246+
)
247+
248+
httpserver.expect_request(
249+
"/somewhere-different/foobar",
250+
method="GET",
251+
).respond_with_json(
252+
simple_user_payload("foobar"),
253+
status=200,
254+
content_type="application/scim+json",
255+
)
256+
257+
result = runner.invoke(
258+
cli,
259+
[
260+
"--url",
261+
httpserver.url_for("/"),
262+
"--service-provider-config",
263+
spc_path,
264+
"--schemas",
265+
schemas_path,
266+
"--resource-types",
267+
resource_types_path,
268+
"query",
269+
"user",
270+
"foobar",
209271
],
210-
).model_dump()
272+
catch_exceptions=False,
273+
)
274+
assert result.exit_code == 0
211275

276+
277+
def test_custom_configuration_by_env(
278+
runner,
279+
httpserver,
280+
simple_user_payload,
281+
tmp_path,
282+
service_provider_configuration,
283+
schemas,
284+
resource_types,
285+
):
286+
"""Test passing custom .JSON configuration files to the command."""
212287
spc_path = tmp_path / "service_provider_configuration.json"
213288
with open(spc_path, "w") as fd:
214-
json.dump(spc, fd)
289+
json.dump(service_provider_configuration.model_dump(), fd)
215290

216-
schemas = [User.to_schema().model_dump()]
217291
schemas_path = tmp_path / "schemas.json"
218292
with open(schemas_path, "w") as fd:
219-
json.dump(schemas, fd)
293+
json.dump([schema.model_dump() for schema in schemas], fd)
220294

221-
resource_types = [
222-
ResourceType(
223-
id="User",
224-
name="User",
225-
endpoint="/somewhere-different",
226-
description="User accounts",
227-
schema_="urn:ietf:params:scim:schemas:core:2.0:User",
228-
).model_dump()
229-
]
230295
resource_types_path = tmp_path / "resource_types.json"
231296
with open(resource_types_path, "w") as fd:
232-
json.dump(resource_types, fd)
297+
json.dump([resource_type.model_dump() for resource_type in resource_types], fd)
233298

234299
httpserver.expect_request(
235300
"/somewhere-different/foobar",

0 commit comments

Comments
 (0)