d2
Version:
Javascript library for DHIS2
776 lines (611 loc) • 27.7 kB
JavaScript
import fixtures from '../../__fixtures__/fixtures'
import AnalyticsRequest from '../AnalyticsRequest'
import ModelDefinition from '../../model/ModelDefinition'
let request
let expectedParameters
const getFuncName = parameter =>
`with${parameter.charAt(0).toUpperCase()}${parameter.slice(1)}`
describe('AnalyticsRequest', () => {
beforeEach(() => {
request = new AnalyticsRequest()
expectedParameters = {}
})
describe('constructor', () => {
it('should not be allowed to be called without new', () => {
expect(() => AnalyticsRequest()).toThrowErrorMatchingSnapshot()
})
it('should initialize properties', () => {
expect(request.parameters).toEqual({})
expect(request.dimensions).toEqual([])
expect(request.filters).toEqual([])
})
it('should have a default endpoint value', () => {
expect(request.endPoint).toEqual('analytics')
})
it('should set the endpoint when passed as argument', () => {
request = new AnalyticsRequest({ endPoint: 'analytics2' })
expect(request.endPoint).toEqual('analytics2')
})
})
describe('properties', () => {
describe('.addDataDimension()', () => {
it('should add the dx dimension', () => {
request.addDataDimension('Jtf34kNZhzP')
expect(request.dimensions).toEqual([
{ dimension: 'dx', items: ['Jtf34kNZhzP'] },
])
})
it('should append unique values to the dx dimension on subsequent calls', () => {
request = request
.addDataDimension('Jtf34kNZhzP')
.addDataDimension([
'Jtf34kNZhzP',
'SA7WeFZnUci',
'V37YqbqpEhV',
'bqK6eSIwo3h',
'cYeuwXTCPkU',
'fbfJHSPpUQD',
])
expect(request.dimensions).toEqual([
{
dimension: 'dx',
items: [
'Jtf34kNZhzP',
'SA7WeFZnUci',
'V37YqbqpEhV',
'bqK6eSIwo3h',
'cYeuwXTCPkU',
'fbfJHSPpUQD',
],
},
])
})
})
describe('.fromModel()', () => {
const chartModelDefinition = ModelDefinition.createFromSchema(
fixtures.get('/api/schemas/chart'),
fixtures.get('/api/attributes').attributes
)
const model = chartModelDefinition.create(
fixtures.get('/chartAllFields')
)
it('should add dimensions from the model', () => {
request = request.fromModel(model)
expect(request.dimensions).toEqual([
{ dimension: 'dx', items: ['Uvn6LCg7dVU', 'sB79w2hiLp8'] },
{
dimension: 'ou',
items: ['USER_ORGUNIT', 'USER_ORGUNIT_CHILDREN'],
},
])
})
it('should add filters from the model', () => {
request = request.fromModel(model)
expect(request.filters).toEqual([
{ dimension: 'pe', items: ['LAST_SIX_MONTH'] },
])
})
it('should convert filters into dimensions when passing the optional flag', () => {
request = request.fromModel(model, true)
expect(request.dimensions).toEqual([
{ dimension: 'dx', items: ['Uvn6LCg7dVU', 'sB79w2hiLp8'] },
{
dimension: 'ou',
items: ['USER_ORGUNIT', 'USER_ORGUNIT_CHILDREN'],
},
{ dimension: 'pe', items: ['LAST_SIX_MONTH'] },
])
})
})
describe('.addOrgUnitDimension()', () => {
it('should add the ou dimension', () => {
request.addOrgUnitDimension(['ImspTQPwCqd'])
expect(request.dimensions).toEqual([
{ dimension: 'ou', items: ['ImspTQPwCqd'] },
])
})
it('should append unique values to the ou dimension on subsequent calls', () => {
request = request
.addOrgUnitDimension(['ImspTQPwCqd'])
.addOrgUnitDimension(['ImspTQPwCqd', 'O6uvpzGd5pu'])
expect(request.dimensions).toEqual([
{ dimension: 'ou', items: ['ImspTQPwCqd', 'O6uvpzGd5pu'] },
])
})
})
describe('.addPeriodDimension()', () => {
it('should add the pe dimension', () => {
request.addPeriodDimension('2017-01')
expect(request.dimensions).toEqual([
{ dimension: 'pe', items: ['2017-01'] },
])
})
it('should append unique values to the pe dimension on subsequent calls', () => {
request = request
.addPeriodDimension('2017-01')
.addPeriodDimension(['2017-01', '2017-02', '2017-03'])
expect(request.dimensions).toEqual([
{
dimension: 'pe',
items: ['2017-01', '2017-02', '2017-03'],
},
])
})
})
describe('.addDimension()', () => {
it('should add the given dimension without any associated value', () => {
request.addDimension('Jtf34kNZhzP')
expect(request.dimensions).toEqual([
{ dimension: 'Jtf34kNZhzP', items: [] },
])
})
it('should add the given dimension with the associated value (passed as string)', () => {
request.addDimension('J5jldMd8OHv', 'CXw2yu5fodb')
expect(request.dimensions).toEqual([
{ dimension: 'J5jldMd8OHv', items: ['CXw2yu5fodb'] },
])
})
it('should append values (passed as array) to the given dimension', () => {
request = request
.addDimension('J5jldMd8OHv', 'CXw2yu5fodb')
.addDimension('J5jldMd8OHv', ['EYbopBOJWsW', 'test'])
expect(request.dimensions).toEqual([
{
dimension: 'J5jldMd8OHv',
items: ['CXw2yu5fodb', 'EYbopBOJWsW', 'test'],
},
])
})
it('should not append a value already present in the dimension', () => {
request = request
.addDimension('J5jldMd8OHv', ['EYbopBOJWsW', 'test'])
.addDimension('J5jldMd8OHv', 'test')
expect(request.dimensions).toEqual([
{
dimension: 'J5jldMd8OHv',
items: ['EYbopBOJWsW', 'test'],
},
])
})
})
describe('.addDataFilter()', () => {
it('should add the dx dimension filter', () => {
request = request.addDataFilter('Jtf34kNZhzP')
expect(request.filters).toEqual([
{ dimension: 'dx', items: ['Jtf34kNZhzP'] },
])
})
})
describe('.addOrgUnitFilter()', () => {
it('should add the ou dimension filter', () => {
request.addOrgUnitFilter(['ImspTQPwCqd'])
expect(request.filters).toEqual([
{ dimension: 'ou', items: ['ImspTQPwCqd'] },
])
})
it('should append unique values to the ou dimension filter on subsequent calls', () => {
request = request
.addOrgUnitFilter('ImspTQPwCqd')
.addOrgUnitFilter(['ImspTQPwCqd', 'O6uvpzGd5pu'])
expect(request.filters).toEqual([
{ dimension: 'ou', items: ['ImspTQPwCqd', 'O6uvpzGd5pu'] },
])
})
})
describe('.addPeriodFilter()', () => {
it('should add the pe dimension filter', () => {
request.addPeriodFilter('2017-01')
expect(request.filters).toEqual([
{ dimension: 'pe', items: ['2017-01'] },
])
})
it('should append unique values to the pe dimension filter on subsequent calls', () => {
request = request
.addPeriodFilter('2017-01')
.addPeriodFilter(['2017-01', '2017-02', '2017-03'])
expect(request.filters).toEqual([
{
dimension: 'pe',
items: ['2017-01', '2017-02', '2017-03'],
},
])
})
})
describe('.addFilter()', () => {
it('should add the given dimensions as filter without any associated value', () => {
request.addFilter('Jtf34kNZhzP')
expect(request.filters).toEqual([
{ dimension: 'Jtf34kNZhzP', items: [] },
])
})
it('should add the given dimensions as filter with the associated value (passed as string)', () => {
request.addFilter('J5jldMd8OHv', 'CXw2yu5fodb')
expect(request.filters).toEqual([
{ dimension: 'J5jldMd8OHv', items: ['CXw2yu5fodb'] },
])
})
it('should append values (passed as array) to the given dimension filter', () => {
request = request
.addFilter('J5jldMd8OHv', 'CXw2yu5fodb')
.addFilter('J5jldMd8OHv', ['EYbopBOJWsW', 'test'])
expect(request.filters).toEqual([
{
dimension: 'J5jldMd8OHv',
items: ['CXw2yu5fodb', 'EYbopBOJWsW', 'test'],
},
])
})
it('should not append a value already present in the dimension filter', () => {
request = request
.addFilter('J5jldMd8OHv', ['EYbopBOJWsW', 'test'])
.addFilter('J5jldMd8OHv', 'test')
expect(request.filters).toEqual([
{
dimension: 'J5jldMd8OHv',
items: ['EYbopBOJWsW', 'test'],
},
])
})
})
describe('.withParameters()', () => {
const params = {
completedOnly: true,
aggregationType: 'AVERAGE',
}
it('should set the given parameters in the request', () => {
request.withParameters(params)
expect(request.parameters).toEqual(params)
})
it('should override a parameter if already present', () => {
request = request.withAggregationType('COUNT')
expect(request.parameters).toEqual({ aggregationType: 'COUNT' })
request = request.withParameters(params)
expect(request.parameters).toEqual(params)
})
})
describe('with boolean parameter', () => {
;[
'aggregateData',
'coordinatesOnly',
'collapseDataDimensions',
'hideEmptyRows',
'hideEmptyColumns',
'hierarchyMeta',
'ignoreLimit',
'includeClusterPoints',
'includeNumDen',
'showHierarchy',
'skipData',
'skipMeta',
'skipRounding',
'tableLayout',
'includeMetadataDetails',
].forEach(parameter => {
const funcName = getFuncName(parameter)
it(`should add the ${parameter} parameter with default value`, () => {
request[funcName]()
expectedParameters[parameter] = true
expect(request.parameters).toEqual(expectedParameters)
})
it(`should replace the ${parameter} parameter on subsequent calls with the specified value`, () => {
request[funcName](false)
expectedParameters[parameter] = false
expect(request.parameters).toEqual(expectedParameters)
})
})
})
describe('with value parameter', () => {
;[
'approvalLevel',
'asc', // XXX
'bbox',
'clusterSize',
'columns', // XXX
'desc', // XXX
'endDate',
'inputIdScheme',
'measureCriteria',
'outputIdScheme',
'preAggregationMeasureCriteria',
'relativePeriodDate',
'rows', // XXX
'stage',
'startDate',
'userOrgUnit',
'value', // XXX
].forEach(parameter => {
const funcName = getFuncName(parameter)
it(`should add the ${parameter} parameter with the specified value`, () => {
request[funcName]('test')
expectedParameters[parameter] = 'test'
expect(request.parameters).toEqual(expectedParameters)
})
it(`should replace the ${parameter} parameter on subsequent calls with the specified value`, () => {
request = request[funcName]('test')
request[funcName]('test2')
expectedParameters[parameter] = 'test2'
expect(request.parameters).toEqual(expectedParameters)
})
it(`should not replace the ${parameter} parameter when called without passing a value`, () => {
request = request[funcName]('test')
request[funcName]()
expectedParameters[parameter] = 'test'
expect(request.parameters).toEqual(expectedParameters)
})
})
})
describe('with numeric value parameter', () => {
const params = {
page: 1,
pageSize: 50,
}
Object.entries(params).forEach(([key, value]) => {
const parameter = key
const funcName = getFuncName(parameter)
it(`should add the ${parameter} parameter with the default value`, () => {
request[funcName]()
expectedParameters[parameter] = value
expect(request.parameters).toEqual(expectedParameters)
})
it(`should add the ${parameter} parameter with the specified value`, () => {
request[funcName](10)
expectedParameters[parameter] = 10
expect(request.parameters).toEqual(expectedParameters)
})
it(`should replace the ${parameter} parameter on subsequent calls with the specified value`, () => {
request = request[funcName](10)
request[funcName](20)
expectedParameters[parameter] = 20
expect(request.parameters).toEqual(expectedParameters)
})
})
})
describe('.withCoordinateField()', () => {
it('should set the coordinateField to the specified value', () => {
request.withCoordinateField('abc')
expect(request.parameters).toEqual({ coordinateField: 'abc' })
})
it('should set the coordinateField to default value when called with no value', () => {
request.withCoordinateField()
expect(request.parameters).toEqual({ coordinateField: 'EVENT' })
})
})
describe('.withFormat()', () => {
it('should set the format to the specified value', () => {
request.withFormat('xml')
expect(request.format).toEqual('xml')
})
it('should set the format to default value when called with no value', () => {
request.withFormat()
expect(request.format).toEqual('json')
})
})
describe('.withPath()', () => {
it('should set the request path to the specified value', () => {
request.withPath('test')
expect(request.path).toEqual('test')
})
it('should replace the path on subsequent requests', () => {
request = request.withPath('test').withPath('another/path')
expect(request.path).toEqual('another/path')
})
it('should not replace the path when called with no value', () => {
request = request.withPath('some/path').withPath()
expect(request.path).toEqual('some/path')
})
})
describe('.withProgram()', () => {
it('should set the program to the specified value', () => {
request.withProgram('eBAyeGv0exc')
expect(request.program).toEqual('eBAyeGv0exc')
})
it('should not replace the program when called with no value', () => {
request = request.withProgram('eBAyeGv0exc').withProgram()
expect(request.program).toEqual('eBAyeGv0exc')
})
})
describe('.withAggregationType()', () => {
it('should add the aggregationType parameter with the specified value', () => {
request.withAggregationType('SUM')
expect(request.parameters).toEqual({ aggregationType: 'SUM' })
})
it('should add the aggregationType parameter and uppercase the value', () => {
request.withAggregationType('stddev')
expect(request.parameters).toEqual({
aggregationType: 'STDDEV',
})
})
it('should allow a aggregationType that is not in present in the list', () => {
request.withAggregationType('new-constant')
expect(request.parameters).toEqual({
aggregationType: 'new-constant',
})
})
})
describe('.withDisplayProperty()', () => {
it('should add the displayProperty parameter with the specified value', () => {
request.withDisplayProperty('NAME')
expect(request.parameters).toEqual({ displayProperty: 'NAME' })
})
it('should add the displayProperty parameter and uppercase the value', () => {
request.withDisplayProperty('shortname')
expect(request.parameters).toEqual({
displayProperty: 'SHORTNAME',
})
})
it('should allow a displayProperty that is not present in the list', () => {
request.withDisplayProperty('new-constant')
expect(request.parameters).toEqual({
displayProperty: 'new-constant',
})
})
})
describe('.withOuMode()', () => {
it('should add the ouMode parameter with the specified value', () => {
request.withOuMode('DESCENDANTS')
expect(request.parameters).toEqual({ ouMode: 'DESCENDANTS' })
})
it('should add the ouMode parameter and uppercase the value', () => {
request.withOuMode('children')
expect(request.parameters).toEqual({ ouMode: 'CHILDREN' })
})
it('should allow a ouMode that is not present in the list', () => {
request.withOuMode('new-constant')
expect(request.parameters).toEqual({ ouMode: 'new-constant' })
})
})
describe('.withOutputType()', () => {
it('should add the outputType parameter with the specified value', () => {
request.withOutputType('EVENT')
expect(request.parameters).toEqual({ outputType: 'EVENT' })
})
it('should add the outputType parameter and uppercase the value', () => {
request.withOutputType('enrollment')
expect(request.parameters).toEqual({ outputType: 'ENROLLMENT' })
})
it('should allow a outputType that is not present in the list', () => {
request.withOutputType('new-constant')
expect(request.parameters).toEqual({
outputType: 'new-constant',
})
})
})
describe('.withEventStatus()', () => {
it('should add the eventStatus parameter with the specified value', () => {
request.withEventStatus('ACTIVE')
expect(request.parameters).toEqual({ eventStatus: 'ACTIVE' })
})
it('should add the eventStatus parameter and uppercase the value', () => {
request.withEventStatus('skipped')
expect(request.parameters).toEqual({ eventStatus: 'SKIPPED' })
})
it('should allow a eventStatus that is not present in the list', () => {
request.withEventStatus('new-constant')
expect(request.parameters).toEqual({
eventStatus: 'new-constant',
})
})
})
describe('.withLimit()', () => {
it('should add the limit parameter with the specified value', () => {
request.withLimit(1000)
expect(request.parameters).toEqual({ limit: 1000 })
})
it('should not allow a limit greater than 10000', () => {
request.withLimit('20000')
expect(request.parameters).toEqual({ limit: 10000 })
})
it('should not replace the value when called with no value', () => {
request = request.withLimit('20000').withLimit()
expect(request.parameters).toEqual({ limit: 10000 })
})
})
describe('.withProgramStatus()', () => {
it('should add the programStatus parameter with the specified value', () => {
request.withProgramStatus('ACTIVE')
expect(request.parameters).toEqual({ programStatus: 'ACTIVE' })
})
it('should add the programStatus parameter and uppercase the value', () => {
request.withProgramStatus('completed')
expect(request.parameters).toEqual({
programStatus: 'COMPLETED',
})
})
it('should allow a programStatus that is not present in the list', () => {
request.withProgramStatus('new-constant')
expect(request.parameters).toEqual({
programStatus: 'new-constant',
})
})
})
describe('.withSortOrder()', () => {
it('should add the sortOrder parameter with the specified value', () => {
request.withSortOrder('ASC')
expect(request.parameters).toEqual({ sortOrder: 'ASC' })
})
it('should add the sortOrder parameter and uppercase the value', () => {
request.withSortOrder('desc')
expect(request.parameters).toEqual({ sortOrder: 'DESC' })
})
it('should allow a sortOrder that is not present in the list', () => {
request.withSortOrder('new-constant')
expect(request.parameters).toEqual({
sortOrder: 'new-constant',
})
})
})
})
describe('.buildUrl()', () => {
it('should append the path to the endpoint', () => {
request = request
.addOrgUnitDimension(['ImspTQPwCqd'])
.withPath('test')
expect(request.buildUrl()).toEqual(
'analytics/test.json?dimension=ou:ImspTQPwCqd'
)
})
it('shold build the URL with path, program and format', () => {
request = request
.withPath('events/aggregate')
.withProgram('program-id')
.withFormat('xml')
.addOrgUnitDimension(['ImspTQPwCqd'])
.addPeriodDimension('201711')
.addDataDimension('test-dx-dim')
const expectedSearchParams = {
'ou:ImspTQPwCqd': 'dimension',
'pe:201711': 'dimension',
'dx:test-dx-dim': 'dimension',
}
const url = new URL(`http://localhost/${request.buildUrl()}`)
const searchParams = {}
let key
let value
url.search
.slice(1)
.split('&')
.forEach(p => {
;[key, value] = p.split('=')
searchParams[value] = key
})
expect(url.pathname).toEqual(
'/analytics/events/aggregate/program-id.xml'
)
expect(searchParams).toEqual(expectedSearchParams)
})
it('should build the URL with a dimension without items', () => {
request = request.addDimension('test-dim')
expect(request.buildUrl()).toEqual(
'analytics.json?dimension=test-dim'
)
})
})
describe('.buildQuery()', () => {
it('should return an empty object when there are no filters nor parameters', () => {
expect(request.buildQuery()).toEqual({})
})
it('should return an object when a filter is added', () => {
request.addOrgUnitFilter(['ImspTQPwCqd'])
expect(request.buildQuery()).toEqual({ filter: ['ou:ImspTQPwCqd'] })
})
it('should return an object when a filter is added with multiple values', () => {
request.addOrgUnitFilter(['ImspTQPwCqd', 'O6uvpzGd5pu'])
expect(request.buildQuery()).toEqual({
filter: ['ou:ImspTQPwCqd;O6uvpzGd5pu'],
})
})
it('should return an object when a parameter is added', () => {
request.withHierarchyMeta()
expect(request.buildQuery()).toEqual({ hierarchyMeta: true })
})
it('should return an object when parameters and filters are added', () => {
request = request
.addOrgUnitFilter(['ImspTQPwCqd', 'O6uvpzGd5pu'])
.withHierarchyMeta(false)
expect(request.buildQuery()).toEqual({
hierarchyMeta: false,
filter: ['ou:ImspTQPwCqd;O6uvpzGd5pu'],
})
})
})
})