Skip to content
Snippets Groups Projects
Commit 699c1096 authored by Daniel Bimschas's avatar Daniel Bimschas
Browse files

HOLI-10718: add events SpaceCreated, SpaceUpdated, SpaceDeleted

parent 45b92b9a
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,11 @@ def get_event_type(cloud_event: CloudEvent) -> str:
def get_event_version(cloud_event: CloudEvent) -> str:
return cloud_event.data['message']['attributes']['eventVersion']
def _validate_event_type(cloud_event: CloudEvent, expected_event_type: str) -> None:
event_type = get_event_type(cloud_event)
if event_type != expected_event_type:
raise ValueError(f'Expected event of type {expected_event_type}, got {event_type}')
@dataclass
class UserPayload:
id: str
......@@ -43,13 +48,55 @@ class UserEvent:
@dataclass
class UserNameUpdatedEvent(UserEvent):
def __init__(self, cloud_event: CloudEvent):
if get_event_type(cloud_event) != 'UserNameUpdated':
raise ValueError(f'Expected event of type UserNameUpdated, got {data['eventType']}')
_validate_event_type(cloud_event, 'UserNameUpdated')
super().__init__(cloud_event)
@dataclass
class UserDeletedEvent(UserEvent):
def __init__(self, cloud_event: CloudEvent):
if get_event_type(cloud_event) != 'UserDeleted':
raise ValueError(f'Expected event of type UserDeleted, got {data['eventType']}')
_validate_event_type(cloud_event, 'UserDeleted')
super().__init__(cloud_event)
@dataclass
class SpacePayload:
id: str
name: str
slug: str
avatar: str
avatar_default_color: str
def __init__(self, data: dict):
self.id = data['space']['id']
self.name = data['space']['name']
self.slug = data['space']['slug']
self.avatar = data['space']['avatar']
self.avatar_default_color = data['space']['avatarDefaultColor']
@dataclass
class SpaceEvent:
event_type: str
event_version: str
space: SpacePayload
def __init__(self, cloud_event: CloudEvent):
self.event_type = get_event_type(cloud_event)
self.event_version = get_event_version(cloud_event)
self.space = SpacePayload(json.loads(base64.b64decode(cloud_event.data['message']['data'])))
@dataclass
class SpaceCreatedEvent(SpaceEvent):
def __init__(self, cloud_event: CloudEvent):
_validate_event_type(cloud_event, 'SpaceCreated')
super().__init__(cloud_event)
@dataclass
class SpaceUpdatedEvent(SpaceEvent):
def __init__(self, cloud_event: CloudEvent):
_validate_event_type(cloud_event, 'SpaceUpdated')
super().__init__(cloud_event)
@dataclass
class SpaceDeletedEvent(SpaceEvent):
def __init__(self, cloud_event: CloudEvent):
_validate_event_type(cloud_event, 'SpaceDeleted')
super().__init__(cloud_event)
\ No newline at end of file
import os
import functions_framework
from typing import Union
from dataclasses import asdict
from cloudevents.http.event import CloudEvent
from events import UserNameUpdatedEvent, get_event_type, get_event_version, UserDeletedEvent
from events import UserNameUpdatedEvent, get_event_type, get_event_version, UserDeletedEvent, SpaceCreatedEvent, \
SpaceUpdatedEvent, SpaceDeletedEvent
from typesense_client import TypesenseClient
from logging import getLogger
......@@ -28,13 +30,37 @@ def process_user_name_updated_event(client: TypesenseClient, event: UserNameUpda
}
}
client.upsert(document)
logger.info(f'Updated user {event.user.id} in Typesense')
logger.info(f'Upserted user {event.user.id} in Typesense')
def process_user_deleted_event(client: TypesenseClient, event: UserDeletedEvent):
logger.debug(f'Processing {event}')
client.delete(f"profile_{event.user.id}")
logger.info(f'Deleted user {event.user.id} from Typesense')
def process_space_upserting_event(client: TypesenseClient, event: Union[SpaceCreatedEvent, SpaceUpdatedEvent]):
logger.debug(f'Processing {event}')
document = {
'id': f'space_{event.space.id}',
'type': 'space',
'title_de': event.space.name,
'title_en': event.space.name,
'description_de': None, # TODO add on sending side
'description_en': None, # TODO add on sending side
'location': None,
'location_lat_lng': None,
'image_url': event.space.avatar,
'link_locators': {
'space': event.space.slug
}
}
client.upsert(document)
logger.info(f'Upserted space {event.space.id} in Typesense')
def process_space_deleted_event(client: TypesenseClient, event: SpaceDeletedEvent):
logger.debug(f'Processing {event}')
client.delete(f"space_{event.space.id}")
logger.info(f'Deleted space {event.space.id} in Typesense')
def process_event(client: TypesenseClient, event: CloudEvent):
type_version = (get_event_type(event), get_event_version(event))
match type_version:
......@@ -47,16 +73,13 @@ def process_event(client: TypesenseClient, event: CloudEvent):
logger.debug('Ignoring UserEmailUpdated event')
pass
case ('SpaceCreated', '1.0.0'):
# TODO implement
logger.debug('Ignoring SpaceCreated event (yet to be implemented)')
process_space_upserting_event(client, SpaceCreatedEvent(event))
pass
case ('SpaceUpdated', '1.0.0'):
# TODO implement
logger.debug('Ignoring SpaceCreated event (yet to be implemented)')
process_space_upserting_event(client, SpaceUpdatedEvent(event))
pass
case ('SpaceDeleted', '1.0.0'):
# TODO implement
logger.debug('Ignoring SpaceCreated event (yet to be implemented)')
process_space_deleted_event(client, SpaceDeletedEvent(event))
pass
case (eventType, eventVersion):
logger.debug(f'Ignoring {eventType} ({eventVersion}) event.')
......
import base64
import json
from unittest.mock import patch
from cloudevents.http import CloudEvent
# noinspection PyPackageRequirements
from cloudevents.http.event import CloudEvent
from main import process_event
attributes = {
......@@ -24,6 +24,14 @@ user_payload = {
'avatar': 'https://ik.imagekit.io/holi/_DEV_/avatar/149a3d29-a0da-4f52-8e1c-660376b7084b_yv31UW7lD0.jpg',
}
space_payload = {
'id': '149a3d29-a0da-4f52-8e1c-660376b7084b',
'name': 'Daniels Space',
'slug': 'daniels-space',
'avatar': 'https://ik.imagekit.io/holi/_DEV_/avatar/149a3d29-a0da-4f52-8e1c-660376b7084b_yv31UW7lD0.jpg',
'avatarDefaultColor': 'ffffff',
}
def message_data(event_type, event_version, data):
return {
'message': {
......@@ -46,10 +54,10 @@ def test_user_name_updated(mock_client):
'type': 'profile',
'title_de': user_payload['name'],
'title_en': user_payload['name'],
'description_de': None, # TODO add on sending side
'description_en': None, # TODO add on sending side
'location': None, # TODO add on sending side
'location_lat_lng': None, # TODO add on sending side
'description_de': None,
'description_en': None,
'location': None,
'location_lat_lng': None,
'image_url': user_payload['avatar'],
'link_locators': {
'profile': user_payload['id'],
......@@ -61,5 +69,40 @@ def test_user_deleted(mock_client):
process_event(mock_client, CloudEvent(attributes, message_data('UserDeleted', '1.0.0', {'user': user_payload})))
mock_client.delete.assert_called_with(f"profile_{user_payload['id']}")
if __name__ == '__main__':
process_event()
\ No newline at end of file
# noinspection DuplicatedCode
@patch('typesense.client.Client')
def test_space_created(mock_client):
process_event(mock_client, CloudEvent(attributes, message_data('SpaceCreated', '1.0.0', {'space': space_payload})))
mock_client.upsert.assert_called_with({
'id': f'space_{space_payload['id']}',
'type': 'space',
'title_de': space_payload['name'],
'title_en': space_payload['name'],
'description_de': None,
'description_en': None,
'location': None,
'location_lat_lng': None,
'image_url': space_payload['avatar'],
'link_locators': {
'space': space_payload['slug'],
}
})
# noinspection DuplicatedCode
@patch('typesense.client.Client')
def test_space_updated(mock_client):
process_event(mock_client, CloudEvent(attributes, message_data('SpaceUpdated', '1.0.0', {'space': space_payload})))
mock_client.upsert.assert_called_with({
'id': f'space_{space_payload['id']}',
'type': 'space',
'title_de': space_payload['name'],
'title_en': space_payload['name'],
'description_de': None,
'description_en': None,
'location': None,
'location_lat_lng': None,
'image_url': space_payload['avatar'],
'link_locators': {
'space': space_payload['slug'],
}
})
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment