Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/loaders/__tests__/thematicLoader.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { getValuesByPeriod, getValueById } from '../thematicLoader.js'

const headers = [{ name: 'pe' }, { name: 'ou' }, { name: 'value' }]

describe('thematicLoader value extraction', () => {
// Analytics returns row values as strings, and computed items (indicators,
// calculations) serialize whole numbers with a trailing ".0" (e.g. "16082.0").
// Both extractors must yield numbers so integers render without decimals.
// See DHIS2-21037.

test('getValueById coerces string values to numbers', () => {
const data = {
headers,
rows: [
['202501', 'ou1', '16082.0'],
['202501', 'ou2', '118.13'],
],
}

expect(getValueById(data)).toEqual({
ou1: 16082,
ou2: 118.13,
})
})

test('getValuesByPeriod coerces string values to numbers per period', () => {
const data = {
headers,
rows: [
['202501', 'ou1', '16082.0'],
['202501', 'ou2', '118.13'],
['202502', 'ou1', '238.0'],
],
}

expect(getValuesByPeriod(data)).toEqual({
202501: {
ou1: { value: 16082 },
ou2: { value: 118.13 },
},
202502: {
ou1: { value: 238 },
},
})
})

test('getValuesByPeriod and getValueById agree on the same value', () => {
const data = {
headers,
rows: [['202501', 'ou1', '238.0']],
}

const byId = getValueById(data)
const byPeriod = getValuesByPeriod(data)

expect(byPeriod['202501'].ou1.value).toBe(byId.ou1)
})
})
12 changes: 7 additions & 5 deletions src/loaders/thematicLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ const getPeriodsFromMetaData = ({ dimensions, items }) =>
}
})

const getValuesByPeriod = (data) => {
export const getValuesByPeriod = (data) => {
const { headers, rows } = data
const periodIndex = findIndex(['name', 'pe'], headers)
const ouIndex = findIndex(['name', 'ou'], headers)
Expand All @@ -355,20 +355,20 @@ const getValuesByPeriod = (data) => {
const period = row[periodIndex]
const periodObj = (obj[period] = obj[period] || {})
periodObj[row[ouIndex]] = {
value: row[valueIndex],
value: Number.parseFloat(row[valueIndex]),
}
return obj
}, {})
}

// Returns an object mapping org. units and values
const getValueById = (data) => {
export const getValueById = (data) => {
const { headers, rows } = data
const ouIndex = findIndex(['name', 'ou'], headers)
const valueIndex = findIndex(['name', 'value'], headers)

return rows.reduce((obj, row) => {
obj[row[ouIndex]] = parseFloat(row[valueIndex])
obj[row[ouIndex]] = Number.parseFloat(row[valueIndex])
return obj
}, {})
}
Expand All @@ -378,7 +378,9 @@ const getOrderedValues = (data) => {
const { headers, rows } = data
const valueIndex = findIndex(['name', 'value'], headers)

return rows.map((row) => parseFloat(row[valueIndex])).sort((a, b) => a - b)
return rows
.map((row) => Number.parseFloat(row[valueIndex]))
.sort((a, b) => a - b)
}

// Load features and data values from api
Expand Down
Loading