|
13 | 13 | from models_library.products import ProductName |
14 | 14 | from models_library.projects import ProjectID |
15 | 15 | from models_library.rpc.webserver.projects import ( |
| 16 | + ListProjectsMarkedAsJobRpcFilter, |
| 17 | + MetadataFilterItem, |
16 | 18 | PageRpcProjectJobRpcGet, |
17 | 19 | ProjectJobRpcGet, |
18 | 20 | ) |
@@ -114,7 +116,9 @@ async def test_rpc_client_list_my_projects_marked_as_jobs( |
114 | 116 | rpc_client=rpc_client, |
115 | 117 | product_name=product_name, |
116 | 118 | user_id=user_id, |
117 | | - filters={"job_parent_resource_name_prefix": "solvers/solver123"}, |
| 119 | + filters=ListProjectsMarkedAsJobRpcFilter( |
| 120 | + job_parent_resource_name_prefix="solvers/solver123" |
| 121 | + ), |
118 | 122 | ) |
119 | 123 |
|
120 | 124 | assert page.meta.total == 1 |
@@ -191,3 +195,115 @@ async def test_errors_on_rpc_client_mark_project_as_job( |
191 | 195 | assert exc_info.value.error_count() == 1 |
192 | 196 | assert exc_info.value.errors()[0]["loc"] == ("job_parent_resource_name",) |
193 | 197 | assert exc_info.value.errors()[0]["type"] == "value_error" |
| 198 | + |
| 199 | + |
| 200 | +async def test_rpc_client_list_projects_marked_as_jobs_with_metadata_filter( |
| 201 | + rpc_client: RabbitMQRPCClient, |
| 202 | + product_name: ProductName, |
| 203 | + logged_user: UserInfoDict, |
| 204 | + user_project: ProjectDict, |
| 205 | + client: TestClient, |
| 206 | +): |
| 207 | + from simcore_service_webserver.projects import _metadata_service |
| 208 | + |
| 209 | + project_uuid = ProjectID(user_project["uuid"]) |
| 210 | + user_id = logged_user["id"] |
| 211 | + |
| 212 | + # Mark the project as a job |
| 213 | + await projects_rpc.mark_project_as_job( |
| 214 | + rpc_client=rpc_client, |
| 215 | + product_name=product_name, |
| 216 | + user_id=user_id, |
| 217 | + project_uuid=project_uuid, |
| 218 | + job_parent_resource_name="solvers/solver123/version/1.2.3", |
| 219 | + ) |
| 220 | + |
| 221 | + # Set custom metadata on the project |
| 222 | + custom_metadata = { |
| 223 | + "solver_type": "FEM", |
| 224 | + "mesh_cells": "10000", |
| 225 | + "domain": "biomedical", |
| 226 | + } |
| 227 | + |
| 228 | + await _metadata_service.set_project_custom_metadata( |
| 229 | + app=client.app, |
| 230 | + user_id=user_id, |
| 231 | + project_uuid=project_uuid, |
| 232 | + value=custom_metadata, |
| 233 | + ) |
| 234 | + |
| 235 | + # Test with exact match on metadata field |
| 236 | + page: PageRpcProjectJobRpcGet = await projects_rpc.list_projects_marked_as_jobs( |
| 237 | + rpc_client=rpc_client, |
| 238 | + product_name=product_name, |
| 239 | + user_id=user_id, |
| 240 | + filters=ListProjectsMarkedAsJobRpcFilter( |
| 241 | + job_parent_resource_name_prefix="solvers/solver123", |
| 242 | + any_of_metadata=[MetadataFilterItem(name="solver_type", pattern="FEM")], |
| 243 | + ), |
| 244 | + ) |
| 245 | + |
| 246 | + assert page.meta.total == 1 |
| 247 | + assert len(page.data) == 1 |
| 248 | + assert page.data[0].uuid == project_uuid |
| 249 | + |
| 250 | + # Test with pattern match on metadata field |
| 251 | + page = await projects_rpc.list_projects_marked_as_jobs( |
| 252 | + rpc_client=rpc_client, |
| 253 | + product_name=product_name, |
| 254 | + user_id=user_id, |
| 255 | + filters=ListProjectsMarkedAsJobRpcFilter( |
| 256 | + any_of_metadata=[MetadataFilterItem(name="mesh_cells", pattern="1*")], |
| 257 | + ), |
| 258 | + ) |
| 259 | + |
| 260 | + assert page.meta.total == 1 |
| 261 | + assert len(page.data) == 1 |
| 262 | + assert page.data[0].uuid == project_uuid |
| 263 | + |
| 264 | + # Test with multiple metadata fields (any match should return the project) |
| 265 | + page = await projects_rpc.list_projects_marked_as_jobs( |
| 266 | + rpc_client=rpc_client, |
| 267 | + product_name=product_name, |
| 268 | + user_id=user_id, |
| 269 | + filters=ListProjectsMarkedAsJobRpcFilter( |
| 270 | + any_of_metadata=[ |
| 271 | + MetadataFilterItem(name="solver_type", pattern="FEM"), |
| 272 | + MetadataFilterItem(name="non_existent", pattern="value"), |
| 273 | + ], |
| 274 | + ), |
| 275 | + ) |
| 276 | + |
| 277 | + assert page.meta.total == 1 |
| 278 | + assert len(page.data) == 1 |
| 279 | + |
| 280 | + # Test with no matches |
| 281 | + page = await projects_rpc.list_projects_marked_as_jobs( |
| 282 | + rpc_client=rpc_client, |
| 283 | + product_name=product_name, |
| 284 | + user_id=user_id, |
| 285 | + filters=ListProjectsMarkedAsJobRpcFilter( |
| 286 | + any_of_metadata=[ |
| 287 | + MetadataFilterItem(name="solver_type", pattern="CFD"), # No match |
| 288 | + ], |
| 289 | + ), |
| 290 | + ) |
| 291 | + |
| 292 | + assert page.meta.total == 0 |
| 293 | + assert len(page.data) == 0 |
| 294 | + |
| 295 | + # Test with combination of resource prefix and metadata |
| 296 | + page = await projects_rpc.list_projects_marked_as_jobs( |
| 297 | + rpc_client=rpc_client, |
| 298 | + product_name=product_name, |
| 299 | + user_id=user_id, |
| 300 | + filters=ListProjectsMarkedAsJobRpcFilter( |
| 301 | + job_parent_resource_name_prefix="wrong/prefix", |
| 302 | + any_of_metadata=[ |
| 303 | + MetadataFilterItem(name="solver_type", pattern="FEM"), |
| 304 | + ], |
| 305 | + ), |
| 306 | + ) |
| 307 | + |
| 308 | + assert page.meta.total == 0 |
| 309 | + assert len(page.data) == 0 |
0 commit comments