Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions api/tests/unit/util/mappers/test_unit_mappers_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,65 @@ def test_map_environment_to_engine__multiple_segments_and_versions__returns_expe
assert segment_featurestate.uuid not in segment_feature_state_uuids


def test_map_environment_to_engine__feature_specific_segment_not_in_env__excludes_segment(
environment: Environment,
feature: "Feature",
feature_specific_segment: Segment,
) -> None:
# Given
# `feature_specific_segment` has no `FeatureSegment` pointing at it
# in this environment, so it has no evaluation path here.

# When
result = engine.map_environment_to_engine(environment)

# Then
segment_ids = [s.id for s in result.project.segments]
assert feature_specific_segment.id not in segment_ids


def test_map_environment_to_engine__feature_specific_segment_in_env__includes_segment(
environment: Environment,
feature: "Feature",
feature_specific_segment: Segment,
) -> None:
# Given
feature_segment = FeatureSegment.objects.create(
feature=feature,
segment=feature_specific_segment,
environment=environment,
)
FeatureState.objects.create(
feature_segment=feature_segment,
feature=feature,
environment=environment,
)

# When
result = engine.map_environment_to_engine(environment)

# Then
segment_ids = [s.id for s in result.project.segments]
assert feature_specific_segment.id in segment_ids


def test_map_environment_to_engine__project_wide_segment_not_in_env__includes_segment(
environment: Environment,
segment: Segment,
) -> None:
# Given
# `segment` is a project-wide segment (Segment.feature_id IS NULL)
# with no `FeatureSegment` in this environment. Project-wide segments
# must remain in the environment document regardless.

# When
result = engine.map_environment_to_engine(environment)

# Then
segment_ids = [s.id for s in result.project.segments]
assert segment.id in segment_ids


def test_map_environment_api_key_to_engine__valid_key__returns_expected_model(
environment: Environment,
environment_api_key: "EnvironmentAPIKey",
Expand Down
17 changes: 13 additions & 4 deletions api/util/mappers/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,6 @@ def map_environment_to_engine(
ps for ps in project.segments.all() if ps.id == ps.version_of_id
]

project_segment_rules_by_segment_id: Dict[
int,
Iterable["SegmentRule"],
] = {segment.pk: segment.rules.all() for segment in project_segments}
project_segment_feature_states_by_segment_id = _get_segment_feature_states(
project_segments,
environment.pk,
Expand All @@ -229,6 +225,19 @@ def map_environment_to_engine(
else []
),
)
# Drop feature-specific segments that have no FeatureSegment in this
# environment — without one, they have no evaluation path here, and
# their rules only inflate the environment document.
project_segments = [
ps
for ps in project_segments
if ps.feature_id is None
or project_segment_feature_states_by_segment_id.get(ps.pk)
]
project_segment_rules_by_segment_id: Dict[
int,
Iterable["SegmentRule"],
] = {segment.pk: segment.rules.all() for segment in project_segments}
environment_feature_states: List["FeatureState"] = _get_prioritised_feature_states(
[
feature_state
Expand Down
Loading