def test_get_variable_value(self, *args): params = {'param1': 'foo', 'param2': 10} defined_variables = BaseVariables() defined_variables.variable1 = MagicMock() engine._get_variable_value(defined_variables, 'variable1', params) defined_variables.variable1.assert_called_once_with(param1='foo', param2=10)
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_run_all_some_rule_triggered(self, *args): """ By default, does not stop on first triggered rule. Returns a list of booleans indicating whether each rule was triggered. """ 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 results = engine.run_all([rule1, rule2], variables, actions) self.assertEqual(results, [True, False]) self.assertEqual(engine.run.call_count, 2) # switch order and try again engine.run.reset_mock() results = engine.run_all([rule2, rule1], variables, actions) self.assertEqual(results, [False, True]) self.assertEqual(engine.run.call_count, 2)
def test_nested_all_and_any(self, *args): conditions = { 'all': [{ 'any': [{ 'name': 1 }, { 'name': 2 }] }, { 'name': 3 }] } bv = BaseVariables() def side_effect(condition, _, **kwargs): condition_check = condition['name'] in [2, 3] return condition_check, {} engine.check_condition.side_effect = side_effect engine.check_conditions_recursively(conditions, bv) self.assertEqual(engine.check_condition.call_count, 3) engine.check_condition.assert_any_call({'name': 1}, bv, override_params=OVERRIDE_NONE) engine.check_condition.assert_any_call({'name': 2}, bv, override_params=OVERRIDE_NONE) engine.check_condition.assert_any_call({'name': 3}, bv, override_params=OVERRIDE_NONE)
def test_check_all_conditions_with_all_false(self, *args): conditions = {'all': [{'thing1': ''}, {'thing2': ''}]} variables = BaseVariables() result = engine.check_conditions_recursively(conditions, variables) self.assertEqual(result, False) engine.check_condition.assert_called_once_with({'thing1': ''}, variables)
def test_nested_all_and_any(self, *args): conditions = { 'all': [{ 'any': [{ 'name': 1 }, { 'name': 2 }] }, { 'name': 3 }] } rule = {'conditions': conditions, 'actions': {}} bv = BaseVariables() def side_effect(condition, _, rule): return ConditionResult(result=condition['name'] in [2, 3], name=condition['name'], operator='', value='', parameters='') engine.check_condition.side_effect = side_effect engine.check_conditions_recursively(conditions, bv, rule) self.assertEqual(engine.check_condition.call_count, 3) engine.check_condition.assert_any_call({'name': 1}, bv, rule) engine.check_condition.assert_any_call({'name': 2}, bv, rule) engine.check_condition.assert_any_call({'name': 3}, bv, rule)
def test_check_any_condition_with_no_items_fails(self): conditions = {'any': []} variables = BaseVariables() rule = {'conditions': conditions, 'actions': []} with self.assertRaises(AssertionError): engine.check_conditions_recursively(conditions, variables, rule)
def test_check_any_conditions_with_all_true(self, *args): conditions = {'any': [{'thing1': ''}, {'thing2': ''}]} variables = BaseVariables() result = engine.check_conditions_recursively(conditions, variables) self.assertEqual(result, T_NO_OVERRIDES) engine.check_condition.assert_called_once_with( {'thing1': ''}, variables, override_params=OVERRIDE_NONE)
def test_check_any_conditions_with_all_true(self, *args): conditions = {'any': [{'thing1': ''}, {'thing2': ''}]} variables = BaseVariables() rule = {'conditions': conditions, 'actions': []} result = engine.check_conditions_recursively(conditions, variables, rule) self.assertEqual(result, (True, [(True,)])) engine.check_condition.assert_called_once_with({'thing1': ''}, variables, rule)
def test_check_all_conditions_with_all_true(self, *args): conditions = {'all': [{'thing1': ''}, {'thing2': ''}]} variables = BaseVariables() result = engine.check_conditions_recursively(conditions, variables) self.assertEqual(result, True) # assert call count and most recent call are as expected self.assertEqual(engine.check_condition.call_count, 2) engine.check_condition.assert_called_with({'thing2': ''}, variables)
def test_check_any_conditions_with_all_false(self, *args): conditions = {'any': [{'thing1': ''}, {'thing2': ''}]} variables = BaseVariables() rule = {'conditions': conditions, 'actions': []} result = engine.check_conditions_recursively(conditions, variables, rule) self.assertEqual(result, (False, [])) # assert call count and most recent call are as expected self.assertEqual(engine.check_condition.call_count, 2) engine.check_condition.assert_called_with(conditions['any'][1], variables, rule)
def test_check_any_conditions_with_all_false(self, *args): conditions = {'any': [{'thing1': ''}, {'thing2': ''}]} variables = BaseVariables() result = engine.check_conditions_recursively(conditions, variables) self.assertEqual(result, F_NO_OVERRIDES) # assert call count and most recent call are as expected self.assertEqual(engine.check_condition.call_count, 2) engine.check_condition.assert_called_with( {'thing2': ''}, variables, override_params=OVERRIDE_NONE)
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_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_nested_all_and_any(self, *args): conditions = {'all': [ {'any': [{'name': 1}, {'name': 2}]}, {'name': 3}]} bv = BaseVariables() def side_effect(condition, _): return condition['name'] in [2,3] engine.check_condition.side_effect = side_effect engine.check_conditions_recursively(conditions, bv) self.assertEqual(engine.check_condition.call_count, 3) engine.check_condition.assert_any_call({'name': 1}, bv) engine.check_condition.assert_any_call({'name': 2}, bv) engine.check_condition.assert_any_call({'name': 3}, bv)
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_check_condition_no_override(self, *args): condition = { 'name': 'name_x', 'operator': 'operator_x', 'value': 'value_x' } variables = BaseVariables() result, overrides = engine.check_condition(condition, variables) self.assertEqual( engine._get_variable_value_and_actions_params.call_count, 1) self.assertEqual(engine._do_operator_comparison.call_count, 1) engine._get_variable_value_and_actions_params.assert_called_with( variables, 'name_x', OVERRIDE_NONE) engine._do_operator_comparison.assert_called_with( FAKE_OPERATOR, 'operator_x', 'value_x') self.assertTrue(result) self.assertDictEqual(overrides, OVERRIDE_A1)
def test_recursive_overrides_collect_repeated(self, *args): conditions = {'all': [{'name': 1}, {'name': 2}]} bv = BaseVariables() def side_effect(condition, _, **kwargs): if condition['name'] == 1: return True, OVERRIDE_C3 elif condition['name'] == 2: return True, OVERRIDE_C4 engine.check_condition.side_effect = side_effect result, overrides = engine.check_conditions_recursively(conditions, bv) self.assertEqual(engine.check_condition.call_count, 2) engine.check_condition.assert_any_call({'name': 1}, bv, override_params=OVERRIDE_NONE) engine.check_condition.assert_any_call({'name': 2}, bv, override_params=OVERRIDE_C3) self.assertTrue(result) self.assertDictEqual(overrides, OVERRIDE_C4)
def test_base_has_no_variables(self): self.assertEqual(len(BaseVariables.get_all_variables()), 0)
def test_check_all_and_any_together(self): conditions = {'any': [], 'all': []} variables = BaseVariables() rule = {"conditions": conditions, "actions": []} with self.assertRaises(AssertionError): engine.check_conditions_recursively(conditions, variables, rule)
def test_check_any_condition_with_no_items_fails(self): with self.assertRaises(AssertionError): engine.check_conditions_recursively({'any': []}, BaseVariables())
def test_check_all_condition_with_no_items_fails(self): conditions = {'all': []} rule = {"conditions": conditions, "actions": []} variables = BaseVariables() with self.assertRaises(AssertionError): engine.check_conditions_recursively(conditions, variables, rule)