fix: follow-up test-script review findings (v3.5.14)

- The SCP80 counter write-back resolves the preset by NAME first (the run
  snapshot prefers the name) and only falls back to an ICCID-looking
  value: presets with digits in their names are found after a page reload
  (the previous fallback ran cardsNormIccid on the name and gave up).
- testScriptProblem validates the *selected* SCP80 source (like the form
  and the server), so source=apdu with only sp filled is caught locally
  instead of failing with a server 400.
- _test_run_start cleans up (_TEST_RUNNING=False, run state error) when
  the worker thread cannot be created/started, and the endpoint answers
  500 with a clear error instead of leaving the card blocked behind a run
  that never started.
- The 5 s poll writes the counter back whenever a run is finished
  (idempotent), so a reloaded page saves it without visiting the pill.
- Mask wildcards ('?') are stripped from the hex fields that cannot carry
  a mask (APDU, secured packet, event/file data, TAR/SPI overrides, DCS,
  extra TLVs); check values keep them.

Tests: frontend +3 (write-back by name / by ICCID, mask-free fields,
source-aware script check), Python +1 (failed thread start unblocks).
586 frontend / 471 Python green; version 3.5.14; sw simple-v267.
This commit is contained in:
2026-09-27 01:52:03 +03:00
parent d1eb88d4d7
commit 2d2a40a73c
6 changed files with 115 additions and 24 deletions
+11
View File
@@ -316,6 +316,17 @@ class TestRunnerDialogue(RunnerTestCase):
self.assertEqual(sum(1 for a in scc.sent if a.startswith('80F2')), 3)
self.assertEqual(run['steps'][0]['sent'], 'STATUS x3')
def test_failed_thread_start_unblocks_the_card(self):
script = T.normalise_script({'steps': [
{'type': 'action', 'kind': 'status', 'params': {}}]}, S._test_command_type)
server = FakeServer(FakeScc())
with mock.patch.object(S.threading, 'Thread', side_effect=RuntimeError('no threads')):
with self.assertRaises(RuntimeError):
S._test_run_start(server, script, {})
self.assertFalse(S._TEST_RUNNING)
self.assertFalse(S._TEST_RUN['running'])
self.assertEqual(S._TEST_RUN['status'], 'error')
def test_stop_before_the_first_step(self):
run = self.run_script(FakeServer(FakeScc()), [
{'type': 'action', 'kind': 'status', 'params': {}},