import/export: Add UserStatus table.

(We support both realm and single-user exports.)
This commit is contained in:
Steve Howell
2021-12-05 12:42:04 +00:00
committed by Tim Abbott
parent 45addcd506
commit 4088be6017
4 changed files with 58 additions and 4 deletions

View File

@@ -62,6 +62,7 @@ from zerver.models import (
UserMessage,
UserPresence,
UserProfile,
UserStatus,
UserTopic,
get_display_recipient,
get_realm,
@@ -238,8 +239,6 @@ NON_EXPORTED_TABLES = {
"zerver_defaultstreamgroup",
"zerver_defaultstreamgroup_streams",
"zerver_submessage",
# This is low priority, since users can easily just reset themselves to away.
"zerver_userstatus",
# Drafts don't need to be exported as they are supposed to be more ephemeral.
"zerver_draft",
# For any tables listed below here, it's a bug that they are not present in the export.
@@ -296,6 +295,7 @@ DATE_FIELDS: Dict[TableName, List[Field]] = {
"zerver_userpresence": ["timestamp"],
"zerver_userprofile": ["date_joined", "last_login", "last_reminder"],
"zerver_userprofile_mirrordummy": ["date_joined", "last_login", "last_reminder"],
"zerver_userstatus": ["timestamp"],
"zerver_usertopic": ["last_updated"],
}
@@ -892,6 +892,13 @@ def add_user_profile_child_configs(user_profile_config: Config) -> None:
parent_key="user_profile__in",
)
Config(
table="zerver_userstatus",
model=UserStatus,
normal_parent=user_profile_config,
parent_key="user_profile__in",
)
Config(
table="zerver_usertopic",
model=UserTopic,

View File

@@ -66,6 +66,7 @@ from zerver.models import (
UserMessage,
UserPresence,
UserProfile,
UserStatus,
UserTopic,
get_huddle_hash,
get_realm,
@@ -108,6 +109,7 @@ ID_MAP: Dict[str, Dict[int, int]] = {
"realmplayground": {},
"message": {},
"user_presence": {},
"userstatus": {},
"useractivity": {},
"useractivityinterval": {},
"usermessage": {},
@@ -1260,6 +1262,14 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
stream.first_message_id = first_message.id
stream.save(update_fields=["first_message_id"])
if "zerver_userstatus" in data:
fix_datetime_fields(data, "zerver_userstatus")
re_map_foreign_keys(data, "zerver_userstatus", "user_profile", related_table="user_profile")
re_map_foreign_keys(data, "zerver_userstatus", "client", related_table="client")
update_model_ids(UserStatus, data, "userstatus")
re_map_realm_emoji_codes(data, table_name="zerver_userstatus")
bulk_import_model(data, UserStatus)
# Do attachments AFTER message data is loaded.
# TODO: de-dup how we read these json files.
fn = os.path.join(import_dir, "attachment.json")

View File

@@ -89,6 +89,7 @@ from zerver.models import (
Stream,
Subscription,
UserProfile,
UserStatus,
clear_supported_auth_backends_cache,
flush_per_request_caches,
get_display_recipient,
@@ -1439,6 +1440,13 @@ Output:
self.assertEqual(dct[realm_emoji_id].realm_id, row.user_profile.realm_id)
count += 1
for row in UserStatus.objects.filter(reaction_type=UserStatus.REALM_EMOJI):
realm_emoji_id = int(row.emoji_code)
assert realm_emoji_id in dct
self.assertEqual(dct[realm_emoji_id].name, row.emoji_name)
self.assertEqual(dct[realm_emoji_id].realm_id, row.user_profile.realm_id)
count += 1
if count == 0:
raise AssertionError("test is meaningless without any pertinent rows")

View File

@@ -19,6 +19,7 @@ from zerver.lib.actions import (
do_deactivate_user,
do_mute_user,
do_update_user_presence,
do_update_user_status,
)
from zerver.lib.avatar_hash import user_avatar_path
from zerver.lib.bot_config import set_bot_config
@@ -64,6 +65,7 @@ from zerver.models import (
UserMessage,
UserPresence,
UserProfile,
UserStatus,
UserTopic,
get_active_streams,
get_client,
@@ -735,10 +737,27 @@ class ImportExportTest(ZulipTestCase):
do_mute_user(cordelia, hamlet)
do_mute_user(cordelia, othello)
do_update_user_presence(
sample_user, get_client("website"), timezone_now(), UserPresence.ACTIVE
client = get_client("website")
do_update_user_presence(sample_user, client, timezone_now(), UserPresence.ACTIVE)
# send Cordelia to the islands
do_update_user_status(
user_profile=cordelia,
away=True,
status_text="in Hawaii",
client_id=client.id,
emoji_name="hawaii",
emoji_code=str(realm_emoji.id),
reaction_type=Reaction.REALM_EMOJI,
)
user_status = UserStatus.objects.order_by("id").last()
assert user_status
# Verify strange invariant for UserStatus/RealmEmoji.
self.assertEqual(user_status.emoji_code, str(realm_emoji.id))
# data to test import of botstoragedata and botconfigdata
bot_profile = do_create_user(
email="bot-1@zulip.com",
@@ -914,6 +933,16 @@ class ImportExportTest(ZulipTestCase):
assert_realm_values(get_realm_emoji_names)
def get_realm_user_statuses(r: Realm) -> Set[Tuple[str, str, int, str]]:
tups = {
(rec.user_profile.full_name, rec.emoji_name, rec.status, rec.status_text)
for rec in UserStatus.objects.filter(user_profile__realm_id=r.id)
}
assert (cordelia.full_name, "hawaii", UserStatus.AWAY, "in Hawaii") in tups
return tups
assert_realm_values(get_realm_user_statuses)
def get_realm_emoji_reactions(r: Realm) -> Set[Tuple[str, str]]:
tups = {
(rec.emoji_name, rec.user_profile.full_name)