Skip to content

Commit bf25a9b

Browse files
AYAHASSAN287dlipicarglitchminermarkoburculfbarbu15
authored
test: First draft for settings wrappers and test file added (#6984)
* test: First draft for settings wrappers and test file added * test: Making changes in test env & add tests * test: Add new test * feat: improve blockchainstate * feat: replace old transfer detection algorithm with multistandardbalance and transferdetector * build: add Android x86_64 support to Makefile (#6990) - Sets MOBILE_GOARCH to amd64 when ARCH is x86_64 - Sets ANDROID_CLANG_TARGET to x86_64-linux-android<API> * ci: use official base docker image for builds Referenced issue: * status-im/infra-ci#188 * test: community chats (#6987) * test: community chats * test: community chats review * test: Adding node tests * test: contact verification (#6997) * chore: point go.mod to original go-ethereum repo * chore: drop usage of non-multichain ethclient methods in rpc chain client * chore: drop usage of non-multichain ethclient methods in community tokens service * chore: drop usage of non-multichain ethclient methods in fees manager * chore: adapt to new geth logger * chore: remove unused log_parser code * chore: replace custom NoSign parameter from bind.TransactOpts * chore: update SingleRequestCodec to go-ethereum upstream * chore: use `go-waku` with upstream `go-ethereum` (#6978) * chore: upgrade go-waku and go-discover * chore: make vendor * feat: go-waku v0.10.0 * chore: fix tests * chore: bump go-waku and go-discover (#6983) * refactor: use common Migrate function - Use sqlite.Migrate in protocol to remove logic duplication. - Remove legacy ad-hoc migration fix. It is now safe to assume that no users are running versions old enough to require this workaround. * refactor: move pubkeys utils from protocol to crypto package These utils are generic enough to be moved to crypto package. * fix: Crash on uninitialized filterManager Not sure if this will only hide the root cause because the proper flow on pairing is unknown to me. But from what I've seen Waku is only started after login. While `subscribe` and `unsubscribe` is used in the pairing flow as well. * test: Add new tests * test: Adding wrappers &tests * test: Add positive & negative tests * test: Added backup tests * feat: clean up balance fetching from token manager (#6991) * feat: improvemets to multistandardbalance controller * feat: introduce tokenbalances package * chore: replace balance fetching capabilities from reader and token manager with tokenbalances * feat: allow overriding multicall3 contract address * chore: fix tests * chore: pr comments * fix(scripts): branch_version_generated use current base branch (#7007) * fix: goimports configuration (#7004) * fix: goimports only 1 local package * fix: vscode settings goimports * fix: un-gitignore IDEA code styles * feat: goland code styles * fix: remove generate_handlers nolint comment * chore: lint-fix all files * feat: local timesource (#7003) * feat: local timesource * fix: nwaku * fix: rebase issues * feat(benchmark): threads and goroutines count (#7006) * feat: added numThreads to expvars * test: added num of threads and goroutines to benchmarks * fix: issues * chore: cleanup chain client and transactor (#7008) * chore: make rpc.Client implement EthClientGetter * chore: remove unused types * chore: cleanup unused methods and use interface instead of rpc Client * chore: cleanup transactor * chore: move pendingtxtracker to separate package * chore: fix tests * test: add all APIs tests * test: Apply linters * fix: reduce test variants to shorten test durations * fix: lints * fix: remove print statements for debug-only purpose * fix: use logger when necessary * chore: use `go-waku` with upstream `go-ethereum` (#6978) * chore: upgrade go-waku and go-discover * chore: make vendor * feat: go-waku v0.10.0 * chore: bump go-waku and go-discover (#6983) * feat: clean up balance fetching from token manager (#6991) * feat: improvemets to multistandardbalance controller * feat: introduce tokenbalances package * chore: replace balance fetching capabilities from reader and token manager with tokenbalances * feat: allow overriding multicall3 contract address * chore: fix tests * chore: pr comments * fix: rebase on develop - remove unused imports * fix: wait longer for backend in Jenkins * test: look for potential problems beyond failing tests * test: test_check_node_config_params * test: service context behavior * test: revert wakuext service name * fix: test_news_feed_enabled * fix: test_news_notifications_enabled * fix: test_toggle_news_notifications_enabled * fix: test_toggle_news_rss_enabled * fix: test_set_valid_backup_path * fix: wait 40s for backend in Jenkins * fix: remove unused function * fix: test_last_tokens_update_advances_after_updating_token_preferences * test: temporary fix for - test_delete_exemptions_invalid_id * test: temporary fix for - test_notifications_set_global_mentions_rejects_wrong_types_and_preserves_value * test: race condition fix for - test_update_keycard_uid_success * test: return to the original timeout value * fix: remove redundant deepcopy * fix: remove line without effect in - test_full_migrate_flow * fix: change to skip annotation * fix: improve assertions * fix: remove ExemptionsDefaults related code * fix: uncomment - test_notifications_set_group_chats_invalid_values * fix: remove Go code for - NotificationsSetGlobalMentions - DeleteExemptions * fix: commented out tests - test_notifications_set_global_mentions_rejects_wrong_types_and_preserves_value - test_delete_exemptions_invalid_id * fix: naming and test clarity * fix: remove redundant news feed tests * fix: regroup tests * fix: re-run stuck codecov tests --------- Co-authored-by: Dario Gabriel Lipicar <[email protected]> Co-authored-by: Mag. <[email protected]> Co-authored-by: markoburcul <[email protected]> Co-authored-by: fbarbu15 <[email protected]> Co-authored-by: Patryk Osmaczko <[email protected]> Co-authored-by: Igor Sirotin <[email protected]> Co-authored-by: Alex Jbanca <[email protected]> Co-authored-by: Roman <[email protected]>
1 parent d8aed51 commit bf25a9b

File tree

11 files changed

+655
-12
lines changed

11 files changed

+655
-12
lines changed

tests-functional/clients/services/settings.py

Lines changed: 128 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,135 @@ class SettingsService(Service):
66
def __init__(self, client: RpcClient):
77
super().__init__(client, "settings")
88

9+
# Base settings
910
def get_settings(self):
10-
response = self.rpc_request("getSettings")
11-
return response
11+
return self.rpc_request("getSettings")
1212

1313
def save_setting(self, key, value):
1414
params = [key, value]
15-
response = self.rpc_request("saveSetting", params)
16-
return response
15+
return self.rpc_request("saveSetting", params)
16+
17+
def get_node_config(self):
18+
return self.rpc_request("nodeConfig")
19+
20+
# Backup Settings
21+
def backup_path(self):
22+
return self.rpc_request("backupPath")
23+
24+
def messages_backup_enabled(self):
25+
return self.rpc_request("messagesBackupEnabled")
26+
27+
# Notifications Settings
28+
def notifications_get_allow_notifications(self):
29+
return self.rpc_request("notificationsGetAllowNotifications")
30+
31+
def notifications_set_allow_notifications(self, value: bool):
32+
params = [value]
33+
return self.rpc_request("notificationsSetAllowNotifications", params)
34+
35+
def notifications_get_one_to_one_chats(self):
36+
return self.rpc_request("notificationsGetOneToOneChats")
37+
38+
def notifications_set_one_to_one_chats(self, value: str):
39+
params = [value]
40+
return self.rpc_request("notificationsSetOneToOneChats", params)
41+
42+
def notifications_get_group_chats(self):
43+
return self.rpc_request("notificationsGetGroupChats")
44+
45+
def notifications_set_group_chats(self, value: str):
46+
params = [value]
47+
return self.rpc_request("notificationsSetGroupChats", params)
48+
49+
def notifications_get_personal_mentions(self):
50+
return self.rpc_request("notificationsGetPersonalMentions")
51+
52+
def notifications_set_personal_mentions(self, value: str):
53+
params = [value]
54+
return self.rpc_request("notificationsSetPersonalMentions", params)
55+
56+
def notifications_get_global_mentions(self):
57+
return self.rpc_request("notificationsGetGlobalMentions")
58+
59+
def notifications_set_global_mentions(self, value: str):
60+
params = [value]
61+
return self.rpc_request("notificationsSetGlobalMentions", params)
62+
63+
def notifications_get_all_messages(self):
64+
return self.rpc_request("notificationsGetAllMessages")
65+
66+
def notifications_set_all_messages(self, value: str):
67+
params = [value]
68+
return self.rpc_request("notificationsSetAllMessages", params)
69+
70+
def notifications_get_contact_requests(self):
71+
return self.rpc_request("notificationsGetContactRequests")
72+
73+
def notifications_set_contact_requests(self, value: str):
74+
params = [value]
75+
return self.rpc_request("notificationsSetContactRequests", params)
76+
77+
def notifications_get_identity_verification_requests(self):
78+
return self.rpc_request("notificationsGetIdentityVerificationRequests")
79+
80+
def notifications_set_identity_verification_requests(self, value: str):
81+
params = [value]
82+
return self.rpc_request("notificationsSetIdentityVerificationRequests", params)
83+
84+
def notifications_get_sound_enabled(self):
85+
return self.rpc_request("notificationsGetSoundEnabled")
86+
87+
def notifications_set_sound_enabled(self, value: bool):
88+
params = [value]
89+
return self.rpc_request("notificationsSetSoundEnabled", params)
90+
91+
def notifications_get_volume(self):
92+
return self.rpc_request("notificationsGetVolume")
93+
94+
def notifications_set_volume(self, value: int):
95+
params = [value]
96+
return self.rpc_request("notificationsSetVolume", params)
97+
98+
def notifications_get_message_preview(self):
99+
return self.rpc_request("notificationsGetMessagePreview")
100+
101+
def notifications_set_message_preview(self, value: int):
102+
params = [value]
103+
return self.rpc_request("notificationsSetMessagePreview", params)
104+
105+
def notifications_get_ex_mute_all_messages(self, id: str):
106+
params = [id]
107+
return self.rpc_request("notificationsGetExMuteAllMessages", params)
108+
109+
def notifications_get_ex_personal_mentions(self, id: str):
110+
params = [id]
111+
return self.rpc_request("notificationsGetExPersonalMentions", params)
112+
113+
def notifications_get_ex_global_mentions(self, id: str):
114+
params = [id]
115+
return self.rpc_request("notificationsGetExGlobalMentions", params)
116+
117+
def notifications_get_ex_other_messages(self, id: str):
118+
params = [id]
119+
return self.rpc_request("notificationsGetExOtherMessages", params)
120+
121+
def notifications_set_exemptions(self, id: str, mute_all_messages: bool, personal_mentions: str, global_mentions: str, other_messages: str):
122+
params = [id, mute_all_messages, personal_mentions, global_mentions, other_messages]
123+
return self.rpc_request("notificationsSetExemptions", params)
124+
125+
def delete_exemptions(self, id: str):
126+
params = [id]
127+
return self.rpc_request("deleteExemptions", params)
128+
129+
def set_bio(self, bio: str):
130+
params = [bio]
131+
return self.rpc_request("setBio", params)
132+
133+
def mnemonic_was_shown(self):
134+
return self.rpc_request("mnemonicWasShown")
135+
136+
def last_tokens_update(self):
137+
return self.rpc_request("lastTokensUpdate")
138+
139+
def thirdparty_services_enabled(self):
140+
return self.rpc_request("thirdpartyServicesEnabled")

tests-functional/clients/status_backend.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from utils import fake
3333
from utils import keys
3434
from utils.config import Config
35+
import copy
3536

3637
NANOSECONDS_PER_SECOND = 1_000_000_000
3738

@@ -80,7 +81,7 @@ def __init__(self, privileged=False, ipv6=USE_IPV6, **kwargs):
8081
self.events = Events()
8182
self.version = "unknown"
8283
self.network_id = 1
83-
84+
self._boot_api_config = None
8485
RpcClient.__init__(self)
8586
ApiClient.__init__(self, self.api_url)
8687
SignalClient.__init__(self, self.ws_url)
@@ -295,13 +296,15 @@ def create_account_and_login(self, password: str, **kwargs):
295296
self._set_display_name(**kwargs)
296297
method = "CreateAccountAndLogin"
297298
data = self._create_account_request(password=password, **kwargs)
299+
self._boot_api_config = copy.deepcopy(data.get("apiConfig", {}))
298300
return self.api_request_json(method, data)
299301

300302
def restore_account_and_login(self, user=user_1, **kwargs):
301303
self._set_display_name(**kwargs)
302304
method = "RestoreAccountAndLogin"
303305
data = self._create_account_request(password=user.password, **kwargs)
304306
data["mnemonic"] = user.passphrase
307+
self._boot_api_config = copy.deepcopy(data.get("apiConfig", {}))
305308
return self.api_request_json(method, data)
306309

307310
def login(self, key_uid, password: str, kdf_iterations=256000):
@@ -472,6 +475,9 @@ def image_server_tls_cert(self):
472475
response = self.api_request(method, {})
473476
return response.content.decode("utf-8")
474477

478+
def get_boot_api_config(self):
479+
return self._boot_api_config
480+
475481
def serialize_legacy_key(self, key):
476482
method = "SerializeLegacyKey"
477483
# Use client.post directly, because this method is old and has json-incompatible arguments

tests-functional/tests/conftest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import pytest
55
from requests import ReadTimeout
66

7-
from clients.anvil import Anvil
8-
from clients.contract_deployers.multicall3 import Multicall3Deployer
9-
from clients.foundry import Foundry
107
from clients.status_backend import StatusBackend
118
from clients.statusgo_container import StatusGoContainer
9+
from clients.anvil import Anvil
10+
from clients.foundry import Foundry
11+
from clients.contract_deployers.multicall3 import Multicall3Deployer
1212
from resources.constants import USE_IPV6
1313
from utils import fake
1414

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import pytest
2+
3+
4+
@pytest.mark.rpc
5+
class TestBackupSettings:
6+
7+
@pytest.fixture(autouse=True)
8+
def setup_backends(self, backend_new_profile):
9+
self.config = backend_new_profile("sender")
10+
11+
@pytest.mark.skip(reason="backend currently does not validate backup-path; it is stored verbatim")
12+
def test_set_invalid_backup_path(self):
13+
invalid_path = "/invalid/path/that/does@$<>not|exist"
14+
result = self.config.settings_service.save_setting("backup-path", invalid_path)
15+
backup_path = self.config.settings_service.backup_path()
16+
assert backup_path != invalid_path, f"Backend incorrectly saved invalid path: {backup_path}"
17+
assert result is None or result == "", f"Expected save_setting to fail or return None, got: {result}"
18+
19+
def test_set_valid_backup_path(self):
20+
current_path = self.config.settings_service.backup_path()
21+
22+
# Verify it is a valid path (not empty and is a string)
23+
assert current_path is not None, "Backup path should not be None"
24+
assert isinstance(current_path, str), f"Expected string, got {type(current_path)}"
25+
assert current_path != "", "Backup path should not be empty"
26+
27+
# Test setting the same path explicitly (round-trip test)
28+
result = self.config.settings_service.save_setting("backup-path", current_path)
29+
assert result is None
30+
assert self.config.settings_service.backup_path() == current_path
31+
32+
def test_get_backup_path_type_and_value(self):
33+
backup_path = self.config.settings_service.backup_path()
34+
assert backup_path is not None, "Expected a non-null backup path"
35+
assert isinstance(backup_path, str), f"Expected string, got {type(backup_path)}"
36+
assert backup_path != "", "Expected backup path to be non-empty"
37+
38+
def test_messages_backup_enabled_type(self):
39+
result = self.config.settings_service.messages_backup_enabled()
40+
assert result is not None, "Expected a non-null result"
41+
assert isinstance(result, bool), f"Expected bool, got {type(result)}"
42+
43+
def test_toggle_messages_backup_enabled(self):
44+
value = True
45+
self.config.settings_service.save_setting("messages-backup-enabled?", value)
46+
result = self.config.settings_service.messages_backup_enabled()
47+
assert isinstance(result, bool)
48+
assert result is value
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import datetime
2+
import time
3+
4+
import pytest
5+
6+
7+
@pytest.mark.rpc
8+
class TestGeneralSettings:
9+
10+
@pytest.fixture(autouse=True)
11+
def setup_backends(self, backend_new_profile):
12+
self.config = backend_new_profile("sender")
13+
14+
def test_thirdparty_services_enabled(self):
15+
result = self.config.settings_service.thirdparty_services_enabled()
16+
assert result is not None, "Expected a non-null result"
17+
assert isinstance(result, bool), f"Expected bool, got {type(result)}"
18+
assert result is True, "Expected True"
19+
20+
def test_last_tokens_update_type_check(self):
21+
result = self.config.settings_service.last_tokens_update()
22+
assert result is not None, "Expected non-null timestamp"
23+
assert isinstance(result, str), f"Expected string, got {type(result)}"
24+
assert result != "", "Expected non-empty string"
25+
26+
def test_last_tokens_update_returns_valid_iso_datetime(self):
27+
result = self.config.settings_service.last_tokens_update()
28+
try:
29+
_ = datetime.datetime.fromisoformat(result.replace("Z", "+00:00"))
30+
except Exception as e:
31+
pytest.fail(f"Returned value is not a valid ISO datetime string: {result}. Error: {e}")
32+
33+
def test_last_tokens_update_advances_after_updating_token_preferences(self):
34+
dummy_prefs = [{"key": "0x1234567890abcdef1234567890abcdef12345678", "position": 1, "visible": True}]
35+
self.config.accounts_service.update_token_preferences(dummy_prefs)
36+
t1_raw = self.config.settings_service.last_tokens_update()
37+
t1 = datetime.datetime.fromisoformat(t1_raw.replace("Z", "+00:00"))
38+
time.sleep(1.2)
39+
current_prefs = self.config.accounts_service.get_token_preferences()
40+
self.config.accounts_service.update_token_preferences(current_prefs)
41+
t2_raw = self.config.settings_service.last_tokens_update()
42+
t2 = datetime.datetime.fromisoformat(t2_raw.replace("Z", "+00:00"))
43+
assert t2 >= t1, f"Expected last-tokens-update to advance or stay same; got T1={t1} T2={t2}"
44+
45+
def test_mnemonic_was_shown(self):
46+
result = self.config.settings_service.mnemonic_was_shown()
47+
assert result is None or result == "", f"Expected no return value, got: {result}"
48+
49+
def test_set_bio_valid_string(self):
50+
valid_bio = "This is a new test bio"
51+
result = self.config.settings_service.set_bio(valid_bio)
52+
assert result is None or result == "", f"Expected None or empty string, got {result}"
53+
54+
def test_set_bio_invalid_type(self):
55+
invalid_bio = 123
56+
try:
57+
result = self.config.settings_service.set_bio(invalid_bio)
58+
pytest.fail(f"Expected an exception for invalid bio {invalid_bio}, got {result}")
59+
except Exception:
60+
assert True
61+
62+
def test_delete_exemptions_valid_id(self):
63+
result = self.config.settings_service.delete_exemptions("12345")
64+
assert result is None or result == "", f"Expected None or empty string, got {result}"
65+
66+
@pytest.mark.skip(reason="Pending on issue resolution https://github.com/status-im/status-go/issues/7102")
67+
def test_delete_exemptions_invalid_id(self):
68+
invalid_id = None
69+
try:
70+
result = self.config.settings_service.delete_exemptions(invalid_id)
71+
pytest.fail(f"Expected exception for invalid id: {invalid_id}, but got {result}")
72+
except Exception:
73+
assert True
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import logging
2+
3+
import pytest
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
@pytest.mark.rpc
9+
class TestNodeConfig:
10+
11+
@pytest.fixture(autouse=True)
12+
def setup_backends(self, backend_new_profile):
13+
self.config = backend_new_profile("sender")
14+
15+
def test_verify_node_config_stability(self):
16+
cfg1 = self.config.settings_service.get_node_config()
17+
cfg2 = self.config.settings_service.get_node_config()
18+
assert cfg1 == cfg2, "NodeConfig should be stable across calls"
19+
20+
def test_check_node_config_params(self):
21+
cfg = self.config.settings_service.get_node_config()
22+
boot_api = self.config.get_boot_api_config()
23+
assert cfg["WSEnabled"] == boot_api["wsEnabled"]
24+
assert cfg["WSHost"] == boot_api["wsHost"]
25+
assert cfg["WSPort"] == boot_api["wsPort"]
26+
assert cfg["HTTPEnabled"] == boot_api["httpEnabled"]
27+
assert cfg["HTTPPort"] == boot_api["httpPort"]
28+
29+
def test_verify_node_config_enforce(self, backend_new_profile):
30+
forced_network_id = 4242
31+
backend = backend_new_profile("forced_network", network_id=forced_network_id)
32+
cfg = backend.settings_service.get_node_config()
33+
network_id = cfg["NetworkId"]
34+
assert network_id is not None, f"NetworkId key missing in node config: {cfg}"
35+
assert int(network_id) == forced_network_id, f"Expected NetworkId={forced_network_id}, got {network_id}"

0 commit comments

Comments
 (0)