analytics: Support DM groups in count message type query.

To maintain API compatibility during and after the migration to direct
message groups for 1:1 and self messages, update the analytics count
query to treat DM groups of size 2 or less as private messages.
This commit is contained in:
Mohammad Reza Kianifar
2025-07-20 00:54:00 +00:00
committed by Tim Abbott
parent 021d6cb169
commit 2aad468807
2 changed files with 57 additions and 3 deletions

View File

@@ -631,9 +631,9 @@ def count_message_type_by_user_query(realm: Realm | None) -> QueryFn:
(
SELECT zerver_userprofile.realm_id, zerver_userprofile.id, count(*),
CASE WHEN
zerver_recipient.type = 1 THEN 'private_message'
zerver_recipient.type = 1 OR (zerver_recipient.type = 3 AND zerver_huddle.group_size <= 2) THEN 'private_message'
WHEN
zerver_recipient.type = 3 THEN 'huddle_message'
zerver_recipient.type = 3 AND zerver_huddle.group_size > 2 THEN 'huddle_message'
WHEN
zerver_stream.invite_only = TRUE THEN 'private_stream'
ELSE 'public_stream'
@@ -650,12 +650,15 @@ def count_message_type_by_user_query(realm: Realm | None) -> QueryFn:
JOIN zerver_recipient
ON
zerver_message.recipient_id = zerver_recipient.id
LEFT JOIN zerver_huddle
ON
zerver_recipient.type_id = zerver_huddle.id
LEFT JOIN zerver_stream
ON
zerver_recipient.type_id = zerver_stream.id
GROUP BY
zerver_userprofile.realm_id, zerver_userprofile.id,
zerver_recipient.type, zerver_stream.invite_only
zerver_recipient.type, zerver_stream.invite_only, zerver_huddle.group_size
) AS subquery
GROUP BY realm_id, id, message_type
"""

View File

@@ -72,6 +72,7 @@ from zerver.models import (
from zerver.models.clients import get_client
from zerver.models.messages import Attachment
from zerver.models.realm_audit_logs import AuditLogEventType
from zerver.models.recipients import get_or_create_direct_message_group
from zerver.models.scheduled_jobs import NotificationTriggers
from zerver.models.users import get_user_by_delivery_email, is_cross_realm_bot_email
from zilencer.models import (
@@ -717,6 +718,56 @@ class TestCountStats(AnalyticsTestCase):
)
self.assertTableState(StreamCount, [], [])
def test_1_to_1_and_self_messages_sent_by_message_type_using_direct_group_message(self) -> None:
stat = COUNT_STATS["messages_sent:message_type:day"]
self.current_property = stat.property
user1 = self.create_user(is_bot=True)
user2 = self.create_user()
user3 = self.create_user()
user1_and_user2_dm_group = get_or_create_direct_message_group([user1.id, user2.id])
user2_and_user3_dm_group = get_or_create_direct_message_group([user2.id, user3.id])
user2_dm_group = get_or_create_direct_message_group([user2.id])
assert user1_and_user2_dm_group.recipient is not None
assert user2_and_user3_dm_group.recipient is not None
assert user2_dm_group.recipient is not None
self.create_message(user1, user1_and_user2_dm_group.recipient)
self.create_message(user2, user2_and_user3_dm_group.recipient)
self.create_message(user2, user2_dm_group.recipient)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO)
self.assertTableState(
UserCount,
["value", "subgroup", "user"],
[
[1, "private_message", user1],
[2, "private_message", user2],
[1, "public_stream", self.hourly_user],
[1, "public_stream", self.daily_user],
],
)
self.assertTableState(
RealmCount,
["value", "subgroup", "realm"],
[
[3, "private_message"],
[2, "public_stream", self.second_realm],
],
)
self.assertTableState(
InstallationCount,
["value", "subgroup"],
[
[3, "private_message"],
[2, "public_stream"],
],
)
self.assertTableState(StreamCount, [], [])
def test_messages_sent_by_message_type_realm_constraint(self) -> None:
# For single Realm