From 5449b332d243bf524d6aabb0013d732a5fb9602c Mon Sep 17 00:00:00 2001 From: allegroai <> Date: Thu, 25 May 2023 19:29:46 +0300 Subject: [PATCH] Support reports from the root project in reports.get_all_ex --- apiserver/bll/project/project_bll.py | 4 +- apiserver/bll/project/sub_projects.py | 4 +- apiserver/services/reports.py | 14 ++++++- apiserver/tests/automated/test_reports.py | 47 +++++++++++++++++++++++ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/apiserver/bll/project/project_bll.py b/apiserver/bll/project/project_bll.py index 2f24013..ea032c3 100644 --- a/apiserver/bll/project/project_bll.py +++ b/apiserver/bll/project/project_bll.py @@ -951,9 +951,7 @@ class ProjectBLL: ) res = ( - {p.id for p in Project.objects(project_query).only("id")} - if project_query - else set() + set(Project.objects(project_query).scalar("id")) if project_query else set() ) for cls_, query_ in child_queries.items(): res |= set( diff --git a/apiserver/bll/project/sub_projects.py b/apiserver/bll/project/sub_projects.py index 7b5d758..ca0883d 100644 --- a/apiserver/bll/project/sub_projects.py +++ b/apiserver/bll/project/sub_projects.py @@ -144,8 +144,8 @@ def _ids_with_children(project_ids: Sequence[str]) -> Sequence[str]: """ Return project ids with the ids of all the subprojects """ - subprojects = Project.objects(path__in=project_ids).only("id") - return list({*project_ids, *(child.id for child in subprojects)}) + children_ids = Project.objects(path__in=project_ids).scalar("id") + return list({*project_ids, *children_ids}) def _update_subproject_names( diff --git a/apiserver/services/reports.py b/apiserver/services/reports.py index 6b662cf..2f5618b 100644 --- a/apiserver/services/reports.py +++ b/apiserver/services/reports.py @@ -171,9 +171,19 @@ def _delete_reports_project_if_empty(project_id): def get_all_ex(call: APICall, company_id, request: GetAllRequest): call_data = call.data call_data["type"] = TaskType.report - call_data["include_subprojects"] = True - process_include_subprojects(call_data) + # bring projects one level down in case not the .reports project was passed + if "project" in call_data: + project_ids = call_data["project"] + if not isinstance(project_ids, list): + project_ids = [project_ids] + call_data["project"] = [ + *project_ids, + *Project.objects( + parent__in=project_ids, basename=reports_project_name + ).scalar("id"), + ] + ret_params = {} tasks = Task.get_many_with_join( company=company_id, diff --git a/apiserver/tests/automated/test_reports.py b/apiserver/tests/automated/test_reports.py index 9ce2970..99f2ea5 100644 --- a/apiserver/tests/automated/test_reports.py +++ b/apiserver/tests/automated/test_reports.py @@ -96,6 +96,44 @@ class TestReports(TestService): self.assertEqual(project.get("parent"), None) self.assertEqual(project.name, ".reports") + def test_root_reports(self): + root_report = self._temp_report(name="Rep1") + project_name = "Test reports" + project = self._temp_project(name=project_name) + project_report = self._temp_report(name="Rep2", project=project) + + projects = self.api.projects.get_all_ex( + name=r"^\.reports$", + children_type="report", + include_stats=True, + check_own_contents=True, + search_hidden=True, + ).projects + self.assertEqual(len(projects), 1) + p = projects[0] + self.assertEqual(p.name, ".reports") + self.assertEqual(p.own_tasks, 1) + + projects = self.api.projects.get_all_ex( + name=rf"^{project_name}/\.reports$", + children_type="report", + include_stats=True, + check_own_contents=True, + search_hidden=True, + ).projects + self.assertEqual(len(projects), 1) + p = projects[0] + self.assertEqual(p.name, f"{project_name}/.reports") + self.assertEqual(p.own_tasks, 1) + + reports = self.api.reports.get_all_ex().tasks + self.assertTrue({root_report, project_report}.issubset({r.id for r in reports})) + reports = self.api.reports.get_all_ex(project=project).tasks + self.assertEqual([project_report], [r.id for r in reports]) + reports = self.api.reports.get_all_ex(project=[None]).tasks + self.assertIn(root_report, {r.id for r in reports}) + self.assertNotIn(project_report, {r.id for r in reports}) + def test_reports_search(self): report_task = self._temp_report(name="Rep1") non_report_task = self._temp_task(name="hello") @@ -236,6 +274,15 @@ class TestReports(TestService): delete_params = {"force": True} + def _temp_project(self, name, **kwargs): + return self.create_temp( + "projects", + delete_params=self.delete_params, + name=name, + description="", + **kwargs, + ) + def _temp_report(self, name, **kwargs): return self.create_temp( "reports",