Skip to content

Commit 2852021

Browse files
committed
tests: add tests for sync groups
1 parent 647f9f2 commit 2852021

File tree

7 files changed

+144
-3
lines changed

7 files changed

+144
-3
lines changed

invenio_cern_sync/authz/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
def request_with_retries(
2222
url, method="GET", payload=None, headers=None, retries=3, delay=5
2323
):
24+
"""Make an HTTP request with retries."""
2425
for attempt in range(retries):
2526
try:
2627
if method.upper() == "GET":
@@ -148,7 +149,6 @@ def get_identities(self, fields=IDENTITY_FIELDS):
148149

149150
def get_groups(self, fields=GROUPS_FIELDS):
150151
"""Get all groups."""
151-
152152
query_params = [("field", value) for value in fields]
153153
query_params += [
154154
("limit", self.limit),

invenio_cern_sync/groups/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2024 CERN.
4+
#
5+
# Invenio-CERN-sync is free software; you can redistribute it and/or modify it under
6+
# the terms of the MIT License; see LICENSE file for more details.
7+
8+
"""Invenio-CERN-sync groups module."""

invenio_cern_sync/groups/sync.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2024 CERN.
4+
#
5+
# Invenio-CERN-sync is free software; you can redistribute it and/or modify it under
6+
# the terms of the MIT License; see LICENSE file for more details.
7+
8+
"""Invenio-CERN-sync groups sync API."""
9+
10+
import time
11+
import uuid
12+
13+
from invenio_oauthclient.handlers.utils import create_or_update_roles
14+
15+
from ..authz.client import AuthZService, KeycloakService
16+
from ..logging import log_info
17+
18+
19+
def _serialize_groups(groups):
20+
"""Serialize groups."""
21+
for group in groups:
22+
yield {
23+
"id": group["groupIdentifier"],
24+
"name": group["displayName"],
25+
"description": group["description"],
26+
}
27+
28+
29+
def sync(**kwargs):
30+
"""Sync CERN groups with local db."""
31+
log_uuid = str(uuid.uuid4())
32+
log_info(log_uuid, "groups_sync", dict(status="fetching-cern-groups"))
33+
start_time = time.time()
34+
35+
overridden_params = kwargs.get("keycloak_service", dict())
36+
keycloak_service = KeycloakService(**overridden_params)
37+
38+
overridden_params = kwargs.get("authz_service", dict())
39+
authz_client = AuthZService(keycloak_service, **overridden_params)
40+
41+
overridden_params = kwargs.get("groups", dict())
42+
groups = authz_client.get_groups(**overridden_params)
43+
44+
roles_ids = create_or_update_roles(_serialize_groups(groups))
45+
46+
total_time = time.time() - start_time
47+
log_info(log_uuid, "groups_sync", dict(status="completed", time=total_time))
48+
49+
return list(roles_ids)

invenio_cern_sync/users/sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def sync(method="AuthZ", **kwargs):
198198
overridden_params = kwargs.get("authz_service", dict())
199199
authz_client = AuthZService(keycloak_service, **overridden_params)
200200

201-
overridden_params = kwargs.get("identities_fields", dict())
201+
overridden_params = kwargs.get("identities", dict())
202202
users = authz_client.get_identities(**overridden_params)
203203
serializer_fn = serialize_cern_identities
204204
elif method == "LDAP":

tests/conftest.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,18 @@ def ldap_users():
108108
}
109109
)
110110
return users
111+
112+
113+
@pytest.fixture()
114+
def authz_groups():
115+
"""Return CERN groups test data."""
116+
groups = []
117+
for i in range(10):
118+
groups.append(
119+
{
120+
"groupIdentifier": f"cern-accounts{i}",
121+
"displayName": f"CERN Accounts {i}",
122+
"description": "This is a test group {i}",
123+
}
124+
)
125+
return groups

tests/test_sync_groups.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2024 CERN.
4+
#
5+
# Invenio-CERN-sync is free software; you can redistribute it and/or modify it
6+
# under the terms of the MIT License; see LICENSE file for more details.
7+
8+
"""Sync groups tests."""
9+
10+
from unittest import mock
11+
from unittest.mock import patch
12+
13+
from invenio_accounts.proxies import current_datastore
14+
15+
from invenio_cern_sync.groups.sync import sync
16+
17+
18+
@patch("invenio_cern_sync.groups.sync.KeycloakService")
19+
@patch("invenio_cern_sync.groups.sync.AuthZService")
20+
def test_sync_groups(
21+
MockAuthZService,
22+
MockKeycloakService,
23+
app,
24+
authz_groups,
25+
):
26+
"""Test sync with AuthZ."""
27+
MockAuthZService.return_value.get_groups.return_value = authz_groups
28+
29+
results = sync()
30+
31+
for expected_group in list(authz_groups):
32+
role = current_datastore.find_role_by_id(expected_group["groupIdentifier"])
33+
assert role.name == expected_group["displayName"]
34+
assert role.description == expected_group["description"]
35+
36+
assert len(results) == len(authz_groups)
37+
38+
39+
@patch("invenio_cern_sync.groups.sync.KeycloakService")
40+
@patch("invenio_cern_sync.groups.sync.AuthZService")
41+
def test_sync_groups_update(
42+
MockAuthZService,
43+
MockKeycloakService,
44+
app,
45+
authz_groups,
46+
):
47+
"""Test sync with AuthZ."""
48+
# prepare the db with the initial data
49+
MockAuthZService.return_value.get_groups.return_value = authz_groups
50+
sync()
51+
52+
new_group = {
53+
"groupIdentifier": "cern-primary-accounts",
54+
"displayName": "CERN Primary Accounts",
55+
"description": "Group for primary CERN accounts",
56+
}
57+
updated_group = {
58+
"groupIdentifier": "cern-accounts3",
59+
"displayName": "New display name",
60+
"description": "New description",
61+
}
62+
63+
MockAuthZService.return_value.get_groups.return_value = [new_group, updated_group]
64+
sync()
65+
66+
for expected_group in [new_group, updated_group]:
67+
role = current_datastore.find_role_by_id(expected_group["groupIdentifier"])
68+
assert role.name == expected_group["displayName"]
69+
assert role.description == expected_group["description"]

tests/test_sync.py renamed to tests/test_sync_users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Invenio-CERN-sync is free software; you can redistribute it and/or modify it
66
# under the terms of the MIT License; see LICENSE file for more details.
77

8-
"""Sync tests."""
8+
"""Sync users tests."""
99

1010
from unittest import mock
1111
from unittest.mock import patch

0 commit comments

Comments
 (0)