mirror of
https://github.com/status-im/spiff-arena.git
synced 2025-02-23 06:58:10 +00:00
fixed is_empty metadata filter and added test to ensure they all work w/ burnettk (#437)
Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
96810f1d67
commit
2d8e262681
@ -563,30 +563,30 @@ class ProcessInstanceReportService:
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
isouter = True
|
isouter = True
|
||||||
conditions = [
|
join_conditions = [
|
||||||
ProcessInstanceModel.id == instance_metadata_alias.process_instance_id,
|
ProcessInstanceModel.id == instance_metadata_alias.process_instance_id,
|
||||||
instance_metadata_alias.key == column["accessor"],
|
instance_metadata_alias.key == column["accessor"],
|
||||||
]
|
]
|
||||||
if filter_for_column:
|
if filter_for_column:
|
||||||
isouter = False
|
isouter = False
|
||||||
if "operator" not in filter_for_column or filter_for_column["operator"] == "equals":
|
if "operator" not in filter_for_column or filter_for_column["operator"] == "equals":
|
||||||
conditions.append(instance_metadata_alias.value == filter_for_column["field_value"])
|
join_conditions.append(instance_metadata_alias.value == filter_for_column["field_value"])
|
||||||
elif filter_for_column["operator"] == "not equals":
|
elif filter_for_column["operator"] == "not_equals":
|
||||||
conditions.append(instance_metadata_alias.value != filter_for_column["field_value"])
|
join_conditions.append(instance_metadata_alias.value != filter_for_column["field_value"])
|
||||||
elif filter_for_column["operator"] == "contains":
|
elif filter_for_column["operator"] == "contains":
|
||||||
conditions.append(instance_metadata_alias.value.like(f"%{filter_for_column['field_value']}%"))
|
join_conditions.append(instance_metadata_alias.value.like(f"%{filter_for_column['field_value']}%"))
|
||||||
elif filter_for_column["operator"] == "is_empty":
|
elif filter_for_column["operator"] == "is_empty":
|
||||||
# we still need to return results if the metadata value is null so make sure it's outer join
|
# we still need to return results if the metadata value is null so make sure it's outer join
|
||||||
isouter = True
|
isouter = True
|
||||||
conditions.append(
|
process_instance_query = process_instance_query.filter(
|
||||||
or_(instance_metadata_alias.value.is_(None), instance_metadata_alias.value == "")
|
or_(instance_metadata_alias.value.is_(None), instance_metadata_alias.value == "")
|
||||||
)
|
)
|
||||||
elif filter_for_column["operator"] == "is_not_empty":
|
elif filter_for_column["operator"] == "is_not_empty":
|
||||||
conditions.append(
|
join_conditions.append(
|
||||||
or_(instance_metadata_alias.value.is_not(None), instance_metadata_alias.value != "")
|
or_(instance_metadata_alias.value.is_not(None), instance_metadata_alias.value != "")
|
||||||
)
|
)
|
||||||
process_instance_query = process_instance_query.join(
|
process_instance_query = process_instance_query.join(
|
||||||
instance_metadata_alias, and_(*conditions), isouter=isouter
|
instance_metadata_alias, and_(*join_conditions), isouter=isouter
|
||||||
).add_columns(func.max(instance_metadata_alias.value).label(column["accessor"]))
|
).add_columns(func.max(instance_metadata_alias.value).label(column["accessor"]))
|
||||||
|
|
||||||
order_by_query_array = []
|
order_by_query_array = []
|
||||||
|
@ -17,6 +17,8 @@ from spiffworkflow_backend.models.permission_target import PermissionTargetModel
|
|||||||
from spiffworkflow_backend.models.process_group import ProcessGroup
|
from spiffworkflow_backend.models.process_group import ProcessGroup
|
||||||
from spiffworkflow_backend.models.process_group import ProcessGroupSchema
|
from spiffworkflow_backend.models.process_group import ProcessGroupSchema
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||||
|
from spiffworkflow_backend.models.process_instance_metadata import ProcessInstanceMetadataModel
|
||||||
|
from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel
|
||||||
from spiffworkflow_backend.models.process_instance_report import ReportMetadata
|
from spiffworkflow_backend.models.process_instance_report import ReportMetadata
|
||||||
from spiffworkflow_backend.models.process_model import NotificationType
|
from spiffworkflow_backend.models.process_model import NotificationType
|
||||||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||||
@ -453,6 +455,52 @@ class BaseTest:
|
|||||||
assert po_curr is not None
|
assert po_curr is not None
|
||||||
assert customer_curr is not None
|
assert customer_curr is not None
|
||||||
|
|
||||||
|
def create_process_instance_with_synthetic_metadata(
|
||||||
|
self, process_model: ProcessModelInfo, process_instance_metadata_dict: dict
|
||||||
|
) -> ProcessInstanceModel:
|
||||||
|
process_instance = self.create_process_instance_from_process_model(process_model=process_model)
|
||||||
|
processor = ProcessInstanceProcessor(process_instance)
|
||||||
|
processor.do_engine_steps(save=True)
|
||||||
|
for key, value in process_instance_metadata_dict.items():
|
||||||
|
process_instance_metadata = ProcessInstanceMetadataModel(
|
||||||
|
process_instance_id=process_instance.id,
|
||||||
|
key=key,
|
||||||
|
value=value,
|
||||||
|
)
|
||||||
|
db.session.add(process_instance_metadata)
|
||||||
|
db.session.commit()
|
||||||
|
return process_instance
|
||||||
|
|
||||||
|
def assert_report_with_process_metadata_operator_includes_instance(
|
||||||
|
self,
|
||||||
|
client: FlaskClient,
|
||||||
|
user: UserModel,
|
||||||
|
process_instance: ProcessInstanceModel,
|
||||||
|
operator: str,
|
||||||
|
filter_field_value: str = "",
|
||||||
|
) -> None:
|
||||||
|
report_metadata: ReportMetadata = {
|
||||||
|
"columns": [
|
||||||
|
{"Header": "ID", "accessor": "id", "filterable": False},
|
||||||
|
{"Header": "Key one", "accessor": "key1", "filterable": False},
|
||||||
|
{"Header": "Key two", "accessor": "key2", "filterable": False},
|
||||||
|
],
|
||||||
|
"order_by": ["status"],
|
||||||
|
"filter_by": [{"field_name": "key1", "field_value": filter_field_value, "operator": operator}],
|
||||||
|
}
|
||||||
|
process_instance_report = ProcessInstanceReportModel.create_report(
|
||||||
|
identifier=f"{process_instance.id}_sure",
|
||||||
|
report_metadata=report_metadata,
|
||||||
|
user=user,
|
||||||
|
)
|
||||||
|
response = self.post_to_process_instance_list(
|
||||||
|
client, user, report_metadata=process_instance_report.get_report_metadata()
|
||||||
|
)
|
||||||
|
assert len(response.json["results"]) == 1
|
||||||
|
assert response.json["results"][0]["id"] == process_instance.id
|
||||||
|
db.session.delete(process_instance_report)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def app_config_mock(self, app: Flask, config_identifier: str, new_config_value: Any) -> Generator:
|
def app_config_mock(self, app: Flask, config_identifier: str, new_config_value: Any) -> Generator:
|
||||||
initial_value = app.config[config_identifier]
|
initial_value = app.config[config_identifier]
|
||||||
|
@ -2848,6 +2848,57 @@ class TestProcessApi(BaseTest):
|
|||||||
assert response.json["pagination"]["pages"] == 1
|
assert response.json["pagination"]["pages"] == 1
|
||||||
assert response.json["pagination"]["total"] == 1
|
assert response.json["pagination"]["total"] == 1
|
||||||
|
|
||||||
|
def test_can_get_process_instance_list_with_report_metadata_using_different_operators(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
process_model = load_test_spec(
|
||||||
|
process_model_id="save_process_instance_metadata/save_process_instance_metadata",
|
||||||
|
bpmn_file_name="save_process_instance_metadata.bpmn",
|
||||||
|
process_model_source_directory="save_process_instance_metadata",
|
||||||
|
)
|
||||||
|
|
||||||
|
process_instance_one_metadata = {"key1": "value1"}
|
||||||
|
process_instance_one = self.create_process_instance_with_synthetic_metadata(
|
||||||
|
process_model=process_model, process_instance_metadata_dict=process_instance_one_metadata
|
||||||
|
)
|
||||||
|
|
||||||
|
process_instance_two_metadata = {"key2": "value2"}
|
||||||
|
process_instance_two = self.create_process_instance_with_synthetic_metadata(
|
||||||
|
process_model=process_model, process_instance_metadata_dict=process_instance_two_metadata
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assert_report_with_process_metadata_operator_includes_instance(
|
||||||
|
client=client, user=with_super_admin_user, process_instance=process_instance_one, operator="is_not_empty"
|
||||||
|
)
|
||||||
|
self.assert_report_with_process_metadata_operator_includes_instance(
|
||||||
|
client=client,
|
||||||
|
user=with_super_admin_user,
|
||||||
|
process_instance=process_instance_one,
|
||||||
|
operator="equals",
|
||||||
|
filter_field_value="value1",
|
||||||
|
)
|
||||||
|
self.assert_report_with_process_metadata_operator_includes_instance(
|
||||||
|
client=client,
|
||||||
|
user=with_super_admin_user,
|
||||||
|
process_instance=process_instance_one,
|
||||||
|
operator="contains",
|
||||||
|
filter_field_value="alu",
|
||||||
|
)
|
||||||
|
self.assert_report_with_process_metadata_operator_includes_instance(
|
||||||
|
client=client,
|
||||||
|
user=with_super_admin_user,
|
||||||
|
process_instance=process_instance_one,
|
||||||
|
operator="not_equals",
|
||||||
|
filter_field_value="hey",
|
||||||
|
)
|
||||||
|
self.assert_report_with_process_metadata_operator_includes_instance(
|
||||||
|
client=client, user=with_super_admin_user, process_instance=process_instance_two, operator="is_empty"
|
||||||
|
)
|
||||||
|
|
||||||
def test_can_get_process_instance_list_with_report_metadata_and_process_initiator(
|
def test_can_get_process_instance_list_with_report_metadata_and_process_initiator(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
|
@ -168,7 +168,7 @@ export default function ProcessInstanceListTable({
|
|||||||
|
|
||||||
const filterOperatorMappings: FilterOperatorMapping = {
|
const filterOperatorMappings: FilterOperatorMapping = {
|
||||||
Is: { id: 'equals', requires_value: true },
|
Is: { id: 'equals', requires_value: true },
|
||||||
'Is Not': { id: 'not equals', requires_value: true },
|
'Is Not': { id: 'not_equals', requires_value: true },
|
||||||
Contains: { id: 'contains', requires_value: true },
|
Contains: { id: 'contains', requires_value: true },
|
||||||
'Is Empty': { id: 'is_empty', requires_value: false },
|
'Is Empty': { id: 'is_empty', requires_value: false },
|
||||||
'Is Not Empty': { id: 'is_not_empty', requires_value: false },
|
'Is Not Empty': { id: 'is_not_empty', requires_value: false },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user