Files
sientia-dataops-laborious-l…/tests/laborious/activities/test_gates.py
vitor-aignosi 43f19ed93a SIENTIAPDE-994
Update requirements.txt with new dependencies and refactor activity methods for improved functionality and error handling
2025-05-08 17:01:40 -03:00

309 lines
9.7 KiB
Python

from unittest.mock import ANY, MagicMock, patch
from pandas import DataFrame
from pytest import fixture, mark
from laborious.activities.gates import Gates
from sientia_do.notifications.models import NotificationLevel
@fixture
def gates():
return Gates(
logger=MagicMock(),
notification_handler=MagicMock()
)
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_specific_variables_null_values_with_stop_policy_only(
filter_functions_mock,
gates
):
specific_variables_null_values_mock = MagicMock(return_value=True)
empty_data_mock = MagicMock(return_value=False)
def functions_side_effect(x):
if x == 'SPECIFIC_VARIABLES_NULL_VALUES':
return specific_variables_null_values_mock
return empty_data_mock
filter_functions_mock.__getitem__.side_effect = functions_side_effect
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'stop',
'VARIABLES': ['variable2']
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == ('stop', -1)
input_args = specific_variables_null_values_mock.call_args
assert input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert input_args[0][1] == input_data['filters']['SPECIFIC_VARIABLES_NULL_VALUES']
empty_data_mock.assert_not_called()
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_specific_variables_null_values_with_continue_policy_only(
filter_functions_mock,
gates
):
specific_variables_null_values_mock = MagicMock(return_value=True)
empty_data_mock = MagicMock(return_value=False)
def functions_side_effect(x):
if x == 'SPECIFIC_VARIABLES_NULL_VALUES':
return specific_variables_null_values_mock
return empty_data_mock
filter_functions_mock.__getitem__.side_effect = functions_side_effect
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'continue',
'VARIABLES': ['variable2']
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == ('continue', 2)
input_args = specific_variables_null_values_mock.call_args
assert input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert input_args[0][1] == input_data['filters']['SPECIFIC_VARIABLES_NULL_VALUES']
empty_data_mock.assert_not_called()
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_specific_variables_null_values_no_filtered(
filter_functions_mock,
gates
):
specific_variables_null_values_mock = MagicMock(return_value=False)
empty_data_mock = MagicMock(return_value=False)
def functions_side_effect(x):
if x == 'SPECIFIC_VARIABLES_NULL_VALUES':
return specific_variables_null_values_mock
return empty_data_mock
filter_functions_mock.__getitem__.side_effect = functions_side_effect
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'stop',
'VARIABLES': ['variable2']
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == (None, 0)
specific_variables_null_values_input_args = specific_variables_null_values_mock.call_args
assert specific_variables_null_values_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert specific_variables_null_values_input_args[0][
1] == input_data['filters']['SPECIFIC_VARIABLES_NULL_VALUES']
empty_data_mock.assert_not_called()
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_one_stop_policy(
filter_functions_mock,
gates
):
specific_variables_null_values_mock = MagicMock(return_value=True)
empty_data_mock = MagicMock(return_value=True)
def functions_side_effect(x):
if x == 'SPECIFIC_VARIABLES_NULL_VALUES':
return specific_variables_null_values_mock
return empty_data_mock
filter_functions_mock.__getitem__.side_effect = functions_side_effect
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'stop',
'VARIABLES': ['variable2']
},
'EMPTY_DATA': {
'POLICY': 'continue',
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == ('stop', -1)
specific_variables_null_values_input_args = specific_variables_null_values_mock.call_args
assert specific_variables_null_values_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert specific_variables_null_values_input_args[0][
1] == input_data['filters']['SPECIFIC_VARIABLES_NULL_VALUES']
empty_data_input_args = empty_data_mock.call_args
assert empty_data_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert empty_data_input_args[0][1] == input_data['filters']['EMPTY_DATA']
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_one_continue_policy(
filter_functions_mock,
gates
):
specific_variables_null_values_mock = MagicMock(return_value=False)
empty_data_mock = MagicMock(return_value=True)
def functions_side_effect(x):
if x == 'SPECIFIC_VARIABLES_NULL_VALUES':
return specific_variables_null_values_mock
return empty_data_mock
filter_functions_mock.__getitem__.side_effect = functions_side_effect
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'stop',
'VARIABLES': ['variable2']
},
'EMPTY_DATA': {
'POLICY': 'continue',
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == ('continue', 2)
specific_variables_null_values_input_args = specific_variables_null_values_mock.call_args
assert specific_variables_null_values_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert specific_variables_null_values_input_args[0][
1] == input_data['filters']['SPECIFIC_VARIABLES_NULL_VALUES']
empty_data_input_args = empty_data_mock.call_args
assert empty_data_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert empty_data_input_args[0][1] == input_data['filters']['EMPTY_DATA']
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_no_filtered(
filter_functions_mock,
gates
):
specific_variables_null_values_mock = MagicMock(return_value=False)
empty_data_mock = MagicMock(return_value=False)
def functions_side_effect(x):
if x == 'SPECIFIC_VARIABLES_NULL_VALUES':
return specific_variables_null_values_mock
return empty_data_mock
filter_functions_mock.__getitem__.side_effect = functions_side_effect
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'stop',
'VARIABLES': ['variable2']
},
'EMPTY_DATA': {
'POLICY': 'continue',
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == (None, 0)
specific_variables_null_values_input_args = specific_variables_null_values_mock.call_args
assert specific_variables_null_values_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
empty_data_input_args = empty_data_mock.call_args
assert empty_data_input_args[0][0].equals(DataFrame(
{'variable': ['variable1', 'variable2'], 'value': [1, 2]}))
assert empty_data_input_args[0][1] == input_data['filters']['EMPTY_DATA']
@mark.asyncio
@patch('laborious.activities.gates.filter_functions')
async def test_input_gate_error(
filter_functions_mock,
gates
):
filter_functions_mock.__getitem__.side_effect = KeyError('test')
input_data = {
'filters': {
'SPECIFIC_VARIABLES_NULL_VALUES': {
'POLICY': 'stop',
'VARIABLES': ['variable2']
}
},
'data': {
'variable': ['variable1', 'variable2'],
'value': [1, 2]
}
}
result = await gates.input_gate(input_data)
assert result == (None, 0)
gates.notification_handler.build_and_send_notification.assert_called_once_with(
notification_id='INTPUT_GATE_ERROR__SPECIFIC_VARIABLES_NULL_VALUES',
message="Error in filter SPECIFIC_VARIABLES_NULL_VALUES:{'POLICY': 'stop', 'VARIABLES': ['variable2']}: \n 'test'",
block='input_gate',
level=NotificationLevel.ERROR,
attachment_content=ANY
)