From 2675d92df700760adf3f908b91f3ef3134bc389e Mon Sep 17 00:00:00 2001 From: NatSquared Date: Tue, 9 Apr 2024 11:54:24 -0700 Subject: [PATCH 1/2] Serialization Take 1 --- CHANGELOG.MD | 7 ++++ met-api/src/met_api/resources/engagement.py | 10 +++-- met-api/tests/unit/api/test_engagement.py | 38 +++++++++---------- .../src/components/landing/LandingContext.tsx | 2 +- .../src/services/engagementService/index.ts | 3 +- 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 8f32cbdad..fa0e5daca 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,10 @@ +## April 09, 2024 + +- **Bugfix**: Stop Axios from trying to be a smarty pants and sending data in a format Flask doesn't understand + - This was preventing the filtering feature from working + - Directly serialize any metadata filters before the request to avoid Axios's new nested object serialization + - Deserialize it again on the Flask side + ## April 08, 2024 - **Bugfix**: Submission of rejected comments [🎟️ DESENG-527](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-527) diff --git a/met-api/src/met_api/resources/engagement.py b/met-api/src/met_api/resources/engagement.py index d26bc151b..ba29a8555 100644 --- a/met-api/src/met_api/resources/engagement.py +++ b/met-api/src/met_api/resources/engagement.py @@ -85,9 +85,13 @@ def get(): if external_user_id is None: exclude_internal = True - metadata = args.getlist('metadata[]') - if metadata: - metadata = [json.loads(m) for m in metadata] + if metadata := args.get('metadata', []): + metadata = json.loads(metadata) + print(metadata) + if not isinstance(metadata, list) or not all(isinstance(item, dict) for item in metadata): + # if metadata is not a list of dictionaries, it is in the wrong format. + # blank it to avoid any issues. + metadata = [] search_options = { 'search_text': args.get('search_text', '', type=str), diff --git a/met-api/tests/unit/api/test_engagement.py b/met-api/tests/unit/api/test_engagement.py index 5cc97a4e1..df22f670c 100644 --- a/met-api/tests/unit/api/test_engagement.py +++ b/met-api/tests/unit/api/test_engagement.py @@ -558,47 +558,46 @@ def test_get_engagements_metadata_match_all(client, session): # pylint:disable= }) # pass in pagination options and do the count metadata_1 = json.dumps( - { + [{ 'name': 'Category', 'values': ['Category value'], 'filter_type': 'chips_all', 'taxon_id': taxon.id - }, + }], separators=(',', ':') # Remove spaces between keys and values ) - print(f'/api/engagements/?metadata[]={metadata_1}') - rv = client.get(f'/api/engagements/?metadata[]={metadata_1}') + rv = client.get(f'/api/engagements/?metadata={metadata_1}') assert rv.status_code == 200 assert rv.json.get('total') == 10 metadata_2 = json.dumps( - { + [{ 'name': 'Category', 'values': ['Different'], 'filter_type': 'chips_all', 'taxon_id': taxon.id - }, + }], separators=(',', ':') # Remove spaces between keys and values ) - rv = client.get(f'/api/engagements/?metadata[]={metadata_2}') + rv = client.get(f'/api/engagements/?metadata={metadata_2}') assert rv.status_code == 200 assert rv.json.get('total') == 1 metadata_3 = json.dumps( - { + [{ 'name': 'Category', 'values': ['Category value', 'Different'], 'filter_type': 'chips_all', 'taxon_id': taxon.id - }, + }], separators=(',', ':') # Remove spaces between keys and values ) rv = client.get( - f'/api/engagements/?metadata[]={metadata_3}') + f'/api/engagements/?metadata={metadata_3}') assert rv.status_code == 200 # the filter should only return the engagement with both values assert rv.json.get('total') == 1 @@ -633,47 +632,46 @@ def test_get_engagements_metadata_match_any(client, session): # pylint:disable= }) # pass in pagination options and do the count metadata_1 = json.dumps( - { + [{ 'name': 'Category', 'values': ['Category value'], 'filter_type': 'chips_any', 'taxon_id': taxon.id - }, + }], separators=(',', ':') # Remove spaces between keys and values ) - print(f'/api/engagements/?metadata[]={metadata_1}') - rv = client.get(f'/api/engagements/?metadata[]={metadata_1}') + rv = client.get(f'/api/engagements/?metadata={metadata_1}') assert rv.status_code == 200 assert rv.json.get('total') == 10 metadata_2 = json.dumps( - { + [{ 'name': 'Category', 'values': ['Different'], 'filter_type': 'chips_any', 'taxon_id': taxon.id - }, + }], separators=(',', ':') # Remove spaces between keys and values ) - rv = client.get(f'/api/engagements/?metadata[]={metadata_2}') + rv = client.get(f'/api/engagements/?metadata={metadata_2}') assert rv.status_code == 200 assert rv.json.get('total') == 1 metadata_3 = json.dumps( - { + [{ 'name': 'Category', 'values': ['Category value', 'Different'], 'filter_type': 'chips_any', 'taxon_id': taxon.id - }, + }], separators=(',', ':') # Remove spaces between keys and values ) rv = client.get( - f'/api/engagements/?metadata[]={metadata_3}') + f'/api/engagements/?metadata={metadata_3}') assert rv.status_code == 200 # the filter should return the engagements with either value assert rv.json.get('total') == 10 diff --git a/met-web/src/components/landing/LandingContext.tsx b/met-web/src/components/landing/LandingContext.tsx index 10988b849..f96a6a19f 100644 --- a/met-web/src/components/landing/LandingContext.tsx +++ b/met-web/src/components/landing/LandingContext.tsx @@ -75,7 +75,7 @@ export const LandingContextProvider = ({ children }: { children: JSX.Element | J include_banner_url: true, engagement_status: status, search_text: name, - metadata: searchFilters.metadata, + metadata: JSON.stringify(searchFilters.metadata), }); setEngagements(loadedEngagements.items); setTotalEngagements(loadedEngagements.total); diff --git a/met-web/src/services/engagementService/index.ts b/met-web/src/services/engagementService/index.ts index cf03a954e..b655306c5 100644 --- a/met-web/src/services/engagementService/index.ts +++ b/met-web/src/services/engagementService/index.ts @@ -6,7 +6,6 @@ import { PatchEngagementRequest, PostEngagementRequest, PutEngagementRequest } f import Endpoints from 'apiManager/endpoints'; import { replaceUrl } from 'helper'; import { Page } from 'services/type'; -import { MetadataFilter } from 'components/metadataManagement/types'; export const fetchAll = async (dispatch: Dispatch): Promise => { const responseData = await http.GetRequest(Endpoints.Engagement.GET_LIST); @@ -28,7 +27,7 @@ interface GetEngagementsParams { published_to_date?: string; include_banner_url?: boolean; has_team_access?: boolean; - metadata?: MetadataFilter[]; + metadata?: string; } export const getEngagements = async (params: GetEngagementsParams = {}): Promise> => { const responseData = await http.GetRequest>(Endpoints.Engagement.GET_LIST, params); From 715b73620ddb3d52f8414c33db54d2beca3c5bb3 Mon Sep 17 00:00:00 2001 From: NatSquared Date: Tue, 9 Apr 2024 14:29:04 -0700 Subject: [PATCH 2/2] don't print(metadata)! --- met-api/src/met_api/resources/engagement.py | 1 - 1 file changed, 1 deletion(-) diff --git a/met-api/src/met_api/resources/engagement.py b/met-api/src/met_api/resources/engagement.py index ba29a8555..e7ca8d450 100644 --- a/met-api/src/met_api/resources/engagement.py +++ b/met-api/src/met_api/resources/engagement.py @@ -87,7 +87,6 @@ def get(): if metadata := args.get('metadata', []): metadata = json.loads(metadata) - print(metadata) if not isinstance(metadata, list) or not all(isinstance(item, dict) for item in metadata): # if metadata is not a list of dictionaries, it is in the wrong format. # blank it to avoid any issues.