Skip to content

Commit

Permalink
Merge pull request #135 from Flagsmith/release/2.1.0
Browse files Browse the repository at this point in the history
Release 2.1.0
  • Loading branch information
matthewelwell authored Jun 29, 2022
2 parents e4b543d + 1e126d3 commit c04eca1
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 66 deletions.
2 changes: 0 additions & 2 deletions flag_engine/api/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from flag_engine.environments.schemas import (
BaseEnvironmentAPIKeySchema,
BaseEnvironmentSchema,
WebhookSchema,
)
from flag_engine.features.schemas import (
BaseFeatureStateSchema,
Expand Down Expand Up @@ -140,7 +139,6 @@ class DjangoEnvironmentSchema(BaseEnvironmentSchema):
dump_only=True,
)
project = fields.Nested(DjangoProjectSchema, dump_only=True)
webhooks = DjangoRelatedManagerField(fields.Nested(WebhookSchema), required=False)

@pre_dump()
def set_environment_key_in_context(self, obj, *args, **kwargs):
Expand Down
5 changes: 1 addition & 4 deletions flag_engine/environments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ def is_valid(self):

@dataclass
class WebhookModel:
created_at: datetime
updated_at: datetime
url: str
secret: str
enabled: bool = True


@dataclass
Expand All @@ -45,7 +42,7 @@ class EnvironmentModel:
mixpanel_config: IntegrationModel = None
heap_config: IntegrationModel = None
dynatrace_config: IntegrationModel = None
webhooks: typing.List[WebhookModel] = field(default_factory=list)
webhook_config: WebhookModel = None

_INTEGRATION_ATTS = [
"amplitude_config",
Expand Down
7 changes: 1 addition & 6 deletions flag_engine/environments/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,8 @@ class Meta:


class WebhookSchema(LoadToModelSchema):
enabled = fields.Bool()
url = fields.URL()
secret = fields.Str()
created_at = fields.DateTime()
updated_at = fields.DateTime()

class Meta:
model_class = WebhookModel
Expand All @@ -46,14 +43,12 @@ class BaseEnvironmentSchema(Schema):
mixpanel_config = fields.Nested(IntegrationSchema, required=False, allow_none=True)
amplitude_config = fields.Nested(IntegrationSchema, required=False, allow_none=True)
dynatrace_config = fields.Nested(IntegrationSchema, required=False, allow_none=True)
webhook_config = fields.Nested(WebhookSchema, required=False, allow_none=True)


class EnvironmentSchema(LoadToModelMixin, BaseEnvironmentSchema):
feature_states = fields.List(fields.Nested(FeatureStateSchema))
project = fields.Nested(ProjectSchema)
webhooks = fields.List(
fields.Nested(WebhookSchema), required=False, allow_none=True
)

class Meta:
model_class = EnvironmentModel
Expand Down
46 changes: 25 additions & 21 deletions flag_engine/segments/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
import typing
from contextlib import suppress
from dataclasses import dataclass, field

import semver
Expand All @@ -23,28 +24,31 @@ class SegmentConditionModel:

def matches_trait_value(self, trait_value: typing.Any) -> bool:
# TODO: move this logic to the evaluator module
if type(self.value) is str and is_semver(self.value):
trait_value = semver.VersionInfo.parse(trait_value)
if self.operator in self.EXCEPTION_OPERATOR_METHODS:
evaluator_function = getattr(
self, self.EXCEPTION_OPERATOR_METHODS.get(self.operator)
with suppress(ValueError):
if type(self.value) is str and is_semver(self.value):
trait_value = semver.VersionInfo.parse(trait_value)
if self.operator in self.EXCEPTION_OPERATOR_METHODS:
evaluator_function = getattr(
self, self.EXCEPTION_OPERATOR_METHODS.get(self.operator)
)
return evaluator_function(trait_value)

matching_function_name = {
constants.EQUAL: "__eq__",
constants.GREATER_THAN: "__gt__",
constants.GREATER_THAN_INCLUSIVE: "__ge__",
constants.LESS_THAN: "__lt__",
constants.LESS_THAN_INCLUSIVE: "__le__",
constants.NOT_EQUAL: "__ne__",
constants.CONTAINS: "__contains__",
}.get(self.operator)
matching_function = getattr(
trait_value, matching_function_name, lambda v: False
)
return evaluator_function(trait_value)

matching_function_name = {
constants.EQUAL: "__eq__",
constants.GREATER_THAN: "__gt__",
constants.GREATER_THAN_INCLUSIVE: "__ge__",
constants.LESS_THAN: "__lt__",
constants.LESS_THAN_INCLUSIVE: "__le__",
constants.NOT_EQUAL: "__ne__",
constants.CONTAINS: "__contains__",
}.get(self.operator)
matching_function = getattr(
trait_value, matching_function_name, lambda v: False
)
to_same_type_as_trait_value = get_casting_function(trait_value)
return matching_function(to_same_type_as_trait_value(self.value))
to_same_type_as_trait_value = get_casting_function(trait_value)
return matching_function(to_same_type_as_trait_value(self.value))

return False

def evaluate_not_contains(self, trait_value: typing.Iterable) -> bool:
return self.value not in trait_value
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name="flagsmith-flag-engine",
version="2.0.7",
version="2.1.0",
author="Flagsmith",
author_email="[email protected]",
packages=find_packages(include=["flag_engine", "flag_engine.*"]),
Expand Down
17 changes: 3 additions & 14 deletions tests/mock_django_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,20 +204,9 @@ def all(self) -> typing.List[DjangoFeatureState]:


@dataclass
class DjangoWebhook:
class DjangoWebhookConfig:
url: str
secret: str
created_at: datetime = field(default_factory=utcnow_with_tz)
updated_at: datetime = field(default_factory=utcnow_with_tz)
enabled: bool = True


@dataclass
class DjangoWebhookRelatedManager:
webhooks: typing.List[DjangoWebhook]

def all(self) -> typing.List[DjangoWebhook]:
return self.webhooks


class DjangoEnvironment:
Expand All @@ -228,7 +217,7 @@ def __init__(
name: str = "Test Environment",
api_key: str = "api-key",
feature_states: typing.List[DjangoFeatureState] = None,
webhooks: typing.List[DjangoWebhook] = None,
webhook_config: DjangoWebhookConfig = None,
):
if feature_states:
assert not any(
Expand All @@ -240,7 +229,7 @@ def __init__(
self.api_key = api_key
self.project = project
self.feature_states = DjangoFeatureStateRelatedManager(feature_states or [])
self.webhooks = DjangoWebhookRelatedManager(webhooks or [])
self.webhook_config = webhook_config


@dataclass
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/api/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
DjangoSegmentCondition,
DjangoSegmentRule,
DjangoTrait,
DjangoWebhook,
DjangoWebhookConfig,
)


Expand Down Expand Up @@ -95,7 +95,7 @@ def django_multivariate_feature_state(django_project):

@pytest.fixture
def django_webhook():
return DjangoWebhook(url="https://my.webhook.com/hook", secret="secret!")
return DjangoWebhookConfig(url="https://my.webhook.com/hook", secret="secret!")


@pytest.fixture()
Expand All @@ -118,7 +118,7 @@ def django_environment(
django_multivariate_feature_state,
django_enabled_feature_state_with_string_value,
],
webhooks=[django_webhook],
webhook_config=django_webhook,
)


Expand Down
8 changes: 3 additions & 5 deletions tests/unit/api/test_document_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,9 @@ def test_build_environment_document(
)
)

assert len(environment_document["webhooks"]) == 1
serialized_webhook = environment_document["webhooks"][0]
assert serialized_webhook["enabled"] == django_webhook.enabled
assert serialized_webhook["url"] == django_webhook.url
assert serialized_webhook["secret"] == django_webhook.secret
assert environment_document["webhook_config"] is not None
assert environment_document["webhook_config"]["url"] == django_webhook.url
assert environment_document["webhook_config"]["secret"] == django_webhook.secret


def test_build_environment_api_key_document(django_environment_api_key):
Expand Down
16 changes: 6 additions & 10 deletions tests/unit/environments/test_environments_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
def test_build_environment_model():
"""Test to exercise the basic fields on the schema."""
# Given
webhook_url = "https://my.webhook.com/hook"
environment_dict = {
"id": 1,
"api_key": "api-key",
Expand All @@ -37,15 +38,10 @@ def test_build_environment_model():
"feature": {"id": 1, "name": "enabled_feature", "type": STANDARD},
}
],
"webhooks": [
{
"url": "https://my.webhook.com/hook",
"secret": "secret!",
"created_at": "2022-05-11T11:33:14.073487+00:00",
"updated_at": "2022-05-11T11:33:14.073487+00:00",
"enabled": True,
}
],
"webhook_config": {
"url": webhook_url,
"secret": "secret!",
},
}

