.F.F.......                                                          [100%]
=================================== FAILURES ===================================
_________________ SettingsTests.test_fire_combination_no_save __________________

self = <test_fall_integration.SettingsTests testMethod=test_fire_combination_no_save>

    def test_fire_combination_no_save(self):
        m=FakeManager(spec()); before=deepcopy(m.group.spec)
>       with self.assertRaisesRegex(ControlError,'NEEDS_MULTI_PROVIDER_RUNTIME_CONFIRMATION'):
E       AssertionError: ControlError not raised

tests/test_fall_integration.py:54: AssertionError
_______ SettingsTests.test_roi_empty_aliases_and_independent_confidence ________

self = <test_fall_integration.SettingsTests testMethod=test_roi_empty_aliases_and_independent_confidence>

    def test_roi_empty_aliases_and_independent_confidence(self):
        values=[]
        for mode in ('missing','null','empty'):
            d=request('FALL','LOITERING')
            for row in d['scenarios']:
                row['confidence']=.35 if row['scenarioCode']=='FALL' else .8
                if mode=='missing':row.pop('rois')
                elif mode=='null':row['rois']=None
>           values.append(ControlService(FakeManager(),'server',spec()).start_camera(Start(json.dumps(d))))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/test_fall_integration.py:66: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
app/secure_control.py:163: in start_camera
    self.validate_request(d)
app/secure_control.py:159: in validate_request
    validate_start(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

d = {'cameraId': 77, 'rtpClockRate': 90000, 'rtspUrl': 'rtsp://fixture.invalid/video', 'scenarios': [{'confidence': 0.8, '...scenarioCode': 'INTRUSION'}, {'confidence': 0.8, 'enabled': True, 'parameters': {}, 'scenarioCode': 'LOITERING'}], ...}

    def validate_start(d):
        camera_id(d)
        required = {'cameraId','rtspUrl','startWallTimeMs','rtpClockRate','scenarios'}
        if not required <= set(d) or set(d)-required-{'recServerId','recCameraId'}:
            raise ControlError('START_FIELDS_INVALID')
        u = d['rtspUrl']
        try:
            p = urlsplit(u)
            if (not isinstance(u, str) or len(u)>4096 or p.scheme!='rtsp' or not p.hostname
                    or p.port == 0 or p.fragment or any(c.isspace() or ord(c)<32 for c in u)):
                raise ValueError()
        except (TypeError, ValueError):
            raise ControlError('RTSP_INVALID') from None
        if type(d['startWallTimeMs']) is not int or not 0 < d['startWallTimeMs'] <= 2**53-1:
            raise ControlError('ANCHOR_INVALID')
        if type(d['rtpClockRate']) is not int or d['rtpClockRate'] != 90000:
            raise ControlError('CLOCK_RATE_UNSUPPORTED')
        scenarios = d['scenarios']
        if not isinstance(scenarios, list) or len(scenarios) != 6:
            raise ControlError('SCENARIO_SNAPSHOT_REQUIRED')
        seen = set()
        for s in scenarios:
            if (not isinstance(s, dict) or not {'scenarioCode','enabled'} <= set(s)
                    or set(s)-{'scenarioCode','enabled','rois','parameters'}):
>               raise ControlError('SCENARIO_FIELDS_INVALID')
E               app.secure_control.ControlError: SCENARIO_FIELDS_INVALID

app/secure_control.py:96: ControlError
=========================== short test summary info ============================
FAILED tests/test_fall_integration.py::SettingsTests::test_fire_combination_no_save
FAILED tests/test_fall_integration.py::SettingsTests::test_roi_empty_aliases_and_independent_confidence
2 failed, 9 passed, 4 subtests passed in 0.58s
