Skip to content

Commit

Permalink
Merge pull request #116 from Flagsmith/release/3.0.0
Browse files Browse the repository at this point in the history
Release 3.0.0
  • Loading branch information
gagantrivedi authored Nov 11, 2022
2 parents 1670282 + a25f0a6 commit f74fd37
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions flag_engine/environments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class EnvironmentModel:
project: ProjectModel
feature_states: typing.List[FeatureStateModel] = field(default_factory=list)
allow_client_traits: bool = True
updated_at: datetime = field(default_factory=utcnow_with_tz)

amplitude_config: IntegrationModel = None
segment_config: IntegrationModel = None
Expand Down
1 change: 1 addition & 0 deletions flag_engine/environments/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class BaseEnvironmentSchema(Schema):
id = fields.Int()
api_key = fields.Str()
allow_client_traits = fields.Bool(required=False, default=True)
updated_at = fields.DateTime()

segment_config = fields.Nested(IntegrationSchema, required=False, allow_none=True)
heap_config = fields.Nested(IntegrationSchema, required=False, allow_none=True)
Expand Down
18 changes: 13 additions & 5 deletions flag_engine/identities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,25 @@ def composite_key(self) -> str:
def generate_composite_key(env_key: str, identifier: str) -> str:
return f"{env_key}_{identifier}"

def update_traits(self, traits: typing.List[TraitModel]) -> typing.List[TraitModel]:
def update_traits(
self, traits: typing.List[TraitModel]
) -> typing.Tuple[typing.List[TraitModel], bool]:
existing_traits = {trait.trait_key: trait for trait in self.identity_traits}
traits_changed = False

for trait in traits:
if trait.trait_value is None:
existing_traits.pop(trait.trait_key, None)
else:
existing_trait = existing_traits.get(trait.trait_key)

if trait.trait_value is None and existing_trait:
existing_traits.pop(trait.trait_key)
traits_changed = True

elif getattr(existing_trait, "trait_value", None) != trait.trait_value:
existing_traits[trait.trait_key] = trait
traits_changed = True

self.identity_traits = list(existing_traits.values())
return self.identity_traits
return self.identity_traits, traits_changed

def prune_features(self, valid_feature_names: typing.List[str]) -> None:
self.identity_features = IdentityFeaturesList(
Expand Down
1 change: 1 addition & 0 deletions flag_engine/projects/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ class ProjectModel:
organisation: OrganisationModel
hide_disabled_flags: bool
segments: typing.List[SegmentModel] = field(default_factory=list)
enable_realtime_updates: bool = False
1 change: 1 addition & 0 deletions flag_engine/projects/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class BaseProjectSchema(Schema):
name = fields.Str()
organisation = fields.Nested(OrganisationSchema)
hide_disabled_flags = fields.Bool()
enable_realtime_updates = fields.Bool()


class ProjectSchema(LoadToModelMixin, BaseProjectSchema):
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.3.0",
version="3.0.0",
author="Flagsmith",
author_email="[email protected]",
packages=find_packages(include=["flag_engine", "flag_engine.*"]),
Expand Down
32 changes: 29 additions & 3 deletions tests/unit/identities/test_identities_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ def test_update_traits_remove_traits_with_none_value(identity_in_segment):
trait_to_remove = TraitModel(trait_key=trait_key, trait_value=None)

# When
updated_traits = identity_in_segment.update_traits([trait_to_remove])
updated_traits, traits_updated = identity_in_segment.update_traits(
[trait_to_remove]
)

# Then
assert identity_in_segment.identity_traits == updated_traits == []
assert traits_updated is True


def test_update_identity_traits_updates_trait_value(identity_in_segment):
Expand All @@ -57,25 +60,48 @@ def test_update_identity_traits_updates_trait_value(identity_in_segment):
trait_to_update = TraitModel(trait_key=trait_key, trait_value=trait_value)

# When
updated_traits = identity_in_segment.update_traits([trait_to_update])
updated_traits, traits_updated = identity_in_segment.update_traits(
[trait_to_update]
)

# Then
assert updated_traits == identity_in_segment.identity_traits
assert len(identity_in_segment.identity_traits) == 1
assert identity_in_segment.identity_traits[0] == trait_to_update
assert traits_updated is True


def test_update_traits_adds_new_traits(identity_in_segment):
# Given
new_trait = TraitModel(trait_key="new_key", trait_value="foobar")

# When
updated_traits = identity_in_segment.update_traits([new_trait])
updated_traits, traits_updated = identity_in_segment.update_traits([new_trait])

# Then
assert updated_traits == identity_in_segment.identity_traits
assert len(identity_in_segment.identity_traits) == 2
assert new_trait in identity_in_segment.identity_traits
assert traits_updated is True


def test_update_traits_returns_false_if_traits_are_not_updated(identity_in_segment):
# Given
trait_key = identity_in_segment.identity_traits[0].trait_key
trait_value = identity_in_segment.identity_traits[0].trait_value

trait_to_update = TraitModel(trait_key=trait_key, trait_value=trait_value)

# When
updated_traits, traits_updated = identity_in_segment.update_traits(
[trait_to_update]
)

# Then
assert updated_traits == identity_in_segment.identity_traits
assert len(identity_in_segment.identity_traits) == 1
assert identity_in_segment.identity_traits[0] == trait_to_update
assert traits_updated is False


def test_appending_feature_states_raises_duplicate_feature_state_if_fs_for_the_feature_already_exists(
Expand Down

0 comments on commit f74fd37

Please sign in to comment.