def test_do_actions_checks_invalid_params(self): @rule_action(params=[{'name': 'param1', 'fieldType': FIELD_NUMERIC}]) def action1(self, param1): pass actions = [{'name': 'action1', 'params': {'param1': 1, 'param2': 2}}] defined_actions = BaseActions() defined_actions.action1 = action1 err_string = 'Invalid parameters param2 for action action1' with self.assertRaisesRegexp(AssertionError, err_string): engine.do_actions(actions, defined_actions)
def test_do_actions(self): actions = [ {'name': 'action1'}, {'name': 'action2', 'params': {'param1': 'foo', 'param2': 10}}] defined_actions = BaseActions() defined_actions.action1 = MagicMock() defined_actions.action2 = MagicMock() engine.do_actions(actions, defined_actions) defined_actions.action1.assert_called_once_with() defined_actions.action2.assert_called_once_with(param1='foo', param2=10)
def test_do_actions(self): actions = [{ 'name': 'action1' }, { 'name': 'action2', 'params': { 'param1': 'foo', 'param2': 10 } }] defined_actions = BaseActions() defined_actions.action1 = MagicMock() defined_actions.action2 = MagicMock() engine.do_actions(actions, defined_actions) defined_actions.action1.assert_called_once_with() defined_actions.action2.assert_called_once_with(param1='foo', param2=10)
def test_do_actions_with_injected_parameters(self): function_params_mock = MagicMock() function_params_mock.varkw = True with patch('business_rules.engine.getfullargspec', return_value=function_params_mock): rule_actions = [{ 'name': 'action1' }, { 'name': 'action2', 'params': { 'param1': 'foo', 'param2': 10 } }] rule = {'conditions': {}, 'actions': rule_actions} defined_actions = BaseActions() defined_actions.action1 = MagicMock() defined_actions.action1.params = [] defined_actions.action2 = MagicMock() defined_actions.action2.params = [{ 'label': 'action2', 'name': 'param1', 'fieldType': fields.FIELD_TEXT, 'defaultValue': None }, { 'label': 'action2', 'name': 'param2', 'fieldType': fields.FIELD_NUMERIC, 'defaultValue': None }] payload = [(True, 'condition_name', 'operator_name', 'condition_value')] engine.do_actions(rule_actions, defined_actions, payload, rule) defined_actions.action1.assert_called_once_with(conditions=payload, rule=rule) defined_actions.action2.assert_called_once_with(param1='foo', param2=10, conditions=payload, rule=rule)
def test_run_that_doesnt_trigger_rule(self, *args): rule = {'conditions': 'blah', 'actions': 'blah2'} variables = BaseVariables() actions = BaseActions() result = engine.run(rule, variables, actions) self.assertEqual(result, False) engine.check_conditions_recursively.assert_called_once_with( rule['conditions'], variables) self.assertEqual(engine.do_actions.call_count, 0)
def test_run_all_stop_on_first(self, *args): rule1 = {'conditions': 'condition1', 'actions': 'action name 1'} rule2 = {'conditions': 'condition2', 'actions': 'action name 2'} variables = BaseVariables() actions = BaseActions() result = engine.run_all([rule1, rule2], variables, actions, stop_on_first_trigger=True) self.assertEqual(result, True) self.assertEqual(engine.run.call_count, 1) engine.run.assert_called_once_with(rule1, variables, actions)
def test_run_that_triggers_rule(self, *args): rule = {'conditions': 'blah', 'actions': 'blah2'} variables = BaseVariables() actions = BaseActions() result = engine.run(rule, variables, actions) expected = None self.assertEqual(result, expected) engine.check_conditions_recursively.assert_called_once_with( rule['conditions'], variables) engine.do_actions.assert_called_once_with(rule['actions'], actions)
def test_async_do_actions(self): actions = [{ 'name': 'action1' }, { 'name': 'action2', 'params': { 'param1': 'foo', 'param2': 10 } }] defined_actions = BaseActions() defined_actions.action1 = AsyncMock() defined_actions.action2 = AsyncMock() asyncio.get_event_loop().run_until_complete( engine.async_do_actions(actions, defined_actions)) defined_actions.action1.assert_called_once_with() defined_actions.action2.assert_called_once_with(param1='foo', param2=10)
def test_do_with_invalid_action(self): actions = [{'name': 'fakeone'}] err_string = "Action fakeone is not defined in class BaseActions" rule = {'conditions': {}, 'actions': {}} checked_conditions_results = [(True, 'condition_name', 'operator_name', 'condition_value')] with self.assertRaisesRegexp(AssertionError, err_string): engine.do_actions(actions, BaseActions(), checked_conditions_results, rule)
def test_async_run_that_triggers_rule(self, *args): rule = {'conditions': 'blah', 'actions': 'blah2'} variables = BaseVariables() actions = BaseActions() result = asyncio.get_event_loop().run_until_complete( engine.async_run(rule, variables, actions)) self.assertEqual(result, True) engine.check_conditions_recursively.assert_called_once_with( rule['conditions'], variables) engine.async_do_actions.assert_called_once_with( rule['actions'], actions)
def test_run_that_triggers_rule_with_overrides(self, *args): rule = {'conditions': 'blah', 'actions': 'blah2'} variables = BaseVariables() actions = BaseActions() result = engine.run(rule, variables, actions) self.assertEqual(result, True) engine.check_conditions_recursively.assert_called_once_with( rule['conditions'], variables) engine.do_actions.assert_called_once_with(rule['actions'], actions, override_params=OVERRIDE_A1)
def test_do_actions(self): function_params_mock = MagicMock() function_params_mock.keywords = None with patch('inspect.getargspec', return_value=function_params_mock): rule_actions = [ { 'name': 'action1' }, { 'name': 'action2', 'params': {'param1': 'foo', 'param2': 10} } ] rule = { 'conditions': { }, 'actions': rule_actions } defined_actions = BaseActions() defined_actions.action1 = MagicMock() defined_actions.action2 = MagicMock() defined_actions.action2.params = { 'param1': fields.FIELD_TEXT, 'param2': fields.FIELD_NUMERIC } payload = [(True, 'condition_name', 'operator_name', 'condition_value')] engine.do_actions(rule_actions, defined_actions, payload, rule) defined_actions.action1.assert_called_once_with() defined_actions.action2.assert_called_once_with(param1='foo', param2=10)
def test_async_run_all_return_false_for_no_execution(self, *args): rule1 = {'conditions': 'condition1', 'actions': 'action name 1'} rule2 = {'conditions': 'condition2', 'actions': 'action name 2'} variables = BaseVariables() actions = BaseActions() result = asyncio.get_event_loop().run_until_complete( engine.async_run_all([rule1, rule2], variables, actions, stop_on_first_trigger=True)) self.assertEqual(result, False) self.assertEqual(engine.async_run.call_count, 2) engine.async_run.assert_has_calls( [call(rule1, variables, actions), call(rule2, variables, actions)])
def test_run_all_some_rule_triggered(self, *args): """ By default, does not stop on first triggered rule. Returns True if any rule was triggered, otherwise False """ rule1 = {'conditions': 'condition1', 'actions': 'action name 1'} rule2 = {'conditions': 'condition2', 'actions': 'action name 2'} variables = BaseVariables() actions = BaseActions() def return_action1(rule, *args, **kwargs): return rule['actions'] == 'action name 1' engine.run.side_effect = return_action1 result = engine.run_all([rule1, rule2], variables, actions) self.assertTrue(result) self.assertEqual(engine.run.call_count, 2) # switch order and try again engine.run.reset_mock() result = engine.run_all([rule2, rule1], variables, actions) self.assertTrue(result) self.assertEqual(engine.run.call_count, 2)
def test_do_actions_with_returned_values(self): actions = [{ 'name': 'action1' }, { 'name': 'action2', 'params': { 'param1': 'foo', 'param2': 10 } }, { 'name': 'action3', 'params': { 'param1': 'baz' } }, { 'name': 'action4', 'params': { 'param1': 'old' } }] defined_actions = BaseActions() defined_actions.action1 = MagicMock(return_value={'param3': 'bar'}) defined_actions.action2 = MagicMock(return_value=[1, 2, 3]) defined_actions.action3 = MagicMock(return_value={'param1': 'new'}) defined_actions.action4 = MagicMock() engine.do_actions(actions, defined_actions) defined_actions.action1.assert_called_once_with() # action result of dict type gets merged into params defined_actions.action2.assert_called_once_with(param1='foo', param2=10, param3='bar') # action result of non-dict type doesn't get merged into params defined_actions.action3.assert_called_once_with(param1='baz') # action result overrides params of the following action defined_actions.action4.assert_called_once_with(param1='new')
def test_base_has_no_actions(self): self.assertEqual(len(BaseActions.get_all_actions()), 0)
def test_do_with_invalid_action(self): actions = [{'name': 'fakeone'}] err_string = "Action fakeone is not defined in class BaseActions" with self.assertRaisesRegexp(AssertionError, err_string): engine.do_actions(actions, BaseActions())