Add snapshot migration for userstories to avoid unnecessary history entries
parent
6faed218ba
commit
76414c75d4
|
@ -93,7 +93,8 @@ def _common_users_values(diff):
|
||||||
if "assigned_to" in diff:
|
if "assigned_to" in diff:
|
||||||
users.update(diff["assigned_to"])
|
users.update(diff["assigned_to"])
|
||||||
if "assigned_users" in diff:
|
if "assigned_users" in diff:
|
||||||
[users.update(usrs_id) if usrs_id else None for usrs_id in diff["assigned_users"]]
|
[users.update(usrs_ids) for usrs_ids in diff["assigned_users"] if
|
||||||
|
usrs_ids]
|
||||||
if users:
|
if users:
|
||||||
values["users"] = _get_users_values(users)
|
values["users"] = _get_users_values(users)
|
||||||
|
|
||||||
|
@ -335,6 +336,12 @@ def userstory_freezer(us) -> dict:
|
||||||
for rp in rpqsd:
|
for rp in rpqsd:
|
||||||
points[str(rp.role_id)] = rp.points_id
|
points[str(rp.role_id)] = rp.points_id
|
||||||
|
|
||||||
|
assigned_users = [u.id for u in us.assigned_users.all()]
|
||||||
|
# Due to multiple assignment migration, for new snapshots we add to
|
||||||
|
# assigned users a list with the 'assigned to' value
|
||||||
|
if us.assigned_to_id and not assigned_users:
|
||||||
|
assigned_users = [us.assigned_to_id]
|
||||||
|
|
||||||
snapshot = {
|
snapshot = {
|
||||||
"ref": us.ref,
|
"ref": us.ref,
|
||||||
"owner": us.owner_id,
|
"owner": us.owner_id,
|
||||||
|
@ -348,7 +355,7 @@ def userstory_freezer(us) -> dict:
|
||||||
"description": us.description,
|
"description": us.description,
|
||||||
"description_html": mdrender(us.project, us.description),
|
"description_html": mdrender(us.project, us.description),
|
||||||
"assigned_to": us.assigned_to_id,
|
"assigned_to": us.assigned_to_id,
|
||||||
"assigned_users": [u.id for u in us.assigned_users.all()],
|
"assigned_users": assigned_users,
|
||||||
"milestone": us.milestone_id,
|
"milestone": us.milestone_id,
|
||||||
"client_requirement": us.client_requirement,
|
"client_requirement": us.client_requirement,
|
||||||
"team_requirement": us.team_requirement,
|
"team_requirement": us.team_requirement,
|
||||||
|
|
|
@ -229,6 +229,31 @@ def get_excluded_fields(typename: str) -> tuple:
|
||||||
return _deprecated_fields.get(typename, ())
|
return _deprecated_fields.get(typename, ())
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_userstory_diff(obj: FrozenObj) -> FrozenObj:
|
||||||
|
# Due to multiple assignment migration, for old snapshots we add a list
|
||||||
|
# with the 'assigned to' value
|
||||||
|
if 'assigned_users' not in obj.snapshot.keys():
|
||||||
|
snapshot = deepcopy(obj.snapshot)
|
||||||
|
snapshot['assigned_users'] = [obj.snapshot['assigned_to']]
|
||||||
|
|
||||||
|
obj = FrozenObj(obj.key, snapshot)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
_migrations = {"userstories.userstory": migrate_userstory_diff}
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_to_last_version(typename: str, obj: FrozenObj) -> FrozenObj:
|
||||||
|
"""""
|
||||||
|
Adapt old snapshots to the last format in order to generate correct diffs.
|
||||||
|
:param typename:
|
||||||
|
:param obj:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return _migrations.get(typename, lambda x: x)(obj)
|
||||||
|
|
||||||
|
|
||||||
def make_diff(oldobj: FrozenObj, newobj: FrozenObj,
|
def make_diff(oldobj: FrozenObj, newobj: FrozenObj,
|
||||||
excluded_keys: tuple = ()) -> FrozenDiff:
|
excluded_keys: tuple = ()) -> FrozenDiff:
|
||||||
"""
|
"""
|
||||||
|
@ -342,6 +367,10 @@ def take_snapshot(obj: object, *, comment: str="", user=None,
|
||||||
new_fobj = freeze_model_instance(obj)
|
new_fobj = freeze_model_instance(obj)
|
||||||
old_fobj, need_real_snapshot = get_last_snapshot_for_key(key)
|
old_fobj, need_real_snapshot = get_last_snapshot_for_key(key)
|
||||||
|
|
||||||
|
# migrate diff to latest schema
|
||||||
|
if old_fobj:
|
||||||
|
old_fobj = migrate_to_last_version(typename, old_fobj)
|
||||||
|
|
||||||
entry_model = apps.get_model("history", "HistoryEntry")
|
entry_model = apps.get_model("history", "HistoryEntry")
|
||||||
user_id = None if user is None else user.id
|
user_id = None if user is None else user.id
|
||||||
user_name = "" if user is None else user.get_full_name()
|
user_name = "" if user is None else user.get_full_name()
|
||||||
|
@ -358,6 +387,7 @@ def take_snapshot(obj: object, *, comment: str="", user=None,
|
||||||
raise RuntimeError("Unexpected condition")
|
raise RuntimeError("Unexpected condition")
|
||||||
|
|
||||||
excluded_fields = get_excluded_fields(typename)
|
excluded_fields = get_excluded_fields(typename)
|
||||||
|
|
||||||
fdiff = make_diff(old_fobj, new_fobj, excluded_fields)
|
fdiff = make_diff(old_fobj, new_fobj, excluded_fields)
|
||||||
|
|
||||||
# If diff and comment are empty, do
|
# If diff and comment are empty, do
|
||||||
|
|
|
@ -90,7 +90,16 @@ class UserStoryListSerializer(ProjectExtraInfoSerializerMixin,
|
||||||
|
|
||||||
:return: User queryset object representing the assigned users
|
:return: User queryset object representing the assigned users
|
||||||
"""
|
"""
|
||||||
return [user.id for user in obj.assigned_users.all()]
|
if not obj.assigned_to:
|
||||||
|
return set([user.id for user in obj.assigned_users.all()])
|
||||||
|
|
||||||
|
assigned_users = [user.id for user in obj.assigned_users.all()] + \
|
||||||
|
[obj.assigned_to.id]
|
||||||
|
|
||||||
|
if not assigned_users:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return set(assigned_users)
|
||||||
|
|
||||||
def get_epic_order(self, obj):
|
def get_epic_order(self, obj):
|
||||||
include_epic_order = getattr(obj, "include_epic_order", False)
|
include_epic_order = getattr(obj, "include_epic_order", False)
|
||||||
|
|
|
@ -104,7 +104,7 @@ def test_create_userstory_with_assigned_users(client):
|
||||||
response = client.json.post(url, json_data)
|
response = client.json.post(url, json_data)
|
||||||
|
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
assert response.data["assigned_users"] == [user.id, user_watcher.id]
|
assert response.data["assigned_users"] == set([user.id, user_watcher.id])
|
||||||
|
|
||||||
|
|
||||||
def test_create_userstory_with_watchers(client):
|
def test_create_userstory_with_watchers(client):
|
||||||
|
|
Loading…
Reference in New Issue