Allow Project Groups to be filtered by project

Currently there is no easy way to find the set of Project Groups that a
specific Project belongs to. This commit adds a parameter to the Project
Groups browse endpoint to enable filtering by Project ID to add this
functionality.

Change-Id: I7b09665bb554c19e8cc4074ce0d1813f3adc4218
This commit is contained in:
Adam Coldrick 2020-09-22 18:42:36 +01:00
parent 37a5ff711b
commit 9ec8875c4c
3 changed files with 45 additions and 6 deletions

View File

@ -166,9 +166,10 @@ class ProjectGroupsController(rest.RestController):
@decorators.db_exceptions
@secure(checks.guest)
@wsme_pecan.wsexpose([wmodels.ProjectGroup], int, int, int, wtypes.text,
wtypes.text, int, wtypes.text, wtypes.text)
wtypes.text, int, int, wtypes.text, wtypes.text)
def get(self, marker=None, offset=None, limit=None, name=None, title=None,
subscriber_id=None, sort_field='id', sort_dir='asc'):
subscriber_id=None, project_id=None, sort_field='id',
sort_dir='asc'):
"""Retrieve a list of projects groups.
Example::
@ -181,6 +182,7 @@ class ProjectGroupsController(rest.RestController):
:param name: A string to filter the name by.
:param title: A string to filter the title by.
:param subscriber_id: The ID of a subscriber to filter by.
:param project_id: The ID of a project to filter by.
:param sort_field: The name of the field to sort on.
:param sort_dir: Sort direction for results (asc, desc).
"""
@ -200,11 +202,13 @@ class ProjectGroupsController(rest.RestController):
name=name,
title=title,
subscriber_id=subscriber_id,
project_id=project_id,
sort_field=sort_field,
sort_dir=sort_dir)
group_count = project_groups.project_group_get_count(
name=name, title=title, subscriber_id=subscriber_id)
name=name, title=title, subscriber_id=subscriber_id,
project_id=project_id)
# Apply the query response headers.
if limit:

View File

@ -47,8 +47,8 @@ def project_group_get_by_name(name):
def project_group_get_all(marker=None, limit=None, offset=None,
subscriber_id=None, sort_field=None, sort_dir=None,
**kwargs):
subscriber_id=None, project_id=None, sort_field=None,
sort_dir=None, **kwargs):
# Sanity checks, in case someone accidentally explicitly passes in 'None'
if not sort_field:
sort_field = 'id'
@ -70,6 +70,16 @@ def project_group_get_all(marker=None, limit=None, offset=None,
subs = subs.subquery()
query = query.join(subs, subs.c.target_id == models.ProjectGroup.id)
# Filtering by project
if project_id:
# We can filter using the project_id column in the
# project_group_mapping table, so we can skip joining the full
# projects table.
pgm = models.project_group_mapping
query = query.join(
(pgm, pgm.c.project_group_id == models.ProjectGroup.id))
query = query.filter(pgm.c.project_id == project_id)
query = api_base.paginate_query(query=query,
model=models.ProjectGroup,
limit=limit,
@ -82,7 +92,7 @@ def project_group_get_all(marker=None, limit=None, offset=None,
return query.all()
def project_group_get_count(subscriber_id=None, **kwargs):
def project_group_get_count(subscriber_id=None, project_id=None, **kwargs):
# Construct the query
query = api_base.model_query(models.ProjectGroup)
query = api_base.apply_query_filters(query=query,
@ -99,6 +109,16 @@ def project_group_get_count(subscriber_id=None, **kwargs):
subs = subs.subquery()
query = query.join(subs, subs.c.target_id == models.ProjectGroup.id)
# Filtering by project
if project_id:
# We can filter using the project_id column in the
# project_group_mapping table, so we can skip joining the full
# projects table.
pgm = models.project_group_mapping
query = query.join(
(pgm, pgm.c.project_group_id == models.ProjectGroup.id))
query = query.filter(pgm.c.project_id == project_id)
return query.count()

View File

@ -171,6 +171,21 @@ class TestProjectGroupSearch(base.FunctionalTest):
result = results.json[1]
self.assertEqual(3, result['id'])
def test_search_by_project(self):
url = self.build_search_url({
'project_id': 3
})
results = self.get_json(url, expect_errors=True)
self.assertEqual(2, len(results.json))
self.assertEqual('2', results.headers['X-Total'])
self.assertFalse('X-Marker' in results.headers)
result = results.json[0]
self.assertEqual(1, result['id'])
result = results.json[1]
self.assertEqual(2, result['id'])
def test_search_limit(self):
url = self.build_search_url({
'title': 'foo',