Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat(notifications): open_period_start_for_group util for threads #83689

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
27 changes: 27 additions & 0 deletions src/sentry/notifications/utils/open_period.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from datetime import datetime

from sentry.models.activity import Activity, ActivityType
from sentry.models.group import Group


def open_period_start_for_group(group: Group) -> datetime | None:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open to moving this somewhere else, i think we should have a single place where we store these types of utils to work with Open Periods for notifications/issue platform.

as we figure out what types of methods exist, we can start bringing them together, open to leaving this as a todo

"""
Get the start of the open period for a group.
This is the last activity of the group that is not a resolution or the first_seen of the group.
We need to check the first seen since we don't create an activity when the group is created.
"""

# Get the last activity of the group
latest_unresolved_activity: Activity | None = (
Activity.objects.filter(
group=group,
type=ActivityType.SET_UNRESOLVED.value,
)
.order_by("-datetime")
.first()
)

if latest_unresolved_activity:
return latest_unresolved_activity.datetime

return group.first_seen
69 changes: 69 additions & 0 deletions tests/sentry/notifications/utils/test_open_period.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from django.utils import timezone

from sentry.models.activity import Activity
from sentry.models.group import GroupStatus
from sentry.notifications.utils.open_period import open_period_start_for_group
from sentry.testutils.cases import TestCase
from sentry.types.activity import ActivityType


class OpenPeriodTestCase(TestCase):
def setUp(self):
self.group = self.create_group()

def test_new_group_returns_first_seen(self) -> None:
"""Test that a new group returns first_seen as the open period start"""
start = open_period_start_for_group(self.group)
assert start == self.group.first_seen

def test_unresolved_group_returns_unresolved_activity(self) -> None:
"""Test that a group with unresolved activity returns that activity time"""
# First resolve the group
self.group.status = GroupStatus.RESOLVED
self.group.save()
resolved_time = timezone.now()
Activity.objects.create(
group=self.group,
project=self.group.project,
type=ActivityType.SET_RESOLVED.value,
datetime=resolved_time,
)

# Then unresolve it
unresolved_time = timezone.now()
self.group.status = GroupStatus.UNRESOLVED
self.group.save()
unresolved_activity = Activity.objects.create(
group=self.group,
project=self.group.project,
type=ActivityType.SET_UNRESOLVED.value,
datetime=unresolved_time,
)

start = open_period_start_for_group(self.group)
assert start is not None
assert start == unresolved_activity.datetime

def test_multiple_unresolved_returns_latest(self) -> None:
"""Test that with multiple unresolved activities, we get the latest one"""
# Create first unresolved activity
first_unresolved = timezone.now()
Activity.objects.create(
group=self.group,
project=self.group.project,
type=ActivityType.SET_UNRESOLVED.value,
datetime=first_unresolved,
)

# Create second unresolved activity
second_unresolved = timezone.now()
second_activity = Activity.objects.create(
group=self.group,
project=self.group.project,
type=ActivityType.SET_UNRESOLVED.value,
datetime=second_unresolved,
)

start = open_period_start_for_group(self.group)
assert start is not None
assert start == second_activity.datetime
Loading