Support query by task state in projects.get_tasks_parents, return task project names

This commit is contained in:
allegroai 2021-01-05 19:02:48 +02:00
parent d7ddfde26e
commit 16430a6636
6 changed files with 126 additions and 43 deletions

View File

@ -1,7 +1,8 @@
from jsonmodels import models, fields
from apiserver.apimodels import ListField
from apiserver.apimodels import ListField, ActualEnumField
from apiserver.apimodels.organization import TagsRequest
from apiserver.database.model import EntityVisibility
class ProjectReq(models.Base):
@ -19,3 +20,5 @@ class ProjectTagsRequest(TagsRequest):
class ProjectTaskParentsRequest(ProjectReq):
projects = ListField(str)
tasks_state = ActualEnumField(EntityVisibility)

View File

@ -1,11 +1,12 @@
from collections import defaultdict
from enum import Enum
from operator import itemgetter
from typing import Sequence, Dict
from typing import Sequence, Dict, Optional
from mongoengine import Q
from apiserver.config_repo import config
from apiserver.database.model import EntityVisibility
from apiserver.database.model.model import Model
from apiserver.database.model.task.task import Task
from apiserver.redis_manager import redman
@ -67,7 +68,10 @@ class OrgBLL:
@classmethod
def get_parent_tasks(
cls, company_id: str, projects: Sequence[str]
cls,
company_id: str,
projects: Sequence[str],
state: Optional[EntityVisibility] = None,
) -> Sequence[dict]:
"""
Get list of unique parent tasks sorted by task name for the passed company projects
@ -76,12 +80,19 @@ class OrgBLL:
query = Q(company=company_id)
if projects:
query &= Q(project__in=projects)
if state == EntityVisibility.archived:
query &= Q(system_tags__in=[EntityVisibility.archived.value])
elif state == EntityVisibility.active:
query &= Q(system_tags__nin=[EntityVisibility.archived.value])
parent_ids = set(Task.objects(query).distinct("parent"))
if not parent_ids:
return []
parents = [
{"id": task.id, "name": task.name}
for task in Task.objects(id__in=parent_ids).only("id", "name")
]
parents = Task.get_many_with_join(
company_id,
query=Q(id__in=parent_ids),
allow_public=True,
override_projection=("id", "name", "project.name"),
)
return sorted(parents, key=itemgetter("name"))

View File

@ -650,6 +650,12 @@ get_task_parents {
type: array
items { type: string }
}
tasks_state {
description: "Return parents for tasks in the specified state. If Null is provided, parents for all task states will be returned."
type: string
enum: [ active, archived ]
default: active
}
}
}
response {
@ -669,6 +675,17 @@ get_task_parents {
description: "The name of the parent task"
type: string
}
project {
type: object
id {
description: "The ID of the parent task project"
type: string
}
name {
description: "The name of the parent task project"
type: string
}
}
}
}
}

View File

@ -429,20 +429,18 @@ def get_tags(call: APICall, company, request: ProjectTagsRequest):
"projects.make_public", min_version="2.9", request_data_model=MakePublicRequest
)
def make_public(call: APICall, company_id, request: MakePublicRequest):
with translate_errors_context():
call.result.data = Project.set_public(
company_id, ids=request.ids, invalid_cls=InvalidProjectId, enabled=True
)
call.result.data = Project.set_public(
company_id, ids=request.ids, invalid_cls=InvalidProjectId, enabled=True
)
@endpoint(
"projects.make_private", min_version="2.9", request_data_model=MakePublicRequest
)
def make_public(call: APICall, company_id, request: MakePublicRequest):
with translate_errors_context():
call.result.data = Project.set_public(
company_id, ids=request.ids, invalid_cls=InvalidProjectId, enabled=False
)
call.result.data = Project.set_public(
company_id, ids=request.ids, invalid_cls=InvalidProjectId, enabled=False
)
@endpoint(
@ -454,5 +452,7 @@ def get_task_parents(
call: APICall, company_id: str, request: ProjectTaskParentsRequest
):
call.result.data = {
"parents": org_bll.get_parent_tasks(company_id, projects=request.projects)
"parents": org_bll.get_parent_tasks(
company_id, projects=request.projects, state=request.tasks_state
)
}

View File

@ -7,33 +7,6 @@ class TestProjectTags(TestService):
def setUp(self, version="2.12"):
super().setUp(version=version)
def test_task_parent(self):
# stand alone task
parent_sa_name = "Test parent parent standalone"
parent_sa = self.new_task(name=parent_sa_name)
self.new_task(name="Test parent task standalone", parent=parent_sa)
# tasks in projects
parent_name = "Test parent parent"
parent = self.new_task(name=parent_name)
p1 = self.create_temp("projects", name="Test parents1", description="test")
self.new_task(project=p1, name="Test parent task1", parent=parent)
p2 = self.create_temp("projects", name="Test parents2", description="test")
self.new_task(project=p1, name="Test parent task2", parent=parent)
parents = self.api.projects.get_task_parents(projects=[p1, p2]).parents
self.assertEqual([{"id": parent, "name": parent_name}], parents)
res = self.api.projects.get_task_parents()
parents = [p for p in res.parents if p.id in (parent, parent_sa)]
self.assertEqual(
[
{"id": parent, "name": parent_name},
{"id": parent_sa, "name": parent_sa_name},
],
parents,
)
def test_project_tags(self):
tags_1 = ["Test tag 1", "Test tag 2"]
tags_2 = ["Test tag 3", "Test tag 4"]

View File

@ -0,0 +1,79 @@
from apiserver.tests.automated import TestService
class TestTaskParent(TestService):
def setUp(self, version="2.12"):
super().setUp(version=version)
def test_query_by_project(self):
# stand alone task
parent_sa_name = "Test parent parent standalone"
parent_sa = self.new_task(name=parent_sa_name)
self.new_task(name="Test parent task standalone", parent=parent_sa)
# tasks in projects
project_name = "Test parents project"
project = self.create_temp("projects", name=project_name, description="test")
parent_name = "Test parent parent"
parent = self.new_task(project=project, name=parent_name)
self.new_task(project=project, name="Test parent task1", parent=parent)
self.new_task(project=project, name="Test parent task2", parent=parent)
parents = self.api.projects.get_task_parents(projects=[project]).parents
self.assertEqual(
[
{
"id": parent,
"name": parent_name,
"project": {"id": project, "name": project_name},
}
],
parents,
)
res = self.api.projects.get_task_parents()
parents = [p for p in res.parents if p.id in (parent, parent_sa)]
self.assertEqual(
[
{
"id": parent,
"name": parent_name,
"project": {"id": project, "name": project_name},
},
{"id": parent_sa, "name": parent_sa_name},
],
parents,
)
def test_query_by_state(self):
project_name = "Test parents project"
project = self.create_temp("projects", name=project_name, description="test")
parent1_name = "Test parent parent1"
parent1 = self.new_task(project=project, name=parent1_name)
t1 = self.new_task(project=project, name="Test parent task1", parent=parent1)
parent2_name = "Test parent parent2"
parent2 = self.new_task(project=project, name=parent2_name)
t2 = self.new_task(project=project, name="Test parent task2", parent=parent2)
self.api.tasks.archive(tasks=[t2])
# No state filter
parents = self.api.projects.get_task_parents(projects=[project]).parents
self.assertEqual([parent1, parent2], [p.id for p in parents])
# Active tasks
parents = self.api.projects.get_task_parents(projects=[project], tasks_state="active").parents
self.assertEqual([parent1], [p.id for p in parents])
# Archived tasks
parents = self.api.projects.get_task_parents(projects=[project], tasks_state="archived").parents
self.assertEqual([parent2], [p.id for p in parents])
def new_task(self, **kwargs):
self.update_missing(
kwargs, type="testing", name="test project tags", input=dict(view=dict())
)
return self.create_temp("tasks", **kwargs)