v3.22.0: the event action uses the Simulator's forms (all modelled events)
The test-script event action edited its fields as a JSON textarea and only accepted the four events events.py builds; every other event needed the raw envelope action with hand-copied hex. It now renders the same EVENT_FORMS form the Phone tab's send dialog uses, for every modelled event (29; no release gating - a script may target another card). - PWA: the field renderer/collector is shared (eventFormFieldsHtml / eventFormValues / eventFormPatternError / eventFormSrc / eventFieldGroupsUpdate); the Phone tab keeps its ids, its release gating and its onchange updaters, the step editor uses test-f-ev- ids, the generic group updater and a live Event data (hex) preview with the one-ENVELOPE check. The event select lists all EVENT_FORMS events (the numeric keys are decimal strings - parseInt(k, 10)); the action stores the collected fields, the built data and the event's source (fixed cfg.src or the cfg.srcField input - the action never carried src before, so MT call / IMS registration / slices could not be network-sourced). The JSON textarea is gone. - engine: the `event` action keeps `fields` validation for the four server-built events (a stray data hex is ignored) and accepts the form-built `data` for every other event - hex-validated and checked against events.EVENT_DATA_MAX (244, the one-ENVELOPE budget; server.py's _EVENT_DATA_MAX now reads it from events.py). The runner builds the four at run time (fresh host clock) and sends the stored data for the rest. - tests: the engine's data path (accepted / missing / malformed / oversized, the four still fields-built), the runner sending the data (fake scc), the editor's collect/prefill/patterns/source (Node), the shared helpers. Docs: test-scripts.md, api.md, help EN/RU. Tests: 838 frontend + 797 Python; sw cache simple-v401.
This commit is contained in:
@@ -15,6 +15,7 @@ if str(PY_SIM) not in sys.path:
|
||||
sys.path.insert(0, str(PY_SIM))
|
||||
|
||||
import pysim_simple_server.server as S
|
||||
import pysim_simple_server.events as events
|
||||
import pysim_simple_server.testscript as T
|
||||
|
||||
|
||||
@@ -218,6 +219,27 @@ class TestValidation(unittest.TestCase):
|
||||
T.normalise_script({'steps': [{'type': 'action', 'kind': 'envelope',
|
||||
'params': {'event': 3, 'src': 'zz'}}]}, _resolver)
|
||||
|
||||
def test_event_action_accepts_the_form_built_data(self):
|
||||
# The events events.py does not model carry the PWA form's built hex;
|
||||
# a modelled event builds from `fields` (a stray data hex is ignored).
|
||||
script = T.normalise_script({'steps': [
|
||||
{'type': 'action', 'kind': 'event',
|
||||
'params': {'event': '0x00', 'data': '1c0100', 'src': '83'}}]}, _resolver)
|
||||
self.assertEqual(script['steps'][0]['params'],
|
||||
{'event': 0x00, 'data': '1C0100', 'src': '83'})
|
||||
script = T.normalise_script({'steps': [
|
||||
{'type': 'action', 'kind': 'event',
|
||||
'params': {'event': '0x03', 'fields': {'status': 1}, 'data': 'AA'}}]}, _resolver)
|
||||
self.assertNotIn('data', script['steps'][0]['params'])
|
||||
self.assertEqual(script['steps'][0]['params']['fields'], {'status': 1})
|
||||
# missing, malformed and oversized data are refused before the run
|
||||
for bad in ({'event': '0x00'},
|
||||
{'event': '0x00', 'data': 'ABC'},
|
||||
{'event': '0x00', 'data': 'AA' * (events.EVENT_DATA_MAX + 1)}):
|
||||
with self.assertRaises(T.ScriptError):
|
||||
T.normalise_script({'steps': [{'type': 'action', 'kind': 'event',
|
||||
'params': bad}]}, _resolver)
|
||||
|
||||
def test_scp80_keyset_number_and_new_content_checks(self):
|
||||
# kvn (1..15) selects the preset's keyset; `por`/`files` are expect
|
||||
# content checks (the PoR contents / the REFRESH file list).
|
||||
@@ -850,8 +872,7 @@ class TestRunnerActions(RunnerTestCase):
|
||||
# the runner logs one step-annotated ENVELOPE line, not the generic
|
||||
# sender pair as well (its line carries the name, src and SW)
|
||||
log = buf.getvalue()
|
||||
self.assertIn('TEST-RUN step 1: ENVELOPE(Event Download) type=0x03 '
|
||||
'(location_status) data=9B0100930752F01000FF0001 src=82 -> SW=9000',
|
||||
self.assertIn('TEST-RUN step 1: ENVELOPE(Event Download) type=0x03 ' '(location_status) data=9B0100930752F01000FF0001 src=82 -> SW=9000',
|
||||
log)
|
||||
self.assertNotIn('ENVELOPE(Event Download): type=', log)
|
||||
self.assertNotIn('ENVELOPE SW:', log)
|
||||
@@ -878,6 +899,22 @@ class TestRunnerActions(RunnerTestCase):
|
||||
self.assertEqual(run['status'], 'ok', run['steps'])
|
||||
self.assertIn('99010082028381', scc3.sent[0].upper())
|
||||
|
||||
def test_event_action_sends_the_form_built_data(self):
|
||||
# The events events.py does not model (e.g. MT call) run with the
|
||||
# PWA form's built hex and its source (network).
|
||||
scc = FakeScc()
|
||||
scc.push('80C2', '', '9000')
|
||||
buf = io.StringIO()
|
||||
with contextlib.redirect_stderr(buf):
|
||||
run = self.run_script(FakeServer(scc), [
|
||||
{'type': 'action', 'kind': 'event',
|
||||
'params': {'event': '0x00', 'data': '1C0100', 'src': '83'}},
|
||||
])
|
||||
self.assertEqual(run['status'], 'ok', run['steps'])
|
||||
self.assertIn('99010082028381' + '1C0100', scc.sent[0].upper())
|
||||
self.assertIn('type=0x00 (0x00) data=1C0100 src=83 -> SW=9000',
|
||||
buf.getvalue())
|
||||
|
||||
def test_scp80_uses_the_preset_and_advances_the_counter(self):
|
||||
scc = FakeScc()
|
||||
server = FakeServer(scc)
|
||||
|
||||
Reference in New Issue
Block a user