# When
Expand All @@ -55,7 +51,7 @@ def test_build_environment_model():
assert environment_model

assert len(environment_model.feature_states) == 1
assert len(environment_model.webhooks) == 1
assert environment_model.webhook_config.url == webhook_url


def test_get_flags_for_environment_returns_feature_states_for_environment_dictionary():
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/segments/test_segments_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
(constants.EQUAL, "bar", "bar", True),
(constants.EQUAL, "bar", "baz", False),
(constants.EQUAL, 1, "1", True),
(constants.EQUAL, 1, "not_an_int", False),
(constants.EQUAL, 1, "2", False),
(constants.EQUAL, True, "True", True),
(constants.EQUAL, False, "False", True),
(constants.EQUAL, False, "True", False),
(constants.EQUAL, True, "False", False),
(constants.EQUAL, 1.23, "1.23", True),
(constants.EQUAL, 1.23, "not_a_float", False),
(constants.EQUAL, 1.23, "4.56", False),
(constants.GREATER_THAN, 2, "1", True),
(constants.GREATER_THAN, 1, "1", False),
Expand Down Expand Up @@ -75,6 +77,7 @@ def test_segment_condition_matches_trait_value(
"operator, trait_value, condition_value, expected_result",
[
(constants.EQUAL, "1.0.0", "1.0.0:semver", True),
(constants.EQUAL, "not_a_semver", "1.0.0:semver", False),
(constants.EQUAL, "1.0.0", "1.0.1:semver", False),
(constants.NOT_EQUAL, "1.0.0", "1.0.0:semver", False),
(constants.NOT_EQUAL, "1.0.0", "1.0.1:semver", True),
Expand Down

0 comments on commit c04eca1

Please sign in to comment.