46 lines
2.1 KiB
Python
46 lines
2.1 KiB
Python
|
|
from contextlib import contextmanager
|
||
|
|
from unittest.mock import MagicMock
|
||
|
|
from app.workflows import worker, classification
|
||
|
|
|
||
|
|
class Cursor:
|
||
|
|
def __init__(self,enabled=True):
|
||
|
|
self.statements=[]
|
||
|
|
self.enabled=enabled
|
||
|
|
self.rows=[]
|
||
|
|
def execute(self,sql,params=None):
|
||
|
|
self.statements.append((sql,params))
|
||
|
|
if 'FROM bmc_workflow_runtime' in sql:
|
||
|
|
self.rows=[{'enabled':self.enabled,'mode':'active','customer_ids':['24']}]
|
||
|
|
elif 'FOR UPDATE SKIP LOCKED' in sql:
|
||
|
|
self.rows=[{'id':'event1','entity_type':'time_entry','entity_id':'9','revision':1,'chain':[],'context':{},'trigger':'time.created'}]
|
||
|
|
elif 'SELECT w.*' in sql:
|
||
|
|
self.rows=[{'id':1,'priority':100,'customer_id':None,'version_id':2,'definition':{'trigger':'time.created','branches':[{'condition':None,'actions':[{'type':'set_billing','method':'invoice'}]}]}}]
|
||
|
|
else: self.rows=[]
|
||
|
|
def fetchone(self): return self.rows.pop(0) if self.rows else None
|
||
|
|
def fetchall(self):
|
||
|
|
rows,self.rows=self.rows,[]
|
||
|
|
return rows
|
||
|
|
|
||
|
|
def setup(monkeypatch,cursor):
|
||
|
|
@contextmanager
|
||
|
|
def transaction(): yield cursor
|
||
|
|
monkeypatch.setattr(worker,'transaction',transaction)
|
||
|
|
monkeypatch.setattr(worker,'load_time_context',lambda *args:{'time_id':9,'customer_id':'99','workflow_revision':1})
|
||
|
|
monkeypatch.setattr(classification,'enrich_time_context',lambda cursor,context:context)
|
||
|
|
|
||
|
|
def test_disabled_runtime_never_dequeues(monkeypatch):
|
||
|
|
cursor=Cursor(enabled=False)
|
||
|
|
setup(monkeypatch,cursor)
|
||
|
|
assert worker.process_pending_events(1)==0
|
||
|
|
assert len(cursor.statements)==1
|
||
|
|
|
||
|
|
def test_outside_allowlist_processes_only_shadow(monkeypatch):
|
||
|
|
cursor=Cursor()
|
||
|
|
setup(monkeypatch,cursor)
|
||
|
|
assert worker.process_pending_events(1,mode='active')==1
|
||
|
|
sqls=[sql for sql,_ in cursor.statements]
|
||
|
|
assert not any('INSERT INTO bmc_billing_decisions' in sql for sql in sqls)
|
||
|
|
execution=next(params for sql,params in cursor.statements if 'INSERT INTO bmc_workflow_executions' in sql)
|
||
|
|
assert execution[1]=='shadow'
|
||
|
|
assert execution[2].adapted['mode']=='shadow'
|