diff --git a/.gitignore b/.gitignore index 5c7b40b26d..434b6c4733 100644 --- a/.gitignore +++ b/.gitignore @@ -105,7 +105,7 @@ __pycache__/ .pytest_cache/ .envrc report/results.xml -tests-functional/coverage +tests-functional/**/coverage tests-functional/reports tests-functional/signals tests-functional/*.log diff --git a/tests-functional/schemas/wakuext_emojiReactionsByChatID b/tests-functional/schemas/wakuext_emojiReactionsByChatID new file mode 100644 index 0000000000..3208938119 --- /dev/null +++ b/tests-functional/schemas/wakuext_emojiReactionsByChatID @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/schema#", + "properties": { + "id": { + "type": "integer" + }, + "jsonrpc": { + "type": "string" + }, + "result": { + "items": { + "properties": { + "chatId": { + "type": "string" + }, + "clock": { + "type": "integer" + }, + "compressedKey": { + "type": "string" + }, + "emojiHash": { + "items": { + "type": "string" + }, + "type": "array" + }, + "emojiId": { + "type": "integer" + }, + "from": { + "type": "string" + }, + "id": { + "type": "string" + }, + "localChatId": { + "type": "string" + }, + "messageId": { + "type": "string" + } + }, + "required": [ + "chatId", + "clock", + "compressedKey", + "emojiHash", + "emojiId", + "from", + "id", + "localChatId", + "messageId" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "id", + "jsonrpc", + "result" + ], + "type": "object" +} \ No newline at end of file diff --git a/tests-functional/schemas/wakuext_emojiReactionsByChatIDMessageID b/tests-functional/schemas/wakuext_emojiReactionsByChatIDMessageID new file mode 100644 index 0000000000..3208938119 --- /dev/null +++ b/tests-functional/schemas/wakuext_emojiReactionsByChatIDMessageID @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/schema#", + "properties": { + "id": { + "type": "integer" + }, + "jsonrpc": { + "type": "string" + }, + "result": { + "items": { + "properties": { + "chatId": { + "type": "string" + }, + "clock": { + "type": "integer" + }, + "compressedKey": { + "type": "string" + }, + "emojiHash": { + "items": { + "type": "string" + }, + "type": "array" + }, + "emojiId": { + "type": "integer" + }, + "from": { + "type": "string" + }, + "id": { + "type": "string" + }, + "localChatId": { + "type": "string" + }, + "messageId": { + "type": "string" + } + }, + "required": [ + "chatId", + "clock", + "compressedKey", + "emojiHash", + "emojiId", + "from", + "id", + "localChatId", + "messageId" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "id", + "jsonrpc", + "result" + ], + "type": "object" +} \ No newline at end of file diff --git a/tests-functional/schemas/wakuext_sendEmojiReaction b/tests-functional/schemas/wakuext_sendEmojiReaction new file mode 100644 index 0000000000..21a284ed46 --- /dev/null +++ b/tests-functional/schemas/wakuext_sendEmojiReaction @@ -0,0 +1,322 @@ +{ + "$schema": "http://json-schema.org/schema#", + "properties": { + "id": { + "type": "integer" + }, + "jsonrpc": { + "type": "string" + }, + "result": { + "properties": { + "chats": { + "items": { + "properties": { + "ReadMessagesAtClockValue": { + "type": "integer" + }, + "active": { + "type": "boolean" + }, + "alias": { + "type": "string" + }, + "chatType": { + "type": "integer" + }, + "color": { + "type": "string" + }, + "deletedAtClockValue": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "emoji": { + "type": "string" + }, + "highlight": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "identicon": { + "type": "string" + }, + "joined": { + "type": "integer" + }, + "lastClockValue": { + "type": "integer" + }, + "lastMessage": { + "properties": { + "alias": { + "type": "string" + }, + "chatId": { + "type": "string" + }, + "clock": { + "type": "integer" + }, + "compressedKey": { + "type": "string" + }, + "contactRequestState": { + "type": "integer" + }, + "contentType": { + "type": "integer" + }, + "displayName": { + "type": "string" + }, + "emojiHash": { + "items": { + "type": "string" + }, + "type": "array" + }, + "ensName": { + "type": "string" + }, + "from": { + "type": "string" + }, + "id": { + "type": "string" + }, + "identicon": { + "type": "string" + }, + "lineCount": { + "type": "integer" + }, + "localChatId": { + "type": "string" + }, + "messageType": { + "type": "integer" + }, + "new": { + "type": "boolean" + }, + "parsedText": { + "items": { + "properties": { + "children": { + "items": { + "properties": { + "literal": { + "type": "string" + } + }, + "required": [ + "literal" + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "required": [ + "children", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "quotedMessage": { + "type": "null" + }, + "replace": { + "type": "string" + }, + "responseTo": { + "type": "string" + }, + "rtl": { + "type": "boolean" + }, + "seen": { + "type": "boolean" + }, + "text": { + "type": "string" + }, + "timestamp": { + "type": "integer" + }, + "whisperTimestamp": { + "type": "integer" + } + }, + "required": [ + "alias", + "chatId", + "clock", + "compressedKey", + "contactRequestState", + "contentType", + "displayName", + "emojiHash", + "ensName", + "from", + "id", + "identicon", + "lineCount", + "localChatId", + "messageType", + "new", + "parsedText", + "quotedMessage", + "replace", + "responseTo", + "rtl", + "seen", + "text", + "timestamp", + "whisperTimestamp" + ], + "type": "object" + }, + "members": { + "type": "null" + }, + "membershipUpdateEvents": { + "type": "null" + }, + "muteTill": { + "type": "string" + }, + "muted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "timestamp": { + "type": "integer" + }, + "unviewedMentionsCount": { + "type": "integer" + }, + "unviewedMessagesCount": { + "type": "integer" + }, + "viewersCanPostReactions": { + "type": "boolean" + } + }, + "required": [ + "ReadMessagesAtClockValue", + "active", + "alias", + "chatType", + "color", + "deletedAtClockValue", + "description", + "emoji", + "highlight", + "id", + "identicon", + "joined", + "lastClockValue", + "lastMessage", + "members", + "membershipUpdateEvents", + "muteTill", + "muted", + "name", + "timestamp", + "unviewedMentionsCount", + "unviewedMessagesCount", + "viewersCanPostReactions" + ], + "type": "object" + }, + "type": "array" + }, + "discordOldestMessageTimestamp": { + "type": "integer" + }, + "emojiReactions": { + "items": { + "properties": { + "chatId": { + "type": "string" + }, + "clock": { + "type": "integer" + }, + "compressedKey": { + "type": "string" + }, + "emojiHash": { + "items": { + "type": "string" + }, + "type": "array" + }, + "emojiId": { + "type": "integer" + }, + "from": { + "type": "string" + }, + "id": { + "type": "string" + }, + "localChatId": { + "type": "string" + }, + "messageId": { + "type": "string" + }, + "messageType": { + "type": "integer" + } + }, + "required": [ + "chatId", + "clock", + "compressedKey", + "emojiHash", + "emojiId", + "from", + "id", + "localChatId", + "messageId", + "messageType" + ], + "type": "object" + }, + "type": "array" + }, + "notifications": { + "type": "null" + } + }, + "required": [ + "chats", + "discordOldestMessageTimestamp", + "emojiReactions", + "notifications" + ], + "type": "object" + } + }, + "required": [ + "id", + "jsonrpc", + "result" + ], + "type": "object" +} \ No newline at end of file diff --git a/tests-functional/schemas/wakuext_sendEmojiReactionRetraction b/tests-functional/schemas/wakuext_sendEmojiReactionRetraction new file mode 100644 index 0000000000..3faedf007d --- /dev/null +++ b/tests-functional/schemas/wakuext_sendEmojiReactionRetraction @@ -0,0 +1,326 @@ +{ + "$schema": "http://json-schema.org/schema#", + "properties": { + "id": { + "type": "integer" + }, + "jsonrpc": { + "type": "string" + }, + "result": { + "properties": { + "chats": { + "items": { + "properties": { + "ReadMessagesAtClockValue": { + "type": "integer" + }, + "active": { + "type": "boolean" + }, + "alias": { + "type": "string" + }, + "chatType": { + "type": "integer" + }, + "color": { + "type": "string" + }, + "deletedAtClockValue": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "emoji": { + "type": "string" + }, + "highlight": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "identicon": { + "type": "string" + }, + "joined": { + "type": "integer" + }, + "lastClockValue": { + "type": "integer" + }, + "lastMessage": { + "properties": { + "alias": { + "type": "string" + }, + "chatId": { + "type": "string" + }, + "clock": { + "type": "integer" + }, + "compressedKey": { + "type": "string" + }, + "contactRequestState": { + "type": "integer" + }, + "contentType": { + "type": "integer" + }, + "displayName": { + "type": "string" + }, + "emojiHash": { + "items": { + "type": "string" + }, + "type": "array" + }, + "ensName": { + "type": "string" + }, + "from": { + "type": "string" + }, + "id": { + "type": "string" + }, + "identicon": { + "type": "string" + }, + "lineCount": { + "type": "integer" + }, + "localChatId": { + "type": "string" + }, + "messageType": { + "type": "integer" + }, + "new": { + "type": "boolean" + }, + "parsedText": { + "items": { + "properties": { + "children": { + "items": { + "properties": { + "literal": { + "type": "string" + } + }, + "required": [ + "literal" + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "required": [ + "children", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "quotedMessage": { + "type": "null" + }, + "replace": { + "type": "string" + }, + "responseTo": { + "type": "string" + }, + "rtl": { + "type": "boolean" + }, + "seen": { + "type": "boolean" + }, + "text": { + "type": "string" + }, + "timestamp": { + "type": "integer" + }, + "whisperTimestamp": { + "type": "integer" + } + }, + "required": [ + "alias", + "chatId", + "clock", + "compressedKey", + "contactRequestState", + "contentType", + "displayName", + "emojiHash", + "ensName", + "from", + "id", + "identicon", + "lineCount", + "localChatId", + "messageType", + "new", + "parsedText", + "quotedMessage", + "replace", + "responseTo", + "rtl", + "seen", + "text", + "timestamp", + "whisperTimestamp" + ], + "type": "object" + }, + "members": { + "type": "null" + }, + "membershipUpdateEvents": { + "type": "null" + }, + "muteTill": { + "type": "string" + }, + "muted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "timestamp": { + "type": "integer" + }, + "unviewedMentionsCount": { + "type": "integer" + }, + "unviewedMessagesCount": { + "type": "integer" + }, + "viewersCanPostReactions": { + "type": "boolean" + } + }, + "required": [ + "ReadMessagesAtClockValue", + "active", + "alias", + "chatType", + "color", + "deletedAtClockValue", + "description", + "emoji", + "highlight", + "id", + "identicon", + "joined", + "lastClockValue", + "lastMessage", + "members", + "membershipUpdateEvents", + "muteTill", + "muted", + "name", + "timestamp", + "unviewedMentionsCount", + "unviewedMessagesCount", + "viewersCanPostReactions" + ], + "type": "object" + }, + "type": "array" + }, + "discordOldestMessageTimestamp": { + "type": "integer" + }, + "emojiReactions": { + "items": { + "properties": { + "chatId": { + "type": "string" + }, + "clock": { + "type": "integer" + }, + "compressedKey": { + "type": "string" + }, + "emojiHash": { + "items": { + "type": "string" + }, + "type": "array" + }, + "emojiId": { + "type": "integer" + }, + "from": { + "type": "string" + }, + "id": { + "type": "string" + }, + "localChatId": { + "type": "string" + }, + "messageId": { + "type": "string" + }, + "messageType": { + "type": "integer" + }, + "retracted": { + "type": "boolean" + } + }, + "required": [ + "chatId", + "clock", + "compressedKey", + "emojiHash", + "emojiId", + "from", + "id", + "localChatId", + "messageId", + "messageType", + "retracted" + ], + "type": "object" + }, + "type": "array" + }, + "notifications": { + "type": "null" + } + }, + "required": [ + "chats", + "discordOldestMessageTimestamp", + "emojiReactions", + "notifications" + ], + "type": "object" + } + }, + "required": [ + "id", + "jsonrpc", + "result" + ], + "type": "object" +} \ No newline at end of file diff --git a/tests-functional/tests/reliability/test_community_messages.py b/tests-functional/tests/reliability/test_community_messages.py index 0a34e003ad..36eb6134a1 100644 --- a/tests-functional/tests/reliability/test_community_messages.py +++ b/tests-functional/tests/reliability/test_community_messages.py @@ -5,7 +5,7 @@ from clients.signals import SignalType -@pytest.mark.usefixtures("setup_two_nodes") +@pytest.mark.usefixtures("setup_two_privileged_nodes") @pytest.mark.reliability class TestCommunityMessages(MessengerTestCase): diff --git a/tests-functional/tests/reliability/test_create_private_groups.py b/tests-functional/tests/reliability/test_create_private_groups.py index 9db0946441..2e896f1190 100644 --- a/tests-functional/tests/reliability/test_create_private_groups.py +++ b/tests-functional/tests/reliability/test_create_private_groups.py @@ -5,7 +5,7 @@ from clients.signals import SignalType -@pytest.mark.usefixtures("setup_two_nodes") +@pytest.mark.usefixtures("setup_two_privileged_nodes") @pytest.mark.reliability class TestCreatePrivateGroups(MessengerTestCase): diff --git a/tests-functional/tests/reliability/test_one_to_one_messages.py b/tests-functional/tests/reliability/test_one_to_one_messages.py index f897ec5f2d..0f3f1d5fe1 100644 --- a/tests-functional/tests/reliability/test_one_to_one_messages.py +++ b/tests-functional/tests/reliability/test_one_to_one_messages.py @@ -5,7 +5,7 @@ from clients.signals import SignalType -@pytest.mark.usefixtures("setup_two_nodes") +@pytest.mark.usefixtures("setup_two_privileged_nodes") @pytest.mark.reliability class TestOneToOneMessages(MessengerTestCase): diff --git a/tests-functional/tests/reliability/test_private_groups_messages.py b/tests-functional/tests/reliability/test_private_groups_messages.py index bd141c77ef..4bbbb16784 100644 --- a/tests-functional/tests/reliability/test_private_groups_messages.py +++ b/tests-functional/tests/reliability/test_private_groups_messages.py @@ -5,7 +5,7 @@ from clients.signals import SignalType -@pytest.mark.usefixtures("setup_two_nodes") +@pytest.mark.usefixtures("setup_two_privileged_nodes") @pytest.mark.reliability class TestPrivateGroupMessages(MessengerTestCase): diff --git a/tests-functional/tests/test_cases.py b/tests-functional/tests/test_cases.py index 3fac2b2ecc..972ba8101c 100644 --- a/tests-functional/tests/test_cases.py +++ b/tests-functional/tests/test_cases.py @@ -210,10 +210,15 @@ class MessengerTestCase(NetworkConditionTestCase): ] @pytest.fixture(scope="function", autouse=False) - def setup_two_nodes(self, request): + def setup_two_privileged_nodes(self, request): request.cls.sender = self.sender = self.initialize_backend(self.await_signals, True) request.cls.receiver = self.receiver = self.initialize_backend(self.await_signals, True) + @pytest.fixture(scope="function", autouse=False) + def setup_two_unprivileged_nodes(self, request): + request.cls.sender = self.sender = self.initialize_backend(self.await_signals, False) + request.cls.receiver = self.receiver = self.initialize_backend(self.await_signals, False) + def initialize_backend(self, await_signals, privileged=True): backend = StatusBackend(await_signals, privileged) backend.init_status_backend() diff --git a/tests-functional/tests/test_waku_rpc.py b/tests-functional/tests/test_waku_rpc.py index 6fae44a34d..3a6d9857dc 100644 --- a/tests-functional/tests/test_waku_rpc.py +++ b/tests-functional/tests/test_waku_rpc.py @@ -23,14 +23,9 @@ def test_(self, method, params): @pytest.mark.rpc -@pytest.mark.usefixtures("setup_two_nodes") +@pytest.mark.usefixtures("setup_two_unprivileged_nodes") class TestDefaultMessaging(MessengerTestCase): - @pytest.fixture(scope="function", autouse=False) - def setup_two_nodes(self, request): - request.cls.sender = self.sender = self.initialize_backend(self.await_signals, False) - request.cls.receiver = self.receiver = self.initialize_backend(self.await_signals, False) - def test_one_to_one_messages(self): self.one_to_one_message(5) @@ -49,11 +44,11 @@ def test_private_group_messages(self): @pytest.mark.rpc @pytest.mark.skip -@pytest.mark.usefixtures("setup_two_nodes") +@pytest.mark.usefixtures("setup_two_privileged_nodes") class TestLightClientMessaging(TestDefaultMessaging): @pytest.fixture(scope="function", autouse=False) - def setup_two_nodes(self, request): + def setup_two_unprivileged_nodes(self, request): request.cls.sender = self.sender = self.initialize_backend(self.await_signals, False) request.cls.receiver = self.receiver = self.initialize_backend(self.await_signals, False) for user in self.sender, self.receiver: diff --git a/tests-functional/tests/test_wakuext_message_reactions.py b/tests-functional/tests/test_wakuext_message_reactions.py new file mode 100644 index 0000000000..88ca289aa5 --- /dev/null +++ b/tests-functional/tests/test_wakuext_message_reactions.py @@ -0,0 +1,102 @@ +import time + +import pytest + +from clients.signals import SignalType +from resources.enums import MessageContentType +from tests.test_cases import MessengerTestCase + + +@pytest.mark.usefixtures("setup_two_unprivileged_nodes") +@pytest.mark.rpc +class TestMessageReactions(MessengerTestCase): + def test_one_to_one_message_reactions(self): + self.make_contacts() + response = self.sender.wakuext_service.send_message(self.receiver.public_key, "test_message") + message = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] + message_id, sender_chat_id = message["id"], message["chatId"] + receiver_chat_id = self.receiver.wakuext_service.rpc_request(method="chats").json()["result"][0]["id"] + response = self.receiver.wakuext_service.rpc_request(method="sendEmojiReaction", params=[receiver_chat_id, message_id, 1]).json() + self.sender.verify_json_schema(response, "wakuext_sendEmojiReaction") + self.sender.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern="emojiReactions", + timeout=60, + ) + + response = self.sender.wakuext_service.rpc_request( + method="emojiReactionsByChatIDMessageID", + params=[sender_chat_id, message_id], + ).json() + self.sender.verify_json_schema(response, "wakuext_emojiReactionsByChatIDMessageID") + result = response["result"] + assert all( + ( + len(result) == 1, + result[0]["chatId"] == receiver_chat_id, + result[0]["messageId"] == message_id, + result[0]["emojiId"] == 1, + ) + ) + emoji_id = result[0]["id"] + + response = self.receiver.wakuext_service.rpc_request( + method="sendEmojiReactionRetraction", + params=[ + emoji_id, + ], + ).json() + self.sender.verify_json_schema(response, "wakuext_sendEmojiReactionRetraction") + assert response["result"]["chats"][0]["id"] == receiver_chat_id + + self.sender.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern="retracted", + timeout=60, + ) + response = self.sender.wakuext_service.rpc_request( + method="emojiReactionsByChatIDMessageID", + params=[sender_chat_id, message_id], + ) + assert not response.json()["result"] + + response = self.sender.wakuext_service.send_message(self.receiver.public_key, "test_message 1") + message_1 = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] + emoji_1_id = self.receiver.wakuext_service.rpc_request(method="sendEmojiReaction", params=[receiver_chat_id, message_1["id"], 2]).json()[ + "result" + ]["emojiReactions"][0]["id"] + self.sender.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=emoji_1_id, + timeout=60, + ) + + response = self.receiver.wakuext_service.send_message(self.sender.public_key, "test_message 2") + message_2 = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] + emoji_2_id = self.sender.wakuext_service.rpc_request(method="sendEmojiReaction", params=[sender_chat_id, message_2["id"], 3]).json()[ + "result" + ]["emojiReactions"][0]["id"] + self.receiver.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=emoji_2_id, + timeout=60, + ) + time.sleep(10) + response = self.sender.wakuext_service.rpc_request(method="emojiReactionsByChatID", params=[sender_chat_id, None, 20]).json() + self.sender.verify_json_schema(response, "wakuext_emojiReactionsByChatID") + result = response["result"] + assert len(result) == 2 + for item in result: + assert all( + ( + item["chatId"] == sender_chat_id, + item["messageId"] == message_2["id"], + item["emojiId"] == 3, + ) + ) or all( + ( + item["chatId"] == receiver_chat_id, + item["messageId"] == message_1["id"], + item["emojiId"] == 2, + ) + )