def test_permalink(self): group = self.create_group() result = serialize(group, self.user, serializer=GroupSerializerSnuba()) assert "http://" in result["permalink"] assert f"{group.organization.slug}/issues/{group.id}" in result["permalink"]
def test_permalink_outside_org(self): outside_user = self.create_user() group = self.create_group() result = serialize(group, outside_user, serializer=GroupSerializerSnuba()) assert result["permalink"] is None
def test_get_start_from_seen_stats(self): for days, expected in [(None, 30), (0, 14), (1000, 90)]: last_seen = None if days is None else before_now(days=days).replace(tzinfo=pytz.UTC) start = GroupSerializerSnuba._get_start_from_seen_stats({"": {"last_seen": last_seen}}) assert iso_format(start) == iso_format(before_now(days=expected))
def test_seen_stats(self): environment = self.create_environment(project=self.project) environment2 = self.create_environment(project=self.project) events = [] for event_id, env, user_id, timestamp in [ ("a" * 32, environment, 1, iso_format(self.min_ago)), ("b" * 32, environment, 2, iso_format(self.min_ago)), ("c" * 32, environment2, 3, iso_format(self.week_ago)), ]: events.append( self.store_event( data={ "event_id": event_id, "fingerprint": ["put-me-in-group1"], "timestamp": timestamp, "environment": env.name, "user": {"id": user_id}, }, project_id=self.project.id, ) ) # Assert all events are in the same group (group_id,) = {e.group.id for e in events} group = Group.objects.get(id=group_id) group.times_seen = 3 group.first_seen = self.week_ago - timedelta(days=5) group.last_seen = self.week_ago group.save() # should use group columns when no environments arg passed result = serialize(group, serializer=GroupSerializerSnuba(environment_ids=[])) assert result["count"] == "3" assert iso_format(result["lastSeen"]) == iso_format(self.min_ago) assert result["firstSeen"] == group.first_seen # update this to something different to make sure it's being used group_env = GroupEnvironment.objects.get(group_id=group_id, environment_id=environment.id) group_env.first_seen = self.day_ago - timedelta(days=3) group_env.save() group_env2 = GroupEnvironment.objects.get(group_id=group_id, environment_id=environment2.id) result = serialize( group, serializer=GroupSerializerSnuba(environment_ids=[environment.id, environment2.id]), ) assert result["count"] == "3" # result is rounded down to nearest second assert iso_format(result["lastSeen"]) == iso_format(self.min_ago) assert iso_format(result["firstSeen"]) == iso_format(group_env.first_seen) assert iso_format(group_env2.first_seen) > iso_format(group_env.first_seen) assert result["userCount"] == 3 result = serialize( group, serializer=GroupSerializerSnuba( environment_ids=[environment.id, environment2.id], start=self.week_ago - timedelta(hours=1), end=self.week_ago + timedelta(hours=1), ), ) assert result["userCount"] == 1 assert iso_format(result["lastSeen"]) == iso_format(self.week_ago) assert iso_format(result["firstSeen"]) == iso_format(self.week_ago) assert result["count"] == "1"
def test_no_user_unsubscribed(self): group = self.create_group() result = serialize(group, serializer=GroupSerializerSnuba()) assert not result["isSubscribed"]
def test_implicit_subscribed(self): user = self.create_user() group = self.create_group() combinations = ( # (default, project, subscribed, has_details) ( NotificationSettingOptionValues.ALWAYS, NotificationSettingOptionValues.DEFAULT, True, False, ), ( NotificationSettingOptionValues.ALWAYS, NotificationSettingOptionValues.ALWAYS, True, False, ), ( NotificationSettingOptionValues.ALWAYS, NotificationSettingOptionValues.SUBSCRIBE_ONLY, False, False, ), ( NotificationSettingOptionValues.ALWAYS, NotificationSettingOptionValues.NEVER, False, True, ), ( NotificationSettingOptionValues.DEFAULT, NotificationSettingOptionValues.DEFAULT, False, False, ), ( NotificationSettingOptionValues.SUBSCRIBE_ONLY, NotificationSettingOptionValues.DEFAULT, False, False, ), ( NotificationSettingOptionValues.SUBSCRIBE_ONLY, NotificationSettingOptionValues.ALWAYS, True, False, ), ( NotificationSettingOptionValues.SUBSCRIBE_ONLY, NotificationSettingOptionValues.SUBSCRIBE_ONLY, False, False, ), ( NotificationSettingOptionValues.SUBSCRIBE_ONLY, NotificationSettingOptionValues.NEVER, False, True, ), ( NotificationSettingOptionValues.NEVER, NotificationSettingOptionValues.DEFAULT, False, True, ), ( NotificationSettingOptionValues.NEVER, NotificationSettingOptionValues.ALWAYS, True, False, ), ( NotificationSettingOptionValues.NEVER, NotificationSettingOptionValues.SUBSCRIBE_ONLY, False, False, ), ( NotificationSettingOptionValues.NEVER, NotificationSettingOptionValues.NEVER, False, True, ), ) for default_value, project_value, is_subscribed, has_details in combinations: UserOption.objects.clear_local_cache() NotificationSetting.objects.update_settings( ExternalProviders.EMAIL, NotificationSettingTypes.WORKFLOW, default_value, user=user, ) NotificationSetting.objects.update_settings( ExternalProviders.EMAIL, NotificationSettingTypes.WORKFLOW, project_value, user=user, project=group.project, ) result = serialize(group, user, serializer=GroupSerializerSnuba()) subscription_details = result.get("subscriptionDetails") assert result["isSubscribed"] is is_subscribed assert ( subscription_details == {"disabled": True} if has_details else subscription_details is None )
def test_implicit_subscribed(self): user = self.create_user() group = self.create_group() combinations = ( # ((default, project), (subscribed, details)) ((UserOptionValue.all_conversations, None), (True, None)), ((UserOptionValue.all_conversations, UserOptionValue.all_conversations), (True, None)), ( (UserOptionValue.all_conversations, UserOptionValue.participating_only), (False, None), ), ( (UserOptionValue.all_conversations, UserOptionValue.no_conversations), (False, { "disabled": True }), ), ((None, None), (False, None)), ((UserOptionValue.participating_only, None), (False, None)), ((UserOptionValue.participating_only, UserOptionValue.all_conversations), (True, None)), ( (UserOptionValue.participating_only, UserOptionValue.participating_only), (False, None), ), ( (UserOptionValue.participating_only, UserOptionValue.no_conversations), (False, { "disabled": True }), ), ((UserOptionValue.no_conversations, None), (False, { "disabled": True })), ((UserOptionValue.no_conversations, UserOptionValue.all_conversations), (True, None)), ((UserOptionValue.no_conversations, UserOptionValue.participating_only), (False, None)), ( (UserOptionValue.no_conversations, UserOptionValue.no_conversations), (False, { "disabled": True }), ), ) def maybe_set_value(project, value): if value is not None: UserOption.objects.set_value(user=user, project=project, key="workflow:notifications", value=value) else: UserOption.objects.unset_value(user=user, project=project, key="workflow:notifications") for options, (is_subscribed, subscription_details) in combinations: default_value, project_value = options UserOption.objects.clear_local_cache() maybe_set_value(None, default_value) maybe_set_value(group.project, project_value) result = serialize(group, user, serializer=GroupSerializerSnuba()) assert result["isSubscribed"] is is_subscribed assert result.get("subscriptionDetails") == subscription_details