From 106793956cd9cacda0c4fb2711065e5cc775167a Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 26 Feb 2024 16:22:52 +0100 Subject: [PATCH] tests: add more granular silent language installation tests --- tests/device_tests/test_language.py | 178 +++++++++++++--------------- tests/ui_tests/fixtures.json | 100 +++++++++++----- 2 files changed, 153 insertions(+), 125 deletions(-) diff --git a/tests/device_tests/test_language.py b/tests/device_tests/test_language.py index d66fa9a2d..5f6f159e9 100644 --- a/tests/device_tests/test_language.py +++ b/tests/device_tests/test_language.py @@ -14,13 +14,16 @@ # You should have received a copy of the License along with this library. # If not, see . +from __future__ import annotations + from copy import deepcopy -from typing import Iterator +from typing import Any, Iterator import pytest from trezorlib import debuglink, device, exceptions, messages, models from trezorlib.debuglink import TrezorClientDebugLink as Client +from trezorlib.debuglink import message_filters from ..translations import LANGUAGES, build_and_sign_blob, get_lang_json, set_language @@ -145,39 +148,6 @@ def test_error_version_mismatch(client: Client): _check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en")) -def test_error_invalid_header_version(client: Client): - assert client.features.language == "en-US" - # Invalid header version - # Version is not a valid semver with integers - with pytest.raises(ValueError), client: - data = get_lang_json("cs") - data["header"]["version"] = "ABC.XYZ.DEF" - device.change_language( - client, - language_data=build_and_sign_blob(data, client.model), - ) - assert client.features.language == "en-US" - _check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en")) - - -def test_error_invalid_signature(client: Client): - assert client.features.language == "en-US" - # Invalid signature - # Changing the data in the signature section - with pytest.raises( - exceptions.TrezorFailure, match="Invalid translations data" - ), client: - good_data = bytearray(build_and_sign_blob("cs", client.model)) - bad_data = bytearray(good_data) - bad_data[128:256] = 128 * b"a" - device.change_language( - client, - language_data=bytes(bad_data), - ) - assert client.features.language == "en-US" - _check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en")) - - @pytest.mark.parametrize("lang", LANGUAGES) def test_full_language_change(client: Client, lang: str): assert client.features.language == "en-US" @@ -276,78 +246,96 @@ def test_reject_update(client: Client): _check_ping_screen_texts(client, get_ping_title("en"), get_ping_button("en")) -def test_silent_update(client: Client): - assert client.features.language == "en-US" - lang = "cs" +def _maybe_confirm_set_language( + client: Client, lang: str, show_display: bool | None, is_displayed: bool +) -> None: language_data = build_and_sign_blob(lang, client.model) - def input_flow_confirm(language: str): - if language == "cs": - title = "NASTAVENÍ JAZYKA" - text = "Změnit jazyk na cs-CZ?" - else: - title = "LANGUAGE SETTINGS" - text = "Change language to cs-CZ?" - - def input_flow(): - yield - layout = client.debug.wait_layout() - assert layout.title() == title - assert layout.text_content() == text - client.debug.press_yes() - - yield - layout = client.debug.wait_layout() - assert layout.text_content() == "Jazyk byl úspěšně změněn" - client.debug.press_yes() - - return input_flow - - def input_flow_silent(): - yield - # It will never reach this - there is just loader on the screen - assert False + CHUNK_SIZE = 1024 + + def chunks(data, size): + for i in range(0, len(data), size): + yield i, min(size, len(data) - i) + + expected_responses_silent: list[Any] = [ + messages.TranslationDataRequest(data_offset=off, data_length=len) + for off, len in chunks(language_data, CHUNK_SIZE) + ] + [message_filters.Success(), message_filters.Features()] + + expected_responses_confirm = expected_responses_silent[:] + # confirmation after first TranslationDataRequest + expected_responses_confirm.insert(1, message_filters.ButtonRequest()) + # success screen before Success / Features + expected_responses_confirm.insert(-2, message_filters.ButtonRequest()) + + if is_displayed: + expected_responses = expected_responses_confirm + else: + expected_responses = expected_responses_silent - # Device is loaded with seed, language change is shown on the screen with client: - client.watch_layout(True) - client.set_input_flow(input_flow_confirm("en")) - device.change_language(client, language_data) + client.set_expected_responses(expected_responses) + device.change_language(client, language_data, show_display=show_display) + assert client.features.language is not None assert client.features.language[:2] == lang - device.wipe(client) + # explicitly handle the cases when expected_responses are correct for + # change_language but incorrect for selected is_displayed mode (otherwise the + # user would get an unhelpful generic expected_responses mismatch) + if is_displayed and client.actual_responses == expected_responses_silent: + raise AssertionError("Change should have been visible but was silent") + if not is_displayed and client.actual_responses == expected_responses_confirm: + raise AssertionError("Change should have been silent but was visible") + # if the expected_responses do not match either, the generic error message will + # be raised by the client context manager + + +@pytest.mark.parametrize( + "show_display, is_displayed", + [ # when device is not initialized, all combinations succeed. + (True, True), + (False, False), + (None, False), # default is False + ], +) +@pytest.mark.setup_client(uninitialized=True) +def test_silent_first_install(client: Client, show_display: bool, is_displayed: bool): + assert not client.features.initialized + _maybe_confirm_set_language(client, "cs", show_display, is_displayed) + + +@pytest.mark.parametrize("show_display", (True, None)) +def test_switch_from_english(client: Client, show_display: bool | None): + assert client.features.initialized assert client.features.language == "en-US" + _maybe_confirm_set_language(client, "cs", show_display, True) - # Device is empty, language is changed silently - with client: - client.watch_layout(True) - client.set_input_flow(input_flow_silent) - device.change_language(client, language_data) - assert client.features.language[:2] == lang - # Same language is set again, shown on screen - with client: - client.watch_layout(True) - client.set_input_flow(input_flow_confirm("cs")) - device.change_language(client, language_data) - assert client.features.language[:2] == lang +def test_switch_from_english_not_silent(client: Client): + assert client.features.initialized + assert client.features.language == "en-US" + with pytest.raises( + exceptions.TrezorFailure, match="Cannot change language without user prompt" + ): + _maybe_confirm_set_language(client, "cs", False, False) - device.wipe(client) + +@pytest.mark.setup_client(uninitialized=True) +def test_switch_language(client: Client): + assert not client.features.initialized assert client.features.language == "en-US" - debuglink.load_device( - client, - mnemonic=" ".join(["all"] * 12), - pin=None, - passphrase_protection=False, - label="test", - ) + # switch to Czech silently + _maybe_confirm_set_language(client, "cs", False, False) - # Device is again loaded with seed, language change is shown on the screen - with client: - client.watch_layout(True) - client.set_input_flow(input_flow_confirm("en")) - device.change_language(client, language_data) - assert client.features.language[:2] == lang + # switch to French silently + with pytest.raises( + exceptions.TrezorFailure, match="Cannot change language without user prompt" + ): + _maybe_confirm_set_language(client, "fr", False, False) - _check_ping_screen_texts(client, get_ping_title(lang), get_ping_button(lang)) + # switch to French with display, explicitly + _maybe_confirm_set_language(client, "fr", True, True) + + # switch back to Czech with display, implicitly + _maybe_confirm_set_language(client, "cs", None, True) diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index a5802b91c..90932f971 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -3649,8 +3649,6 @@ "TR_cs_test_language.py::test_error_invalid_data_hash": "71a89aedd03ff90c662b0190e0d467442b9ba8f75b42737c50eaf4d69817c6fa", "TR_cs_test_language.py::test_error_invalid_data_length": "02e362fe1a3c830bd5cec9a2fde39ad32453800ccc4f3caf00f629813d9b2ce0", "TR_cs_test_language.py::test_error_invalid_header_magic": "02e362fe1a3c830bd5cec9a2fde39ad32453800ccc4f3caf00f629813d9b2ce0", -"TR_cs_test_language.py::test_error_invalid_header_version": "02e362fe1a3c830bd5cec9a2fde39ad32453800ccc4f3caf00f629813d9b2ce0", -"TR_cs_test_language.py::test_error_invalid_signature": "02e362fe1a3c830bd5cec9a2fde39ad32453800ccc4f3caf00f629813d9b2ce0", "TR_cs_test_language.py::test_error_too_long": "02e362fe1a3c830bd5cec9a2fde39ad32453800ccc4f3caf00f629813d9b2ce0", "TR_cs_test_language.py::test_error_version_mismatch": "02e362fe1a3c830bd5cec9a2fde39ad32453800ccc4f3caf00f629813d9b2ce0", "TR_cs_test_language.py::test_full_language_change[cs]": "99d0b7bb982c85a962e32412c4c6453c6aea8b82f5d73ea2c306e1e8a831dea5", @@ -3660,7 +3658,13 @@ "TR_cs_test_language.py::test_full_language_change[fr]": "18ef4870bf5ee29d49ece9e92910bf3772e5bebde6c642929126d22a84086557", "TR_cs_test_language.py::test_language_is_removed_after_wipe": "3fed5c087d565830eae7c0647a4c1ef9350595f550062ae575a97f50cdd7d826", "TR_cs_test_language.py::test_reject_update": "94873b672e55ac3a766fe78cce140e27fe5fbbe4a837bc0e64bb46592ec5d4e3", -"TR_cs_test_language.py::test_silent_update": "a84304d3e385ec4058f0a24befad2258bbc05a2d16f4b72575c261229f5ed362", +"TR_cs_test_language.py::test_silent_first_install[False-False]": "cfca3550117beb0f44e6fecb844dfbbf2a182dd440a117398ff04603b6d365f2", +"TR_cs_test_language.py::test_silent_first_install[None-False]": "cfca3550117beb0f44e6fecb844dfbbf2a182dd440a117398ff04603b6d365f2", +"TR_cs_test_language.py::test_silent_first_install[True-True]": "980f87f189c299eabdea79fd17ee666798786f0abf040e3528d15da9ef64421c", +"TR_cs_test_language.py::test_switch_from_english[None]": "6be222894012b260aa66a38cff70ecd78b9f31f933c2d108de2ac08291cb8127", +"TR_cs_test_language.py::test_switch_from_english[True]": "6be222894012b260aa66a38cff70ecd78b9f31f933c2d108de2ac08291cb8127", +"TR_cs_test_language.py::test_switch_from_english_not_silent": "0014957129d3c34df2b2174c8fd770563e5f79e79b5152b22883b39569c4550e", +"TR_cs_test_language.py::test_switch_language": "3178eba877e67bef8f27429929b9130dcf6b6f98fadb0a830b9d45f3c4c0ae4a", "TR_cs_test_language.py::test_translations_renders_on_screen": "be601d81b272fa966d1392ddf48e8ed522fcb4916bdb9c712a3c1c06c9ae553a", "TR_cs_test_msg_applysettings.py::test_apply_homescreen_tr_toif_good": "d2e9ddb474a242c5bee49b3647d1151c3b078976b386d9a6408ddca8138096f3", "TR_cs_test_msg_applysettings.py::test_apply_homescreen_tr_toif_with_long_label": "e54ce8daf0f240096612320da0c75a794bcc021bf17d23b0af1a7ed2036443b4", @@ -5012,8 +5016,6 @@ "TR_de_test_language.py::test_error_invalid_data_hash": "001546a6d7d6fd797f5d358a85afbb653ab3dba0ee15650b38981149460e33ad", "TR_de_test_language.py::test_error_invalid_data_length": "84138ca1475cc52d9eb63b38826db3e857741f4da5194bd58a9fb3632ef9d9d5", "TR_de_test_language.py::test_error_invalid_header_magic": "84138ca1475cc52d9eb63b38826db3e857741f4da5194bd58a9fb3632ef9d9d5", -"TR_de_test_language.py::test_error_invalid_header_version": "84138ca1475cc52d9eb63b38826db3e857741f4da5194bd58a9fb3632ef9d9d5", -"TR_de_test_language.py::test_error_invalid_signature": "84138ca1475cc52d9eb63b38826db3e857741f4da5194bd58a9fb3632ef9d9d5", "TR_de_test_language.py::test_error_too_long": "84138ca1475cc52d9eb63b38826db3e857741f4da5194bd58a9fb3632ef9d9d5", "TR_de_test_language.py::test_error_version_mismatch": "84138ca1475cc52d9eb63b38826db3e857741f4da5194bd58a9fb3632ef9d9d5", "TR_de_test_language.py::test_full_language_change[cs]": "b9b49f071757548a9502db2efef0ee7686f130e2a4fa1c01954b13e8a2d4833c", @@ -5023,7 +5025,13 @@ "TR_de_test_language.py::test_full_language_change[fr]": "fda57886e4c371f3219a29dd54b01de43e96bbb94a6fcc7d6c9e1bd1e7e30ace", "TR_de_test_language.py::test_language_is_removed_after_wipe": "f330e4d64e824ff1f20541ccedba6fbb80ccdf61a3a5197eed59789db8f3216e", "TR_de_test_language.py::test_reject_update": "c030eaa1b84ee548a68f0e20ad74201cbbeea1f09095dfafe0465020f3215a7a", -"TR_de_test_language.py::test_silent_update": "ed24fddb1ba9593380a12bad0a4b2b58cb0119ea83e717e83703eee7fc2fcc95", +"TR_de_test_language.py::test_silent_first_install[False-False]": "84a63e9be7b085d0b8ce087df8d575342a90157a52811decea69ba2083be41c1", +"TR_de_test_language.py::test_silent_first_install[None-False]": "84a63e9be7b085d0b8ce087df8d575342a90157a52811decea69ba2083be41c1", +"TR_de_test_language.py::test_silent_first_install[True-True]": "6108380651fe9016680a8f8b786ad37dd85bafc79c04c565a3b585abeb9f1c09", +"TR_de_test_language.py::test_switch_from_english[None]": "14b2652fcf2fbe73394c4ddaf035fa1830ec426a5cdf00b97b2a990fa070733f", +"TR_de_test_language.py::test_switch_from_english[True]": "14b2652fcf2fbe73394c4ddaf035fa1830ec426a5cdf00b97b2a990fa070733f", +"TR_de_test_language.py::test_switch_from_english_not_silent": "734df403a42da192b49b0bfc990db9f4b84e118c0b678da7e159e6a0c2a86896", +"TR_de_test_language.py::test_switch_language": "31ed10ba59a29b3c4a61e848cbb1a89fc31f03f9ad723bf358bc9654eeb9053a", "TR_de_test_language.py::test_translations_renders_on_screen": "fffccd195b57d14281cb540af6aab7b3a7f92a4c99fccf0e879613fdb97b5aed", "TR_de_test_msg_applysettings.py::test_apply_homescreen_tr_toif_good": "30b469a1fb9e03d651dd0e07f705e7e7f834adaf03d06972c3c464a095820650", "TR_de_test_msg_applysettings.py::test_apply_homescreen_tr_toif_with_long_label": "10695655e2026fae50529e65dd58f2b21ed52fb9ac8df0d074c98e63bb849624", @@ -6375,8 +6383,6 @@ "TR_en_test_language.py::test_error_invalid_data_hash": "0cb01b8002472dff316d6eb3ba901dffb762d88fdf61e5ef8642ca7772d3e71c", "TR_en_test_language.py::test_error_invalid_data_length": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6", "TR_en_test_language.py::test_error_invalid_header_magic": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6", -"TR_en_test_language.py::test_error_invalid_header_version": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6", -"TR_en_test_language.py::test_error_invalid_signature": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6", "TR_en_test_language.py::test_error_too_long": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6", "TR_en_test_language.py::test_error_version_mismatch": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6", "TR_en_test_language.py::test_full_language_change[cs]": "ba3669f5c7043e8021d84589d5c173eb1d3f6b2402f1e31525ce832094ca1e20", @@ -6386,7 +6392,13 @@ "TR_en_test_language.py::test_full_language_change[fr]": "2f3a0e8541cc7b96dc983d4de2149e4e2b230b43e1971153ec6bc82e7dadafb8", "TR_en_test_language.py::test_language_is_removed_after_wipe": "5363564a612486602f3e6c94cb5d18ef82c2253dfe51df4623d56b5bab920a2e", "TR_en_test_language.py::test_reject_update": "949fb112e684d3fb8a204a8ce15a202ebe9613bd3a453408138b3e54bb42e99a", -"TR_en_test_language.py::test_silent_update": "d8bc60cdfdce974b5e7259b7910c4178ae2b29a9a185fefe730c131fafba750c", +"TR_en_test_language.py::test_silent_first_install[False-False]": "8c6d7a8d499e4ede3d42cb6ef67cbde9f7dd35d518bacaa538e900bf3944b250", +"TR_en_test_language.py::test_silent_first_install[None-False]": "8c6d7a8d499e4ede3d42cb6ef67cbde9f7dd35d518bacaa538e900bf3944b250", +"TR_en_test_language.py::test_silent_first_install[True-True]": "2cdc473638078db0ed9406d904c2198946de9c31093df69268a6de87545c8ab6", +"TR_en_test_language.py::test_switch_from_english[None]": "47bd3a1f3c7ac6c6fec5c9c22219c6c638375f4810043ca29312fd3755356655", +"TR_en_test_language.py::test_switch_from_english[True]": "47bd3a1f3c7ac6c6fec5c9c22219c6c638375f4810043ca29312fd3755356655", +"TR_en_test_language.py::test_switch_from_english_not_silent": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095", +"TR_en_test_language.py::test_switch_language": "d227f924d8b76642511d25f78c646be6232c71db4d40fe6916b4364a58e70c4a", "TR_en_test_language.py::test_translations_renders_on_screen": "baf3b0e15c9ccced6ce4d4fb4d026d61cee7d7e557434aa6dbfbc78d1dd54420", "TR_en_test_msg_applysettings.py::test_apply_homescreen_tr_toif_good": "fc78876e183a82d8099263e5b3858620f65f7842f7d31f4679dddcb045f1dfb2", "TR_en_test_msg_applysettings.py::test_apply_homescreen_tr_toif_with_long_label": "57dc2b38db364a7ba43566c700ab27a3e98a08e64efc564db53b61aa6f4098aa", @@ -7738,8 +7750,6 @@ "TR_es_test_language.py::test_error_invalid_data_hash": "1e4a266ea51d55976cf4a1f8655e58629092b617c9d36e0603a5081961130564", "TR_es_test_language.py::test_error_invalid_data_length": "7fe6f34be4850fe62d0125548db36aa49493f7ef08781916025877445700ccae", "TR_es_test_language.py::test_error_invalid_header_magic": "7fe6f34be4850fe62d0125548db36aa49493f7ef08781916025877445700ccae", -"TR_es_test_language.py::test_error_invalid_header_version": "7fe6f34be4850fe62d0125548db36aa49493f7ef08781916025877445700ccae", -"TR_es_test_language.py::test_error_invalid_signature": "7fe6f34be4850fe62d0125548db36aa49493f7ef08781916025877445700ccae", "TR_es_test_language.py::test_error_too_long": "7fe6f34be4850fe62d0125548db36aa49493f7ef08781916025877445700ccae", "TR_es_test_language.py::test_error_version_mismatch": "7fe6f34be4850fe62d0125548db36aa49493f7ef08781916025877445700ccae", "TR_es_test_language.py::test_full_language_change[cs]": "5499d72b948c2b12fbf42cab072a8fea155a759a144930b7786104b32391e490", @@ -7749,7 +7759,13 @@ "TR_es_test_language.py::test_full_language_change[fr]": "0f7df785e611deec165dcce914efbabb497cba640795c8b90f396c223af7f3f0", "TR_es_test_language.py::test_language_is_removed_after_wipe": "7a7d05f7feed0938e23ec6ac76133246f6dbd626969efe43b0122bb2801e4e93", "TR_es_test_language.py::test_reject_update": "72b5cc4bb1d3a1024ef5348356565e711392fc379afee08a9d4275b7d627c213", -"TR_es_test_language.py::test_silent_update": "f1205df1c47f4b200af848b150c72b66dfcf7ebd20c2087a31341047a198a92d", +"TR_es_test_language.py::test_silent_first_install[False-False]": "fe722b1d027ca3b5af955c350722176de874b9d22446492a1b80d3f74d5bebfe", +"TR_es_test_language.py::test_silent_first_install[None-False]": "fe722b1d027ca3b5af955c350722176de874b9d22446492a1b80d3f74d5bebfe", +"TR_es_test_language.py::test_silent_first_install[True-True]": "0033ba8e0e156f7a2f80caafd1c899572717ee7da0785f2d2269ac418e2c45c5", +"TR_es_test_language.py::test_switch_from_english[None]": "81cc930de51884130ce9db2436a174f82b35f5f63355b1c0c3b1e78bc3a00ba8", +"TR_es_test_language.py::test_switch_from_english[True]": "81cc930de51884130ce9db2436a174f82b35f5f63355b1c0c3b1e78bc3a00ba8", +"TR_es_test_language.py::test_switch_from_english_not_silent": "a9b0e47be4dac0a6e99582439a6225527e8e365b7e74cca03892675853b1a152", +"TR_es_test_language.py::test_switch_language": "2993b2aecba562707e306426b9de9c041785f82d47ffbafdb5d558f6648b3265", "TR_es_test_language.py::test_translations_renders_on_screen": "300210d6d6cb920795fcbaf5efabadfa10a06462a311bbf1428e6ac6b80a40de", "TR_es_test_msg_applysettings.py::test_apply_homescreen_tr_toif_good": "158963b7b966fe95b92d8a4be19971c5321847154c2e574de04e361750537569", "TR_es_test_msg_applysettings.py::test_apply_homescreen_tr_toif_with_long_label": "2e80ee5ab2d87d55f9c96460eda140a7074faa2d5237d23057de2b12cbbb61ec", @@ -9101,8 +9117,6 @@ "TR_fr_test_language.py::test_error_invalid_data_hash": "c3c594c2d963c7562250b5cae43e6933a6c67c8b7aa7063e58de94e56fdad446", "TR_fr_test_language.py::test_error_invalid_data_length": "cb1cd75e37f30dacba9ccd6d4a9d0ada0179a8ac056340ce16edb802d16fac8c", "TR_fr_test_language.py::test_error_invalid_header_magic": "cb1cd75e37f30dacba9ccd6d4a9d0ada0179a8ac056340ce16edb802d16fac8c", -"TR_fr_test_language.py::test_error_invalid_header_version": "cb1cd75e37f30dacba9ccd6d4a9d0ada0179a8ac056340ce16edb802d16fac8c", -"TR_fr_test_language.py::test_error_invalid_signature": "cb1cd75e37f30dacba9ccd6d4a9d0ada0179a8ac056340ce16edb802d16fac8c", "TR_fr_test_language.py::test_error_too_long": "cb1cd75e37f30dacba9ccd6d4a9d0ada0179a8ac056340ce16edb802d16fac8c", "TR_fr_test_language.py::test_error_version_mismatch": "cb1cd75e37f30dacba9ccd6d4a9d0ada0179a8ac056340ce16edb802d16fac8c", "TR_fr_test_language.py::test_full_language_change[cs]": "7715e87e6a60006e6d6c61cde25ba2bc88540bd078f56d39ba1919e53e2dba99", @@ -9112,7 +9126,13 @@ "TR_fr_test_language.py::test_full_language_change[fr]": "7fae72778d7111b0d7746ce3fdfdae724415f651b2c3e195da55dc3cf6e24f8e", "TR_fr_test_language.py::test_language_is_removed_after_wipe": "9c12ba731cef7dd8a2fbb421aa328af48ed383b9d4ea4edb6cfbe6bd7a594115", "TR_fr_test_language.py::test_reject_update": "4c1d851a4f7ca6075e71d096a4b124b31f8ff280d609cc2495ded9750f057b51", -"TR_fr_test_language.py::test_silent_update": "cf65c68c90b206e2a97c9bf51d9e149b4197a7b050f3a6af4aa96a15254d980e", +"TR_fr_test_language.py::test_silent_first_install[False-False]": "79baf3cf0b204f265a80ce571552b1fb082aeb72cc37d515b6682365a6ebeae4", +"TR_fr_test_language.py::test_silent_first_install[None-False]": "79baf3cf0b204f265a80ce571552b1fb082aeb72cc37d515b6682365a6ebeae4", +"TR_fr_test_language.py::test_silent_first_install[True-True]": "41aa1b307824a1a11a0b6c5cf8651ff5c5e10cce93fd00523c9f4fa479a4c69b", +"TR_fr_test_language.py::test_switch_from_english[None]": "bb46ea113250150bd51ca80987a2ed75b33b6d35b26281a22411f158a4204bef", +"TR_fr_test_language.py::test_switch_from_english[True]": "bb46ea113250150bd51ca80987a2ed75b33b6d35b26281a22411f158a4204bef", +"TR_fr_test_language.py::test_switch_from_english_not_silent": "2d59eedb25da2468512d9576ef7d7f4528804d4fb8bb1921d4ee8d4d20d91196", +"TR_fr_test_language.py::test_switch_language": "c661df1f59509ae664e8731b444bcaf23b6068b49b28bf36b5733b6fba7fce25", "TR_fr_test_language.py::test_translations_renders_on_screen": "8b10d800ab66299a70c2bc569138031b5d9bd7be519980e180b7853433037cae", "TR_fr_test_msg_applysettings.py::test_apply_homescreen_tr_toif_good": "61e42f4eef33a9f482a1593dc245186e26883d3b78e3d48af1651bfb5fe6e3d6", "TR_fr_test_msg_applysettings.py::test_apply_homescreen_tr_toif_with_long_label": "184525975dc813659ec4b463cd09b71eefa7ddb250f01dd34b3c1a0010d203ed", @@ -10771,8 +10791,6 @@ "TT_cs_test_language.py::test_error_invalid_data_hash": "f839ad9340a0fbc2c26aeacd077a278c90b1544c62c185f403c4e791b00d232a", "TT_cs_test_language.py::test_error_invalid_data_length": "011d289134e070f0f1b21939ddd9dc8003ab02c8ff29db2db8b349eed7478b92", "TT_cs_test_language.py::test_error_invalid_header_magic": "011d289134e070f0f1b21939ddd9dc8003ab02c8ff29db2db8b349eed7478b92", -"TT_cs_test_language.py::test_error_invalid_header_version": "011d289134e070f0f1b21939ddd9dc8003ab02c8ff29db2db8b349eed7478b92", -"TT_cs_test_language.py::test_error_invalid_signature": "011d289134e070f0f1b21939ddd9dc8003ab02c8ff29db2db8b349eed7478b92", "TT_cs_test_language.py::test_error_too_long": "011d289134e070f0f1b21939ddd9dc8003ab02c8ff29db2db8b349eed7478b92", "TT_cs_test_language.py::test_error_version_mismatch": "011d289134e070f0f1b21939ddd9dc8003ab02c8ff29db2db8b349eed7478b92", "TT_cs_test_language.py::test_full_language_change[cs]": "b837b129f22886f15e2cf5183adc44561ba24de2848097fbbbfc6c44fd34728d", @@ -10782,7 +10800,13 @@ "TT_cs_test_language.py::test_full_language_change[fr]": "5b6297ad7b03664e18a95b8eb32ff4f0fd76f827da64559e09815fa506812440", "TT_cs_test_language.py::test_language_is_removed_after_wipe": "a3ae02a5a95dbfa4ffde27c66ab3b5a766aa0e84e04c64504c19a3ae432d0e8b", "TT_cs_test_language.py::test_reject_update": "baabea339f79af37b0184349a1d1e360cbbf111fc8fe8c7bf89f6ee8b6091cbb", -"TT_cs_test_language.py::test_silent_update": "9cca353e4b1a07d422b09bd1477705283fcfcc157f6c6a724a5c352df2216033", +"TT_cs_test_language.py::test_silent_first_install[False-False]": "b8494f22dfd7426af61780d585cedbdfbdd20c65721cc50e599e6f0c97aec1cb", +"TT_cs_test_language.py::test_silent_first_install[None-False]": "b8494f22dfd7426af61780d585cedbdfbdd20c65721cc50e599e6f0c97aec1cb", +"TT_cs_test_language.py::test_silent_first_install[True-True]": "6f6459ab5c1f6c307019b9d5aea2e4f5a09c1d970770f2b6cef2d6b0f5c6d9f4", +"TT_cs_test_language.py::test_switch_from_english[None]": "e9797de1f140ecdfcf8922b67e663ba7af1730d53ff38b4a1f33f484b38396f5", +"TT_cs_test_language.py::test_switch_from_english[True]": "e9797de1f140ecdfcf8922b67e663ba7af1730d53ff38b4a1f33f484b38396f5", +"TT_cs_test_language.py::test_switch_from_english_not_silent": "24633a26cdca3b628311460762d4a3bd6de6ac3d12475175dd24420fe8df40a3", +"TT_cs_test_language.py::test_switch_language": "9cd751812d02a2dce1dbe4d7b49f247286e490c25cc46a5e45e2140df1ada6e9", "TT_cs_test_language.py::test_translations_renders_on_screen": "29e8127373ad1c7c383deaa04f8bdcaca8f245eefcc710b3b50ceb5d1f154b22", "TT_cs_test_msg_applysettings.py::test_apply_homescreen_jpeg": "9fad96569555ce39a883e478c87d5c5f1f08a25458833834b27b4285d66ada47", "TT_cs_test_msg_applysettings.py::test_apply_homescreen_jpeg_progressive": "b5a62384cb7191d76f1a33b653ae1491788dbc611f484742707c95602298af87", @@ -12214,8 +12238,6 @@ "TT_de_test_language.py::test_error_invalid_data_hash": "449c596f93b1a7833e9631c0d8fe1f3f09eb64f3bf6006cf0ed22f08d051e263", "TT_de_test_language.py::test_error_invalid_data_length": "aa98140621cbb05cbaaad67e2fbaeba12f6d5ece97cb5cef993b6a263cce38b2", "TT_de_test_language.py::test_error_invalid_header_magic": "aa98140621cbb05cbaaad67e2fbaeba12f6d5ece97cb5cef993b6a263cce38b2", -"TT_de_test_language.py::test_error_invalid_header_version": "aa98140621cbb05cbaaad67e2fbaeba12f6d5ece97cb5cef993b6a263cce38b2", -"TT_de_test_language.py::test_error_invalid_signature": "aa98140621cbb05cbaaad67e2fbaeba12f6d5ece97cb5cef993b6a263cce38b2", "TT_de_test_language.py::test_error_too_long": "aa98140621cbb05cbaaad67e2fbaeba12f6d5ece97cb5cef993b6a263cce38b2", "TT_de_test_language.py::test_error_version_mismatch": "aa98140621cbb05cbaaad67e2fbaeba12f6d5ece97cb5cef993b6a263cce38b2", "TT_de_test_language.py::test_full_language_change[cs]": "14d372b0e5e896a15209b36c23196fa2b445124ff07eac3e8e550f79ef53fc52", @@ -12225,7 +12247,13 @@ "TT_de_test_language.py::test_full_language_change[fr]": "256177588435bf75d7bb339e835a6e79f8d10314f155784047b9d5a77a5c5e72", "TT_de_test_language.py::test_language_is_removed_after_wipe": "5b9f5817ba4e243d41262887aa338bb674f700ce47e1b50bc564cfd665876799", "TT_de_test_language.py::test_reject_update": "adef723d293c68592689b4fafbe87e6811656e6ea962484474594ce8f2407b4b", -"TT_de_test_language.py::test_silent_update": "eb921dc09253bc1019b737134880cb8b463b8ea8d2286c5a1acdad1d2fccec82", +"TT_de_test_language.py::test_silent_first_install[False-False]": "629c908f9d1d76b1248297c5a2eb9ee4933d54c53003329599312d6f292d4c7d", +"TT_de_test_language.py::test_silent_first_install[None-False]": "629c908f9d1d76b1248297c5a2eb9ee4933d54c53003329599312d6f292d4c7d", +"TT_de_test_language.py::test_silent_first_install[True-True]": "b5c51aa5234462c28aebbb1eb08d95da257557508b81b5e062ff05d893864b64", +"TT_de_test_language.py::test_switch_from_english[None]": "e058c2547a47e5592f0101ae076fd524dba3a5586ab6ba0f8ed679c1d6641535", +"TT_de_test_language.py::test_switch_from_english[True]": "e058c2547a47e5592f0101ae076fd524dba3a5586ab6ba0f8ed679c1d6641535", +"TT_de_test_language.py::test_switch_from_english_not_silent": "f3c1080628d56137fa597f86b6b11a6442ac36d30bc4630a1da1f9c662838b1f", +"TT_de_test_language.py::test_switch_language": "4987d445aa4db7d2b9728c44bed8123b2b080c432e36248083a32ba9f3198e57", "TT_de_test_language.py::test_translations_renders_on_screen": "00ec765b78d1751da86f8e1a40b93670a57a7e57ce6c06a1d6f5631cbbedb2df", "TT_de_test_msg_applysettings.py::test_apply_homescreen_jpeg": "1b11556c545da921ec13699de08ebbcfcd5482975a6cab5933af547c1c190e54", "TT_de_test_msg_applysettings.py::test_apply_homescreen_jpeg_progressive": "eddbeacf3bd533bd744db1675b8c13814c7b212aa894e7a7adf5b93005af4d13", @@ -13657,8 +13685,6 @@ "TT_en_test_language.py::test_error_invalid_data_hash": "67782b952469c260afac92bac1efc2ba9c2f342319ae95fb5e91c843da2a6e46", "TT_en_test_language.py::test_error_invalid_data_length": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739", "TT_en_test_language.py::test_error_invalid_header_magic": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739", -"TT_en_test_language.py::test_error_invalid_header_version": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739", -"TT_en_test_language.py::test_error_invalid_signature": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739", "TT_en_test_language.py::test_error_too_long": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739", "TT_en_test_language.py::test_error_version_mismatch": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739", "TT_en_test_language.py::test_full_language_change[cs]": "1359095f8b87e599c6fd88c15dd257c09c4afb3095d4db671e1746dfc4017604", @@ -13668,7 +13694,13 @@ "TT_en_test_language.py::test_full_language_change[fr]": "a6b00695cb76f4fcc7197d37df49c3b1997da6ed23f2c21330d30e0f28dc910d", "TT_en_test_language.py::test_language_is_removed_after_wipe": "20955fc2d8ae93c616be7041440c1e86a6a92e3235b352abdf0f17d95319d600", "TT_en_test_language.py::test_reject_update": "78b8f16e00c5d653a7d5c0929d21ae8ae1c76798fe28f0eb6edee8e2ee8b0202", -"TT_en_test_language.py::test_silent_update": "adc7d11983056a7fc66669c23162c2f09e8d65bc3992f2037ce7092ed4af1410", +"TT_en_test_language.py::test_silent_first_install[False-False]": "bbd64861dce4334f1d4a49cdccf981c854b72fe6807adfa516d115337eb60a36", +"TT_en_test_language.py::test_silent_first_install[None-False]": "bbd64861dce4334f1d4a49cdccf981c854b72fe6807adfa516d115337eb60a36", +"TT_en_test_language.py::test_silent_first_install[True-True]": "731c195ff8462396a6d3b1acc9b41d9258d96ac5053e777b9f3906a5611ea4be", +"TT_en_test_language.py::test_switch_from_english[None]": "d4072a9dae776c7fec7eae5f2ef1d9e944d0927b368d9f1e0a1c3fe8f6e2919a", +"TT_en_test_language.py::test_switch_from_english[True]": "d4072a9dae776c7fec7eae5f2ef1d9e944d0927b368d9f1e0a1c3fe8f6e2919a", +"TT_en_test_language.py::test_switch_from_english_not_silent": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3", +"TT_en_test_language.py::test_switch_language": "ea97a14817a6343259ad69aa1fa0ef06509ab9052d896fe67db64a98ecc643c0", "TT_en_test_language.py::test_translations_renders_on_screen": "5af6cd73525ef98f4151bf97d73bd92be0866bc99406f339a4aeab95e3a95048", "TT_en_test_msg_applysettings.py::test_apply_homescreen_jpeg": "0e2a71ac60add6bebc03645b6f4f6f19abdba56f1e55e799479b116e5a66aef6", "TT_en_test_msg_applysettings.py::test_apply_homescreen_jpeg_progressive": "4d7c67024ee17436071e5cf2f79c36453249c95314a732580623cb1f1cdbfdf3", @@ -15118,8 +15150,6 @@ "TT_es_test_language.py::test_error_invalid_data_hash": "1af05b4747855d9479d1d34bd3f1bc17cfe57f60a5c7bfdb4e93ceb331f13b2b", "TT_es_test_language.py::test_error_invalid_data_length": "cece2fdd44e917f03f20485e030d2ae3a614143360ce784cc7a3f43da9751f46", "TT_es_test_language.py::test_error_invalid_header_magic": "cece2fdd44e917f03f20485e030d2ae3a614143360ce784cc7a3f43da9751f46", -"TT_es_test_language.py::test_error_invalid_header_version": "cece2fdd44e917f03f20485e030d2ae3a614143360ce784cc7a3f43da9751f46", -"TT_es_test_language.py::test_error_invalid_signature": "cece2fdd44e917f03f20485e030d2ae3a614143360ce784cc7a3f43da9751f46", "TT_es_test_language.py::test_error_too_long": "cece2fdd44e917f03f20485e030d2ae3a614143360ce784cc7a3f43da9751f46", "TT_es_test_language.py::test_error_version_mismatch": "cece2fdd44e917f03f20485e030d2ae3a614143360ce784cc7a3f43da9751f46", "TT_es_test_language.py::test_full_language_change[cs]": "a786fa6053511bd1be10fd59016991fa079e8ee3c565d6533568d690541412e3", @@ -15129,7 +15159,13 @@ "TT_es_test_language.py::test_full_language_change[fr]": "a8d92d89b104b2fc3ee65e17d870366fd22fa910d2971d1c61319078a15244bc", "TT_es_test_language.py::test_language_is_removed_after_wipe": "6a92f98a10478ddc916f0b8f6c56b13cae1f458a9ad86eb6c8f46a9033abcdec", "TT_es_test_language.py::test_reject_update": "107634fbdacc72337abd7de1291904e6297bf5dd9551163780a1438b6d965949", -"TT_es_test_language.py::test_silent_update": "605a09f42c127ef4467b88b8173cc7f113e5d28b31c74512b331b74e074d689f", +"TT_es_test_language.py::test_silent_first_install[False-False]": "b307450f1f7e6118118b631c8354e9acb89f90f5755294ebb45b610ee8fc23c2", +"TT_es_test_language.py::test_silent_first_install[None-False]": "b307450f1f7e6118118b631c8354e9acb89f90f5755294ebb45b610ee8fc23c2", +"TT_es_test_language.py::test_silent_first_install[True-True]": "bc9bdd3d18dd96508b582f2857db7fc0a82a07a33da183c83175303bc5d0eee6", +"TT_es_test_language.py::test_switch_from_english[None]": "9dd9403584a75607f9f42ca859bf30b2ba1ac7d90ae923a52317d946cdbe6ee2", +"TT_es_test_language.py::test_switch_from_english[True]": "9dd9403584a75607f9f42ca859bf30b2ba1ac7d90ae923a52317d946cdbe6ee2", +"TT_es_test_language.py::test_switch_from_english_not_silent": "2798ba0027990ef7dfbadb74ec534fad4cb2698a62a6faf891f90b8cc3b874e2", +"TT_es_test_language.py::test_switch_language": "bebdee51e66ac9568e79a2c4b6f29306fea00cf9655c3a90c54611be1f239aa3", "TT_es_test_language.py::test_translations_renders_on_screen": "2e945f0cd09141d24d86a2b9619581088a0ea5ec157379da4e7149459c65fc32", "TT_es_test_msg_applysettings.py::test_apply_homescreen_jpeg": "86311915f84c811d5b011af80327112f650baa241bcb019ba58276fa27685e45", "TT_es_test_msg_applysettings.py::test_apply_homescreen_jpeg_progressive": "a94fffcba3fdd453aa33c43a34d8522cd47bf215e4848bb887f4769dc5420665", @@ -16561,8 +16597,6 @@ "TT_fr_test_language.py::test_error_invalid_data_hash": "43d82fabe548153d7cbde335cd0e80ac0d444ba58628b0a4fef503817d2fb82b", "TT_fr_test_language.py::test_error_invalid_data_length": "cf1b79fdfa5643710dabe6a0dc9abc8ebf227f617e7bc2214bcffe465dc81670", "TT_fr_test_language.py::test_error_invalid_header_magic": "cf1b79fdfa5643710dabe6a0dc9abc8ebf227f617e7bc2214bcffe465dc81670", -"TT_fr_test_language.py::test_error_invalid_header_version": "cf1b79fdfa5643710dabe6a0dc9abc8ebf227f617e7bc2214bcffe465dc81670", -"TT_fr_test_language.py::test_error_invalid_signature": "cf1b79fdfa5643710dabe6a0dc9abc8ebf227f617e7bc2214bcffe465dc81670", "TT_fr_test_language.py::test_error_too_long": "cf1b79fdfa5643710dabe6a0dc9abc8ebf227f617e7bc2214bcffe465dc81670", "TT_fr_test_language.py::test_error_version_mismatch": "cf1b79fdfa5643710dabe6a0dc9abc8ebf227f617e7bc2214bcffe465dc81670", "TT_fr_test_language.py::test_full_language_change[cs]": "447d14f4f54f2b9e7f894514770d73a47958503a93983fb48b8f54f2c8e1fa8a", @@ -16572,7 +16606,13 @@ "TT_fr_test_language.py::test_full_language_change[fr]": "f59be182fa1ff0bfb9230b69a49dabfed30394618e2eaf11597c8a109a7bab95", "TT_fr_test_language.py::test_language_is_removed_after_wipe": "a474ebb565e9e2fc01647fe2ae739519f25807562abe757ac55d20814b3458af", "TT_fr_test_language.py::test_reject_update": "1ea4e3f645e5d788714b61525c0eee446a306f2844fec383460e45574f9a5de5", -"TT_fr_test_language.py::test_silent_update": "22785c108bee4ac76af3a923a9d35a316d9153fefb9221a855912eab24fd3d32", +"TT_fr_test_language.py::test_silent_first_install[False-False]": "d0046d29c419e87c0f3881d7c9308c9621dc111a6b5a914eb8bd63266a7d7b91", +"TT_fr_test_language.py::test_silent_first_install[None-False]": "d0046d29c419e87c0f3881d7c9308c9621dc111a6b5a914eb8bd63266a7d7b91", +"TT_fr_test_language.py::test_silent_first_install[True-True]": "9c67d06a18c5c1c8f7016c5280d9275a6eb7d3b5672e0da276c0a01b102e80cf", +"TT_fr_test_language.py::test_switch_from_english[None]": "9fcd8061d44e55942221e65c13f20c39b0e36619e236e7a7c2bbd3e43abab322", +"TT_fr_test_language.py::test_switch_from_english[True]": "9fcd8061d44e55942221e65c13f20c39b0e36619e236e7a7c2bbd3e43abab322", +"TT_fr_test_language.py::test_switch_from_english_not_silent": "44384285d55f517fd9644ea67051c07c34dad16b278eb4b2534091581756979e", +"TT_fr_test_language.py::test_switch_language": "b8fa1068af12657179987aa8d31c665dc53d2ab1304c67e4968bb63d7a9ff1cb", "TT_fr_test_language.py::test_translations_renders_on_screen": "3704b37de0d90dfe0f9d2451b2920787d1d0da3c102d93e43f98e00a888811c5", "TT_fr_test_msg_applysettings.py::test_apply_homescreen_jpeg": "7dd352a6c4e12d3cad9e6ef85541941c4c0cdd57d6b2a9b5d312d3ea055ac51c", "TT_fr_test_msg_applysettings.py::test_apply_homescreen_jpeg_progressive": "a96ae889c91bb377c6932cd37e0ce914bd4d8ab551b553d5f6f5d2ab6e9f7e0f",