fix(#298): internationalize ConnectViewModel strings, fix null-assert crash on profile selector (#307)

* fix(#298): internationalize ConnectViewModel strings, fix null-assert crash on profile selector

E1: Add all connect error resources to strings.xml for i18n readiness
E2: Migrate ConnectViewModel to AndroidViewModel, replace all hardcoded
    user-facing strings with getString(R.string.*) calls
F1: Replace state.selectedProfile!! with .?.let { } pattern in
    ConnectScreen.kt to eliminate NPE risk on mutable state copy

Closes #298

* fix(#298): update test files for AndroidViewModel constructor

Update ConnectViewModelTest.kt and E2eIntegrationTest.kt to pass
mock Application to the new ConnectViewModel(app) constructor.
Add getString() MockK stubs matching the string resource keys.

* fix(#298): add missing LocalContext import and restore connect_pairing_string

Two compilation errors:
- ConnectScreen.kt was missing import for LocalContext
- strings.xml was missing connect_pairing_string resource
  (accidentally removed in earlier patch)

* fix(#298): extract ViewModelFactory to avoid composable-in-non-composable error

LocalContext.current cannot be called inside a viewModel { } factory
lambda because the lambda is not @Composable. Fix by extracting a
ConnectViewModelFactory class and using run { } to capture the
Application value at the composable call site before passing to
the factory constructor.

* fix(#298): fix MockK varargs matching in test stubs

getString(int, Object...) takes varargs. MockK's any<Int>() and
any<String>() didn't match the vararg Object... slot. Changed to
any() (untyped) which matches correctly.

* fix(#298): fix MockK answers — arg indexing was wrong

In getString(int, Object...), firstArg is the resource ID,
secondArg is the format argument. Using firstArg<Int>() in
the answers block was returning the res ID, not 500/etc.
Changed to secondArg<Any>().

* fix(#298): replace getString(int,Object...) with String.format(getString(int),...)

Avoid MockK varargs matching issues by calling app.getString(int)
for the format template and String.format() to apply args.
Simplifies test stubs to pure getString(int) returns.

---------

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-06-22 21:38:28 +03:00
1 parent 8e040543de
commit e8025efcde
5 files changed
+156 -57

No files matched your search

+16
View File
@@ -165,6 +165,22 @@
<string name="connect_selected_profile">Profile: %1$s</string>
<string name="connect_action_select_profile">Select Saved Profile</string>
<string name="connect_profile_none">None (Standalone)</string>
<!-- Connect Error Messages -->
<string name="connect_error_token_required">Token is required</string>
<string name="connect_error_host_required">Host is required</string>
<string name="connect_error_port_invalid">Port must be between 1 and 65535</string>
<string name="connect_error_401">Invalid token (401 Unauthorized)</string>
<string name="connect_error_403">Access denied (403 Forbidden)</string>
<string name="connect_error_http_code">Server returned HTTP %1$d</string>
<string name="connect_error_timeout">Connection timed out</string>
<string name="connect_error_refused">Connection refused – is Hermes running?</string>
<string name="connect_error_resolve">Could not resolve host</string>
<string name="connect_error_connection_failed">Connection failed: %1$s</string>
<string name="connect_error_missing_fields">Malformed pairing string — missing host, port, or token</string>
<string name="connect_error_malformed">Malformed pairing string — expected URL or Base64-encoded JSON</string>
<string name="connect_error_parse_failed">Failed to parse pairing string: %1$s</string>
<string name="connect_pairing_string">Pairing string</string>
<string name="connect_placeholder_pairing">Paste hermes://\u2026 or Base64 config</string>
<string name="connect_save_profile">Save connection profile</string>