From 55a5d79e1bea29c39c7cd75895801ea2c451c802 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Wed, 3 Sep 2025 15:44:07 +0200 Subject: [PATCH 01/28] [CHA-1230] support delivery receipts --- stream_chat/async_chat/channel.py | 3 +++ stream_chat/base/channel.py | 12 ++++++++++++ stream_chat/channel.py | 3 +++ stream_chat/tests/test_channel.py | 19 +++++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/stream_chat/async_chat/channel.py b/stream_chat/async_chat/channel.py index a66fb7f..489d26f 100644 --- a/stream_chat/async_chat/channel.py +++ b/stream_chat/async_chat/channel.py @@ -138,6 +138,9 @@ async def mark_read(self, user_id: str, **data: Any) -> StreamResponse: async def mark_unread(self, user_id: str, **data: Any) -> StreamResponse: payload = add_user_id(data, user_id) return await self.client.post(f"{self.url}/unread", data=payload) + + async def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: + return await self.client.post("channels/delivered", data=data) async def get_replies(self, parent_id: str, **options: Any) -> StreamResponse: return await self.client.get(f"messages/{parent_id}/replies", params=options) diff --git a/stream_chat/base/channel.py b/stream_chat/base/channel.py index 8e300a5..5892da2 100644 --- a/stream_chat/base/channel.py +++ b/stream_chat/base/channel.py @@ -292,6 +292,18 @@ def mark_unread( :return: The server response """ pass + + @abc.abstractmethod + def mark_delivered( + self, data: Dict[str, Any] + ) -> Union[StreamResponse, Awaitable[StreamResponse], None]: + """ + Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled + + :param data: MarkDeliveredOptions containing channel_delivered_message and other optional fields + :return: The server response or None if delivery receipts are disabled + """ + pass @abc.abstractmethod def get_replies( diff --git a/stream_chat/channel.py b/stream_chat/channel.py index 2373811..45fec85 100644 --- a/stream_chat/channel.py +++ b/stream_chat/channel.py @@ -139,6 +139,9 @@ def mark_read(self, user_id: str, **data: Any) -> StreamResponse: def mark_unread(self, user_id: str, **data: Any) -> StreamResponse: payload = add_user_id(data, user_id) return self.client.post(f"{self.url}/unread", data=payload) + + def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: + return self.client.post("channels/delivered", data=data) def get_replies(self, parent_id: str, **options: Any) -> StreamResponse: return self.client.get(f"messages/{parent_id}/replies", params=options) diff --git a/stream_chat/tests/test_channel.py b/stream_chat/tests/test_channel.py index 193b44b..e3a371a 100644 --- a/stream_chat/tests/test_channel.py +++ b/stream_chat/tests/test_channel.py @@ -202,6 +202,25 @@ def test_mark_unread(self, channel: Channel, random_user: Dict): channel.send_message({"id": msg_id, "text": "helloworld"}, random_user["id"]) response = channel.mark_unread(random_user["id"], message_id=msg_id) assert "duration" in response + + def test_mark_delivered(self, channel: Channel, random_user: Dict): + delivery_data = { + "channel_delivered_message": {channel.id: "test-message-id"}, + "user_id": random_user["id"] + } + + response = channel.mark_delivered(delivery_data) + assert response is not None + + delivery_data_with_options = { + "channel_delivered_message": {channel.id: "test-message-id-2"}, + "user_id": random_user["id"], + "client_id": "test-client", + "connection_id": "test-connection" + } + + response = channel.mark_delivered(delivery_data_with_options) + assert response is not None def test_get_messages(self, channel: Channel, random_user: Dict): msg_id = str(uuid.uuid4()) From 8ece3b14e01ce939d4d4f282d8156d0ed5575c3a Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 12 Sep 2025 15:33:24 +0200 Subject: [PATCH 02/28] fix --- stream_chat/async_chat/channel.py | 3 -- stream_chat/async_chat/client.py | 45 +++++++++++++++++++++ stream_chat/base/channel.py | 12 ------ stream_chat/base/client.py | 26 ++++++++++++ stream_chat/channel.py | 3 -- stream_chat/client.py | 45 +++++++++++++++++++++ stream_chat/tests/test_channel.py | 19 --------- stream_chat/tests/test_client.py | 55 ++++++++++++++++++++++++++ stream_chat/types/delivery_receipts.py | 0 9 files changed, 171 insertions(+), 37 deletions(-) create mode 100644 stream_chat/types/delivery_receipts.py diff --git a/stream_chat/async_chat/channel.py b/stream_chat/async_chat/channel.py index 489d26f..4660a35 100644 --- a/stream_chat/async_chat/channel.py +++ b/stream_chat/async_chat/channel.py @@ -139,9 +139,6 @@ async def mark_unread(self, user_id: str, **data: Any) -> StreamResponse: payload = add_user_id(data, user_id) return await self.client.post(f"{self.url}/unread", data=payload) - async def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: - return await self.client.post("channels/delivered", data=data) - async def get_replies(self, parent_id: str, **options: Any) -> StreamResponse: return await self.client.get(f"messages/{parent_id}/replies", params=options) diff --git a/stream_chat/async_chat/client.py b/stream_chat/async_chat/client.py index ce07f6d..20e647e 100644 --- a/stream_chat/async_chat/client.py +++ b/stream_chat/async_chat/client.py @@ -986,6 +986,51 @@ async def update_user_location( params = {"user_id": user_id, **options} return await self.put("users/live_locations", data=data, params=params) + async def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: + """ + Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled + + :param data: MarkDeliveredOptions containing latest_delivered_messages and other optional fields + :return: The server response or None if delivery receipts are disabled + """ + # Validate required fields + if not data.get("latest_delivered_messages"): + raise ValueError("latest_delivered_messages must not be empty") + + # Ensure either user or user_id is provided + if not data.get("user") and not data.get("user_id"): + raise ValueError("either user or user_id must be provided") + + return await self.post("channels/delivered", data=data) + + async def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid: str) -> Optional[StreamResponse]: + """ + Convenience method to mark a message as delivered for a specific user. + + :param user_id: The user ID + :param message_id: The message ID + :param channel_cid: The channel CID (channel_type:channel_id) + :return: The server response or None if delivery receipts are disabled + """ + if not user_id: + raise ValueError("user ID must not be empty") + if not message_id: + raise ValueError("message ID must not be empty") + if not channel_cid: + raise ValueError("channel CID must not be empty") + + data = { + "latest_delivered_messages": [ + { + "cid": channel_cid, + "id": message_id + } + ], + "user_id": user_id + } + + return await self.mark_delivered(data) + async def close(self) -> None: await self.session.close() diff --git a/stream_chat/base/channel.py b/stream_chat/base/channel.py index 5892da2..5a0b2fa 100644 --- a/stream_chat/base/channel.py +++ b/stream_chat/base/channel.py @@ -293,18 +293,6 @@ def mark_unread( """ pass - @abc.abstractmethod - def mark_delivered( - self, data: Dict[str, Any] - ) -> Union[StreamResponse, Awaitable[StreamResponse], None]: - """ - Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled - - :param data: MarkDeliveredOptions containing channel_delivered_message and other optional fields - :return: The server response or None if delivery receipts are disabled - """ - pass - @abc.abstractmethod def get_replies( self, parent_id: str, **options: Any diff --git a/stream_chat/base/client.py b/stream_chat/base/client.py index c6f2d94..d64c6f9 100644 --- a/stream_chat/base/client.py +++ b/stream_chat/base/client.py @@ -1537,6 +1537,32 @@ def update_user_location( """ pass + @abc.abstractmethod + def mark_delivered( + self, data: Dict[str, Any] + ) -> Union[StreamResponse, Awaitable[StreamResponse], None]: + """ + Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled + + :param data: MarkDeliveredOptions containing latest_delivered_messages and other optional fields + :return: The server response or None if delivery receipts are disabled + """ + pass + + @abc.abstractmethod + def mark_delivered_simple( + self, user_id: str, message_id: str, channel_cid: str + ) -> Union[StreamResponse, Awaitable[StreamResponse], None]: + """ + Convenience method to mark a message as delivered for a specific user. + + :param user_id: The user ID + :param message_id: The message ID + :param channel_cid: The channel CID (channel_type:channel_id) + :return: The server response or None if delivery receipts are disabled + """ + pass + ##################### # Private methods # ##################### diff --git a/stream_chat/channel.py b/stream_chat/channel.py index 45fec85..c233cdc 100644 --- a/stream_chat/channel.py +++ b/stream_chat/channel.py @@ -140,9 +140,6 @@ def mark_unread(self, user_id: str, **data: Any) -> StreamResponse: payload = add_user_id(data, user_id) return self.client.post(f"{self.url}/unread", data=payload) - def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: - return self.client.post("channels/delivered", data=data) - def get_replies(self, parent_id: str, **options: Any) -> StreamResponse: return self.client.get(f"messages/{parent_id}/replies", params=options) diff --git a/stream_chat/client.py b/stream_chat/client.py index b9572b1..72dd41e 100644 --- a/stream_chat/client.py +++ b/stream_chat/client.py @@ -939,3 +939,48 @@ def update_user_location( data.update(cast(dict, options)) params = {"user_id": user_id, **options} return self.put("users/live_locations", data=data, params=params) + + def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: + """ + Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled + + :param data: MarkDeliveredOptions containing latest_delivered_messages and other optional fields + :return: The server response or None if delivery receipts are disabled + """ + # Validate required fields + if not data.get("latest_delivered_messages"): + raise ValueError("latest_delivered_messages must not be empty") + + # Ensure either user or user_id is provided + if not data.get("user") and not data.get("user_id"): + raise ValueError("either user or user_id must be provided") + + return self.post("channels/delivered", data=data) + + def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid: str) -> Optional[StreamResponse]: + """ + Convenience method to mark a message as delivered for a specific user. + + :param user_id: The user ID + :param message_id: The message ID + :param channel_cid: The channel CID (channel_type:channel_id) + :return: The server response or None if delivery receipts are disabled + """ + if not user_id: + raise ValueError("user ID must not be empty") + if not message_id: + raise ValueError("message ID must not be empty") + if not channel_cid: + raise ValueError("channel CID must not be empty") + + data = { + "latest_delivered_messages": [ + { + "cid": channel_cid, + "id": message_id + } + ], + "user_id": user_id + } + + return self.mark_delivered(data) \ No newline at end of file diff --git a/stream_chat/tests/test_channel.py b/stream_chat/tests/test_channel.py index e3a371a..ed9018d 100644 --- a/stream_chat/tests/test_channel.py +++ b/stream_chat/tests/test_channel.py @@ -203,25 +203,6 @@ def test_mark_unread(self, channel: Channel, random_user: Dict): response = channel.mark_unread(random_user["id"], message_id=msg_id) assert "duration" in response - def test_mark_delivered(self, channel: Channel, random_user: Dict): - delivery_data = { - "channel_delivered_message": {channel.id: "test-message-id"}, - "user_id": random_user["id"] - } - - response = channel.mark_delivered(delivery_data) - assert response is not None - - delivery_data_with_options = { - "channel_delivered_message": {channel.id: "test-message-id-2"}, - "user_id": random_user["id"], - "client_id": "test-client", - "connection_id": "test-connection" - } - - response = channel.mark_delivered(delivery_data_with_options) - assert response is not None - def test_get_messages(self, channel: Channel, random_user: Dict): msg_id = str(uuid.uuid4()) channel.send_message({"id": msg_id, "text": "helloworld"}, random_user["id"]) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 4361169..e89f37a 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1016,3 +1016,58 @@ def test_query_message_history( assert len(response_next["message_history"]) == 1 assert response_next["message_history"][0]["text"] == "helloworld-2" + + def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: Dict): + """Test marking messages as delivered""" + # Test with basic delivery data using new format + delivery_data = { + "latest_delivered_messages": [ + { + "cid": channel.cid, + "id": "test-message-id" + } + ], + "user_id": random_user["id"] + } + + response = client.mark_delivered(delivery_data) + assert response is not None + + # Test with multiple messages + delivery_data_multiple = { + "latest_delivered_messages": [ + { + "cid": channel.cid, + "id": "test-message-id-1" + }, + { + "cid": channel.cid, + "id": "test-message-id-2" + } + ], + "user_id": random_user["id"] + } + + response = client.mark_delivered(delivery_data_multiple) + assert response is not None + + def test_mark_delivered_simple(self, client: StreamChat, channel: Channel, random_user: Dict): + """Test the convenience method for marking messages as delivered""" + response = client.mark_delivered_simple( + user_id=random_user["id"], + message_id="test-message-id", + channel_cid=channel.cid + ) + assert response is not None + + def test_mark_delivered_validation(self, client: StreamChat, random_user: Dict): + """Test validation of mark_delivered method""" + # Test empty latest_delivered_messages + with pytest.raises(ValueError, match="latest_delivered_messages must not be empty"): + client.mark_delivered({"user_id": random_user["id"]}) + + # Test missing user and user_id + with pytest.raises(ValueError, match="either user or user_id must be provided"): + client.mark_delivered({ + "latest_delivered_messages": [{"cid": "test:channel", "id": "test"}] + }) diff --git a/stream_chat/types/delivery_receipts.py b/stream_chat/types/delivery_receipts.py new file mode 100644 index 0000000..e69de29 From 59d5dcc85164d68f919ab06517c766a2a24e990d Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 07:35:54 +0200 Subject: [PATCH 03/28] lint --- stream_chat/async_chat/channel.py | 2 +- stream_chat/async_chat/client.py | 21 ++++++++------------- stream_chat/base/channel.py | 2 +- stream_chat/channel.py | 2 +- stream_chat/client.py | 21 ++++++++------------- stream_chat/tests/test_channel.py | 2 +- 6 files changed, 20 insertions(+), 30 deletions(-) diff --git a/stream_chat/async_chat/channel.py b/stream_chat/async_chat/channel.py index 4660a35..a66fb7f 100644 --- a/stream_chat/async_chat/channel.py +++ b/stream_chat/async_chat/channel.py @@ -138,7 +138,7 @@ async def mark_read(self, user_id: str, **data: Any) -> StreamResponse: async def mark_unread(self, user_id: str, **data: Any) -> StreamResponse: payload = add_user_id(data, user_id) return await self.client.post(f"{self.url}/unread", data=payload) - + async def get_replies(self, parent_id: str, **options: Any) -> StreamResponse: return await self.client.get(f"messages/{parent_id}/replies", params=options) diff --git a/stream_chat/async_chat/client.py b/stream_chat/async_chat/client.py index 20e647e..d9918b8 100644 --- a/stream_chat/async_chat/client.py +++ b/stream_chat/async_chat/client.py @@ -989,24 +989,24 @@ async def update_user_location( async def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: """ Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled - + :param data: MarkDeliveredOptions containing latest_delivered_messages and other optional fields :return: The server response or None if delivery receipts are disabled """ # Validate required fields if not data.get("latest_delivered_messages"): raise ValueError("latest_delivered_messages must not be empty") - + # Ensure either user or user_id is provided if not data.get("user") and not data.get("user_id"): raise ValueError("either user or user_id must be provided") - + return await self.post("channels/delivered", data=data) async def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid: str) -> Optional[StreamResponse]: """ Convenience method to mark a message as delivered for a specific user. - + :param user_id: The user ID :param message_id: The message ID :param channel_cid: The channel CID (channel_type:channel_id) @@ -1018,19 +1018,14 @@ async def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid raise ValueError("message ID must not be empty") if not channel_cid: raise ValueError("channel CID must not be empty") - + data = { - "latest_delivered_messages": [ - { - "cid": channel_cid, - "id": message_id - } - ], + "latest_delivered_messages": [{"cid": channel_cid,"id": message_id}], "user_id": user_id } - + return await self.mark_delivered(data) - + async def close(self) -> None: await self.session.close() diff --git a/stream_chat/base/channel.py b/stream_chat/base/channel.py index 5a0b2fa..8e300a5 100644 --- a/stream_chat/base/channel.py +++ b/stream_chat/base/channel.py @@ -292,7 +292,7 @@ def mark_unread( :return: The server response """ pass - + @abc.abstractmethod def get_replies( self, parent_id: str, **options: Any diff --git a/stream_chat/channel.py b/stream_chat/channel.py index c233cdc..2373811 100644 --- a/stream_chat/channel.py +++ b/stream_chat/channel.py @@ -139,7 +139,7 @@ def mark_read(self, user_id: str, **data: Any) -> StreamResponse: def mark_unread(self, user_id: str, **data: Any) -> StreamResponse: payload = add_user_id(data, user_id) return self.client.post(f"{self.url}/unread", data=payload) - + def get_replies(self, parent_id: str, **options: Any) -> StreamResponse: return self.client.get(f"messages/{parent_id}/replies", params=options) diff --git a/stream_chat/client.py b/stream_chat/client.py index 72dd41e..6bc5b3c 100644 --- a/stream_chat/client.py +++ b/stream_chat/client.py @@ -943,24 +943,26 @@ def update_user_location( def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: """ Send the mark delivered event for this user, only works if the `delivery_receipts` setting is enabled - + :param data: MarkDeliveredOptions containing latest_delivered_messages and other optional fields :return: The server response or None if delivery receipts are disabled """ # Validate required fields if not data.get("latest_delivered_messages"): raise ValueError("latest_delivered_messages must not be empty") - + # Ensure either user or user_id is provided if not data.get("user") and not data.get("user_id"): raise ValueError("either user or user_id must be provided") - + return self.post("channels/delivered", data=data) - def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid: str) -> Optional[StreamResponse]: + def mark_delivered_simple( + self, user_id: str, message_id: str, channel_cid: str + ) -> Optional[StreamResponse]: """ Convenience method to mark a message as delivered for a specific user. - + :param user_id: The user ID :param message_id: The message ID :param channel_cid: The channel CID (channel_type:channel_id) @@ -972,15 +974,8 @@ def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid: str) raise ValueError("message ID must not be empty") if not channel_cid: raise ValueError("channel CID must not be empty") - data = { - "latest_delivered_messages": [ - { - "cid": channel_cid, - "id": message_id - } - ], + "latest_delivered_messages": [{"cid": channel_cid,"id": message_id}], "user_id": user_id } - return self.mark_delivered(data) \ No newline at end of file diff --git a/stream_chat/tests/test_channel.py b/stream_chat/tests/test_channel.py index ed9018d..193b44b 100644 --- a/stream_chat/tests/test_channel.py +++ b/stream_chat/tests/test_channel.py @@ -202,7 +202,7 @@ def test_mark_unread(self, channel: Channel, random_user: Dict): channel.send_message({"id": msg_id, "text": "helloworld"}, random_user["id"]) response = channel.mark_unread(random_user["id"], message_id=msg_id) assert "duration" in response - + def test_get_messages(self, channel: Channel, random_user: Dict): msg_id = str(uuid.uuid4()) channel.send_message({"id": msg_id, "text": "helloworld"}, random_user["id"]) From ffae07e5c2019230f36f0d0634988b7800df9d80 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 07:46:03 +0200 Subject: [PATCH 04/28] lint --- stream_chat/async_chat/client.py | 4 ++-- stream_chat/client.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/stream_chat/async_chat/client.py b/stream_chat/async_chat/client.py index d9918b8..212487e 100644 --- a/stream_chat/async_chat/client.py +++ b/stream_chat/async_chat/client.py @@ -1020,8 +1020,8 @@ async def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid raise ValueError("channel CID must not be empty") data = { - "latest_delivered_messages": [{"cid": channel_cid,"id": message_id}], - "user_id": user_id + "latest_delivered_messages": [{"cid": channel_cid, "id": message_id}], + "user_id": user_id, } return await self.mark_delivered(data) diff --git a/stream_chat/client.py b/stream_chat/client.py index 6bc5b3c..4a7dd38 100644 --- a/stream_chat/client.py +++ b/stream_chat/client.py @@ -975,7 +975,7 @@ def mark_delivered_simple( if not channel_cid: raise ValueError("channel CID must not be empty") data = { - "latest_delivered_messages": [{"cid": channel_cid,"id": message_id}], - "user_id": user_id + "latest_delivered_messages": [{"cid": channel_cid, "id": message_id}], + "user_id": user_id, } - return self.mark_delivered(data) \ No newline at end of file + return self.mark_delivered(data) From dd76f81073e22838ebe6f1a783e7143975bbd495 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:32:07 +0200 Subject: [PATCH 05/28] clean up --- stream_chat/tests/test_client.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index e89f37a..497d33b 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1018,8 +1018,6 @@ def test_query_message_history( assert response_next["message_history"][0]["text"] == "helloworld-2" def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: Dict): - """Test marking messages as delivered""" - # Test with basic delivery data using new format delivery_data = { "latest_delivered_messages": [ { @@ -1033,7 +1031,6 @@ def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: response = client.mark_delivered(delivery_data) assert response is not None - # Test with multiple messages delivery_data_multiple = { "latest_delivered_messages": [ { @@ -1052,7 +1049,6 @@ def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: assert response is not None def test_mark_delivered_simple(self, client: StreamChat, channel: Channel, random_user: Dict): - """Test the convenience method for marking messages as delivered""" response = client.mark_delivered_simple( user_id=random_user["id"], message_id="test-message-id", @@ -1061,12 +1057,9 @@ def test_mark_delivered_simple(self, client: StreamChat, channel: Channel, rando assert response is not None def test_mark_delivered_validation(self, client: StreamChat, random_user: Dict): - """Test validation of mark_delivered method""" - # Test empty latest_delivered_messages with pytest.raises(ValueError, match="latest_delivered_messages must not be empty"): client.mark_delivered({"user_id": random_user["id"]}) - # Test missing user and user_id with pytest.raises(ValueError, match="either user or user_id must be provided"): client.mark_delivered({ "latest_delivered_messages": [{"cid": "test:channel", "id": "test"}] From 2fdcf18152dea7f4d4da9426b8101de130acb698 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:33:51 +0200 Subject: [PATCH 06/28] clean up --- stream_chat/tests/test_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 497d33b..3a6b48e 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1017,7 +1017,7 @@ def test_query_message_history( assert len(response_next["message_history"]) == 1 assert response_next["message_history"][0]["text"] == "helloworld-2" - def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: Dict): + def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: Dict): delivery_data = { "latest_delivered_messages": [ { From 531a00f3063faa8ea9b863e4d039966ba522b2b7 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:47:04 +0200 Subject: [PATCH 07/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 3a6b48e..0ec307f 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1020,10 +1020,7 @@ def test_query_message_history( def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: Dict): delivery_data = { "latest_delivered_messages": [ - { - "cid": channel.cid, - "id": "test-message-id" - } + {"cid": channel.cid, "id": "test-message-id"} ], "user_id": random_user["id"] } From f8c29ef4c1a1334cd4ba8668e2b933961f333f89 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:47:15 +0200 Subject: [PATCH 08/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 0ec307f..feb61f7 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1022,7 +1022,7 @@ def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: "latest_delivered_messages": [ {"cid": channel.cid, "id": "test-message-id"} ], - "user_id": random_user["id"] + "user_id": random_user["id"], } response = client.mark_delivered(delivery_data) From efa0baaba62dd75bfc8f0e849c4fc19ae2ee562c Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:47:24 +0200 Subject: [PATCH 09/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index feb61f7..7f72663 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1027,7 +1027,6 @@ def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: response = client.mark_delivered(delivery_data) assert response is not None - delivery_data_multiple = { "latest_delivered_messages": [ { From 8ef832074b1922d9a2a209530df3901479287b3f Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:47:31 +0200 Subject: [PATCH 10/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 7f72663..dc16948 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1024,7 +1024,6 @@ def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: ], "user_id": random_user["id"], } - response = client.mark_delivered(delivery_data) assert response is not None delivery_data_multiple = { From 4cb92c288dc5189a2d3fc44e8129fcb681108758 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:47:40 +0200 Subject: [PATCH 11/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index dc16948..66b7826 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1047,7 +1047,7 @@ def test_mark_delivered_simple(self, client: StreamChat, channel: Channel, rando response = client.mark_delivered_simple( user_id=random_user["id"], message_id="test-message-id", - channel_cid=channel.cid + channel_cid=channel.cid, ) assert response is not None From f8fac50816edc2bc8a3ecfa5ebbd2ac4d314abb5 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:47:51 +0200 Subject: [PATCH 12/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 66b7826..ebaa478 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1052,7 +1052,9 @@ def test_mark_delivered_simple(self, client: StreamChat, channel: Channel, rando assert response is not None def test_mark_delivered_validation(self, client: StreamChat, random_user: Dict): - with pytest.raises(ValueError, match="latest_delivered_messages must not be empty"): + with pytest.raises( + ValueError, match="latest_delivered_messages must not be empty" + ): client.mark_delivered({"user_id": random_user["id"]}) with pytest.raises(ValueError, match="either user or user_id must be provided"): From c893dfec07d17f46893829ca581fafdd0c47b433 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:00 +0200 Subject: [PATCH 13/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index ebaa478..f6dc690 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1017,7 +1017,9 @@ def test_query_message_history( assert len(response_next["message_history"]) == 1 assert response_next["message_history"][0]["text"] == "helloworld-2" - def test_mark_delivered(self, client: StreamChat, channel: Channel, random_user: Dict): + def test_mark_delivered( + self, client: StreamChat, channel: Channel, random_user: Dict + ): delivery_data = { "latest_delivered_messages": [ {"cid": channel.cid, "id": "test-message-id"} From 6256a0bec3cfa37038c27ffe298ccd2b7490b548 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:11 +0200 Subject: [PATCH 14/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index f6dc690..8e3c8bf 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1030,14 +1030,8 @@ def test_mark_delivered( assert response is not None delivery_data_multiple = { "latest_delivered_messages": [ - { - "cid": channel.cid, - "id": "test-message-id-1" - }, - { - "cid": channel.cid, - "id": "test-message-id-2" - } + {"cid": channel.cid, "id": "test-message-id-1"}, + {"cid": channel.cid, "id": "test-message-id-2"}, ], "user_id": random_user["id"] } From 3015746b9729ef1042cc0c6497995bcccbf1abba Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:21 +0200 Subject: [PATCH 15/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 8e3c8bf..8dbaab1 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1033,7 +1033,7 @@ def test_mark_delivered( {"cid": channel.cid, "id": "test-message-id-1"}, {"cid": channel.cid, "id": "test-message-id-2"}, ], - "user_id": random_user["id"] + "user_id": random_user["id"], } response = client.mark_delivered(delivery_data_multiple) From d2591b233d6c7630cddd5e24d113dcb240cf0d2e Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:30 +0200 Subject: [PATCH 16/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 8dbaab1..2450bdc 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1035,7 +1035,6 @@ def test_mark_delivered( ], "user_id": random_user["id"], } - response = client.mark_delivered(delivery_data_multiple) assert response is not None From d4dfdc10a210966bae2c45dc5191c58aa13bbf65 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:40 +0200 Subject: [PATCH 17/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 2450bdc..a428eef 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1038,7 +1038,9 @@ def test_mark_delivered( response = client.mark_delivered(delivery_data_multiple) assert response is not None - def test_mark_delivered_simple(self, client: StreamChat, channel: Channel, random_user: Dict): + def test_mark_delivered_simple( + self, client: StreamChat, channel: Channel, random_user: Dict + ): response = client.mark_delivered_simple( user_id=random_user["id"], message_id="test-message-id", From a74a603ea562b7d1607ce791ace2404931e5779b Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:49 +0200 Subject: [PATCH 18/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index a428eef..9b39fdf 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1053,7 +1053,6 @@ def test_mark_delivered_validation(self, client: StreamChat, random_user: Dict): ValueError, match="latest_delivered_messages must not be empty" ): client.mark_delivered({"user_id": random_user["id"]}) - with pytest.raises(ValueError, match="either user or user_id must be provided"): client.mark_delivered({ "latest_delivered_messages": [{"cid": "test:channel", "id": "test"}] From f41635617477cd111003bc5a431697482863dda3 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 15 Sep 2025 10:48:58 +0200 Subject: [PATCH 19/28] Update stream_chat/tests/test_client.py Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- stream_chat/tests/test_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 9b39fdf..a2cecc9 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -1054,6 +1054,6 @@ def test_mark_delivered_validation(self, client: StreamChat, random_user: Dict): ): client.mark_delivered({"user_id": random_user["id"]}) with pytest.raises(ValueError, match="either user or user_id must be provided"): - client.mark_delivered({ - "latest_delivered_messages": [{"cid": "test:channel", "id": "test"}] - }) + client.mark_delivered( + {"latest_delivered_messages": [{"cid": "test:channel", "id": "test"}]} + ) From 8c3bfaf82d4764a9f28f9b3d9a470def185a9e03 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 13:34:07 +0200 Subject: [PATCH 20/28] fix lint --- stream_chat/types/delivery_receipts.py | 55 ++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/stream_chat/types/delivery_receipts.py b/stream_chat/types/delivery_receipts.py index e69de29..8cf8b74 100644 --- a/stream_chat/types/delivery_receipts.py +++ b/stream_chat/types/delivery_receipts.py @@ -0,0 +1,55 @@ +import sys +from typing import Dict, List, Optional + +if sys.version_info >= (3, 8): + from typing import TypedDict +else: + from typing_extensions import TypedDict + + +class DeliveredMessageConfirmation(TypedDict): + """ + Confirmation of a delivered message. + + Parameters: + cid: Channel CID (channel_type:channel_id) + id: Message ID + """ + cid: str + id: str + + +class MarkDeliveredOptions(TypedDict, total=False): + """ + Options for marking messages as delivered. + + Parameters: + latest_delivered_messages: List of delivered message confirmations + user: Optional user object + user_id: Optional user ID + """ + latest_delivered_messages: List[DeliveredMessageConfirmation] + user: Optional[Dict] # UserResponse equivalent + user_id: Optional[str] + + +class ChannelReadStatus(TypedDict, total=False): + """ + Channel read status information. + + Parameters: + last_read: Last read timestamp + unread_messages: Number of unread messages + user: User information + first_unread_message_id: ID of first unread message + last_read_message_id: ID of last read message + last_delivered_at: Last delivered timestamp + last_delivered_message_id: ID of last delivered message + """ + last_read: str # ISO format string for timestamp + unread_messages: int + user: Dict # UserResponse equivalent + first_unread_message_id: Optional[str] + last_read_message_id: Optional[str] + last_delivered_at: Optional[str] # ISO format string for timestamp + last_delivered_message_id: Optional[str] \ No newline at end of file From d1c1f5a65038e4abb3b8637b1c2c6745b4711f88 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 13:40:21 +0200 Subject: [PATCH 21/28] lint fix --- stream_chat/async_chat/client.py | 4 +++- stream_chat/types/delivery_receipts.py | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/stream_chat/async_chat/client.py b/stream_chat/async_chat/client.py index 212487e..fddfb1d 100644 --- a/stream_chat/async_chat/client.py +++ b/stream_chat/async_chat/client.py @@ -1003,7 +1003,9 @@ async def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse] return await self.post("channels/delivered", data=data) - async def mark_delivered_simple(self, user_id: str, message_id: str, channel_cid: str) -> Optional[StreamResponse]: + async def mark_delivered_simple( + self, user_id: str, message_id: str, channel_cid: str + ) -> Optional[StreamResponse]: """ Convenience method to mark a message as delivered for a specific user. diff --git a/stream_chat/types/delivery_receipts.py b/stream_chat/types/delivery_receipts.py index 8cf8b74..47f3b80 100644 --- a/stream_chat/types/delivery_receipts.py +++ b/stream_chat/types/delivery_receipts.py @@ -10,11 +10,12 @@ class DeliveredMessageConfirmation(TypedDict): """ Confirmation of a delivered message. - + Parameters: cid: Channel CID (channel_type:channel_id) id: Message ID """ + cid: str id: str @@ -22,12 +23,13 @@ class DeliveredMessageConfirmation(TypedDict): class MarkDeliveredOptions(TypedDict, total=False): """ Options for marking messages as delivered. - + Parameters: latest_delivered_messages: List of delivered message confirmations user: Optional user object user_id: Optional user ID """ + latest_delivered_messages: List[DeliveredMessageConfirmation] user: Optional[Dict] # UserResponse equivalent user_id: Optional[str] @@ -36,7 +38,7 @@ class MarkDeliveredOptions(TypedDict, total=False): class ChannelReadStatus(TypedDict, total=False): """ Channel read status information. - + Parameters: last_read: Last read timestamp unread_messages: Number of unread messages @@ -46,10 +48,11 @@ class ChannelReadStatus(TypedDict, total=False): last_delivered_at: Last delivered timestamp last_delivered_message_id: ID of last delivered message """ + last_read: str # ISO format string for timestamp unread_messages: int user: Dict # UserResponse equivalent first_unread_message_id: Optional[str] last_read_message_id: Optional[str] last_delivered_at: Optional[str] # ISO format string for timestamp - last_delivered_message_id: Optional[str] \ No newline at end of file + last_delivered_message_id: Optional[str] From ba0136267b7de48ce46c56c76a0a1d4917eb70eb Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 15:17:54 +0200 Subject: [PATCH 22/28] fix unit test --- stream_chat/client.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stream_chat/client.py b/stream_chat/client.py index 4a7dd38..4d09a53 100644 --- a/stream_chat/client.py +++ b/stream_chat/client.py @@ -955,7 +955,8 @@ def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: if not data.get("user") and not data.get("user_id"): raise ValueError("either user or user_id must be provided") - return self.post("channels/delivered", data=data) + params = {"user_id": user_id} + return self.post("channels/delivered", data=data, params=params) def mark_delivered_simple( self, user_id: str, message_id: str, channel_cid: str @@ -978,4 +979,4 @@ def mark_delivered_simple( "latest_delivered_messages": [{"cid": channel_cid, "id": message_id}], "user_id": user_id, } - return self.mark_delivered(data) + return self.mark_delivered(data=data) From 0d077889c1d2943e07eeca1136cb9603813e8f04 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 16:39:08 +0200 Subject: [PATCH 23/28] fix unit tests --- stream_chat/tests/async_chat/conftest.py | 22 ++++++ stream_chat/tests/async_chat/test_client.py | 75 ++++++++++++++++---- stream_chat/tests/conftest.py | 22 ++++++ stream_chat/tests/test_client.py | 76 +++++++++++++++++---- 4 files changed, 171 insertions(+), 24 deletions(-) diff --git a/stream_chat/tests/async_chat/conftest.py b/stream_chat/tests/async_chat/conftest.py index 425cee0..950c87c 100644 --- a/stream_chat/tests/async_chat/conftest.py +++ b/stream_chat/tests/async_chat/conftest.py @@ -141,3 +141,25 @@ async def hard_delete_users(client: StreamChatAsync, user_ids: List[str]): ) except Exception: pass + + +async def cleanup_blocklists_async(client: StreamChatAsync): + """Clean up test blocklists""" + try: + # Delete common test blocklist names + test_blocklists = ["Foo", "TestBlocklist", "TestBlocklistAsync"] + for blocklist_name in test_blocklists: + try: + await client.delete_blocklist(blocklist_name) + except Exception: + pass # Blocklist might not exist + except Exception: + pass + + +@pytest.fixture(autouse=True, scope="session") +async def cleanup_test_data(): + """Global cleanup for test data""" + yield + # This runs after all tests complete + # Add any global cleanup here if needed \ No newline at end of file diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index 4907841..fb09186 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -722,26 +722,77 @@ async def test_query_channels_members_in( assert len(response["channels"][0]["members"]) == 9 async def test_create_blocklist(self, client: StreamChatAsync): - await client.create_blocklist(name="Foo", words=["fudge", "heck"], type="word") + blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" + await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + # Clean up after test + try: + await client.delete_blocklist(blocklist_name) + except Exception: + pass async def test_list_blocklists(self, client: StreamChatAsync): - response = await client.list_blocklists() - assert len(response["blocklists"]) == 2 - blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} - assert "Foo" in blocklist_names + # First, clean up any existing test blocklists + await cleanup_blocklists_async(client) + + # Create a test blocklist + blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" + await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + try: + response = await client.list_blocklists() + # Should have at least 1 blocklist (the one we just created) + assert len(response["blocklists"]) >= 1 + blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} + assert blocklist_name in blocklist_names + finally: + # Clean up + try: + await client.delete_blocklist(blocklist_name) + except Exception: + pass async def test_get_blocklist(self, client: StreamChatAsync): - response = await client.get_blocklist("Foo") - assert response["blocklist"]["name"] == "Foo" - assert response["blocklist"]["words"] == ["fudge", "heck"] + blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" + await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + try: + response = await client.get_blocklist(blocklist_name) + assert response["blocklist"]["name"] == blocklist_name + assert response["blocklist"]["words"] == ["fudge", "heck"] + finally: + # Clean up + try: + await client.delete_blocklist(blocklist_name) + except Exception: + pass async def test_update_blocklist(self, client: StreamChatAsync): - await client.update_blocklist("Foo", words=["dang"]) - response = await client.get_blocklist("Foo") - assert response["blocklist"]["words"] == ["dang"] + blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" + await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + try: + await client.update_blocklist(blocklist_name, words=["dang"]) + response = await client.get_blocklist(blocklist_name) + assert response["blocklist"]["words"] == ["dang"] + finally: + # Clean up + try: + await client.delete_blocklist(blocklist_name) + except Exception: + pass async def test_delete_blocklist(self, client: StreamChatAsync): - await client.delete_blocklist("Foo") + blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" + await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + await client.delete_blocklist(blocklist_name) + + # Verify it's deleted + try: + await client.get_blocklist(blocklist_name) + pytest.fail("Blocklist should have been deleted") + except Exception: + pass # Expected - blocklist should not exist async def test_check_push( self, client: StreamChatAsync, channel: Channel, random_user: Dict diff --git a/stream_chat/tests/conftest.py b/stream_chat/tests/conftest.py index 3fe5e7a..7739285 100644 --- a/stream_chat/tests/conftest.py +++ b/stream_chat/tests/conftest.py @@ -131,3 +131,25 @@ def hard_delete_users(client: StreamChat, user_ids: List[str]): client.delete_users(user_ids, "hard", conversations="hard", messages="hard") except Exception: pass + + +def cleanup_blocklists(client: StreamChat): + """Clean up test blocklists""" + try: + # Delete common test blocklist names + test_blocklists = ["Foo", "TestBlocklist", "TestBlocklistAsync"] + for blocklist_name in test_blocklists: + try: + client.delete_blocklist(blocklist_name) + except Exception: + pass # Blocklist might not exist + except Exception: + pass + + +@pytest.fixture(autouse=True, scope="session") +def cleanup_test_data(): + """Global cleanup for test data""" + yield + # This runs after all tests complete + # Add any global cleanup here if needed \ No newline at end of file diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index a2cecc9..02530b3 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -699,26 +699,78 @@ def test_query_channels_members_in( assert len(response["channels"][0]["members"]) == 9 def test_create_blocklist(self, client: StreamChat): - client.create_blocklist(name="Foo", words=["fudge", "heck"], type="word") + # Use a unique name to avoid conflicts + blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" + client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + # Clean up after test + try: + client.delete_blocklist(blocklist_name) + except Exception: + pass def test_list_blocklists(self, client: StreamChat): - response = client.list_blocklists() - assert len(response["blocklists"]) == 2 - blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} - assert "Foo" in blocklist_names + # First, clean up any existing test blocklists + cleanup_blocklists(client) + + # Create a test blocklist + blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" + client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + try: + response = client.list_blocklists() + # Should have at least 1 blocklist (the one we just created) + assert len(response["blocklists"]) >= 1 + blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} + assert blocklist_name in blocklist_names + finally: + # Clean up + try: + client.delete_blocklist(blocklist_name) + except Exception: + pass def test_get_blocklist(self, client: StreamChat): - response = client.get_blocklist("Foo") - assert response["blocklist"]["name"] == "Foo" - assert response["blocklist"]["words"] == ["fudge", "heck"] + blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" + client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + try: + response = client.get_blocklist(blocklist_name) + assert response["blocklist"]["name"] == blocklist_name + assert response["blocklist"]["words"] == ["fudge", "heck"] + finally: + # Clean up + try: + client.delete_blocklist(blocklist_name) + except Exception: + pass def test_update_blocklist(self, client: StreamChat): - client.update_blocklist("Foo", words=["dang"]) - response = client.get_blocklist("Foo") - assert response["blocklist"]["words"] == ["dang"] + blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" + client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + + try: + client.update_blocklist(blocklist_name, words=["dang"]) + response = client.get_blocklist(blocklist_name) + assert response["blocklist"]["words"] == ["dang"] + finally: + # Clean up + try: + client.delete_blocklist(blocklist_name) + except Exception: + pass def test_delete_blocklist(self, client: StreamChat): - client.delete_blocklist("Foo") + blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" + client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + client.delete_blocklist(blocklist_name) + + # Verify it's deleted + try: + client.get_blocklist(blocklist_name) + pytest.fail("Blocklist should have been deleted") + except Exception: + pass # Expected - blocklist should not exist def test_check_push(self, client: StreamChat, channel: Channel, random_user: Dict): msg = {"id": str(uuid.uuid4()), "text": "/giphy wave"} From e9f53391df0aeedd4d1c60ea04da7d77ea52b1a2 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 16:40:37 +0200 Subject: [PATCH 24/28] lint fix --- stream_chat/tests/async_chat/conftest.py | 2 +- stream_chat/tests/async_chat/test_client.py | 36 ++++++++++++++------- stream_chat/tests/conftest.py | 2 +- stream_chat/tests/test_client.py | 36 ++++++++++++++------- 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/stream_chat/tests/async_chat/conftest.py b/stream_chat/tests/async_chat/conftest.py index 950c87c..0d47483 100644 --- a/stream_chat/tests/async_chat/conftest.py +++ b/stream_chat/tests/async_chat/conftest.py @@ -162,4 +162,4 @@ async def cleanup_test_data(): """Global cleanup for test data""" yield # This runs after all tests complete - # Add any global cleanup here if needed \ No newline at end of file + # Add any global cleanup here if needed diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index fb09186..0c911ba 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -723,8 +723,10 @@ async def test_query_channels_members_in( async def test_create_blocklist(self, client: StreamChatAsync): blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + await client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + # Clean up after test try: await client.delete_blocklist(blocklist_name) @@ -734,16 +736,20 @@ async def test_create_blocklist(self, client: StreamChatAsync): async def test_list_blocklists(self, client: StreamChatAsync): # First, clean up any existing test blocklists await cleanup_blocklists_async(client) - + # Create a test blocklist blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + await client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + try: response = await client.list_blocklists() # Should have at least 1 blocklist (the one we just created) assert len(response["blocklists"]) >= 1 - blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} + blocklist_names = { + blocklist["name"] for blocklist in response["blocklists"] + } assert blocklist_name in blocklist_names finally: # Clean up @@ -754,8 +760,10 @@ async def test_list_blocklists(self, client: StreamChatAsync): async def test_get_blocklist(self, client: StreamChatAsync): blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + await client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + try: response = await client.get_blocklist(blocklist_name) assert response["blocklist"]["name"] == blocklist_name @@ -769,8 +777,10 @@ async def test_get_blocklist(self, client: StreamChatAsync): async def test_update_blocklist(self, client: StreamChatAsync): blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + await client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + try: await client.update_blocklist(blocklist_name, words=["dang"]) response = await client.get_blocklist(blocklist_name) @@ -784,9 +794,11 @@ async def test_update_blocklist(self, client: StreamChatAsync): async def test_delete_blocklist(self, client: StreamChatAsync): blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + await client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) await client.delete_blocklist(blocklist_name) - + # Verify it's deleted try: await client.get_blocklist(blocklist_name) diff --git a/stream_chat/tests/conftest.py b/stream_chat/tests/conftest.py index 7739285..0a52d7b 100644 --- a/stream_chat/tests/conftest.py +++ b/stream_chat/tests/conftest.py @@ -152,4 +152,4 @@ def cleanup_test_data(): """Global cleanup for test data""" yield # This runs after all tests complete - # Add any global cleanup here if needed \ No newline at end of file + # Add any global cleanup here if needed diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 02530b3..bfc7f08 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -701,8 +701,10 @@ def test_query_channels_members_in( def test_create_blocklist(self, client: StreamChat): # Use a unique name to avoid conflicts blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + # Clean up after test try: client.delete_blocklist(blocklist_name) @@ -712,16 +714,20 @@ def test_create_blocklist(self, client: StreamChat): def test_list_blocklists(self, client: StreamChat): # First, clean up any existing test blocklists cleanup_blocklists(client) - + # Create a test blocklist blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + try: response = client.list_blocklists() # Should have at least 1 blocklist (the one we just created) assert len(response["blocklists"]) >= 1 - blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} + blocklist_names = { + blocklist["name"] for blocklist in response["blocklists"] + } assert blocklist_name in blocklist_names finally: # Clean up @@ -732,8 +738,10 @@ def test_list_blocklists(self, client: StreamChat): def test_get_blocklist(self, client: StreamChat): blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + try: response = client.get_blocklist(blocklist_name) assert response["blocklist"]["name"] == blocklist_name @@ -747,8 +755,10 @@ def test_get_blocklist(self, client: StreamChat): def test_update_blocklist(self, client: StreamChat): blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") - + client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) + try: client.update_blocklist(blocklist_name, words=["dang"]) response = client.get_blocklist(blocklist_name) @@ -762,9 +772,11 @@ def test_update_blocklist(self, client: StreamChat): def test_delete_blocklist(self, client: StreamChat): blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist(name=blocklist_name, words=["fudge", "heck"], type="word") + client.create_blocklist( + name=blocklist_name, words=["fudge", "heck"], type="word" + ) client.delete_blocklist(blocklist_name) - + # Verify it's deleted try: client.get_blocklist(blocklist_name) From e77f7f8464952a15cc528f75bfe9979c1c496b63 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 16:48:37 +0200 Subject: [PATCH 25/28] fix unit tesrts --- stream_chat/client.py | 5 +++++ stream_chat/tests/async_chat/test_client.py | 4 ++-- stream_chat/tests/test_client.py | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/stream_chat/client.py b/stream_chat/client.py index 4d09a53..7d57c95 100644 --- a/stream_chat/client.py +++ b/stream_chat/client.py @@ -955,6 +955,11 @@ def mark_delivered(self, data: Dict[str, Any]) -> Optional[StreamResponse]: if not data.get("user") and not data.get("user_id"): raise ValueError("either user or user_id must be provided") + # Extract user_id from data + user_id = data.get("user_id") or data.get("user", {}).get("id") + if not user_id: + raise ValueError("user_id must be provided") + params = {"user_id": user_id} return self.post("channels/delivered", data=data, params=params) diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index 0c911ba..c4aee63 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -6,7 +6,7 @@ from contextlib import suppress from datetime import datetime from operator import itemgetter -from typing import Dict, List +from typing import Dict, List, Any, Optional import aiohttp import jwt @@ -15,7 +15,7 @@ from stream_chat.async_chat import StreamChatAsync from stream_chat.async_chat.channel import Channel from stream_chat.base.exceptions import StreamAPIException -from stream_chat.tests.async_chat.conftest import hard_delete_users +from stream_chat.tests.async_chat.conftest import hard_delete_users, cleanup_blocklists_async from stream_chat.tests.utils import wait_for_async diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index bfc7f08..4ac1a0c 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -6,7 +6,7 @@ from contextlib import suppress from datetime import datetime from operator import itemgetter -from typing import Dict, List +from typing import Dict, List, Any, Optional import jwt import pytest @@ -15,7 +15,7 @@ from stream_chat import StreamChat from stream_chat.base.exceptions import StreamAPIException from stream_chat.channel import Channel -from stream_chat.tests.conftest import hard_delete_users +from stream_chat.tests.conftest import hard_delete_users, cleanup_blocklists from stream_chat.tests.utils import wait_for From fcc7dbcc143a2717d17c7d308b6a36e676ca2c4d Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 16:49:44 +0200 Subject: [PATCH 26/28] lint fix --- stream_chat/tests/async_chat/test_client.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index c4aee63..f7af487 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -15,7 +15,10 @@ from stream_chat.async_chat import StreamChatAsync from stream_chat.async_chat.channel import Channel from stream_chat.base.exceptions import StreamAPIException -from stream_chat.tests.async_chat.conftest import hard_delete_users, cleanup_blocklists_async +from stream_chat.tests.async_chat.conftest import ( + hard_delete_users, + cleanup_blocklists_async, +) from stream_chat.tests.utils import wait_for_async From a5c76fdbc2f94334dafc406e10ff26ca9ff96171 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 16:54:52 +0200 Subject: [PATCH 27/28] lint --- stream_chat/tests/async_chat/test_client.py | 4 ++-- stream_chat/tests/test_client.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index f7af487..c865002 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -6,7 +6,7 @@ from contextlib import suppress from datetime import datetime from operator import itemgetter -from typing import Dict, List, Any, Optional +from typing import Dict, List import aiohttp import jwt @@ -16,8 +16,8 @@ from stream_chat.async_chat.channel import Channel from stream_chat.base.exceptions import StreamAPIException from stream_chat.tests.async_chat.conftest import ( - hard_delete_users, cleanup_blocklists_async, + hard_delete_users, ) from stream_chat.tests.utils import wait_for_async diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 4ac1a0c..0c13b4c 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -6,7 +6,7 @@ from contextlib import suppress from datetime import datetime from operator import itemgetter -from typing import Dict, List, Any, Optional +from typing import Dict, List import jwt import pytest @@ -15,7 +15,7 @@ from stream_chat import StreamChat from stream_chat.base.exceptions import StreamAPIException from stream_chat.channel import Channel -from stream_chat.tests.conftest import hard_delete_users, cleanup_blocklists +from stream_chat.tests.conftest import cleanup_blocklists, hard_delete_users from stream_chat.tests.utils import wait_for From a01d6c4b54382eb8de13bb14f37d77009ca37053 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 3 Oct 2025 17:39:40 +0200 Subject: [PATCH 28/28] revert --- stream_chat/tests/async_chat/conftest.py | 22 ----- stream_chat/tests/async_chat/test_client.py | 92 +++------------------ stream_chat/tests/conftest.py | 22 ----- stream_chat/tests/test_client.py | 90 +++----------------- 4 files changed, 26 insertions(+), 200 deletions(-) diff --git a/stream_chat/tests/async_chat/conftest.py b/stream_chat/tests/async_chat/conftest.py index 0d47483..425cee0 100644 --- a/stream_chat/tests/async_chat/conftest.py +++ b/stream_chat/tests/async_chat/conftest.py @@ -141,25 +141,3 @@ async def hard_delete_users(client: StreamChatAsync, user_ids: List[str]): ) except Exception: pass - - -async def cleanup_blocklists_async(client: StreamChatAsync): - """Clean up test blocklists""" - try: - # Delete common test blocklist names - test_blocklists = ["Foo", "TestBlocklist", "TestBlocklistAsync"] - for blocklist_name in test_blocklists: - try: - await client.delete_blocklist(blocklist_name) - except Exception: - pass # Blocklist might not exist - except Exception: - pass - - -@pytest.fixture(autouse=True, scope="session") -async def cleanup_test_data(): - """Global cleanup for test data""" - yield - # This runs after all tests complete - # Add any global cleanup here if needed diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index c865002..4907841 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -15,10 +15,7 @@ from stream_chat.async_chat import StreamChatAsync from stream_chat.async_chat.channel import Channel from stream_chat.base.exceptions import StreamAPIException -from stream_chat.tests.async_chat.conftest import ( - cleanup_blocklists_async, - hard_delete_users, -) +from stream_chat.tests.async_chat.conftest import hard_delete_users from stream_chat.tests.utils import wait_for_async @@ -725,89 +722,26 @@ async def test_query_channels_members_in( assert len(response["channels"][0]["members"]) == 9 async def test_create_blocklist(self, client: StreamChatAsync): - blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - # Clean up after test - try: - await client.delete_blocklist(blocklist_name) - except Exception: - pass + await client.create_blocklist(name="Foo", words=["fudge", "heck"], type="word") async def test_list_blocklists(self, client: StreamChatAsync): - # First, clean up any existing test blocklists - await cleanup_blocklists_async(client) - - # Create a test blocklist - blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - try: - response = await client.list_blocklists() - # Should have at least 1 blocklist (the one we just created) - assert len(response["blocklists"]) >= 1 - blocklist_names = { - blocklist["name"] for blocklist in response["blocklists"] - } - assert blocklist_name in blocklist_names - finally: - # Clean up - try: - await client.delete_blocklist(blocklist_name) - except Exception: - pass + response = await client.list_blocklists() + assert len(response["blocklists"]) == 2 + blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} + assert "Foo" in blocklist_names async def test_get_blocklist(self, client: StreamChatAsync): - blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - try: - response = await client.get_blocklist(blocklist_name) - assert response["blocklist"]["name"] == blocklist_name - assert response["blocklist"]["words"] == ["fudge", "heck"] - finally: - # Clean up - try: - await client.delete_blocklist(blocklist_name) - except Exception: - pass + response = await client.get_blocklist("Foo") + assert response["blocklist"]["name"] == "Foo" + assert response["blocklist"]["words"] == ["fudge", "heck"] async def test_update_blocklist(self, client: StreamChatAsync): - blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - try: - await client.update_blocklist(blocklist_name, words=["dang"]) - response = await client.get_blocklist(blocklist_name) - assert response["blocklist"]["words"] == ["dang"] - finally: - # Clean up - try: - await client.delete_blocklist(blocklist_name) - except Exception: - pass + await client.update_blocklist("Foo", words=["dang"]) + response = await client.get_blocklist("Foo") + assert response["blocklist"]["words"] == ["dang"] async def test_delete_blocklist(self, client: StreamChatAsync): - blocklist_name = f"TestBlocklistAsync_{uuid.uuid4().hex[:8]}" - await client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - await client.delete_blocklist(blocklist_name) - - # Verify it's deleted - try: - await client.get_blocklist(blocklist_name) - pytest.fail("Blocklist should have been deleted") - except Exception: - pass # Expected - blocklist should not exist + await client.delete_blocklist("Foo") async def test_check_push( self, client: StreamChatAsync, channel: Channel, random_user: Dict diff --git a/stream_chat/tests/conftest.py b/stream_chat/tests/conftest.py index 0a52d7b..3fe5e7a 100644 --- a/stream_chat/tests/conftest.py +++ b/stream_chat/tests/conftest.py @@ -131,25 +131,3 @@ def hard_delete_users(client: StreamChat, user_ids: List[str]): client.delete_users(user_ids, "hard", conversations="hard", messages="hard") except Exception: pass - - -def cleanup_blocklists(client: StreamChat): - """Clean up test blocklists""" - try: - # Delete common test blocklist names - test_blocklists = ["Foo", "TestBlocklist", "TestBlocklistAsync"] - for blocklist_name in test_blocklists: - try: - client.delete_blocklist(blocklist_name) - except Exception: - pass # Blocklist might not exist - except Exception: - pass - - -@pytest.fixture(autouse=True, scope="session") -def cleanup_test_data(): - """Global cleanup for test data""" - yield - # This runs after all tests complete - # Add any global cleanup here if needed diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 0c13b4c..a2cecc9 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -15,7 +15,7 @@ from stream_chat import StreamChat from stream_chat.base.exceptions import StreamAPIException from stream_chat.channel import Channel -from stream_chat.tests.conftest import cleanup_blocklists, hard_delete_users +from stream_chat.tests.conftest import hard_delete_users from stream_chat.tests.utils import wait_for @@ -699,90 +699,26 @@ def test_query_channels_members_in( assert len(response["channels"][0]["members"]) == 9 def test_create_blocklist(self, client: StreamChat): - # Use a unique name to avoid conflicts - blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - # Clean up after test - try: - client.delete_blocklist(blocklist_name) - except Exception: - pass + client.create_blocklist(name="Foo", words=["fudge", "heck"], type="word") def test_list_blocklists(self, client: StreamChat): - # First, clean up any existing test blocklists - cleanup_blocklists(client) - - # Create a test blocklist - blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - try: - response = client.list_blocklists() - # Should have at least 1 blocklist (the one we just created) - assert len(response["blocklists"]) >= 1 - blocklist_names = { - blocklist["name"] for blocklist in response["blocklists"] - } - assert blocklist_name in blocklist_names - finally: - # Clean up - try: - client.delete_blocklist(blocklist_name) - except Exception: - pass + response = client.list_blocklists() + assert len(response["blocklists"]) == 2 + blocklist_names = {blocklist["name"] for blocklist in response["blocklists"]} + assert "Foo" in blocklist_names def test_get_blocklist(self, client: StreamChat): - blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - try: - response = client.get_blocklist(blocklist_name) - assert response["blocklist"]["name"] == blocklist_name - assert response["blocklist"]["words"] == ["fudge", "heck"] - finally: - # Clean up - try: - client.delete_blocklist(blocklist_name) - except Exception: - pass + response = client.get_blocklist("Foo") + assert response["blocklist"]["name"] == "Foo" + assert response["blocklist"]["words"] == ["fudge", "heck"] def test_update_blocklist(self, client: StreamChat): - blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - - try: - client.update_blocklist(blocklist_name, words=["dang"]) - response = client.get_blocklist(blocklist_name) - assert response["blocklist"]["words"] == ["dang"] - finally: - # Clean up - try: - client.delete_blocklist(blocklist_name) - except Exception: - pass + client.update_blocklist("Foo", words=["dang"]) + response = client.get_blocklist("Foo") + assert response["blocklist"]["words"] == ["dang"] def test_delete_blocklist(self, client: StreamChat): - blocklist_name = f"TestBlocklist_{uuid.uuid4().hex[:8]}" - client.create_blocklist( - name=blocklist_name, words=["fudge", "heck"], type="word" - ) - client.delete_blocklist(blocklist_name) - - # Verify it's deleted - try: - client.get_blocklist(blocklist_name) - pytest.fail("Blocklist should have been deleted") - except Exception: - pass # Expected - blocklist should not exist + client.delete_blocklist("Foo") def test_check_push(self, client: StreamChat, channel: Channel, random_user: Dict): msg = {"id": str(uuid.uuid4()), "text": "/giphy wave"}