diff --git a/tests-functional/README.MD b/tests-functional/README.MD index f72c9336fb4..1d7a39f3a1d 100644 --- a/tests-functional/README.MD +++ b/tests-functional/README.MD @@ -41,6 +41,23 @@ Functional tests for status-go * In `./tests-functional/tests` directory run `pytest -m rpc` * To run tests against binary run `pytest -m --url=http:: --user_dir=/` +### Prerequisites for Mac OSx users +If you see errors at attempt to run tests, try to run in terminal: +```shell +sock.connect(self.unix_socket) +``` +If you see +``` +PermissionError: [Errno 13] Permission denied +``` + +Please follow this fix: https://github.com/docker/compose/issues/10299#issuecomment-1438247730 + +If you're on MacOS and `/var/run/docker.sock` doesn't exist, you need to create a symlink to the docker socket: +```shell +sudo ln -s $HOME/.docker/run/docker.sock /var/run/docker.sock +``` + ## Implementation details - Functional tests are implemented in `./tests-functional/tests` based on [pytest](https://docs.pytest.org/en/8.2.x/) @@ -51,17 +68,9 @@ Functional tests for status-go # Known issues -## Docker permission denied +## Import issues -When running tests with auto-creating status-backend containers, you might face this: -```shell -sock.connect(self.unix_socket) -PermissionError: [Errno 13] Permission denied -``` +If you see some import issues, make sure that you have all requirements installed from `requirements.txt` -Please follow this fix: https://github.com/docker/compose/issues/10299#issuecomment-1438247730 - -If you're on MacOS and `/var/run/docker.sock` doesn't exist, you need to create a symlink to the docker socket: -```shell -sudo ln -s $HOME/.docker/run/docker.sock /var/run/docker.sock -``` \ No newline at end of file +### For PyCharm users +Make sure that you made `test-functional` source folder (Right click > Mark directory as > Source folder) diff --git a/tests-functional/clients/services/wakuext.py b/tests-functional/clients/services/wakuext.py index 765af594c70..11f614d03b1 100644 --- a/tests-functional/clients/services/wakuext.py +++ b/tests-functional/clients/services/wakuext.py @@ -69,3 +69,8 @@ def send_community_chat_message(self, chat_id, message, content_type=MessageCont params = [{"chatId": chat_id, "text": message, "contentType": content_type}] response = self.rpc_request("sendChatMessage", params) return response.json() + + def set_light_client(self, enabled=True): + params = [{"enabled": enabled}] + response = self.rpc_request("setLightClient", params) + return response.json() diff --git a/tests-functional/clients/signals.py b/tests-functional/clients/signals.py index 49e098a0847..d6ddfb7dbc8 100644 --- a/tests-functional/clients/signals.py +++ b/tests-functional/clients/signals.py @@ -16,6 +16,7 @@ class SignalType(Enum): NODE_READY = "node.ready" NODE_STARTED = "node.started" NODE_LOGIN = "node.login" + NODE_LOGOUT = "node.stopped" MEDIASERVER_STARTED = "mediaserver.started" WALLET_SUGGESTED_ROUTES = "wallet.suggested.routes" WALLET_ROUTER_SIGN_TRANSACTIONS = "wallet.router.sign-transactions" @@ -98,6 +99,10 @@ def wait_for_login(self): assert not signal["event"]["error"] return signal + def wait_for_logout(self): + signal = self.wait_for_signal(SignalType.NODE_LOGOUT.value) + return signal + def find_signal_containing_pattern(self, signal_type, event_pattern, timeout=20): start_time = time.time() while True: diff --git a/tests-functional/schemas/wakuext_getSavedAddresses b/tests-functional/schemas/wakuext_getSavedAddresses new file mode 100644 index 00000000000..1ed000bd6d5 --- /dev/null +++ b/tests-functional/schemas/wakuext_getSavedAddresses @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/schema#", + "properties": { + "id": { + "type": "integer" + }, + "jsonrpc": { + "type": "string" + }, + "result": { + "items": { + "properties": { + "address": { + "type": "string" + }, + "chainShortNames": { + "type": "string" + }, + "colorId": { + "type": "string" + }, + "createdAt": { + "type": "integer" + }, + "ens": { + "type": "string" + }, + "isTest": { + "type": "boolean" + }, + "mixedcaseAddress": { + "type": "string" + }, + "name": { + "type": "string" + }, + "removed": { + "type": "boolean" + } + }, + "required": [ + "address", + "chainShortNames", + "colorId", + "createdAt", + "ens", + "isTest", + "mixedcaseAddress", + "name", + "removed" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "id", + "jsonrpc", + "result" + ], + "type": "object" +} \ No newline at end of file diff --git a/tests-functional/schemas/wakuext_getSavedAddressesPerMode b/tests-functional/schemas/wakuext_getSavedAddressesPerMode new file mode 100644 index 00000000000..1ed000bd6d5 --- /dev/null +++ b/tests-functional/schemas/wakuext_getSavedAddressesPerMode @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/schema#", + "properties": { + "id": { + "type": "integer" + }, + "jsonrpc": { + "type": "string" + }, + "result": { + "items": { + "properties": { + "address": { + "type": "string" + }, + "chainShortNames": { + "type": "string" + }, + "colorId": { + "type": "string" + }, + "createdAt": { + "type": "integer" + }, + "ens": { + "type": "string" + }, + "isTest": { + "type": "boolean" + }, + "mixedcaseAddress": { + "type": "string" + }, + "name": { + "type": "string" + }, + "removed": { + "type": "boolean" + } + }, + "required": [ + "address", + "chainShortNames", + "colorId", + "createdAt", + "ens", + "isTest", + "mixedcaseAddress", + "name", + "removed" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "id", + "jsonrpc", + "result" + ], + "type": "object" +} \ No newline at end of file diff --git a/tests-functional/tests/reliability/test_contact_request.py b/tests-functional/tests/reliability/test_contact_request.py index 7a6e3dcf247..c6c1eb1528e 100644 --- a/tests-functional/tests/reliability/test_contact_request.py +++ b/tests-functional/tests/reliability/test_contact_request.py @@ -10,40 +10,7 @@ class TestContactRequests(MessengerTestCase): def test_contact_request_baseline(self, execution_number=1, network_condition=None): - message_text = f"test_contact_request_{execution_number}_{uuid4()}" - sender = self.initialize_backend(await_signals=self.await_signals) - receiver = self.initialize_backend(await_signals=self.await_signals) - - existing_contacts = receiver.wakuext_service.get_contacts() - - if sender.public_key in str(existing_contacts): - pytest.skip("Contact request was already sent for this sender<->receiver. Skipping test!!") - - if network_condition: - network_condition(receiver) - - response = sender.wakuext_service.send_contact_request(receiver.public_key, message_text) - expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.CONTACT_REQUEST.value)[0] - - messages_new_event = receiver.find_signal_containing_pattern( - SignalType.MESSAGES_NEW.value, - event_pattern=expected_message.get("id"), - timeout=60, - ) - - signal_messages_texts = [] - if "messages" in messages_new_event.get("event", {}): - signal_messages_texts.extend(message["text"] for message in messages_new_event["event"]["messages"] if "text" in message) - - assert ( - f"@{sender.public_key} sent you a contact request" in signal_messages_texts - ), "Couldn't find the signal corresponding to the contact request" - - self.validate_signal_event_against_response( - signal_event=messages_new_event, - fields_to_validate={"text": "text"}, - expected_message=expected_message, - ) + self.add_contact(execution_number, network_condition) @pytest.mark.parametrize("execution_number", range(10)) def test_multiple_contact_requests(self, execution_number): diff --git a/tests-functional/tests/reliability/test_create_private_groups.py b/tests-functional/tests/reliability/test_create_private_groups.py index 16d66dd9c8f..9db09464419 100644 --- a/tests-functional/tests/reliability/test_create_private_groups.py +++ b/tests-functional/tests/reliability/test_create_private_groups.py @@ -3,7 +3,6 @@ import pytest from tests.test_cases import MessengerTestCase from clients.signals import SignalType -from resources.enums import MessageContentType @pytest.mark.usefixtures("setup_two_nodes") @@ -12,29 +11,7 @@ class TestCreatePrivateGroups(MessengerTestCase): def test_create_private_group_baseline(self, private_groups_count=1): self.make_contacts() - - private_groups = [] - for i in range(private_groups_count): - private_group_name = f"private_group_{i+1}_{uuid4()}" - response = self.sender.wakuext_service.create_group_chat_with_members([self.receiver.public_key], private_group_name) - - expected_group_creation_msg = f"@{self.sender.public_key} created the group {private_group_name}" - expected_message = self.get_message_by_content_type( - response, content_type=MessageContentType.SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP.value, message_pattern=expected_group_creation_msg - )[0] - - private_groups.append(expected_message) - sleep(0.01) - - for i, expected_message in enumerate(private_groups): - messages_new_event = self.receiver.find_signal_containing_pattern( - SignalType.MESSAGES_NEW.value, event_pattern=expected_message.get("id"), timeout=60 - ) - self.validate_signal_event_against_response( - signal_event=messages_new_event, - expected_message=expected_message, - fields_to_validate={"text": "text"}, - ) + self.create_private_group(private_groups_count) def test_multiple_one_create_private_groups(self): self.test_create_private_group_baseline(private_groups_count=50) 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 faf6536f56c..f897ec5f2d3 100644 --- a/tests-functional/tests/reliability/test_one_to_one_messages.py +++ b/tests-functional/tests/reliability/test_one_to_one_messages.py @@ -3,7 +3,6 @@ import pytest from tests.test_cases import MessengerTestCase from clients.signals import SignalType -from resources.enums import MessageContentType @pytest.mark.usefixtures("setup_two_nodes") @@ -11,25 +10,7 @@ class TestOneToOneMessages(MessengerTestCase): def test_one_to_one_message_baseline(self, message_count=1): - sent_messages = [] - for i in range(message_count): - message_text = f"test_message_{i+1}_{uuid4()}" - response = self.sender.wakuext_service.send_message(self.receiver.public_key, message_text) - expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] - sent_messages.append(expected_message) - sleep(0.01) - - for i, expected_message in enumerate(sent_messages): - messages_new_event = self.receiver.find_signal_containing_pattern( - SignalType.MESSAGES_NEW.value, - event_pattern=expected_message.get("id"), - timeout=60, - ) - self.validate_signal_event_against_response( - signal_event=messages_new_event, - fields_to_validate={"text": "text"}, - expected_message=expected_message, - ) + self.one_to_one_message(message_count) def test_multiple_one_to_one_messages(self): self.test_one_to_one_message_baseline(message_count=50) diff --git a/tests-functional/tests/reliability/test_private_groups_messages.py b/tests-functional/tests/reliability/test_private_groups_messages.py index 3bf37b9a8b6..bd141c77ef0 100644 --- a/tests-functional/tests/reliability/test_private_groups_messages.py +++ b/tests-functional/tests/reliability/test_private_groups_messages.py @@ -3,7 +3,6 @@ import pytest from tests.test_cases import MessengerTestCase from clients.signals import SignalType -from resources.enums import MessageContentType @pytest.mark.usefixtures("setup_two_nodes") @@ -13,26 +12,7 @@ class TestPrivateGroupMessages(MessengerTestCase): def test_private_group_messages_baseline(self, message_count=1): self.make_contacts() self.private_group_id = self.join_private_group() - - sent_messages = [] - for i in range(message_count): - message_text = f"test_message_{i+1}_{uuid4()}" - response = self.sender.wakuext_service.send_group_chat_message(self.private_group_id, message_text) - expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] - sent_messages.append(expected_message) - sleep(0.01) - - for _, expected_message in enumerate(sent_messages): - messages_new_event = self.receiver.find_signal_containing_pattern( - SignalType.MESSAGES_NEW.value, - event_pattern=expected_message.get("id"), - timeout=60, - ) - self.validate_signal_event_against_response( - signal_event=messages_new_event, - fields_to_validate={"text": "text"}, - expected_message=expected_message, - ) + self.private_group_message(message_count, self.private_group_id) def test_multiple_group_chat_messages(self): self.test_private_group_messages_baseline(message_count=50) diff --git a/tests-functional/tests/test_cases.py b/tests-functional/tests/test_cases.py index c94e630334d..b7df351f5df 100644 --- a/tests-functional/tests/test_cases.py +++ b/tests-functional/tests/test_cases.py @@ -206,15 +206,16 @@ class MessengerTestCase(NetworkConditionTestCase): SignalType.MESSAGES_NEW.value, SignalType.MESSAGE_DELIVERED.value, SignalType.NODE_LOGIN.value, + SignalType.NODE_LOGOUT.value, ] @pytest.fixture(scope="function", autouse=False) def setup_two_nodes(self, request): - request.cls.sender = self.sender = self.initialize_backend(await_signals=self.await_signals) - request.cls.receiver = self.receiver = self.initialize_backend(await_signals=self.await_signals) + request.cls.sender = self.sender = self.initialize_backend(self.await_signals) + request.cls.receiver = self.receiver = self.initialize_backend(self.await_signals) - def initialize_backend(self, await_signals, **kwargs): - backend = StatusBackend(await_signals=await_signals, privileged=True) + def initialize_backend(self, await_signals, privileged=True, **kwargs): + backend = StatusBackend(await_signals, privileged) backend.init_status_backend() backend.create_account_and_login(**kwargs) backend.find_public_key() @@ -278,9 +279,15 @@ def join_private_group(self): response = self.sender.wakuext_service.create_group_chat_with_members([self.receiver.public_key], private_group_name) expected_group_creation_msg = f"@{self.sender.public_key} created the group {private_group_name}" expected_message = self.get_message_by_content_type( - response, content_type=MessageContentType.SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP.value, message_pattern=expected_group_creation_msg + response, + content_type=MessageContentType.SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP.value, + message_pattern=expected_group_creation_msg, )[0] - self.receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=expected_message.get("id"), timeout=60) + self.receiver.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=expected_message.get("id"), + timeout=60, + ) return response.get("result", {}).get("chats", [])[0].get("id") def create_and_join_community(self): @@ -332,3 +339,109 @@ def community_messages(self, message_chat_id, message_count): fields_to_validate={"text": "text"}, expected_message=expected_message, ) + + def one_to_one_message(self, message_count): + sent_messages = [] + for i in range(message_count): + message_text = f"test_message_{i+1}_{uuid4()}" + response = self.sender.wakuext_service.send_message(self.receiver.public_key, message_text) + expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] + sent_messages.append(expected_message) + time.sleep(0.01) + + for i, expected_message in enumerate(sent_messages): + messages_new_event = self.receiver.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=expected_message.get("id"), + timeout=60, + ) + self.validate_signal_event_against_response( + signal_event=messages_new_event, + fields_to_validate={"text": "text"}, + expected_message=expected_message, + ) + + def add_contact(self, execution_number, network_condition=None, privileged=True): + message_text = f"test_contact_request_{execution_number}_{uuid4()}" + sender = self.initialize_backend(await_signals=self.await_signals, privileged=privileged) + receiver = self.initialize_backend(await_signals=self.await_signals, privileged=privileged) + + existing_contacts = receiver.wakuext_service.get_contacts() + + if sender.public_key in str(existing_contacts): + pytest.skip("Contact request was already sent for this sender<->receiver. Skipping test!!") + + if network_condition: + network_condition(receiver) + + response = sender.wakuext_service.send_contact_request(receiver.public_key, message_text) + expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.CONTACT_REQUEST.value)[0] + + messages_new_event = receiver.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=expected_message.get("id"), + timeout=60, + ) + + signal_messages_texts = [] + if "messages" in messages_new_event.get("event", {}): + signal_messages_texts.extend(message["text"] for message in messages_new_event["event"]["messages"] if "text" in message) + + assert ( + f"@{sender.public_key} sent you a contact request" in signal_messages_texts + ), "Couldn't find the signal corresponding to the contact request" + + self.validate_signal_event_against_response( + signal_event=messages_new_event, + fields_to_validate={"text": "text"}, + expected_message=expected_message, + ) + + def create_private_group(self, private_groups_count): + private_groups = [] + for i in range(private_groups_count): + private_group_name = f"private_group_{i+1}_{uuid4()}" + response = self.sender.wakuext_service.create_group_chat_with_members([self.receiver.public_key], private_group_name) + + expected_group_creation_msg = f"@{self.sender.public_key} created the group {private_group_name}" + expected_message = self.get_message_by_content_type( + response, + content_type=MessageContentType.SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP.value, + message_pattern=expected_group_creation_msg, + )[0] + + private_groups.append(expected_message) + time.sleep(0.01) + + for i, expected_message in enumerate(private_groups): + messages_new_event = self.receiver.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=expected_message.get("id"), + timeout=60, + ) + self.validate_signal_event_against_response( + signal_event=messages_new_event, + expected_message=expected_message, + fields_to_validate={"text": "text"}, + ) + + def private_group_message(self, message_count, private_group_id): + sent_messages = [] + for i in range(message_count): + message_text = f"test_message_{i+1}_{uuid4()}" + response = self.sender.wakuext_service.send_group_chat_message(private_group_id, message_text) + expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.TEXT_PLAIN.value)[0] + sent_messages.append(expected_message) + time.sleep(0.01) + + for _, expected_message in enumerate(sent_messages): + messages_new_event = self.receiver.find_signal_containing_pattern( + SignalType.MESSAGES_NEW.value, + event_pattern=expected_message.get("id"), + timeout=60, + ) + self.validate_signal_event_against_response( + signal_event=messages_new_event, + fields_to_validate={"text": "text"}, + expected_message=expected_message, + ) diff --git a/tests-functional/tests/test_waku_rpc.py b/tests-functional/tests/test_waku_rpc.py index 927cb2234f7..6fae44a34d1 100644 --- a/tests-functional/tests/test_waku_rpc.py +++ b/tests-functional/tests/test_waku_rpc.py @@ -1,12 +1,6 @@ import random -import time -from dataclasses import dataclass -from typing import Optional - import pytest - -from conftest import option -from test_cases import StatusBackendTestCase +from test_cases import StatusBackendTestCase, MessengerTestCase class TestRpc(StatusBackendTestCase): @@ -28,73 +22,45 @@ def test_(self, method, params): self.rpc_client.verify_json_schema(response.json(), method) -@pytest.mark.skip("to be reworked via status-backend") -class TestRpcMessaging(StatusBackendTestCase): - @dataclass - class User: - rpc_url: str - chat_public_key: Optional[str] = None - chat_id: Optional[str] = None - - def test_add_contact(self): - _id = str(random.randint(1, 8888)) - - self.user_1 = self.User(rpc_url=option.rpc_url) - self.user_2 = self.User(rpc_url=option.rpc_url_2) +@pytest.mark.rpc +@pytest.mark.usefixtures("setup_two_nodes") +class TestDefaultMessaging(MessengerTestCase): - # get chat public key - for user in self.user_1, self.user_2: - response = self.rpc_client.rpc_request("accounts_getAccounts", [], _id, url=user.rpc_url) - self.rpc_client.verify_is_valid_json_rpc_response(response) + @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) - user.chat_public_key = next( - (item["public-key"] for item in response.json()["result"] if item["chat"]), - None, - ) + def test_one_to_one_messages(self): + self.one_to_one_message(5) - # send contact requests - for sender in self.user_1, self.user_2: - for receiver in self.user_1, self.user_2: - if sender != receiver: - response = self.rpc_client.rpc_request( - method="wakuext_sendContactRequest", - params=[ - { - "id": receiver.chat_public_key, - "message": f"contact request from {sender.chat_public_key}: sent at {time.time()}", - } - ], - request_id=99, - url=sender.rpc_url, - ) - - self.rpc_client.verify_is_valid_json_rpc_response(response) - sender.chat_id = response.json()["result"]["chats"][0]["lastMessage"]["id"] - - # accept contact requests - for user in self.user_1, self.user_2: - response = self.rpc_client.rpc_request( - method="wakuext_acceptContactRequest", - params=[ - { - "id": user.chat_id, - } - ], - request_id=99, - url=user.rpc_url, - ) - self.rpc_client.verify_is_valid_json_rpc_response(response) - - # verify contacts - for user in (self.user_1, self.user_2), (self.user_2, self.user_1): - response = self.rpc_client.rpc_request( - method="wakuext_contacts", - params=[], - request_id=99, - url=user[0].rpc_url, - ) - self.rpc_client.verify_is_valid_json_rpc_response(response) - - response = response.json() - assert response["result"][0]["added"] is True - assert response["result"][0]["id"] == user[1].chat_public_key + def test_add_contact(self): + self.add_contact(execution_number=1, network_condition=None, privileged=False) + + def test_create_private_group(self): + self.make_contacts() + self.create_private_group(1) + + def test_private_group_messages(self): + self.make_contacts() + self.private_group_id = self.join_private_group() + self.private_group_message(5, self.private_group_id) + + +@pytest.mark.rpc +@pytest.mark.skip +@pytest.mark.usefixtures("setup_two_nodes") +class TestLightClientMessaging(TestDefaultMessaging): + + @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) + for user in self.sender, self.receiver: + key_uid = user.node_login_event["event"]["account"]["key-uid"] + user.wakuext_service.set_light_client(True) + user.logout() + user.wait_for_logout() + user.login(key_uid) + user.prepare_wait_for_signal("node.login", 1) + user.wait_for_login() diff --git a/tests-functional/tests/test_wakuext_savedAddress.py b/tests-functional/tests/test_wakuext_savedAddress.py new file mode 100644 index 00000000000..eb8813386f0 --- /dev/null +++ b/tests-functional/tests/test_wakuext_savedAddress.py @@ -0,0 +1,141 @@ +import pytest +import logging + +from test_cases import StatusBackendTestCase + + +@pytest.mark.rpc +@pytest.mark.wallet +class TestSavedAddresses(StatusBackendTestCase): + + @pytest.mark.parametrize( + "method, params", + [ + ( + "wakuext_upsertSavedAddress", + [ + { + "address": "0xcf2272205cc0cf96cfbb9dd740bd681d1e86901e", + "name": "some_random_address", + "colorId": "green", + "isTest": False, + "chainShortNames": "", + } + ], + ), + ( + "wakuext_upsertSavedAddress", + [ + { + "address": "0x8e58eb36c7b77d6c43fc05c8fd3fe645d1d39588", + "mixedcaseAddress": "0x8e58eb36c7b77d6C43fC05C8Fd3FE645d1d39588", + "name": "yellow_ENS", + "colorId": "yellow", + "ens": "some_yellow_ENS.eth", + "isTest": False, + "chainShortNames": "", + } + ], + ), + ( + "wakuext_upsertSavedAddress", + [ + { + "address": "0xc6a54e79fb8915efbe00a8adac5bd94b68022fb6", + "name": "test_address_pretty_long_name WITH Cap letters", + "colorId": "blue", + "ens": "test_some_yellow_ENS.eth", + "isTest": False, + "chainShortNames": "orb:opt", + } + ], + ), + ], + ) + def test_add_saved_address(self, method, params): + """Test adding saved addresses and verifying their presence in the lists.""" + + logging.info("Step: Adding item in mainnet mode") + self.rpc_client.rpc_valid_request(method, params) + response = self.rpc_client.rpc_valid_request("wakuext_getSavedAddresses", []) + + logging.info("Step: Verifying the item is in the saved addresses list") + self.rpc_client.verify_json_schema(response.json(), "wakuext_getSavedAddresses") + assert any(params[0].items() <= item.items() for item in response.json()["result"]), f"{params[0]['name']} not found in getSavedAddresses" + + logging.info("Step: Checking if the item is listed under mainnet saved addresses") + response = self.rpc_client.rpc_valid_request("wakuext_getSavedAddressesPerMode", [False]) + self.rpc_client.verify_json_schema(response.json(), "wakuext_getSavedAddressesPerMode") + assert any( + params[0].items() <= item.items() for item in response.json()["result"] + ), f"{params[0]['name']} not found in getSavedAddressesPerMode" + + logging.info("Step: Ensuring the item is NOT in the testnet saved addresses list") + response = self.rpc_client.rpc_valid_request("wakuext_getSavedAddressesPerMode", [True]) + assert response.json()["result"] is None, "wakuext_getSavedAddressesPerMode for test mode is not empty" + + def test_delete_saved_address(self): + """Test deleting a saved address and verifying its removal.""" + address, is_test = "0xc6a54e79fb8915efbe00a8adac5bd94b68022fb6", True + params = [ + { + "address": address, + "name": "testnet_yellow_ENS", + "colorId": "red", + "ens": "some_red_ENS.stateofus.eth", + "isTest": is_test, + } + ] + + logging.info("Step: Adding item in testnet mode") + self.rpc_client.rpc_valid_request("wakuext_upsertSavedAddress", params) + + logging.info("Step: Verifying the item exists in testnet saved addresses") + response = self.rpc_client.rpc_valid_request("wakuext_getSavedAddressesPerMode", [is_test]) + assert any( + params[0].items() <= item.items() for item in response.json()["result"] + ), f"{params[0]['name']} not found in getSavedAddressesPerMode" + + logging.info("Step: Deleting the item and verifying removal") + self.rpc_client.rpc_valid_request("wakuext_deleteSavedAddress", [address, is_test]) + response = self.rpc_client.rpc_valid_request("wakuext_getSavedAddressesPerMode", [is_test]) + assert response.json()["result"] is None, "getSavedAddressesPerMode for test mode is not empty" + + def test_remaining_capacity_for_saved_addresses(self): + """Test checking the remaining capacity for saved addresses.""" + is_test = False + addresses = [ + "0x0a27AF951DAD6228Fd8A692992Be23527219FcaD", + "0xAC65F396C9032e249F4c8Dc430531eEa57152fd4", + "0x172cf0afc54C8A145bdD2781d04f3a1e2a074437", + "0x4473a1AebEC875e8027544A032666C1A329021CE", + "0x2E4FEC1aaE712dCAD560A69739d0DbB225Cd7c75", + "0x90956c8d09D2651c7930996d61D21ba5D7D0bDf1", + "0xc864d0Ec046ea0B8Edd00d49edfe3A19368C59F8", + "0x89e03B5342c75a68FC61C85cC2a58bDd61Bf264e", + "0x1049e21dE0fBDa877C2780A85875e135a73433F1", + "0xc742524aEd5742aa75a5DcdCec1bFBe12Dc29BC0", + "0xaE406B10C55924e96B5Ee267501B169ED37e6814", + "0x9B6248818aab31018C54f9D63535D07bCeE061e5", + "0x2C7b097427d0Da09A30d4FE9bD1aaBa956CE1538", + "0xc9a087C44C7A098569cD9295593609050A0F292e", + "0x901F90De45C31215b0F99b4F52F1D4b317302f72", + "0xD73E3f566d3Eb55E9c292A798600F7dc0ece4351", + "0xd06f43DEf63102A8137337eaafcF43c45D6a2708", + "0x474fc93f36Aa0ed1A80c0D836cFB3acFE80C2D42", + "0xE14e345d9bbadf6796DC7fEdf8f2625aDc11509b", + "0x09B69c2F46E7F63131C54BAfae242EEc2C600762", + ] + + logging.info("Step: Checking remaining capacity") + response = self.rpc_client.rpc_valid_request("wakuext_remainingCapacityForSavedAddresses", [is_test]) + remaining_capacity = response.json()["result"] + + logging.info("Step: adding addresses to fill capacity") + for i in range(remaining_capacity): + self.rpc_client.rpc_valid_request("wakuext_upsertSavedAddress", [{"address": addresses[i], "name": f"test{i}", "isTest": is_test}]) + + logging.info("Step: Verifying that capacity is now 0") + response = self.rpc_client.rpc_request("wakuext_remainingCapacityForSavedAddresses", [is_test]) + self.rpc_client.verify_is_json_rpc_error(response) + assert response.json()["error"]["message"] == "no more save addresses can be added"