From d2feecd4430561abe5d22830afaece73c19a7a0f Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 3 May 2022 14:48:47 -0400 Subject: [PATCH] Bugfix - allow filtering on multiple workflow tags at once. --- lib/galaxy/managers/workflows.py | 12 +++++++--- lib/galaxy_test/api/test_workflows.py | 33 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/galaxy/managers/workflows.py b/lib/galaxy/managers/workflows.py index 96fcd06e33e..33a1b5a5676 100644 --- a/lib/galaxy/managers/workflows.py +++ b/lib/galaxy/managers/workflows.py @@ -27,6 +27,7 @@ from sqlalchemy import ( true, ) from sqlalchemy.orm import ( + aliased, joinedload, Query, subqueryload, @@ -160,7 +161,10 @@ class WorkflowsManager(sharable.SharableModelManager): parsed_search = parse_filters_structured(search_query, INDEX_SEARCH_FILTERS) def w_tag_filter(term_text: str, quoted: bool): - return tag_filter(model.StoredWorkflowTagAssociation, term_text, quoted) + nonlocal query + alias = aliased(model.StoredWorkflowTagAssociation) + query = query.outerjoin(model.StoredWorkflow.tags.of_type(alias)) + return tag_filter(alias, term_text, quoted) def name_filter(term): return text_column_filter(model.StoredWorkflow.name, term) @@ -170,7 +174,8 @@ class WorkflowsManager(sharable.SharableModelManager): key = term.filter q = term.text if key == "tag": - query = query.filter(w_tag_filter(term.text, term.quoted)) + tf = w_tag_filter(term.text, term.quoted) + query = query.filter(tf) elif key == "name": query = query.filter(name_filter(term)) elif key == "is": @@ -182,11 +187,12 @@ class WorkflowsManager(sharable.SharableModelManager): raise exceptions.RequestParameterInvalidException(message) query = query.filter(model.StoredWorkflowUserShareAssociation.user == user) elif isinstance(term, RawTextTerm): + tf = w_tag_filter(term.text, False) query = query.filter( raw_text_column_filter( [ model.StoredWorkflow.name, - w_tag_filter(term.text, False), + tf, ], term, ) diff --git a/lib/galaxy_test/api/test_workflows.py b/lib/galaxy_test/api/test_workflows.py index fbcb2e5a76f..935719c08d4 100644 --- a/lib/galaxy_test/api/test_workflows.py +++ b/lib/galaxy_test/api/test_workflows.py @@ -493,6 +493,39 @@ class WorkflowsApiTestCase(BaseWorkflowsApiTestCase, ChangeDatatypeTestCase): index_ids = self.workflow_populator.index_ids(search="tag:moocowatag") assert workflow_id_1 in index_ids + def test_index_search_tags_multiple(self): + name1 = self.dataset_populator.get_random_name() + name2 = self.dataset_populator.get_random_name() + name3 = self.dataset_populator.get_random_name() + workflow_id_1 = self.workflow_populator.simple_workflow(name1) + workflow_id_2 = self.workflow_populator.simple_workflow(name2) + workflow_id_3 = self.workflow_populator.simple_workflow(name3) + self.workflow_populator.set_tags(workflow_id_1, ["multipletagfilter1", "multipletagfilter2", "decoy1"]) + self.workflow_populator.set_tags(workflow_id_2, ["multipletagfilter1", "decoy2"]) + self.workflow_populator.set_tags(workflow_id_3, ["multipletagfilter2", "decoy3"]) + + for search in ["multipletagfilter1", "tag:ipletagfilter1", "tag:'multipletagfilter1'"]: + index_ids = self.workflow_populator.index_ids(search=search) + assert workflow_id_1 in index_ids + assert workflow_id_2 in index_ids + assert workflow_id_3 not in index_ids + + for search in ["multipletagfilter2", "tag:ipletagfilter2", "tag:'multipletagfilter2'"]: + index_ids = self.workflow_populator.index_ids(search=search) + assert workflow_id_1 in index_ids + assert workflow_id_2 not in index_ids + assert workflow_id_3 in index_ids + + for search in [ + "multipletagfilter2 multipletagfilter1", + "tag:filter2 tag:tagfilter1", + "tag:'multipletagfilter2' tag:'multipletagfilter1'", + ]: + index_ids = self.workflow_populator.index_ids(search=search) + assert workflow_id_1 in index_ids + assert workflow_id_2 not in index_ids + assert workflow_id_3 not in index_ids + def test_search_casing(self): name1, name2 = ( self.dataset_populator.get_random_name().upper(),