From 601c39a756491192e30571e49eedd2214ce3736e Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Mon, 16 Oct 2023 18:05:57 -0300 Subject: [PATCH 1/8] fix(ttc): add tree cover density validation to getWHEREQuery method Now when the user select a thresold on the ttc layer, tree cover density widget will ignore that and keep fetching using >=10% of thresold and the right table wri_tropical_tree_cover__decile --- services/analysis-cached.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/services/analysis-cached.js b/services/analysis-cached.js index 299ee31820..cbec3a054d 100644 --- a/services/analysis-cached.js +++ b/services/analysis-cached.js @@ -85,6 +85,14 @@ const SQL_QUERIES = { const ALLOWED_PARAMS = { annual: ['adm0', 'adm1', 'adm2', 'threshold', 'forestType', 'landCategory'], + treeCoverDensity: [ + 'adm0', + 'adm1', + 'adm2', + 'threshold', + 'forestType', + 'landCategory', + ], integrated_alerts: [ 'adm0', 'adm1', @@ -340,6 +348,8 @@ export const getWHEREQuery = (params) => { (!isNaN(value) && !['adm0', 'confidence'].includes(p)) ); + const isTreeCoverDensity = dataset === 'treeCoverDensity'; + let paramKey = p; if (p === 'confidence') paramKey = 'confidence__cat'; if (p === 'threshold') { @@ -386,12 +396,12 @@ export const getWHEREQuery = (params) => { }` : '' }${ - !isPolyname - ? `${paramKey}${comparisonString}${ + !isPolyname && isTreeCoverDensity && p === 'threshold' + ? '' + : `${paramKey}${comparisonString}${ isNumericValue ? value : `'${value}'` }` - : '' - }${isLast ? '' : ' AND '}`; + }${isLast || isTreeCoverDensity ? '' : ' AND '}`; paramString = paramString.concat(polynameString); }); @@ -2065,7 +2075,10 @@ export const getTreeCoverDensity = (params) => { getLocationSelect({ ...params, cast: false }) ) .replace(/{location}/g, getLocationSelect({ ...params })) - .replace('{WHERE}', getWHEREQuery({ ...params, dataset: 'annual' })) + .replace( + '{WHERE}', + getWHEREQuery({ ...params, dataset: 'treeCoverDensity' }) + ) ); return dataRequest.get(url).then((response) => response.data); From abc47eb569a1f1d680b3537fb432753558a3b358 Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Tue, 17 Oct 2023 15:35:36 -0300 Subject: [PATCH 2/8] fix(ttc): refactor getWHEREQuery - Improve readability - Add tree cover density validation to remove threshold paramater from layers - Split responsibilities to follow single-responsibility principle --- services/analysis-cached.js | 196 ++++++++++++++++++++---------------- 1 file changed, 109 insertions(+), 87 deletions(-) diff --git a/services/analysis-cached.js b/services/analysis-cached.js index cbec3a054d..a9dc0cf165 100644 --- a/services/analysis-cached.js +++ b/services/analysis-cached.js @@ -313,101 +313,123 @@ const getLocationSelect = ({ ); }; +const isNumber = (value) => !!(typeof value === 'number' || !isNaN(value)); + +const translateParameterKey = (parameterKey, { type, dataset }) => { + let paramKey = ''; + + if (parameterKey === 'confidence') paramKey = 'confidence__cat'; + if (parameterKey === 'adm0' && type === 'country') paramKey = 'iso'; + if (parameterKey === 'adm1' && type === 'country') paramKey = 'adm1'; + if (parameterKey === 'adm2' && type === 'country') paramKey = 'adm2'; + if (parameterKey === 'adm0' && type === 'geostore') paramKey = 'geostore__id'; + if (parameterKey === 'adm0' && type === 'wdpa') + paramKey = 'wdpa_protected_area__id'; + + if (parameterKey === 'threshold') { + if (dataset === 'tropicalTreeCover') { + paramKey = 'wri_tropical_tree_cover__decile'; + } else { + paramKey = 'umd_tree_cover_density_2000__threshold'; + } + } + + return paramKey; +}; + // build {where} statement for query -export const getWHEREQuery = (params) => { - const allPolynames = forestTypes.concat(landCategories); - const paramKeys = params && Object.keys(params); - const allowedParams = ALLOWED_PARAMS[params.dataset || 'annual']; - const paramKeysFiltered = paramKeys.filter( - (p) => (params[p] || p === 'threshold') && allowedParams.includes(p) - ); +export const getWHEREQuery = (params = {}) => { const { type, dataset } = params || {}; - let comparisonString = ' = '; - if (paramKeysFiltered && paramKeysFiltered.length) { - let paramString = 'WHERE '; - paramKeysFiltered.forEach((p, i) => { - const isLast = paramKeysFiltered.length - 1 === i; - const isPolyname = ['forestType', 'landCategory'].includes(p); - const value = isPolyname ? 1 : params[p]; - const polynameMeta = allPolynames.find( - (pname) => pname.value === params[p] - ); - const tableKey = - polynameMeta && - (polynameMeta.tableKey || polynameMeta.tableKeys[dataset || 'annual']); - - /* TODO - perform better casting / allow to configure types: - AS for example wdpa_protected_area__id needs to be a string, - even that it evaluates AS a number. - Note that the postgres tables will allow us to cast at the query level. - */ - // const zeroString = polynameMeta?.dataType === 'keyword' ? "'0'" : '0'; - let isNumericValue = !!( - typeof value === 'number' || - (!isNaN(value) && !['adm0', 'confidence'].includes(p)) - ); - - const isTreeCoverDensity = dataset === 'treeCoverDensity'; - - let paramKey = p; - if (p === 'confidence') paramKey = 'confidence__cat'; - if (p === 'threshold') { - // paramKey = 'umd_tree_cover_density__threshold'; - comparisonString = ' = '; - - if (dataset === 'tropicalTreeCover') { - paramKey = 'wri_tropical_tree_cover__decile'; - } else { - paramKey = 'umd_tree_cover_density_2000__threshold'; - } - - // } - } - if (p === 'adm0' && type === 'country') paramKey = 'iso'; - if (p === 'adm1' && type === 'country') paramKey = 'adm1'; - if (p === 'adm2' && type === 'country') paramKey = 'adm2'; - if (p === 'adm0' && type === 'geostore') paramKey = 'geostore__id'; - if (p === 'adm0' && type === 'wdpa') { - paramKey = 'wdpa_protected_area__id'; - isNumericValue = false; + + const allFilterOptions = forestTypes.concat(landCategories); + const allowedParams = ALLOWED_PARAMS[params.dataset || 'annual']; + const isTreeCoverDensity = dataset === 'treeCoverDensity'; + const comparisonString = ' = '; + + let paramString = 'WHERE '; + let paramKeys = Object.keys(params).filter((parameterName) => { + return ( + (params[parameterName] || parameterName === 'threshold') && + allowedParams.includes(parameterName) + ); + }); + + if (!paramKeys?.length) { + return ''; + } + + /* + * Removing threshold from Tree Cover Density request + * Tree Cover Density has a default threshold >=10 + */ + if (isTreeCoverDensity && paramKeys.includes('threshold')) { + paramKeys = paramKeys.filter((item) => item !== 'threshold'); + } + + paramKeys.forEach((parameter, index) => { + const isLastParameter = paramKeys.length - 1 === index; + const hasFilterOption = ['forestType', 'landCategory'].includes(parameter); + const value = hasFilterOption ? 1 : params[parameter]; + const polynameMeta = allFilterOptions.find( + (pname) => pname.value === params[parameter] + ); + const tableKey = + polynameMeta && + (polynameMeta.tableKey || polynameMeta.tableKeys[dataset || 'annual']); + let isNumericValue = isNumber(value); + + const paramKey = translateParameterKey(parameter, params); + + if (parameter === 'adm0' && type === 'wdpa') { + isNumericValue = false; + } + + if (dataset === 'net_change') { + isNumericValue = false; + } + + const hasPrefixIs__ = hasFilterOption && tableKey.includes('is__'); + let WHERE = ''; + + if (hasFilterOption) { + if (hasPrefixIs__) { + WHERE = `${WHERE}${tableKey} = 'true'`; } - if (dataset === 'net_change') { - isNumericValue = false; + + if (!hasPrefixIs__) { + WHERE = `${WHERE}${tableKey} IS NOT NULL`; } - const polynameString = ` - ${ - isPolyname && tableKey.includes('is__') ? `${tableKey} = 'true'` : '' - }${ - isPolyname && !tableKey.includes('is__') - ? `${tableKey} IS NOT NULL` - : '' - }${ - isPolyname && + if ( polynameMeta && - !tableKey.includes('is__') && + !hasPrefixIs__ && polynameMeta.default && polynameMeta.categories - ? ` AND ${tableKey} ${polynameMeta.comparison || '='} ${ - polynameMeta?.dataType === 'keyword' - ? `'${polynameMeta?.default}'` - : `${polynameMeta?.default}` - }` - : '' - }${ - !isPolyname && isTreeCoverDensity && p === 'threshold' - ? '' - : `${paramKey}${comparisonString}${ - isNumericValue ? value : `'${value}'` - }` - }${isLast || isTreeCoverDensity ? '' : ' AND '}`; - - paramString = paramString.concat(polynameString); - }); - return paramString; - } - return ''; + ) { + WHERE = `${WHERE} AND ${tableKey} ${polynameMeta.comparison || '='} ${ + polynameMeta?.dataType === 'keyword' + ? `'${polynameMeta?.default}'` + : `${polynameMeta?.default}` + }`; + } + } + + if (!hasFilterOption) { + WHERE = `${WHERE}${paramKey}${comparisonString}${ + isNumericValue ? value : `'${value}'` + }`; + } + + if (isLastParameter) { + WHERE = `${WHERE} `; + } else { + WHERE = `${WHERE} AND `; + } + + paramString = paramString.concat(WHERE); + }); + + return paramString; }; export const getDatesFilter = ({ startDate }) => { From d47133233dd6411a7959e8cc9f9760e2c876b63a Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Fri, 20 Oct 2023 12:39:12 -0300 Subject: [PATCH 3/8] chore(analysis-cached): move getWhereQuery and dependencies to a different file --- services/analysis-cached.js | 176 +----------------------- services/get-where-query.js | 102 ++++++++++++++ utils/get-where-query-allowed-params.js | 50 +++++++ utils/get-where-query-translation.js | 23 ++++ 4 files changed, 179 insertions(+), 172 deletions(-) create mode 100644 services/get-where-query.js create mode 100644 utils/get-where-query-allowed-params.js create mode 100644 utils/get-where-query-translation.js diff --git a/services/analysis-cached.js b/services/analysis-cached.js index a9dc0cf165..0eafe2f79d 100644 --- a/services/analysis-cached.js +++ b/services/analysis-cached.js @@ -1,12 +1,16 @@ import { cartoRequest, dataRequest } from 'utils/request'; import { PROXIES } from 'utils/proxies'; + import forestTypes from 'data/forest-types'; import landCategories from 'data/land-categories'; import DATASETS from 'data/analysis-datasets.json'; import DATASETS_VERSIONS from 'data/analysis-datasets-versions.json'; + import snakeCase from 'lodash/snakeCase'; import moment from 'moment'; +import { getWHEREQuery } from './get-where-query'; + const VIIRS_START_YEAR = 2012; const SQL_QUERIES = { @@ -83,59 +87,6 @@ const SQL_QUERIES = { 'SELECT {select_location}, wri_tropical_tree_cover__decile, SUM(wri_tropical_tree_cover_extent__ha) AS wri_tropical_tree_cover_extent__ha FROM data {WHERE} AND wri_tropical_tree_cover__decile >= 0 GROUP BY {location}, wri_tropical_tree_cover__decile ORDER BY {location}, wri_tropical_tree_cover__decile', }; -const ALLOWED_PARAMS = { - annual: ['adm0', 'adm1', 'adm2', 'threshold', 'forestType', 'landCategory'], - treeCoverDensity: [ - 'adm0', - 'adm1', - 'adm2', - 'threshold', - 'forestType', - 'landCategory', - ], - integrated_alerts: [ - 'adm0', - 'adm1', - 'adm2', - 'forestType', - 'landCategory', - 'is__confirmed_alert', - ], - glad: [ - 'adm0', - 'adm1', - 'adm2', - 'forestType', - 'landCategory', - 'is__confirmed_alert', - ], - viirs: ['adm0', 'adm1', 'adm2', 'forestType', 'landCategory', 'confidence'], - modis: ['adm0', 'adm1', 'adm2', 'forestType', 'landCategory', 'confidence'], - modis_burned_area: [ - 'adm0', - 'adm1', - 'adm2', - 'threshold', - 'forestType', - 'landCategory', - 'confidence', - ], - net_change: [ - 'adm0', - 'adm1', - 'adm2', - 'threshold', - 'forestType', - 'landCategory', - 'confidence', - ], - tropicalTreeCover: ['adm0', 'adm1', 'adm2', 'threshold', 'forestType'], -}; - -// -// function for building analysis table queries from params -// - const typeByGrouped = { global: { default: 'adm0', @@ -313,125 +264,6 @@ const getLocationSelect = ({ ); }; -const isNumber = (value) => !!(typeof value === 'number' || !isNaN(value)); - -const translateParameterKey = (parameterKey, { type, dataset }) => { - let paramKey = ''; - - if (parameterKey === 'confidence') paramKey = 'confidence__cat'; - if (parameterKey === 'adm0' && type === 'country') paramKey = 'iso'; - if (parameterKey === 'adm1' && type === 'country') paramKey = 'adm1'; - if (parameterKey === 'adm2' && type === 'country') paramKey = 'adm2'; - if (parameterKey === 'adm0' && type === 'geostore') paramKey = 'geostore__id'; - if (parameterKey === 'adm0' && type === 'wdpa') - paramKey = 'wdpa_protected_area__id'; - - if (parameterKey === 'threshold') { - if (dataset === 'tropicalTreeCover') { - paramKey = 'wri_tropical_tree_cover__decile'; - } else { - paramKey = 'umd_tree_cover_density_2000__threshold'; - } - } - - return paramKey; -}; - -// build {where} statement for query -export const getWHEREQuery = (params = {}) => { - const { type, dataset } = params || {}; - - const allFilterOptions = forestTypes.concat(landCategories); - const allowedParams = ALLOWED_PARAMS[params.dataset || 'annual']; - const isTreeCoverDensity = dataset === 'treeCoverDensity'; - const comparisonString = ' = '; - - let paramString = 'WHERE '; - let paramKeys = Object.keys(params).filter((parameterName) => { - return ( - (params[parameterName] || parameterName === 'threshold') && - allowedParams.includes(parameterName) - ); - }); - - if (!paramKeys?.length) { - return ''; - } - - /* - * Removing threshold from Tree Cover Density request - * Tree Cover Density has a default threshold >=10 - */ - if (isTreeCoverDensity && paramKeys.includes('threshold')) { - paramKeys = paramKeys.filter((item) => item !== 'threshold'); - } - - paramKeys.forEach((parameter, index) => { - const isLastParameter = paramKeys.length - 1 === index; - const hasFilterOption = ['forestType', 'landCategory'].includes(parameter); - const value = hasFilterOption ? 1 : params[parameter]; - const polynameMeta = allFilterOptions.find( - (pname) => pname.value === params[parameter] - ); - const tableKey = - polynameMeta && - (polynameMeta.tableKey || polynameMeta.tableKeys[dataset || 'annual']); - let isNumericValue = isNumber(value); - - const paramKey = translateParameterKey(parameter, params); - - if (parameter === 'adm0' && type === 'wdpa') { - isNumericValue = false; - } - - if (dataset === 'net_change') { - isNumericValue = false; - } - - const hasPrefixIs__ = hasFilterOption && tableKey.includes('is__'); - let WHERE = ''; - - if (hasFilterOption) { - if (hasPrefixIs__) { - WHERE = `${WHERE}${tableKey} = 'true'`; - } - - if (!hasPrefixIs__) { - WHERE = `${WHERE}${tableKey} IS NOT NULL`; - } - - if ( - polynameMeta && - !hasPrefixIs__ && - polynameMeta.default && - polynameMeta.categories - ) { - WHERE = `${WHERE} AND ${tableKey} ${polynameMeta.comparison || '='} ${ - polynameMeta?.dataType === 'keyword' - ? `'${polynameMeta?.default}'` - : `${polynameMeta?.default}` - }`; - } - } - - if (!hasFilterOption) { - WHERE = `${WHERE}${paramKey}${comparisonString}${ - isNumericValue ? value : `'${value}'` - }`; - } - - if (isLastParameter) { - WHERE = `${WHERE} `; - } else { - WHERE = `${WHERE} AND `; - } - - paramString = paramString.concat(WHERE); - }); - - return paramString; -}; - export const getDatesFilter = ({ startDate }) => { const startYear = startDate ? moment(startDate).year() diff --git a/services/get-where-query.js b/services/get-where-query.js new file mode 100644 index 0000000000..5b8d732b50 --- /dev/null +++ b/services/get-where-query.js @@ -0,0 +1,102 @@ +import ALLOWED_PARAMS from 'utils/get-where-query-allowed-params'; +import { translateParameterKey } from 'utils/get-where-query-translation'; + +import forestTypes from 'data/forest-types'; +import landCategories from 'data/land-categories'; + +const isNumber = (value) => !!(typeof value === 'number' || !isNaN(value)); + +// build {where} statement for query +export const getWHEREQuery = (params = {}) => { + const { type, dataset } = params || {}; + + const allFilterOptions = forestTypes.concat(landCategories); + const allowedParams = ALLOWED_PARAMS[params.dataset || 'annual']; + const isTreeCoverDensity = dataset === 'treeCoverDensity'; + const comparisonString = ' = '; + + let paramString = 'WHERE '; + let paramKeys = Object.keys(params).filter((parameterName) => { + return ( + (params[parameterName] || parameterName === 'threshold') && + allowedParams.includes(parameterName) + ); + }); + + if (!paramKeys?.length) { + return ''; + } + + /* + * Removing threshold from Tree Cover Density request + * Tree Cover Density has a default threshold >=10 + */ + if (isTreeCoverDensity && paramKeys.includes('threshold')) { + paramKeys = paramKeys.filter((item) => item !== 'threshold'); + } + + paramKeys.forEach((parameter, index) => { + const isLastParameter = paramKeys.length - 1 === index; + const hasFilterOption = ['forestType', 'landCategory'].includes(parameter); + const value = hasFilterOption ? 1 : params[parameter]; + const polynameMeta = allFilterOptions.find( + (pname) => pname.value === params[parameter] + ); + const tableKey = + polynameMeta && + (polynameMeta.tableKey || polynameMeta.tableKeys[dataset || 'annual']); + let isNumericValue = isNumber(value); + + const paramKey = translateParameterKey(parameter, params); + + if (parameter === 'adm0' && type === 'wdpa') { + isNumericValue = false; + } + + if (dataset === 'net_change') { + isNumericValue = false; + } + + const hasPrefixIs__ = hasFilterOption && tableKey.includes('is__'); + let WHERE = ''; + + if (hasFilterOption) { + if (hasPrefixIs__) { + WHERE = `${WHERE}${tableKey} = 'true'`; + } + + if (!hasPrefixIs__) { + WHERE = `${WHERE}${tableKey} IS NOT NULL`; + } + + if ( + polynameMeta && + !hasPrefixIs__ && + polynameMeta.default && + polynameMeta.categories + ) { + WHERE = `${WHERE} AND ${tableKey} ${polynameMeta.comparison || '='} ${ + polynameMeta?.dataType === 'keyword' + ? `'${polynameMeta?.default}'` + : `${polynameMeta?.default}` + }`; + } + } + + if (!hasFilterOption) { + WHERE = `${WHERE}${paramKey}${comparisonString}${ + isNumericValue ? value : `'${value}'` + }`; + } + + if (isLastParameter) { + WHERE = `${WHERE} `; + } else { + WHERE = `${WHERE} AND `; + } + + paramString = paramString.concat(WHERE); + }); + + return paramString; +}; diff --git a/utils/get-where-query-allowed-params.js b/utils/get-where-query-allowed-params.js new file mode 100644 index 0000000000..a28e1ce40b --- /dev/null +++ b/utils/get-where-query-allowed-params.js @@ -0,0 +1,50 @@ +const ALLOWED_PARAMS = { + annual: ['adm0', 'adm1', 'adm2', 'threshold', 'forestType', 'landCategory'], + treeCoverDensity: [ + 'adm0', + 'adm1', + 'adm2', + 'threshold', + 'forestType', + 'landCategory', + ], + integrated_alerts: [ + 'adm0', + 'adm1', + 'adm2', + 'forestType', + 'landCategory', + 'is__confirmed_alert', + ], + glad: [ + 'adm0', + 'adm1', + 'adm2', + 'forestType', + 'landCategory', + 'is__confirmed_alert', + ], + viirs: ['adm0', 'adm1', 'adm2', 'forestType', 'landCategory', 'confidence'], + modis: ['adm0', 'adm1', 'adm2', 'forestType', 'landCategory', 'confidence'], + modis_burned_area: [ + 'adm0', + 'adm1', + 'adm2', + 'threshold', + 'forestType', + 'landCategory', + 'confidence', + ], + net_change: [ + 'adm0', + 'adm1', + 'adm2', + 'threshold', + 'forestType', + 'landCategory', + 'confidence', + ], + tropicalTreeCover: ['adm0', 'adm1', 'adm2', 'threshold', 'forestType'], +}; + +export default ALLOWED_PARAMS; diff --git a/utils/get-where-query-translation.js b/utils/get-where-query-translation.js new file mode 100644 index 0000000000..e1f3238622 --- /dev/null +++ b/utils/get-where-query-translation.js @@ -0,0 +1,23 @@ +export const translateParameterKey = (parameterKey, { type, dataset }) => { + let paramKey = ''; + + if (parameterKey === 'confidence') paramKey = 'confidence__cat'; + if (parameterKey === 'adm0' && type === 'country') paramKey = 'iso'; + if (parameterKey === 'adm1' && type === 'country') paramKey = 'adm1'; + if (parameterKey === 'adm2' && type === 'country') paramKey = 'adm2'; + if (parameterKey === 'adm0' && type === 'geostore') paramKey = 'geostore__id'; + if (parameterKey === 'adm0' && type === 'wdpa') + paramKey = 'wdpa_protected_area__id'; + + if (parameterKey === 'threshold') { + if (dataset === 'tropicalTreeCover') { + paramKey = 'wri_tropical_tree_cover__decile'; + } else { + paramKey = 'umd_tree_cover_density_2000__threshold'; + } + } + + return paramKey; +}; + +export default translateParameterKey; From 93ab2b5897183c06834914b35029da98cdba12c0 Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Fri, 20 Oct 2023 13:13:24 -0300 Subject: [PATCH 4/8] chore(jest): add absolute path config --- jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jest.config.js b/jest.config.js index 72bc8f57c7..93fe46175e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -12,6 +12,7 @@ module.exports = { '!/coverage/**', '!/cypress/**', ], + moduleDirectories: ['node_modules', ''], moduleNameMapper: { // Handle CSS imports (with CSS modules) // https://jestjs.io/docs/webpack#mocking-css-modules From 3d29ded7d701059a7b238e9f236b9de8dad511a4 Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Fri, 20 Oct 2023 13:15:52 -0300 Subject: [PATCH 5/8] chore(jest): add getWhereQuery test for tree cover density widget inside ttc scenario --- services/__tests__/get-where-query.spec.js | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 services/__tests__/get-where-query.spec.js diff --git a/services/__tests__/get-where-query.spec.js b/services/__tests__/get-where-query.spec.js new file mode 100644 index 0000000000..32c28b58ba --- /dev/null +++ b/services/__tests__/get-where-query.spec.js @@ -0,0 +1,36 @@ +import { getWHEREQuery } from '../get-where-query'; + +describe('getWHEREQuery', () => { + describe('Tree Cover Density query', () => { + let params; + + beforeEach(() => { + params = { + type: 'country', + adm0: 'PER', + pathname: '/map/[[...location]]', + locationType: 'country', + extentYear: 2020, + url: 'https://tiles.globalforestwatch.org/wri_tropical_tree_cover/v2020/ttcd_{thresh}/{z}/{x}/{y}.png', + thresh: '40', + threshold: 40, + confirmedOnly: 0, + gladLOnly: 0, + gladSOnly: 0, + raddOnly: 0, + startDayIndex: 0, + endDayIndex: null, + numberOfDays: null, + dataset: 'treeCoverDensity', + }; + }); + + // Tree Cover Density has a default threshold + it('should return the default threshold even when user set a different threshold', () => { + const query = getWHEREQuery(params); + const expected = "WHERE iso = 'PER' "; + + expect(query).toEqual(expected); + }); + }); +}); From fcb2b1456f5de0b2c1d258b51c01517f9a2ec65c Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Fri, 20 Oct 2023 13:31:23 -0300 Subject: [PATCH 6/8] chore(jest): add getWhereQuery general test --- services/__tests__/get-where-query.spec.js | 59 ++++++++++++---------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/services/__tests__/get-where-query.spec.js b/services/__tests__/get-where-query.spec.js index 32c28b58ba..9652d46b2c 100644 --- a/services/__tests__/get-where-query.spec.js +++ b/services/__tests__/get-where-query.spec.js @@ -1,36 +1,39 @@ import { getWHEREQuery } from '../get-where-query'; describe('getWHEREQuery', () => { - describe('Tree Cover Density query', () => { - let params; + it('should return an string with each parameter separated by AND', () => { + const params = { + type: 'country', + adm0: 'BRA', + locationType: 'country', + extentYear: 2000, + thresh: 30, + threshold: 30, + forestType: 'plantations', + dataset: 'annual', + }; + const query = getWHEREQuery(params); + const expected = + "WHERE iso = 'BRA' AND umd_tree_cover_density_2000__threshold = 30 AND gfw_planted_forests__type IS NOT NULL "; - beforeEach(() => { - params = { - type: 'country', - adm0: 'PER', - pathname: '/map/[[...location]]', - locationType: 'country', - extentYear: 2020, - url: 'https://tiles.globalforestwatch.org/wri_tropical_tree_cover/v2020/ttcd_{thresh}/{z}/{x}/{y}.png', - thresh: '40', - threshold: 40, - confirmedOnly: 0, - gladLOnly: 0, - gladSOnly: 0, - raddOnly: 0, - startDayIndex: 0, - endDayIndex: null, - numberOfDays: null, - dataset: 'treeCoverDensity', - }; - }); + expect(query).toEqual(expected); + }); + + // Tree Cover Density has a default threshold + it('should not return threshold for Tree Cover Density', () => { + const params = { + type: 'country', + adm0: 'PER', + locationType: 'country', + extentYear: 2020, + thresh: '40', + threshold: 40, // passing threshold as parameter from tropical tree cover layer + dataset: 'treeCoverDensity', + }; - // Tree Cover Density has a default threshold - it('should return the default threshold even when user set a different threshold', () => { - const query = getWHEREQuery(params); - const expected = "WHERE iso = 'PER' "; + const query = getWHEREQuery(params); + const expected = "WHERE iso = 'PER' "; - expect(query).toEqual(expected); - }); + expect(query).toEqual(expected); }); }); From c860d122ad8c657446f599f986634ee8dde10229 Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Fri, 20 Oct 2023 13:38:38 -0300 Subject: [PATCH 7/8] chore(jest): add a non expected example --- services/__tests__/get-where-query.spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/__tests__/get-where-query.spec.js b/services/__tests__/get-where-query.spec.js index 9652d46b2c..921bec8a25 100644 --- a/services/__tests__/get-where-query.spec.js +++ b/services/__tests__/get-where-query.spec.js @@ -33,7 +33,9 @@ describe('getWHEREQuery', () => { const query = getWHEREQuery(params); const expected = "WHERE iso = 'PER' "; + const notExpected = 'AND umd_tree_cover_density_2000__threshold = 40 '; expect(query).toEqual(expected); + expect(query).not.toEqual(notExpected); }); }); From 84b776d48eb09034bae85391a8f9a6f6ac04dd9a Mon Sep 17 00:00:00 2001 From: Willian Viana Date: Fri, 20 Oct 2023 13:47:25 -0300 Subject: [PATCH 8/8] chore(jest): improve readability --- services/get-where-query.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/services/get-where-query.js b/services/get-where-query.js index 5b8d732b50..30dfdb734e 100644 --- a/services/get-where-query.js +++ b/services/get-where-query.js @@ -39,12 +39,13 @@ export const getWHEREQuery = (params = {}) => { const isLastParameter = paramKeys.length - 1 === index; const hasFilterOption = ['forestType', 'landCategory'].includes(parameter); const value = hasFilterOption ? 1 : params[parameter]; - const polynameMeta = allFilterOptions.find( + const filterOption = allFilterOptions.find( (pname) => pname.value === params[parameter] ); + const tableKey = - polynameMeta && - (polynameMeta.tableKey || polynameMeta.tableKeys[dataset || 'annual']); + filterOption && + (filterOption.tableKey || filterOption.tableKeys[dataset || 'annual']); let isNumericValue = isNumber(value); const paramKey = translateParameterKey(parameter, params); @@ -70,15 +71,15 @@ export const getWHEREQuery = (params = {}) => { } if ( - polynameMeta && + filterOption && !hasPrefixIs__ && - polynameMeta.default && - polynameMeta.categories + filterOption.default && + filterOption.categories ) { - WHERE = `${WHERE} AND ${tableKey} ${polynameMeta.comparison || '='} ${ - polynameMeta?.dataType === 'keyword' - ? `'${polynameMeta?.default}'` - : `${polynameMeta?.default}` + WHERE = `${WHERE} AND ${tableKey} ${filterOption.comparison || '='} ${ + filterOption?.dataType === 'keyword' + ? `'${filterOption?.default}'` + : `${filterOption?.default}` }`; } }