From bd9b1f41fbc04d0a44750541ad74f77f5762b3e9 Mon Sep 17 00:00:00 2001 From: mattgd Date: Tue, 2 Jul 2024 16:18:57 -0400 Subject: [PATCH] Updates. --- tests/test_events.py | 31 +++++++++++++++ .../fixtures/mock_directory_sync_event.py | 39 +++++++++++++++++++ tests/utils/fixtures/mock_event.py | 7 +++- workos/event_objects/directory.py | 25 +++++++++--- workos/event_objects/directory_group.py | 4 +- workos/event_objects/directory_user.py | 12 +++--- workos/events.py | 18 ++++++--- 7 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 tests/utils/fixtures/mock_directory_sync_event.py diff --git a/tests/test_events.py b/tests/test_events.py index 8805517d..50d909df 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1,6 +1,7 @@ import pytest from workos.events import Events from tests.utils.fixtures.mock_event import MockEvent +from tests.utils.fixtures.mock_directory_sync_event import MockDirectorySyncEvent class TestEvents(object): @@ -8,6 +9,27 @@ class TestEvents(object): def setup(self, set_api_key, set_client_id): self.events = Events() + @pytest.fixture + def mock_directory_sync_events(self): + events = [MockDirectorySyncEvent(id=str(i)).to_dict() for i in range(100)] + + return { + "data": events, + "list_metadata": {"after": None}, + "metadata": { + "params": { + "events": None, + "limit": None, + "organization_id": None, + "after": None, + "range_start": None, + "range_end": None, + "default_limit": True, + }, + "method": Events.list_directory_sync_events, + }, + } + @pytest.fixture def mock_events(self): events = [MockEvent(id=str(i)).to_dict() for i in range(100)] @@ -29,6 +51,15 @@ def mock_events(self): }, } + def test_list_directory_sync_events( + self, mock_directory_sync_events, mock_request_method + ): + mock_request_method("get", mock_directory_sync_events, 200) + + events = self.events.list_directory_sync_events() + + assert events == mock_directory_sync_events + def test_list_events(self, mock_events, mock_request_method): mock_request_method("get", mock_events, 200) diff --git a/tests/utils/fixtures/mock_directory_sync_event.py b/tests/utils/fixtures/mock_directory_sync_event.py new file mode 100644 index 00000000..93070829 --- /dev/null +++ b/tests/utils/fixtures/mock_directory_sync_event.py @@ -0,0 +1,39 @@ +import datetime +from workos.resources.base import WorkOSBaseResource +from workos.event_objects.directory_user import DirectoryUserEvent + + +class MockDirectorySyncEvent(WorkOSBaseResource): + def __init__(self, id): + self.object = "event" + self.id = id + self.event = "dsync.user.created" + self.data = { + "id": "directory_user_01E1X1B89NH8Z3SDFJR4H7RGX7", + "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", + "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", + "idp_id": "8931", + "emails": [ + {"primary": True, "type": "work", "value": "lela.block@example.com"} + ], + "first_name": "Lela", + "last_name": "Block", + "job_title": "Software Engineer", + "username": "lela.block@example.com", + "state": "active", + "created_at": "2021-06-25T19:07:33.155Z", + "updated_at": "2021-06-25T19:07:33.155Z", + "custom_attributes": {"department": "Engineering"}, + "raw_attributes": {}, + "object": "directory_user", + } + + self.created_at = datetime.datetime.now() + + OBJECT_FIELDS = [ + "object", + "id", + "event", + "data", + "created_at", + ] diff --git a/tests/utils/fixtures/mock_event.py b/tests/utils/fixtures/mock_event.py index 0acdda4d..a7a756e3 100644 --- a/tests/utils/fixtures/mock_event.py +++ b/tests/utils/fixtures/mock_event.py @@ -6,8 +6,11 @@ class MockEvent(WorkOSBaseResource): def __init__(self, id): self.object = "event" self.id = id - self.event = "dsync.user.created" - self.data = {"id": "event_01234ABCD", "organization_id": "org_1234"} + self.event = "user.created" + self.data = { + "id": "user_01E4ZCR3C5A4QZ2Z2JQXGKZJ9E", + "email": "todd@example.com", + } self.created_at = datetime.datetime.now() OBJECT_FIELDS = [ diff --git a/workos/event_objects/directory.py b/workos/event_objects/directory.py index 5e86aa3c..3ed1993d 100644 --- a/workos/event_objects/directory.py +++ b/workos/event_objects/directory.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Literal from enum import Enum from workos.utils.types import JsonDict @@ -12,7 +12,6 @@ class DirectoryType(Enum): FOURTH_HR = "fourth hr" GENERIC_SCIM_v2 = "generic scim v2.0" GOOGLE = "gsuite directory" - GUSTO = "gusto" HIBOB = "hibob" JUMPCLOUD_SCIM_v2 = "jump cloud scim v2.0" OKTA_SCIM_v2 = "okta scim v2.0" @@ -37,7 +36,7 @@ def __init__(self, attributes: JsonDict) -> None: self.domain: str = attributes["domain"] -class DirectoryEvent: +class DirectoryEventWithLegacyFields: def __init__(self, attributes) -> None: self.id: str = attributes["id"] self.name: str = attributes["name"] @@ -50,8 +49,19 @@ def __init__(self, attributes) -> None: self.created_at: str = attributes["created_at"] self.updated_at: str = attributes["updated_at"] self.external_key: str = attributes["external_key"] - # always 'directory' for this event - self.object: str = attributes["object"] + self.object: Literal["directory"] = attributes["object"] + + +class DirectoryEvent: + def __init__(self, attributes) -> None: + self.id: str = attributes["id"] + self.name: str = attributes["name"] + self.type: DirectoryType = DirectoryType(attributes["type"]) + self.state: DirectoryState = DirectoryState.ACTIVE + self.organization_id: str = attributes["organization_id"] + self.created_at: str = attributes["created_at"] + self.updated_at: str = attributes["updated_at"] + self.object: Literal["directory"] = attributes["object"] class DirectoryActivatedEvent: @@ -61,7 +71,9 @@ def __init__(self, attributes: JsonDict) -> None: self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] - self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) + self.data: DirectoryEventWithLegacyFields = DirectoryEventWithLegacyFields( + attributes["data"] + ) class DirectoryDeletedEvent: @@ -71,4 +83,5 @@ def __init__(self, attributes: JsonDict) -> None: self.event: str = attributes["event"] self.id: str = attributes["id"] self.created_at = attributes["created_at"] + self.state: DirectoryState = DirectoryState.DELETING self.data: DirectoryEvent = DirectoryEvent(attributes["data"]) diff --git a/workos/event_objects/directory_group.py b/workos/event_objects/directory_group.py index c078c571..488f3970 100644 --- a/workos/event_objects/directory_group.py +++ b/workos/event_objects/directory_group.py @@ -1,3 +1,4 @@ +from typing import Literal from workos.utils.types import JsonDict @@ -12,8 +13,7 @@ def __init__(self, attributes) -> None: self.updated_at: str = attributes["updated_at"] self.raw_attributes: JsonDict = attributes.get("raw_attributes", {}) self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) - # always 'directory_group' for this event - self.object: str = attributes["object"] + self.object: Literal["directory_group"] = attributes["object"] class DirectoryGroupCreatedEvent: diff --git a/workos/event_objects/directory_user.py b/workos/event_objects/directory_user.py index 1f6eda00..fe6c74f5 100644 --- a/workos/event_objects/directory_user.py +++ b/workos/event_objects/directory_user.py @@ -1,4 +1,4 @@ -from typing import Optional, List +from typing import Optional, List, Literal from enum import Enum from workos.utils.types import JsonDict @@ -21,18 +21,19 @@ class DirectoryUserState(Enum): class DirectoryUserEvent: - def __init__(self, attributes) -> None: + def __init__(self, attributes: JsonDict) -> None: self.id: str = attributes["id"] - self.name: str = attributes["name"] self.idp_id: str = attributes["idp_id"] self.directory_id: str = attributes["directory_id"] self.organization_id: str = attributes["organization_id"] self.first_name: Optional[str] = attributes.get("first_name") self.last_name: Optional[str] = attributes.get("last_name") self.job_title: Optional[str] = attributes.get("job_title") + self.emails: List[DirectoryUserEmail] = [] for email in attributes.get("emails"): - self.emails.push(DirectoryUserEmail(email)) + self.emails.append(DirectoryUserEmail(email)) + self.username: Optional[str] = attributes.get("username") self.state: DirectoryUserState = DirectoryUserState(attributes["state"]) self.custom_attributes: JsonDict = attributes.get("custom_attributes", {}) @@ -43,8 +44,7 @@ def __init__(self, attributes) -> None: DirectoryUserRole(attributes["role"]) if attributes.get("role") else None ) self.previous_attributes: JsonDict = attributes.get("previous_attributes", {}) - # always 'directory_user' for this event - self.object: str = attributes["object"] + self.object: Literal["directory_user"] = attributes["object"] class DirectoryUserCreatedEvent: diff --git a/workos/events.py b/workos/events.py index 3c6fda72..0c700e1b 100644 --- a/workos/events.py +++ b/workos/events.py @@ -1,4 +1,3 @@ -from warnings import warn import workos from workos.utils.request import ( RequestHelper, @@ -68,7 +67,7 @@ def request_helper(self): self._request_helper = RequestHelper() return self._request_helper - def list_dsync_events( + def list_directory_sync_events( self, limit: Optional[int] = None, organization_id: Optional[str] = None, @@ -81,7 +80,7 @@ def list_dsync_events( default_limit = True params = { - "events": DSYNC_EVENT_TYPES.keys(), + "events": list(DSYNC_EVENT_TO_OBJECT.keys()), "limit": limit, "after": after, "organization_id": organization_id, @@ -96,15 +95,22 @@ def list_dsync_events( token=workos.api_key, ) - response = { - "object": "list", + response["metadata"] = { "params": params, + "method": Events.list_directory_sync_events, } + if "default_limit" in locals(): + if "metadata" in response and "params" in response["metadata"]: + response["metadata"]["params"]["default_limit"] = default_limit + else: + response["metadata"] = {"params": {"default_limit": default_limit}} + data = [] for list_data in response["data"]: - data.push(DSYNC_EVENT_TYPES[list_data["event"]](list_data)) + data.append(DSYNC_EVENT_TO_OBJECT[list_data["event"]](list_data)) response["data"] = data + return response def list_events(