Skip to content

Commit 6dcd671

Browse files
committed
feat(groups): implemented memberfields (#139)
1 parent 74e3251 commit 6dcd671

5 files changed

Lines changed: 142 additions & 6 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,5 @@ Anybody using this code is more than welcome to contribute with change requests
8989

9090
* benste - implemented for use at Evangelische Kirchengemeinde Baiersbronn (https://www.evang-kirche-baiersbronn.de/)
9191
* kolibri52 - Jonathan supporting Liebenzeller Gemeinschaft Oettingen (https://lgv-oe.de/)
92-
* fschrempf - Frieder supporting CVJM Esslingen e. V. (https://cvjm-esslingen.de)
92+
* fschrempf - Frieder supporting CVJM Esslingen e. V. (https://cvjm-esslingen.de)
93+
* wengc3 - https://github.com/wengc3

churchtools_api/groups.py

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,42 @@ def update_group(self, group_id: int, data: dict) -> dict:
219219
)
220220
return None
221221

222+
def update_group_member(self, group_id: int, person_id: int, data: dict) -> dict:
223+
"""Update a field of the given member in group.
224+
225+
to loookup available names use get_group_member(group_id=xxx).
226+
227+
Arguments:
228+
group_id: number of the group to update
229+
person_id: number of the member to update
230+
data: all group member fields
231+
232+
Returns:
233+
dict with updated group member
234+
"""
235+
url = self.domain + f"/api/groups/{group_id}/members/{person_id}"
236+
headers = {
237+
"accept": "application/json",
238+
"Content-Type": "application/json",
239+
}
240+
response = self.session.patch(url=url, headers=headers, data=json.dumps(data))
241+
242+
if response.status_code == requests.codes.ok:
243+
response_content = json.loads(response.content)
244+
response_data = response_content["data"].copy()
245+
logger.debug(
246+
"First response of Update Group Member successful len=%s",
247+
len(response_content),
248+
)
249+
250+
return response_data
251+
logger.warning(
252+
"%s Something went wrong updating group: %s",
253+
response.status_code,
254+
response.content,
255+
)
256+
return None
257+
222258
def delete_group(self, group_id: int) -> bool:
223259
"""Delete the given group.
224260
@@ -311,10 +347,11 @@ def get_group_members(self, group_id: int, **kwargs: dict) -> list[dict]:
311347
312348
Arguments:
313349
group_id: group id
314-
kwargs: see below
350+
kwargs: see API documentation - only tested cases below
315351
316352
Kwargs:
317353
role_ids: list[int]: optional filter list of role ids
354+
person_ids: list[int]: optional filter by person_id
318355
319356
Returns:
320357
list of group member dicts
@@ -325,6 +362,8 @@ def get_group_members(self, group_id: int, **kwargs: dict) -> list[dict]:
325362

326363
if "role_ids" in kwargs:
327364
params["role_ids[]"] = kwargs["role_ids"]
365+
if "person_ids" in kwargs:
366+
params["person_id[]"] = kwargs["person_ids"]
328367

329368
response = self.session.get(url=url, headers=headers, params=params)
330369

@@ -345,6 +384,38 @@ def get_group_members(self, group_id: int, **kwargs: dict) -> list[dict]:
345384
)
346385
return None
347386

387+
def get_group_memberfields(self, group_id: int) -> list[dict]:
388+
"""Get list of member fields for the given group.
389+
390+
Arguments:
391+
group_id: group id
392+
393+
Returns:
394+
list of group member fields dicts
395+
"""
396+
url = self.domain + f"/api/groups/{group_id}/memberfields"
397+
headers = {"accept": "application/json"}
398+
params = {}
399+
400+
response = self.session.get(url=url, headers=headers, params=params)
401+
402+
if response.status_code == requests.codes.ok:
403+
response_content = json.loads(response.content)
404+
405+
response_data = self.combine_paginated_response_data(
406+
response_content,
407+
url=url,
408+
headers=headers,
409+
)
410+
return [response_data] if isinstance(response_data, dict) else response_data
411+
412+
logger.warning(
413+
"%s Something went wrong fetching group member fields: %s",
414+
response.status_code,
415+
response.content,
416+
)
417+
return None
418+
348419
def get_groups_members(
349420
self,
350421
group_ids: list[int] | None = None,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "churchtools-api"
3-
version = "1.7.2"
3+
version = "1.7.3"
44
description = "A python wrapper for use with ChurchToolsAPI"
55
authors = [
66
"bensteUEM",

tests/test_churchtools_api_groups.py

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,42 @@ def test_update_group(self) -> None:
223223
groups = self.api.get_groups(group_id=SAMPLE_GROUP_ID)
224224
assert groups[0]["information"]["note"] == ""
225225

226+
def test_update_group_member(self) -> None:
227+
"""Checks that a field of a group member can be set.
228+
229+
to some value and the returned group member has this field value set.
230+
Also cleans the field after executing the test
231+
232+
IMPORTANT - This test method and the parameters used depend on target system!
233+
the hard coded sample exists on ELKW1610.KRZ.TOOLS
234+
"""
235+
SAMPLE_GROUP_ID = 103
236+
SAMPLE_MEMBER_ID = 513
237+
238+
# check comment is empty as prerequisite
239+
pre_test_user_state = self.api.get_group_members(
240+
group_id=SAMPLE_GROUP_ID, person_ids=[SAMPLE_MEMBER_ID]
241+
)[0]
242+
assert pre_test_user_state.get("comment") is None
243+
244+
# set a new sample comment
245+
data = {"comment": "Updated Over API"}
246+
group_member_update_result = self.api.update_group_member(
247+
group_id=SAMPLE_GROUP_ID, person_id=SAMPLE_MEMBER_ID, data=data
248+
)
249+
assert group_member_update_result["comment"] == data["comment"]
250+
251+
# cleanup / delete comment after test
252+
group_member_update_result = self.api.update_group_member(
253+
group_id=SAMPLE_GROUP_ID,
254+
person_id=SAMPLE_MEMBER_ID,
255+
data={"comment": None},
256+
)
257+
members = self.api.get_group_members(
258+
group_id=SAMPLE_GROUP_ID, person_ids=[SAMPLE_MEMBER_ID]
259+
)
260+
assert members[0]["comment"] is None
261+
226262
def test_get_group_members(self) -> None:
227263
"""Checks if group members can be retrieved.
228264
@@ -233,13 +269,16 @@ def test_get_group_members(self) -> None:
233269
"""
234270
SAMPLE_GROUP_ID = 103
235271
SAMPLE_GROUPTYPE_ROLE_ID = 16
236-
members = self.api.get_group_members(group_id=SAMPLE_GROUP_ID)
272+
SAMPLE_USER_ID = 513
237273

274+
# 1. retrieve all group member by group_id
275+
members = self.api.get_group_members(group_id=SAMPLE_GROUP_ID)
238276
assert members is not None
239277
assert members != []
240278
for member in members:
241279
assert "personId" in member
242280

281+
# 2. retrieve group members by role
243282
members = self.api.get_group_members(
244283
group_id=SAMPLE_GROUP_ID,
245284
role_ids=[SAMPLE_GROUPTYPE_ROLE_ID],
@@ -250,10 +289,35 @@ def test_get_group_members(self) -> None:
250289
assert "personId" in member
251290
assert member["groupTypeRoleId"] == SAMPLE_GROUPTYPE_ROLE_ID
252291

292+
# 3. retrieve group members by person_id
293+
members = self.api.get_group_members(
294+
group_id=SAMPLE_GROUP_ID,
295+
person_ids=[SAMPLE_USER_ID],
296+
)
297+
assert members is not None
298+
assert members != []
299+
assert len(members) == 1
300+
assert members[0]["personId"] == SAMPLE_USER_ID
301+
302+
def test_get_group_memberfields(self) -> None:
303+
"""Checks if group member fields can be retrieved from a group.
304+
305+
IMPORTANT - This test method and the parameters used depend on target system!
306+
the hard coded sample exists on ELKW1610.KRZ.TOOLS
307+
"""
308+
SAMPLE_GROUP_ID = 103
309+
memberfields = self.api.get_group_memberfields(group_id=SAMPLE_GROUP_ID)
310+
311+
assert memberfields is not None
312+
assert memberfields != []
313+
for memberfield in memberfields:
314+
assert "type" in memberfield
315+
assert "id" in memberfield["field"]
316+
253317
def test_get_groups_members(self) -> None:
254318
"""Check that a list of groups is received.
255319
256-
when asking by person and optional role id.
320+
when requesting by person and optional role id.
257321
258322
IMPORTANT - This test method and the parameters used depend on target system!
259323
the hard coded sample exists on ELKW1610.KRZ.TOOLS

version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import os
44

5-
VERSION = "1.7.2"
5+
VERSION = "1.7.3"
66
__version__ = VERSION
77

88
if __name__ == "__main__":

0 commit comments

Comments
 (0)