Addressed comments in the PR.

This commit is contained in:
julio.oliveira 2024-01-22 15:19:37 -03:00
parent cbde1bebee
commit b14c447fcf
2 changed files with 34 additions and 7 deletions

View File

@ -130,20 +130,19 @@ class ConditionSet:
:param ruleset: A dictionary mapping a logical operator to a list of conditional rules :param ruleset: A dictionary mapping a logical operator to a list of conditional rules
""" """
def __init__(self, ruleset): def __init__(self, ruleset):
if type(ruleset) is not dict: if type(ruleset) is not dict:
raise ValueError(f"Ruleset must be a dictionary, not {type(ruleset)}.") raise ValueError(f"Ruleset must be a dictionary, not {type(ruleset)}.")
if len(ruleset) < 1:
raise ValueError(f"Ruleset must have exactly one logical operator (found {len(ruleset)})")
self.logic = None self.logic = None
# If logic type use it, else return the ruleset # If logic type use it, else return the ruleset
if len(ruleset) == 1: if len(ruleset) == 1:
logic = list(ruleset.keys())[0] logic = list(ruleset.keys())[0]
if logic.lower() in (AND, OR): if logic not in (AND, OR):
self.logic = logic.lower() raise ValueError(
else: f"Invalid logic type: {logic} (must be '{AND}' or '{OR}'). Please check documentation.")
raise ValueError(f"Invalid logic type: {logic} (must be '{AND}' or '{OR}')") self.logic = logic.lower()
# Compile the set of Conditions # Compile the set of Conditions
self.conditions = [ self.conditions = [
@ -151,7 +150,10 @@ class ConditionSet:
for rule in ruleset[self.logic] for rule in ruleset[self.logic]
] ]
else: else:
self.conditions = [Condition(**ruleset)] try:
self.conditions = [Condition(**ruleset)]
except TypeError:
raise ValueError(f"Incorrect key(s) informed. Please check documentation.")
def eval(self, data): def eval(self, data):
""" """

View File

@ -10,6 +10,7 @@ from django.http import HttpResponse
from django.urls import reverse from django.urls import reverse
from extras.choices import EventRuleActionChoices, ObjectChangeActionChoices from extras.choices import EventRuleActionChoices, ObjectChangeActionChoices
from extras.events import enqueue_object, flush_events, serialize_for_event from extras.events import enqueue_object, flush_events, serialize_for_event
from extras.forms import SavedFilterForm, EventRuleForm
from extras.models import EventRule, Tag, Webhook from extras.models import EventRule, Tag, Webhook
from extras.webhooks import generate_signature, send_webhook from extras.webhooks import generate_signature, send_webhook
from requests import Session from requests import Session
@ -442,3 +443,27 @@ class EventRuleTest(APITestCase):
# Evaluate the conditions (status NOT in ['planned, 'staging']) # Evaluate the conditions (status NOT in ['planned, 'staging'])
self.assertTrue(event_rule.eval_conditions(data)) self.assertTrue(event_rule.eval_conditions(data))
def test_event_rule_conditions_with_incorrect_key_must_return_false(self):
"""
Test Event Rule with incorrect condition (key "foo" is wrong). Must return false.
"""
ct = ContentType.objects.get(app_label='extras', model='webhook')
site_ct = ContentType.objects.get_for_model(Site)
webhook = Webhook.objects.create(name='Webhook 100', payload_url='http://example.com/?1', http_method='POST')
form = EventRuleForm({
"name": "Event Rule 1",
"type_create": True,
"type_update": True,
"action_object_type": ct.pk,
"action_type": "webhook",
"action_choice": webhook.pk,
"content_types": [site_ct.pk],
"conditions": {
"foo": "status.value",
"value": "active"
}
})
self.assertFalse(form.is_valid())