Skip to content

Commit

Permalink
fix: add regex and negation options for conditional profiles (#48)
Browse files Browse the repository at this point in the history
fix: add unit test for conditional profile negation

fix: update backend unit test
  • Loading branch information
wojtekzyla committed Sep 15, 2023
1 parent 3e68a2f commit a34ab61
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 19 deletions.
17 changes: 12 additions & 5 deletions backend/SC4SNMP_UI_backend/common/backend_ui_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def __init__(self, *args, **kwargs):
"lt": "less than",
"gt": "greater than",
"equals": "equals",
"in": "in"
"in": "in",
"regex": "regex"
}
self.__ui2backend_conditional_operations = {}
for key, value in self.__backend2ui_conditional_operations.items():
Expand Down Expand Up @@ -107,14 +108,15 @@ def backend2ui(self, document: dict, **kwargs):
for back_condition in document[profile_name]["conditions"]:
field = back_condition["field"]
operation = self.__backend2ui_conditional_operations[back_condition["operation"]]
negate_operation = back_condition.get("negate_operation", False)
value = []
if operation == "in":
for v in back_condition["value"]:
value.append(str(v))
else:
value.append(str(back_condition["value"]))
conditional.append(
{"field": field, "operation": operation, "value": value}
{"field": field, "operation": operation, "value": value, "negateOperation": negate_operation}
)
conditions = {
"condition": "conditional",
Expand Down Expand Up @@ -160,9 +162,14 @@ def ui2backend(self, document: dict, **kwargs):
value.append(string_value_to_numeric(v))
else:
value = string_value_to_numeric(ui_condition["value"][0])
conditions.append(
{"field": field, "operation": operation, "value": value}
)
if ui_condition["negateOperation"]:
conditions.append(
{"field": field, "operation": operation, "value": value, "negate_operation": True}
)
else:
conditions.append(
{"field": field, "operation": operation, "value": value}
)
elif document['conditions']['condition'] != "standard":
condition = {
'type': document['conditions']['condition']
Expand Down
12 changes: 6 additions & 6 deletions backend/tests/common/test_backend_ui_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ def setUpClass(cls):
"field": "",
"patterns": [],
"conditions": [
{"field": "field: IF-MIB.ifAdminStatus", "operation": "in", "value":["0", "down"]},
{"field": "field: IF-MIB.ifOperStatus", "operation": "equals", "value": ["up"]},
{"field": "field: IF-MIB.ifIndex", "operation": "less than", "value": ["3"]},
{"field": "field: IF-MIB.ifIndex", "operation": "greater than", "value": ["5"]}
{"field": "field: IF-MIB.ifAdminStatus", "operation": "in", "value":["0", "down"], 'negateOperation': False,},
{"field": "field: IF-MIB.ifOperStatus", "operation": "equals", "value": ["up"], 'negateOperation': True,},
{"field": "field: IF-MIB.ifIndex", "operation": "less than", "value": ["3"], 'negateOperation': False,},
{"field": "field: IF-MIB.ifIndex", "operation": "greater than", "value": ["5"], 'negateOperation': True,}
]
},
"varBinds": [{"component": "IF-MIB", "object": "ifInDiscards", "index": "1"},
Expand Down Expand Up @@ -123,9 +123,9 @@ def setUpClass(cls):
"frequency": 30,
"conditions": [
{"field": "field: IF-MIB.ifAdminStatus", "operation": "in", "value": [0, "down"]},
{"field": "field: IF-MIB.ifOperStatus", "operation": "equals", "value": "up"},
{"field": "field: IF-MIB.ifOperStatus", "operation": "equals", "value": "up", 'negate_operation': True},
{"field": "field: IF-MIB.ifIndex", "operation": "lt", "value": 3},
{"field": "field: IF-MIB.ifIndex", "operation": "gt", "value": 5}
{"field": "field: IF-MIB.ifIndex", "operation": "gt", "value": 5, 'negate_operation': True}
],
"varBinds": [["IF-MIB", "ifInDiscards", "1"], ["IF-MIB"], ["IF-MIB", "ifOutErrors"]]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {useProfileContext} from "../../store/profile-contxt";
import {validationGroup, validationMessage} from "../../styles/ValidationStyles";
import {useProfilesValidationContxt} from "../../store/profiles-validation-contxt";
import ConditionalIn from "./ConditionalIn";
import Switch from '@splunk/react-ui/Switch';

function Conditional(props){
const ProfCtx = useProfileContext();
Expand Down Expand Up @@ -93,13 +94,20 @@ function Conditional(props){
const newIndex = rowItems.length;
const keyID = createDOMID();
const conditionalCopy = ProfCtx.conditional;
conditionalCopy.push({field: "", operation: "equals", value: [""]});
conditionalCopy.push({field: "", operation: "equals", value: [""], negateOperation: false});
indicesCopy[`${keyID}`] = newIndex;
setIndices(indicesCopy);
ProfCtx.setConditional(conditionalCopy);
setReload((prev)=>{return !prev});
};

const handleNegation = (index) => {
const conditionalCopy = ProfCtx.conditional;
conditionalCopy[index].negateOperation = !conditionalCopy[index].negateOperation
ProfCtx.setConditional(conditionalCopy);
setReload((prev)=>{return !prev});
}

const loadFormRows = () => {
let index = -1;
const newIndices = {};
Expand All @@ -125,6 +133,7 @@ function Conditional(props){
<Select.Option data-test="sc4snmp:form:conditional-equals" label="equals" value="equals"/>
<Select.Option data-test="sc4snmp:form:conditional-lt" label="less than" value="less than"/>
<Select.Option data-test="sc4snmp:form:conditional-gt" label="greater than" value="greater than"/>
<Select.Option data-test="sc4snmp:form:conditional-regex" label="regex" value="regex"/>
<Select.Option data-test="sc4snmp:form:conditional-in" label="in" value="in"/>
</Select>
<P/>
Expand All @@ -149,6 +158,15 @@ function Conditional(props){
</div>
)
}
<Switch
data-test="sc4snmp:conditional-negation"
value="statementNegation"
onClick={() => handleNegation(newIndices[`${keyID}`])}
selected={condition.negateOperation}
appearance="toggle"
>
Statement negation
</Switch>
</Card.Body>
</Card>
</FormRows.Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ import React from 'react';

const sameConditions = (configuredConditions, fieldName, newConditionKeys) => {
/*
configuredConditions: {"fieldName1": [["fieldName1", "value1"], ["fieldName1", "value2", "value3"]]}
configuredConditions: {"fieldName1": [["fieldName1", "value1", "<operation_type>"], ["fieldName1", "value2", "value3", "<operation_type>"]]}
fieldName: "fieldName1"
newConditionKeys: ["fieldName1", "value5"]
newConditionKeys: ["fieldName1", "value5", "<operation_type>"]
*/
let result = false;
if (fieldName in configuredConditions && fieldName.length > 0){
for (const keys of configuredConditions[fieldName]){
if (keys.length === newConditionKeys.length){
return keys.every(element => {
return !!newConditionKeys.includes(element);
result = keys.every((element, i) => {
return !!newConditionKeys.includes(element) && !!keys.includes(newConditionKeys[i]);
});
}
return false
}
} else{
console.log("fieldName not in configuredConditions")
return false
}
return result;
}

const validateProfiles = (validationObj) => {
Expand Down Expand Up @@ -145,7 +145,8 @@ const validateProfiles = (validationObj) => {
fieldKey = `${field}`;
conditionKeys = [fieldKey];
values.forEach(v => {conditionKeys.push(`${v}`)});
conditionKeys.push(validationObj.conditions.conditions[i].operation)
conditionKeys.push(validationObj.conditions.conditions[i].operation);
conditionKeys.push(`negateOperation=${validationObj.conditions.conditions[i].negateOperation}`);
if (sameConditions(configuredConditions, fieldKey, conditionKeys)){
message = "The same condition has been already configured for this profile"
if (i in errors.varBinds){
Expand Down
37 changes: 37 additions & 0 deletions frontend/packages/manager/src/tests/AddProfileModal.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -453,4 +453,41 @@ describe("AddProfileModal", () => {
const sameConditionalError = screen.getByDataTest("sc4snmp:conditional-condition-error")
expect(sameConditionalError.textContent).toBe("The same value has been already configured for this condition")
})

it("Test statement negation makes two profiles different", async () => {
renderModal({profileType: "conditional"})
const submitButton = screen.getByDataTest("sc4snmp:form:submit-form-button");
const addConditionalButton = screen.getByDataTest("sc4snmp:form:add-conditional-profile").querySelector(`[data-test="add-row"]`)

fireEvent.click(addConditionalButton);
fireEvent.click(addConditionalButton);
await sleep(10)

const fieldInput0 =
screen.getAllByDataTest("sc4snmp:form:conditional-field")[0].querySelector('[data-test="textbox"]')
const valueInput0 =
screen.getAllByDataTest("sc4snmp:form:conditional-condition")[0].querySelector('[data-test="textbox"]')
fireEvent.change(fieldInput0, {target: {value: "test"}})
fireEvent.change(valueInput0, {target: {value: "a"}})

const fieldInput1 =
screen.getAllByDataTest("sc4snmp:form:conditional-field")[1].querySelector('[data-test="textbox"]')
const valueInput1 =
screen.getAllByDataTest("sc4snmp:form:conditional-condition")[1].querySelector('[data-test="textbox"]')
fireEvent.change(fieldInput1, {target: {value: "test"}})
fireEvent.change(valueInput1, {target: {value: "a"}})

fireEvent.click(submitButton)
await sleep(5);

expect(screen.queryByText("The same condition has been already configured for this profile")).toBeInTheDocument();

const negation0 = screen.getAllByDataTest("sc4snmp:conditional-negation")[0].querySelector('[data-test="button"]')
fireEvent.click(negation0)
await sleep(5);
fireEvent.click(submitButton)
await sleep(5);

expect(screen.queryByText("The same condition has been already configured for this profile")).not.toBeInTheDocument();
})
})

0 comments on commit a34ab61

Please sign in to comment.