mirror of
https://github.com/we-promise/sure.git
synced 2026-09-09 08:34:26 +00:00
* fix(i18n): localize Onchain wallet setup * Use idiomatic quantity tracking copy (#3344) --------- Co-authored-by: Johns <19662585+Rowdy@users.noreply.github.com>
172 lines
7.1 KiB
Ruby
172 lines
7.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "test_helper"
|
|
|
|
class OnchainWalletItemsLocalizationTest < ActionDispatch::IntegrationTest
|
|
include OnchainTestHelper
|
|
|
|
MODAL_HEADERS = { "Turbo-Frame" => "modal" }.freeze
|
|
|
|
TRANSLATED_SCOPES = %w[
|
|
onchain_wallet_items.new_wallet
|
|
onchain_wallet_items.choose_chain
|
|
onchain_wallet_items.errors
|
|
onchain_wallet_items.price_provider_warning
|
|
onchain_wallet_items.enable_crypto_prices
|
|
onchain_wallet_items.link_wallet
|
|
onchain_wallet_items.provider_connection
|
|
onchain_wallet_items.token_review
|
|
onchain_wallet_items.token_review_form
|
|
].freeze
|
|
|
|
TRANSLATED_SETTINGS_KEYS = %w[
|
|
settings.providers.taglines.onchain_wallet
|
|
settings.providers.onchain_wallet_panel.add_wallet
|
|
settings.providers.onchain_wallet_panel.keyless_title
|
|
settings.providers.onchain_wallet_panel.keyless_body
|
|
].freeze
|
|
|
|
setup do
|
|
sign_in users(:family_admin)
|
|
register_fake_chain!
|
|
end
|
|
|
|
teardown do
|
|
unregister_fake_chain!
|
|
end
|
|
|
|
test "the Onchain add-wallet slice resolves directly in German" do
|
|
translated_keys.each do |key|
|
|
assert I18n.exists?(key, :de, fallback: false), "de is missing #{key}"
|
|
end
|
|
end
|
|
|
|
test "German translations preserve interpolation and pluralization contracts" do
|
|
address = OnchainTestHelper::FAKE_ADDRESS
|
|
|
|
assert_equal address,
|
|
I18n.t("onchain_wallet_items.choose_chain.subtitle", locale: :de, fallback: false, address: address)
|
|
assert_equal "Fake Chain · #{address}",
|
|
I18n.t("onchain_wallet_items.token_review.subtitle", locale: :de, fallback: false,
|
|
chain: "Fake Chain", address: address)
|
|
exchange_rate_body = I18n.t("onchain_wallet_items.price_provider_warning.exchange_rate_body",
|
|
locale: :de, fallback: false, currency: "EUR")
|
|
%w[USD EUR EXCHANGE_RATE_PROVIDER Frankfurter API-Schlüssel].each do |technical_term|
|
|
assert_match technical_term, exchange_rate_body
|
|
end
|
|
tagline = I18n.t("settings.providers.taglines.onchain_wallet", locale: :de, fallback: false)
|
|
%w[Bitcoin EVM Solana].each { |brand_or_network| assert_match brand_or_network, tagline }
|
|
assert_match "USDC",
|
|
I18n.t("onchain_wallet_items.link_wallet.errors.some_failed", locale: :de,
|
|
fallback: false, assets: "USDC")
|
|
assert_equal "1 Vermögenswert dieser Wallet wird verfolgt.",
|
|
I18n.t("onchain_wallet_items.link_wallet.success", locale: :de, fallback: false, count: 1)
|
|
assert_equal "2 Vermögenswerte dieser Wallet werden verfolgt.",
|
|
I18n.t("onchain_wallet_items.link_wallet.success", locale: :de, fallback: false, count: 2)
|
|
assert_match "25", I18n.t("onchain_wallet_items.token_review_form.assets_truncated",
|
|
locale: :de, fallback: false, count: 25)
|
|
end
|
|
|
|
test "the German add-wallet form renders its security guidance" do
|
|
get new_wallet_onchain_wallet_items_url(locale: :de), headers: MODAL_HEADERS
|
|
|
|
assert_response :success
|
|
assert_match "Selbstverwahrte Wallet hinzufügen", response.body
|
|
assert_match "Nur Lesezugriff, keine Schlüssel erforderlich", response.body
|
|
assert_match "Mit diesen Daten lassen sich keine Vermögenswerte übertragen.", response.body
|
|
assert_match "Gib niemals eine Seed-Phrase oder einen Private Key ein.", response.body
|
|
assert_match "Bitcoin wird jeweils über eine einzelne Adresse verfolgt.", response.body
|
|
end
|
|
|
|
test "the German token review renders selection guidance" do
|
|
stub_fake_snapshot(
|
|
OnchainTestHelper::FAKE_ADDRESS,
|
|
Onchain::Snapshot.new(
|
|
assets: [
|
|
fake_native_asset(quantity: 2),
|
|
fake_token_asset(symbol: "USDC", contract: "0xusdc", quantity: 10, notable: false),
|
|
fake_token_asset(symbol: "Visit site to claim", contract: "0xspam", quantity: 1, notable: false)
|
|
],
|
|
movements: []
|
|
)
|
|
)
|
|
|
|
post preview_wallet_onchain_wallet_items_url(locale: :de),
|
|
params: {
|
|
address: OnchainTestHelper::FAKE_ADDRESS,
|
|
chain: OnchainTestHelper::FAKE_CHAIN
|
|
},
|
|
headers: MODAL_HEADERS
|
|
|
|
assert_response :success
|
|
assert_match "Vermögenswerte zum Verfolgen auswählen", response.body
|
|
assert_match "Wallets erhalten Spam-Airdrops", response.body
|
|
assert_match "Kein Preis verfügbar; wird nur anhand der Menge verfolgt", response.body
|
|
assert_match "USDC", response.body
|
|
end
|
|
|
|
test "the German account method selector localizes the Onchain entry" do
|
|
get new_crypto_url(locale: :de, step: "method_select"), headers: MODAL_HEADERS
|
|
|
|
assert_response :success
|
|
assert_match "Selbstverwahrte Wallet", response.body
|
|
assert_no_match "Self-custody wallet", response.body
|
|
end
|
|
|
|
test "a German recovery state hides the external provider error" do
|
|
external_error = "external explorer exposed a private diagnostic"
|
|
OnchainTestHelper::FakeAdapter.error = StandardError.new(external_error)
|
|
|
|
assert_difference "DebugLogEntry.count", 1 do
|
|
post preview_wallet_onchain_wallet_items_url(locale: :de),
|
|
params: {
|
|
address: OnchainTestHelper::FAKE_ADDRESS,
|
|
chain: OnchainTestHelper::FAKE_CHAIN
|
|
},
|
|
headers: MODAL_HEADERS
|
|
end
|
|
|
|
assert_response :unprocessable_entity
|
|
assert_match "Beim Lesen dieser Wallet ist etwas schiefgelaufen.", response.body
|
|
assert_no_match external_error, response.body
|
|
end
|
|
|
|
test "representative English output remains unchanged" do
|
|
I18n.with_locale(:en) do
|
|
assert_equal "Add a self-custody wallet", I18n.t("onchain_wallet_items.new_wallet.title", fallback: false)
|
|
assert_equal "Read-only, no keys required",
|
|
I18n.t("settings.providers.onchain_wallet_panel.keyless_title", fallback: false)
|
|
assert_equal "Only public chain data is read. Never enter a seed phrase or private key.",
|
|
I18n.t("onchain_wallet_items.new_wallet.read_only_note", fallback: false)
|
|
assert_equal "Self-custody wallet",
|
|
I18n.t("onchain_wallet_items.provider_connection.name", fallback: false)
|
|
end
|
|
|
|
get new_wallet_onchain_wallet_items_url(locale: :en), headers: MODAL_HEADERS
|
|
|
|
assert_response :success
|
|
assert_match "Add a self-custody wallet", response.body
|
|
assert_match "Read-only, no keys required", response.body
|
|
assert_match "Never enter a seed phrase or private key.", response.body
|
|
end
|
|
|
|
private
|
|
def translated_keys
|
|
scoped_keys = TRANSLATED_SCOPES.flat_map do |scope|
|
|
translations = I18n.t(scope, locale: :en, fallback: false, default: nil)
|
|
assert_kind_of Hash, translations, "#{scope} must remain a translation subtree"
|
|
|
|
flatten_keys(translations).map { |key| "#{scope}.#{key}" }
|
|
end
|
|
|
|
scoped_keys + TRANSLATED_SETTINGS_KEYS
|
|
end
|
|
|
|
def flatten_keys(translations, prefix = nil)
|
|
translations.flat_map do |key, value|
|
|
path = [ prefix, key ].compact.join(".")
|
|
value.is_a?(Hash) ? flatten_keys(value, path) : path
|
|
end
|
|
end
|
|
end
|