Skip to content

Commit

Permalink
Add feature flag API to Event
Browse files Browse the repository at this point in the history
  • Loading branch information
imjoehaines committed Jul 24, 2023
1 parent 9754c5b commit 6b7bf5d
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 2 deletions.
27 changes: 25 additions & 2 deletions bugsnag/event.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, Optional, List # noqa
from typing import Any, Dict, Optional, List, Union # noqa
import linecache
import logging
import os
Expand All @@ -14,6 +14,7 @@
from bugsnag.utils import fully_qualified_class_name as class_name
from bugsnag.utils import FilterDict, package_version, SanitizingJSONEncoder
from bugsnag.error import Error
from bugsnag.feature_flags import FeatureFlag, FeatureFlagDelegate

__all__ = ('Event',)

Expand Down Expand Up @@ -65,6 +66,7 @@ def __init__(self, exception: BaseException, config, request_config,
self._breadcrumbs = [
deepcopy(breadcrumb) for breadcrumb in config.breadcrumbs
]
self._feature_flag_delegate = FeatureFlagDelegate()

def get_config(key):
return options.pop(key, getattr(self.config, key))
Expand Down Expand Up @@ -237,6 +239,26 @@ def add_tab(self, name, dictionary):

self.metadata[name].update(dictionary)

@property
def feature_flags(self) -> List[FeatureFlag]:
return self._feature_flag_delegate.to_list()

def add_feature_flag(
self,
name: Union[str, bytes],
variant: Union[None, str, bytes] = None
) -> None:
self._feature_flag_delegate.add(name, variant)

def add_feature_flags(self, feature_flags: List[FeatureFlag]) -> None:
self._feature_flag_delegate.merge(feature_flags)

def clear_feature_flag(self, name: Union[str, bytes]) -> None:
self._feature_flag_delegate.remove(name)

def clear_feature_flags(self) -> None:
self._feature_flag_delegate.clear()

def _generate_error_list(
self,
exception: BaseException,
Expand Down Expand Up @@ -437,6 +459,7 @@ def _payload(self):
"session": self.session,
"breadcrumbs": [
breadcrumb.to_dict() for breadcrumb in self._breadcrumbs
]
],
"featureFlags": self._feature_flag_delegate.to_json()
}]
})
91 changes: 91 additions & 0 deletions tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from bugsnag.breadcrumbs import Breadcrumb, BreadcrumbType
from bugsnag.configuration import Configuration
from bugsnag.event import Event
from bugsnag.feature_flags import FeatureFlag
from tests import fixtures


Expand Down Expand Up @@ -448,3 +449,93 @@ def test_breadcrumb_array_is_always_in_payload(self):
payload = json.loads(event._payload())

assert payload['events'][0]['breadcrumbs'] == []

def test_feature_flags_can_be_added_individually(self):
config = Configuration()
event = self.event_class(Exception('oops'), config, {})

assert event.feature_flags == []

event.add_feature_flag('one')
event.add_feature_flag('two', 'a')
event.add_feature_flag('three', None)

assert event.feature_flags == [
FeatureFlag('one'),
FeatureFlag('two', 'a'),
FeatureFlag('three')
]

def test_feature_flags_can_be_added_in_bulk(self):
config = Configuration()
event = self.event_class(Exception('oops'), config, {})

assert event.feature_flags == []

event.add_feature_flags([
FeatureFlag('a', '1'),
FeatureFlag('b'),
FeatureFlag('c', '3')
])

assert event.feature_flags == [
FeatureFlag('a', '1'),
FeatureFlag('b'),
FeatureFlag('c', '3')
]

def test_feature_flags_can_be_removed_individually(self):
config = Configuration()
event = self.event_class(Exception('oops'), config, {})

assert event.feature_flags == []

event.add_feature_flags([
FeatureFlag('a', '1'),
FeatureFlag('b'),
FeatureFlag('c', '3')
])

event.clear_feature_flag('b')

assert event.feature_flags == [
FeatureFlag('a', '1'),
FeatureFlag('c', '3')
]

def test_feature_flags_can_be_cleared(self):
config = Configuration()
event = self.event_class(Exception('oops'), config, {})

assert event.feature_flags == []

event.add_feature_flags([
FeatureFlag('a', '1'),
FeatureFlag('b'),
FeatureFlag('c', '3')
])

event.clear_feature_flags()

assert event.feature_flags == []

def test_feature_flags_are_included_in_payload(self):
config = Configuration()
event = self.event_class(Exception('oops'), config, {})

assert event.feature_flags == []

event.add_feature_flags([
FeatureFlag('a', '1'),
FeatureFlag('b'),
FeatureFlag('c', '3')
])

payload = json.loads(event._payload())
feature_flags = payload['events'][0]['featureFlags']

assert feature_flags == [
{'name': 'a', 'variant': '1'},
{'name': 'b'},
{'name': 'c', 'variant': '3'}
]

0 comments on commit 6b7bf5d

Please sign in to comment.