* Add timeline tests
* Improve factory * Add default to exclude fieldsremotes/origin/3.4.0rc
parent
de7ab4c474
commit
f95d9f28be
|
@ -81,7 +81,8 @@ _values_impl_map = {}
|
|||
# this fields are marked as hidden).
|
||||
_not_important_fields = {
|
||||
"epics.epic": frozenset(["epics_order", "user_stories"]),
|
||||
"userstories.userstory": frozenset(["backlog_order", "sprint_order", "kanban_order"]),
|
||||
"userstories.userstory": frozenset(
|
||||
["backlog_order", "sprint_order", "kanban_order"]),
|
||||
"tasks.task": frozenset(["us_order", "taskboard_order"]),
|
||||
}
|
||||
|
||||
|
@ -195,7 +196,8 @@ def freeze_model_instance(obj: object) -> FrozenObj:
|
|||
key = make_key_from_model_object(obj)
|
||||
impl_fn = _freeze_impl_map[typename]
|
||||
snapshot = impl_fn(obj)
|
||||
assert isinstance(snapshot, dict), "freeze handlers should return always a dict"
|
||||
assert isinstance(snapshot, dict), \
|
||||
"freeze handlers should return always a dict"
|
||||
|
||||
return FrozenObj(key, snapshot)
|
||||
|
||||
|
@ -224,7 +226,7 @@ def get_excluded_fields(typename: str) -> tuple:
|
|||
"""
|
||||
Get excluded and deprected fields to avoid in the diff
|
||||
"""
|
||||
return _deprecated_fields.get(typename)
|
||||
return _deprecated_fields.get(typename, ())
|
||||
|
||||
|
||||
def make_diff(oldobj: FrozenObj, newobj: FrozenObj,
|
||||
|
@ -233,7 +235,8 @@ def make_diff(oldobj: FrozenObj, newobj: FrozenObj,
|
|||
Compute a diff between two frozen objects.
|
||||
"""
|
||||
|
||||
assert isinstance(newobj, FrozenObj), "newobj parameter should be instance of FrozenObj"
|
||||
assert isinstance(newobj, FrozenObj), \
|
||||
"newobj parameter should be instance of FrozenObj"
|
||||
|
||||
if oldobj is None:
|
||||
return FrozenDiff(newobj.key, {}, newobj.snapshot)
|
||||
|
@ -254,7 +257,8 @@ def make_diff_values(typename: str, fdiff: FrozenDiff) -> dict:
|
|||
"""
|
||||
|
||||
if typename not in _values_impl_map:
|
||||
log.warning("No implementation found of '{}' for values.".format(typename))
|
||||
log.warning(
|
||||
"No implementation found of '{}' for values.".format(typename))
|
||||
return {}
|
||||
|
||||
impl_fn = _values_impl_map[typename]
|
||||
|
@ -306,10 +310,12 @@ def get_modified_fields(obj: object, last_modifications):
|
|||
"""
|
||||
key = make_key_from_model_object(obj)
|
||||
entry_model = apps.get_model("history", "HistoryEntry")
|
||||
history_entries = (entry_model.objects
|
||||
.filter(key=key)
|
||||
.order_by("-created_at")
|
||||
.values_list("diff", flat=True)[0:last_modifications])
|
||||
history_entries = (
|
||||
entry_model.objects.filter(key=key)
|
||||
.order_by("-created_at")
|
||||
.values_list("diff",
|
||||
flat=True)[0:last_modifications]
|
||||
)
|
||||
|
||||
modified_fields = []
|
||||
for history_entry in history_entries:
|
||||
|
@ -319,7 +325,8 @@ def get_modified_fields(obj: object, last_modifications):
|
|||
|
||||
|
||||
@tx.atomic
|
||||
def take_snapshot(obj: object, *, comment: str="", user=None, delete: bool=False):
|
||||
def take_snapshot(obj: object, *, comment: str="", user=None,
|
||||
delete: bool=False):
|
||||
"""
|
||||
Given any model instance with registred content type,
|
||||
create new history entry of "change" type.
|
||||
|
@ -355,7 +362,9 @@ def take_snapshot(obj: object, *, comment: str="", user=None, delete: bool=False
|
|||
|
||||
# If diff and comment are empty, do
|
||||
# not create empty history entry
|
||||
if (not fdiff.diff and not comment and old_fobj is not None and entry_type != HistoryType.delete):
|
||||
if (not fdiff.diff and
|
||||
not comment and old_fobj is not None and
|
||||
entry_type != HistoryType.delete):
|
||||
return None
|
||||
|
||||
fvals = make_diff_values(typename, fdiff)
|
||||
|
@ -384,7 +393,8 @@ def take_snapshot(obj: object, *, comment: str="", user=None, delete: bool=False
|
|||
|
||||
# High level query api
|
||||
|
||||
def get_history_queryset_by_model_instance(obj: object, types=(HistoryType.change,),
|
||||
def get_history_queryset_by_model_instance(obj: object,
|
||||
types=(HistoryType.change,),
|
||||
include_hidden=False):
|
||||
"""
|
||||
Get one page of history for specified object.
|
||||
|
@ -404,16 +414,18 @@ def prefetch_owners_in_history_queryset(qs):
|
|||
users = get_user_model().objects.filter(id__in=user_ids)
|
||||
users_by_id = {u.id: u for u in users}
|
||||
for history_entry in qs:
|
||||
history_entry.prefetch_owner(users_by_id.get(history_entry.user["pk"], None))
|
||||
history_entry.prefetch_owner(users_by_id.get(history_entry.user["pk"],
|
||||
None))
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
# Freeze & value register
|
||||
register_freeze_implementation("projects.project", project_freezer)
|
||||
register_freeze_implementation("milestones.milestone", milestone_freezer,)
|
||||
register_freeze_implementation("milestones.milestone", milestone_freezer)
|
||||
register_freeze_implementation("epics.epic", epic_freezer)
|
||||
register_freeze_implementation("epics.relateduserstory", epic_related_userstory_freezer)
|
||||
register_freeze_implementation("epics.relateduserstory",
|
||||
epic_related_userstory_freezer)
|
||||
register_freeze_implementation("userstories.userstory", userstory_freezer)
|
||||
register_freeze_implementation("issues.issue", issue_freezer)
|
||||
register_freeze_implementation("tasks.task", task_freezer)
|
||||
|
@ -422,7 +434,8 @@ register_freeze_implementation("wiki.wikipage", wikipage_freezer)
|
|||
register_values_implementation("projects.project", project_values)
|
||||
register_values_implementation("milestones.milestone", milestone_values)
|
||||
register_values_implementation("epics.epic", epic_values)
|
||||
register_values_implementation("epics.relateduserstory", epic_related_userstory_values)
|
||||
register_values_implementation("epics.relateduserstory",
|
||||
epic_related_userstory_values)
|
||||
register_values_implementation("userstories.userstory", userstory_values)
|
||||
register_values_implementation("issues.issue", issue_values)
|
||||
register_values_implementation("tasks.task", task_values)
|
||||
|
|
|
@ -295,6 +295,15 @@ class UserStoryFactory(Factory):
|
|||
due_date = factory.LazyAttribute(lambda o: date.today() + timedelta(days=7))
|
||||
due_date_reason = factory.Faker("words")
|
||||
|
||||
@factory.post_generation
|
||||
def assigned_users(self, create, users_list, **kwargs):
|
||||
if not create:
|
||||
return
|
||||
|
||||
if users_list:
|
||||
for user in users_list:
|
||||
self.assigned_users.add(user)
|
||||
|
||||
|
||||
class TaskFactory(Factory):
|
||||
class Meta:
|
||||
|
|
|
@ -448,10 +448,12 @@ def test_delete_membership_timeline():
|
|||
def test_comment_user_story_timeline():
|
||||
user_story = factories.UserStoryFactory.create(subject="test us timeline")
|
||||
history_services.take_snapshot(user_story, user=user_story.owner)
|
||||
history_services.take_snapshot(user_story, user=user_story.owner, comment="testing comment")
|
||||
history_services.take_snapshot(user_story, user=user_story.owner,
|
||||
comment="testing comment")
|
||||
project_timeline = service.get_project_timeline(user_story.project)
|
||||
assert project_timeline[0].event_type == "userstories.userstory.change"
|
||||
assert project_timeline[0].data["userstory"]["subject"] == "test us timeline"
|
||||
assert project_timeline[0].data["userstory"]["subject"] \
|
||||
== "test us timeline"
|
||||
assert project_timeline[0].data["comment"] == "testing comment"
|
||||
|
||||
|
||||
|
@ -465,7 +467,9 @@ def test_owner_user_story_timeline():
|
|||
|
||||
def test_assigned_to_user_story_timeline():
|
||||
membership = factories.MembershipFactory.create()
|
||||
user_story = factories.UserStoryFactory.create(subject="test us timeline", assigned_to=membership.user, project=membership.project)
|
||||
user_story = factories.UserStoryFactory.create(subject="test us timeline",
|
||||
assigned_to=membership.user,
|
||||
project=membership.project)
|
||||
history_services.take_snapshot(user_story, user=user_story.owner)
|
||||
user_timeline = service.get_profile_timeline(user_story.assigned_to)
|
||||
assert user_timeline[0].event_type == "userstories.userstory.create"
|
||||
|
@ -492,6 +496,30 @@ def test_due_date_user_story_timeline():
|
|||
str(new_due_date.date())]
|
||||
|
||||
|
||||
def test_assigned_users_user_story_timeline():
|
||||
membership = factories.MembershipFactory.create()
|
||||
user_story = factories.UserStoryFactory.create(subject="test us timeline",
|
||||
project=membership.project)
|
||||
history_services.take_snapshot(user_story, user=user_story.owner)
|
||||
user_timeline = service.get_profile_timeline(user_story.owner)
|
||||
|
||||
assert user_timeline[0].event_type == "userstories.userstory.create"
|
||||
assert user_timeline[0].data["userstory"]["subject"] == "test us timeline"
|
||||
|
||||
user_story.assigned_to = membership.user
|
||||
user_story.assigned_users = (membership.user,)
|
||||
user_story.save()
|
||||
|
||||
history_services.take_snapshot(user_story, user=user_story.owner)
|
||||
|
||||
user_timeline = service.get_profile_timeline(user_story.owner)
|
||||
|
||||
assert user_timeline[0].event_type == "userstories.userstory.change"
|
||||
assert "assigned_to" not in user_timeline[0].data["values_diff"].keys()
|
||||
assert user_timeline[0].data["values_diff"]['assigned_users'] == \
|
||||
[None, membership.user.username]
|
||||
|
||||
|
||||
def test_user_data_for_non_system_users():
|
||||
user_story = factories.UserStoryFactory.create(subject="test us timeline")
|
||||
history_services.take_snapshot(user_story, user=user_story.owner)
|
||||
|
@ -520,9 +548,11 @@ def test_user_data_for_unactived_users():
|
|||
serialized_obj.data["data"]["user"]["is_profile_visible"] = False
|
||||
serialized_obj.data["data"]["user"]["username"] = "deleted-user"
|
||||
|
||||
|
||||
def test_timeline_error_use_member_ids_instead_of_memberships_ids():
|
||||
user_story = factories.UserStoryFactory.create(subject="test error use member ids instead of "
|
||||
"memberships ids")
|
||||
user_story = factories.UserStoryFactory.create(
|
||||
subject="test error use member ids instead of "
|
||||
"memberships ids")
|
||||
|
||||
member_user = user_story.owner
|
||||
external_user = factories.UserFactory.create()
|
||||
|
|
Loading…
Reference in New Issue