diff --git a/tests/conftest.py b/tests/conftest.py index 9e4d42e..9186850 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,102 +2,74 @@ import pytest -# EXTRACTS FROM GROUPS ENDPOINT: - - -@pytest.fixture() -def simple_role_data() -> dict: - """Represent the simplest possible Role in this implementation. - - For testing Role in isolation. - Item from 'groups' (root) -> 'roles'. - """ - return { - "id": "001", - "name": "My role", - } +# EXTRACTS FROM EVENTS ENDPOINT: @pytest.fixture() -def simple_subgroup_data() -> dict: - """Represent the simplest possible Subgroup in this implementation. - - For testing Subgroup in isolation. - Item from 'groups' (root) -> {group} -> 'subGroups' - """ - return { - "id": "8CC576609CF3DCBC44469A799E76B22B", - "name": "Subgroup A1", - } +def simple_event_data() -> dict: + """Simplest possible event data in this implementation. + For testing Event in isolation. -@pytest.fixture() -def simple_profile_data() -> dict: - """Represent the simplest possible Profile in this implementation. - - For testing Profile in isolation. - Item from 'groups' (root) -> {group} -> 'members' -> {member} -> {profile} + Item from 'events' (root). """ return { - "id": "364C188137AD92DC0F32E1A31A0E1731", + "id": "E1", + "heading": "Event One", + "responses": { + "acceptedIds": [], + "declinedIds": [], + "unansweredIds": [], + "waitinglistIds": [], + "unconfirmedIds": [], + }, + "type": "EVENT", + "createdTime": "2020-12-31T19:00:00Z", + "endTimestamp": "2024-08-15T11:00:00Z", + "startTimestamp": "2021-07-06T06:00:00Z", } @pytest.fixture() -def simple_member_data() -> dict: - """Represent the simplest possible Member in this implementation. +def complex_event_data() -> dict: + """Event data with all implemented fields populated. - For testing Member in isolation. - Item from 'groups' (root) -> {group} -> 'members'. + Item from 'events' (root). """ return { - "createdTime": "2022-03-24T16:36:29Z", - # email is optional - "firstName": "Brendan", - "id": "6F63AF02CE05328153ABA477C76E6189", - "lastName": "Gleason", - # phoneNumber is optional - # profile is optional - # roles is optional - "subGroups": [], + "id": "E2", + "heading": "Event Two", + "responses": { + "acceptedIds": ["AC1"], + "declinedIds": ["DC1"], + "unansweredIds": ["UA1"], + "waitinglistIds": ["WL1"], + "unconfirmedIds": ["UC1"], + }, + "type": "RECURRING", + "createdTime": "2019-04-24T19:00:00Z", + "endTimestamp": "2024-08-15T11:00:00Z", + "startTimestamp": "2022-11-04T06:00:00Z", + # optional: + "cancelled": "True", + "inviteTime": "2021-01-04T06:00:00Z", } -@pytest.fixture() -def member_with_profile_data() -> dict: - """Represent a single Member with Profile. - - All supported input fields are supplied. - Item from 'groups' (root) -> {group} -> 'members'. - """ - return { - "createdTime": "2022-03-24T16:36:29Z", - "email": "ciarán@example.com", - "firstName": "Ciarán", - "id": "F59D764E4CE0B643DF4C0CF5E5B2B059", - "lastName": "Hinds", - "phoneNumber": "+123456789", - "profile": { - "id": "364C188137AD92DC0F32E1A31A0E1731", - }, - "roles": [ - "F2DFF55011800E66CDDAF2FD8A72039B", - ], - "subGroups": [ - "9E95A326090B256E2E9DAA6C0114E1D8", - ], - } +# EXTRACTS FROM GROUPS ENDPOINT: @pytest.fixture() def simple_group_data() -> dict: - """Represent the simplest possible Group in this implementation. + """Simplest possible group data in this implementation. + + For testing Group in isolation. Item from 'groups' (root). """ return { - "id": "8B4A6A9C60397A41D6D2414AFD520152", - "name": "Group A", + "id": "G1", + "name": "Group One", "members": [], # assumed always exists, may be empty "roles": [], # assumed always exists, may be empty "subGroups": [], # assumed always exists, may be empty @@ -106,105 +78,120 @@ def simple_group_data() -> dict: @pytest.fixture() def complex_group_data() -> dict: - """Represent a single Group with a single Member, single Subgroup, single Role. + """Group data with all implemented fields populated. The Member is in the Subgroup, and has the Role. All supported input fields are supplied. Item from 'groups' (root). """ return { - "id": "20EA715745389FCDED2C280A8ACB74A6", + "id": "G2", + "name": "Group Two", "members": [ { "createdTime": "2022-03-24T16:36:29Z", "email": "brendan@example.com", "firstName": "Brendan", - "id": "6F63AF02CE05328153ABA477C76E6189", + "id": "G2M1", "lastName": "Gleason", "phoneNumber": "+123456789", "profile": { - "id": "364C188137AD92DC0F32E1A31A0E1731", + "id": "G2M1P1", }, - "roles": [ - "29A7724B47ABEE7B3C9DC347E13A50B4", - ], - "subGroups": [ - "BB6B3C3592C5FC71DBDD5258D45EF6D4", - ], + "roles": ["G2R1"], + "subGroups": ["G2S1"], }, ], - "name": "Group B", - "subGroups": [ + "roles": [ { - "id": "BB6B3C3592C5FC71DBDD5258D45EF6D4", - "name": "Subgroup B1", + "id": "G2R1", + "name": "Role B2", }, ], - "roles": [ + "subGroups": [ { - "id": "29A7724B47ABEE7B3C9DC347E13A50B4", - "name": "Role B2", + "id": "G2S1", + "name": "Subgroup B1", }, ], } -# EXTRACTS FROM EVENTS ENDPOINT: +@pytest.fixture() +def simple_member_data() -> dict: + """Simplest possible member data in this implementation. + + For testing Member in isolation. + Item from 'groups' (root) -> {group} -> 'members'. + """ + return { + "id": "M1", + "firstName": "Brendan", + "lastName": "Gleason", + "subGroups": [], + "createdTime": "2022-03-24T16:36:29Z", + } @pytest.fixture() -def simple_event_data() -> dict: - """Represent the simplest possible Event in this implementation. +def complex_member_data() -> dict: + """Member data with all implemented fields populated. - Item from 'events' (root). + Item from 'groups' (root) -> {group} -> 'members'. """ return { - "id": "E001", - "heading": "Event 1", - "type": "EVENT", - "responses": { - "acceptedIds": [], - "declinedIds": [], - "unansweredIds": [], - "waitinglistIds": [], - "unconfirmedIds": [], + "id": "M2", + "firstName": "Ciarán", + "lastName": "Hinds", + "createdTime": "2022-03-24T16:36:29Z", + # optional: + "email": "ciarán@example.com", + "phoneNumber": "+123456789", + "profile": { + "id": "M2P2", }, - "createdTime": "2020-12-31T19:00:00Z", - "endTimestamp": "2024-08-15T11:00:00Z", - "startTimestamp": "2021-07-06T06:00:00Z", + "roles": [ + "M2R2", + ], + "subGroups": [ + "M2S2", + ], } @pytest.fixture() -def complex_event_data() -> dict: - """Represent a single Event with Responses. +def simple_profile_data() -> dict: + """Simplest possible profile data in this implementation. - All supported input fields are supplied. - Item from 'events' (root). + For testing Profile in isolation. + Item from 'groups' (root) -> {group} -> 'members' -> {member} -> {profile} """ return { - "id": "E002", - "cancelled": "True", - "heading": "Event 2", - "type": "RECURRING", - "responses": { - "acceptedIds": [ - "B24FA75A4CCBC63199A57361E88B0646", - ], - "declinedIds": [ - "B4C5339E366FB5350310F2F8EA069F41", - ], - "unansweredIds": [ - "3E546CDE2EAE242C1B8281C2042B5990", - ], - "waitinglistIds": [ - "0362B36507E156365471B64574EB6764", - ], - "unconfirmedIds": [ - "2D1BB37608F09511FD5F280D219DFD97", - ], - }, - "createdTime": "2019-04-24T19:00:00Z", - "endTimestamp": "2024-08-15T11:00:00Z", - "startTimestamp": "2022-11-04T06:00:00Z", + "id": "P1", + } + + +@pytest.fixture() +def simple_role_data() -> dict: + """Simplest possible role data in this implementation. + + For testing Role in isolation. + Item from 'groups' (root) -> 'roles'. + """ + return { + "id": "R1", + "name": "Role One", + } + + +@pytest.fixture() +def simple_subgroup_data() -> dict: + """Simplest possible subgroup data in this implementation. + + For testing Subgroup in isolation. + Item from 'groups' (root) -> {group} -> 'subGroups' + """ + return { + "id": "S1", + "name": "Subgroup One", } diff --git a/tests/test_event.py b/tests/test_event.py index 4e6e03e..14dc523 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -6,67 +6,65 @@ def test_from_dict_simple(simple_event_data: dict) -> None: - """Test that Event is created from the simplest possible dict representation. - - Verify values of all attributes. - """ + """Test that Event is created from the simplest possible data.""" + # arrange + # act my_event = Event(**simple_event_data) - - assert my_event.uid == "E001" - assert my_event.heading == "Event 1" - assert my_event.type is EventType.EVENT - assert my_event.url == "https://spond.com/client/sponds/E001/" + # assert + assert my_event.uid == "E1" + assert my_event.heading == "Event One" assert my_event.responses.accepted_uids == [] assert my_event.responses.declined_uids == [] assert my_event.responses.unanswered_uids == [] assert my_event.responses.waiting_list_uids == [] assert my_event.responses.unconfirmed_uids == [] + assert my_event.type is EventType.EVENT assert my_event.created_time == datetime(2020, 12, 31, 19, 0, tzinfo=timezone.utc) assert my_event.end_time == datetime(2024, 8, 15, 11, 0, tzinfo=timezone.utc) assert my_event.start_time == datetime(2021, 7, 6, 6, 0, tzinfo=timezone.utc) + # - optional: + assert my_event.cancelled is None + assert my_event.invite_time is None + # - properties: assert str(my_event) == ( "Event(" - "uid='E001', " - "heading='Event 1', " + "uid='E1', " + "heading='Event One', " "start_time: 2021-07-06 06:00:00+00:00, " "…)" ) + assert my_event.url == "https://spond.com/client/sponds/E1/" def test_from_dict_complex(complex_event_data: dict) -> None: - """Test that Event is created from dict. + """Test that Event is created from dict with all supported attributes. Verify values of all attributes. """ + # arrange + # act my_event = Event(**complex_event_data) - - assert my_event.uid == "E002" - assert my_event.cancelled is True - assert my_event.heading == "Event 2" + # assert + assert my_event.uid == "E2" + assert my_event.heading == "Event Two" + assert my_event.responses.accepted_uids == ["AC1"] + assert my_event.responses.declined_uids == ["DC1"] + assert my_event.responses.unanswered_uids == ["UA1"] + assert my_event.responses.waiting_list_uids == ["WL1"] + assert my_event.responses.unconfirmed_uids == ["UC1"] assert my_event.type is EventType.RECURRING - assert my_event.url == "https://spond.com/client/sponds/E002/" - assert my_event.responses.accepted_uids == [ - "B24FA75A4CCBC63199A57361E88B0646", - ] - assert my_event.responses.declined_uids == [ - "B4C5339E366FB5350310F2F8EA069F41", - ] - assert my_event.responses.unanswered_uids == [ - "3E546CDE2EAE242C1B8281C2042B5990", - ] - assert my_event.responses.waiting_list_uids == [ - "0362B36507E156365471B64574EB6764", - ] - assert my_event.responses.unconfirmed_uids == [ - "2D1BB37608F09511FD5F280D219DFD97", - ] assert my_event.created_time == datetime(2019, 4, 24, 19, 0, tzinfo=timezone.utc) assert my_event.end_time == datetime(2024, 8, 15, 11, 0, tzinfo=timezone.utc) assert my_event.start_time == datetime(2022, 11, 4, 6, 0, tzinfo=timezone.utc) + # - optional: + assert my_event.cancelled is True + assert my_event.invite_time == datetime(2021, 1, 4, 6, 0, tzinfo=timezone.utc) + # - properties: assert str(my_event) == ( "Event(" - "uid='E002', " - "heading='Event 2', " + "uid='E2', " + "heading='Event Two', " "start_time: 2022-11-04 06:00:00+00:00, " "…)" ) + assert my_event.url == "https://spond.com/client/sponds/E2/" diff --git a/tests/test_group.py b/tests/test_group.py index 0c4dab4..d8f7377 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -6,49 +6,39 @@ def test_from_dict_simple(simple_group_data: dict) -> None: - """Test that Group is created from the simplest possible dict representation. - - Verify values of all attributes. - """ + """Test that Group is created from the simplest possible data.""" # arrange - # act my_group = Group(**simple_group_data) - # assert - assert my_group.uid == "8B4A6A9C60397A41D6D2414AFD520152" - assert my_group.name == "Group A" + assert my_group.uid == "G1" + assert my_group.name == "Group One" assert my_group.members == [] assert my_group.roles == [] assert my_group.subgroups == [] - assert str(my_group) == ( - "Group(" "uid='8B4A6A9C60397A41D6D2414AFD520152', " "name='Group A', " "…)" - ) + assert str(my_group) == ("Group(uid='G1', name='Group One', …)") def test_from_dict_with_member_role_subgroup(complex_group_data: dict) -> None: """Test that nested Member, Role, Subgroup are created from dict.""" # arrange - # act my_group = Group(**complex_group_data) - # assert - assert my_group.members[0].uid == "6F63AF02CE05328153ABA477C76E6189" - assert my_group.roles[0].uid == "29A7724B47ABEE7B3C9DC347E13A50B4" - assert my_group.subgroups[0].uid == "BB6B3C3592C5FC71DBDD5258D45EF6D4" + assert my_group.uid == "G2" + assert my_group.members[0].uid == "G2M1" + assert my_group.roles[0].uid == "G2R1" + assert my_group.subgroups[0].uid == "G2S1" def test_member_by_id__happy_path(complex_group_data: dict) -> None: """Test that Member is returned from a valid uid.""" # arrange my_group = Group(**complex_group_data) - # act - my_member = my_group.member_by_id("6F63AF02CE05328153ABA477C76E6189") - + my_member = my_group.member_by_id("G2M1") # assert - assert my_member.uid == "6F63AF02CE05328153ABA477C76E6189" + assert my_member.uid == "G2M1" def test_member_by_id__unmatched_id_raises_lookup_error( @@ -57,44 +47,38 @@ def test_member_by_id__unmatched_id_raises_lookup_error( """Test that LookupError is raised when uid can't be matched against a Member.""" # arrange my_group = Group(**complex_group_data) - - # act + # assert with pytest.raises(LookupError): - my_member = my_group.member_by_id("DUMMY_ID") + my_member = my_group.member_by_id("DUMMY_ID") # act def test_role_by_id__happy_path(complex_group_data: dict) -> None: """Test that Role is returned from a valid uid.""" # arrange my_group = Group(**complex_group_data) - # act - my_role = my_group.role_by_id("29A7724B47ABEE7B3C9DC347E13A50B4") - + my_role = my_group.role_by_id("G2R1") # assert - assert my_role.uid == "29A7724B47ABEE7B3C9DC347E13A50B4" + assert my_role.uid == "G2R1" def test_role_by_id__unmatched_id_raises_lookup_error(complex_group_data: dict) -> None: """Test that LookupError is raised when uid can't be matched against a Role.""" # arrange my_group = Group(**complex_group_data) - - # act + # assert with pytest.raises(LookupError): - my_role = my_group.role_by_id("DUMMY_ID") + my_role = my_group.role_by_id("DUMMY_ID") # act def test_subgroup_by_id__happy_path(complex_group_data: dict) -> None: """Test that Subgroup is returned from a valid uid.""" # arrange my_group = Group(**complex_group_data) - # act - my_subgroup = my_group.subgroup_by_id("BB6B3C3592C5FC71DBDD5258D45EF6D4") - + my_subgroup = my_group.subgroup_by_id("G2S1") # assert - assert my_subgroup.uid == "BB6B3C3592C5FC71DBDD5258D45EF6D4" + assert my_subgroup.uid == "G2S1" def test_subgroup_by_id__unmatched_id_raises_lookup_error( @@ -103,23 +87,20 @@ def test_subgroup_by_id__unmatched_id_raises_lookup_error( """Test that LookupError is raised when uid can't be matched against a Subgroup.""" # arrange my_group = Group(**complex_group_data) - - # act + # assert with pytest.raises(LookupError): - my_subgroup = my_group.subgroup_by_id("DUMMY_ID") + my_subgroup = my_group.subgroup_by_id("DUMMY_ID") # act def test_members_by_subgroup__happy_path(complex_group_data: dict) -> None: """Test that Members are returned from a valid Subgroup.""" # arrange my_group = Group(**complex_group_data) - my_subgroup = my_group.subgroup_by_id("BB6B3C3592C5FC71DBDD5258D45EF6D4") - + my_subgroup = my_group.subgroup_by_id("G2S1") # act my_subgroup_members = my_group.members_by_subgroup(my_subgroup) - # assert - assert my_subgroup_members[0].uid == "6F63AF02CE05328153ABA477C76E6189" + assert my_subgroup_members[0].uid == "G2M1" def test_members_by_subgroup__not_subgroup_raises_type_error( @@ -128,9 +109,8 @@ def test_members_by_subgroup__not_subgroup_raises_type_error( """Test that TypeError is raised if `subgroup` isn't a Subgroup.""" # arrange my_group = Group(**complex_group_data) - role_not_subgroup = my_group.role_by_id("29A7724B47ABEE7B3C9DC347E13A50B4") - - # act + role_not_subgroup = my_group.role_by_id("G2R1") + # assert with pytest.raises(TypeError): # Ignore Mypy error - test purposely passes incompatible type my_subgroup_members = my_group.members_by_subgroup(role_not_subgroup) # type: ignore[arg-type] @@ -140,13 +120,11 @@ def test_members_by_role__happy_path(complex_group_data: dict) -> None: """Test that Members are returned from a valid Role.""" # arrange my_group = Group(**complex_group_data) - my_role = my_group.role_by_id("29A7724B47ABEE7B3C9DC347E13A50B4") - + my_role = my_group.role_by_id("G2R1") # act my_role_members = my_group.members_by_role(my_role) - # assert - assert my_role_members[0].uid == "6F63AF02CE05328153ABA477C76E6189" + assert my_role_members[0].uid == "G2M1" def test_members_by_role__not_role_raises_type_error( @@ -155,8 +133,7 @@ def test_members_by_role__not_role_raises_type_error( """Test that TypeError is raised if `role` isn't a Role.""" # arrange my_group = Group(**complex_group_data) - subgroup_not_role = my_group.subgroup_by_id("BB6B3C3592C5FC71DBDD5258D45EF6D4") - + subgroup_not_role = my_group.subgroup_by_id("G2S1") # act with pytest.raises(TypeError): # Ignore Mypy error - test purposely passes incompatible type diff --git a/tests/test_member.py b/tests/test_member.py index d7ad652..d40418c 100644 --- a/tests/test_member.py +++ b/tests/test_member.py @@ -6,76 +6,56 @@ def test_from_dict_simple(simple_member_data: dict) -> None: - """Test that Member is created from the simplest possible dict representation. - - Verify values of all attributes. - """ + """Test that Member is created from the simplest possible data.""" + # arrange + # act my_member = Member(**simple_member_data) - - assert my_member.uid == "6F63AF02CE05328153ABA477C76E6189" + # assert + assert my_member.uid == "M1" assert my_member.created_time == datetime( - 2022, - 3, - 24, - 16, - 36, - 29, - tzinfo=timezone.utc, + 2022, 3, 24, 16, 36, 29, tzinfo=timezone.utc ) - assert my_member.email is None assert my_member.first_name == "Brendan" assert my_member.last_name == "Gleason" - assert my_member.full_name == "Brendan Gleason" + # - optionally populated: + assert my_member.subgroup_uids == [] + # - optional: + assert my_member.email is None assert my_member.phone_number is None assert my_member.profile is None assert my_member.role_uids is None - assert my_member.subgroup_uids == [] - assert str(my_member) == ( - "Member(" - "uid='6F63AF02CE05328153ABA477C76E6189', " - "full_name='Brendan Gleason', " - "…)" - ) - - -def test_from_dict_with_profile(member_with_profile_data: dict) -> None: - """Test that Member is created from dict. + # - properties: + assert str(my_member) == ("Member(uid='M1', full_name='Brendan Gleason', …)") + assert my_member.full_name == "Brendan Gleason" - Verify values of all attributes. - """ - my_member = Member(**member_with_profile_data) - assert my_member.uid == "F59D764E4CE0B643DF4C0CF5E5B2B059" +def test_from_dict_full(complex_member_data: dict) -> None: + """Test that Member is created from dict with all supported attributes.""" + # arrange + # act + my_member = Member(**complex_member_data) + # assert + assert my_member.uid == "M2" assert my_member.created_time == datetime( - 2022, - 3, - 24, - 16, - 36, - 29, - tzinfo=timezone.utc, + 2022, 3, 24, 16, 36, 29, tzinfo=timezone.utc ) - assert my_member.email == "ciarán@example.com" assert my_member.first_name == "Ciarán" assert my_member.last_name == "Hinds" - assert my_member.full_name == "Ciarán Hinds" + # - optionally populated: + assert my_member.subgroup_uids[0] == "M2S2" + # - optional: + assert my_member.email == "ciarán@example.com" assert my_member.phone_number == "+123456789" - # Ignore Mypy error: + # Ignore Mypy errors: # Item "None" of "Profile | None" has no attribute "uid" [union-attr] assert ( my_member.profile.uid # type: ignore[union-attr] - == "364C188137AD92DC0F32E1A31A0E1731" + == "M2P2" ) - # Ignore Mypy error: - # Value of type "list[str] | None" is not indexable [index] assert ( my_member.role_uids[0] # type: ignore[index] - == "F2DFF55011800E66CDDAF2FD8A72039B" - ) - assert my_member.subgroup_uids[0] == "9E95A326090B256E2E9DAA6C0114E1D8" - assert str(my_member) == ( - "Member(" - "uid='F59D764E4CE0B643DF4C0CF5E5B2B059', " - "full_name='Ciarán Hinds', " - "…)" + == "M2R2" ) + # - properties: + assert str(my_member) == ("Member(uid='M2', full_name='Ciarán Hinds', …)") + assert my_member.full_name == "Ciarán Hinds" diff --git a/tests/test_profile.py b/tests/test_profile.py index c7408f2..e922d8e 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -4,10 +4,10 @@ def test_from_dict(simple_profile_data: dict) -> None: - """Test that Profile is created from the simplest possible dict representation. - - Verify values of all attributes. - """ + """Test that Profile is created from the simplest possible data dict.""" + # arrange + # act my_profile = Profile(**simple_profile_data) - assert my_profile.uid == "364C188137AD92DC0F32E1A31A0E1731" - assert str(my_profile) == ("Profile(uid='364C188137AD92DC0F32E1A31A0E1731')") + # assert + assert my_profile.uid == "P1" + assert str(my_profile) == ("Profile(uid='P1')") diff --git a/tests/test_role.py b/tests/test_role.py index 5a1dd46..a7718a2 100644 --- a/tests/test_role.py +++ b/tests/test_role.py @@ -4,12 +4,11 @@ def test_from_dict(simple_role_data: dict) -> None: - """Test that Event is created from the simplest possible dict representation. - - Verify values of all attributes. - """ + """Test that Role is created from the simplest possible data dict.""" + # arrange + # act my_role = Role(**simple_role_data) - - assert my_role.uid == "001" - assert my_role.name == "My role" - assert str(my_role) == "Role(uid='001', name='My role')" + # assert + assert my_role.uid == "R1" + assert my_role.name == "Role One" + assert str(my_role) == "Role(uid='R1', name='Role One')" diff --git a/tests/test_subgroup.py b/tests/test_subgroup.py index 39d6841..10ccbab 100644 --- a/tests/test_subgroup.py +++ b/tests/test_subgroup.py @@ -4,15 +4,11 @@ def test_from_dict(simple_subgroup_data: dict) -> None: - """Test that Subgroup is created from the simplest possible dict representation. - - Verify values of all attributes. - """ + """Test that Subgroup is created from the simplest possible data dict.""" + # arrange + # act my_subgroup = Subgroup(**simple_subgroup_data) - - assert my_subgroup.uid == "8CC576609CF3DCBC44469A799E76B22B" - assert my_subgroup.name == "Subgroup A1" - assert ( - str(my_subgroup) - == "Subgroup(uid='8CC576609CF3DCBC44469A799E76B22B', name='Subgroup A1')" - ) + # assert + assert my_subgroup.uid == "S1" + assert my_subgroup.name == "Subgroup One" + assert str(my_subgroup) == "Subgroup(uid='S1', name='Subgroup One')"