* Add timeline tests

* Improve factory
* Add default to exclude fields
remotes/origin/3.4.0rc
Álex Hermida 2018-04-09 21:39:10 +02:00
parent de7ab4c474
commit f95d9f28be
3 changed files with 73 additions and 21 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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()