Add unfinished land use class,group,order impl
This commit is contained in:
parent
bb30aa7098
commit
4bda0f0aa6
4
app/package-lock.json
generated
4
app/package-lock.json
generated
@ -2410,7 +2410,7 @@
|
|||||||
},
|
},
|
||||||
"babel-plugin-syntax-object-rest-spread": {
|
"babel-plugin-syntax-object-rest-spread": {
|
||||||
"version": "6.13.0",
|
"version": "6.13.0",
|
||||||
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||||
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
@ -9729,7 +9729,7 @@
|
|||||||
},
|
},
|
||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import db from '../../db';
|
import db from '../../db';
|
||||||
|
|
||||||
export async function getLanduseGroupFromClass(classes: string[]): Promise<string[]> {
|
export async function getLandUseGroupFromClass(classes: string[]): Promise<string[]> {
|
||||||
if (classes.length === 0) return [];
|
if (classes.length === 0) return [];
|
||||||
|
|
||||||
return (await db.many(
|
return (await db.many(
|
||||||
|
@ -15,3 +15,10 @@ export class DatabaseError extends Error {
|
|||||||
this.detail = detail;
|
this.detail = detail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DomainLogicError extends Error {
|
||||||
|
constructor(message?: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'DomainLogicError';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
103
app/src/api/services/__tests__/domainLogic/landUse.test.ts
Normal file
103
app/src/api/services/__tests__/domainLogic/landUse.test.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { DomainLogicError } from '../../../errors/general';
|
||||||
|
import { LandUseState, updateLandUse } from '../../domainLogic/landUse';
|
||||||
|
|
||||||
|
const testClassToGroup = {
|
||||||
|
'Animal breeding places': 'Agriculture',
|
||||||
|
'Egg grading place': 'Agriculture',
|
||||||
|
'Fish farm': 'Fisheries',
|
||||||
|
'Brewery': 'Manufacturing',
|
||||||
|
'Business meeting places': 'Offices'
|
||||||
|
};
|
||||||
|
const testGroupToOrder = {
|
||||||
|
'Agriculture': 'Agriculture And Fisheries',
|
||||||
|
'Fisheries': 'Agriculture And Fisheries',
|
||||||
|
'Manufacturing': 'Industry And Business',
|
||||||
|
'Offices': 'Industry And Business'
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.mock('../../../dataAccess/landUse', () => ({
|
||||||
|
getLandUseGroupFromClass: jest.fn((classes: string[]) => {
|
||||||
|
const groups = _.chain(classes).map(c => testClassToGroup[c]).uniq().value();
|
||||||
|
|
||||||
|
return Promise.resolve(groups);
|
||||||
|
}),
|
||||||
|
getLandUseOrderGromGroup: jest.fn((groups: string[]) => {
|
||||||
|
const orders = _.chain(groups).map(g => testGroupToOrder[g]).uniq().value();
|
||||||
|
|
||||||
|
let result: string;
|
||||||
|
if(orders.length == 0) result = null;
|
||||||
|
else if(orders.length == 1) result = orders[0];
|
||||||
|
else result = 'Mixed Use';
|
||||||
|
|
||||||
|
return Promise.resolve(result);
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('updateLandUse()', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
[{
|
||||||
|
landUseClass: [],
|
||||||
|
landUseGroup: [],
|
||||||
|
landUseOrder: null
|
||||||
|
}, {
|
||||||
|
landUseClass: ['Animal breeding places']
|
||||||
|
}, {
|
||||||
|
landUseClass: ['Animal breeding places'],
|
||||||
|
landUseGroup: ['Agriculture'],
|
||||||
|
landUseOrder: 'Agriculture And Fisheries'
|
||||||
|
}],
|
||||||
|
|
||||||
|
[{
|
||||||
|
landUseClass: ['Animal breeding places'],
|
||||||
|
landUseGroup: ['Agriculture'],
|
||||||
|
landUseOrder: 'Agriculture And Fisheries'
|
||||||
|
}, {
|
||||||
|
landUseClass: ['Fish farm']
|
||||||
|
}, {
|
||||||
|
landUseClass: ['Fish farm'],
|
||||||
|
landUseGroup: ['Fisheries'],
|
||||||
|
landUseOrder: 'Agriculture And Fisheries'
|
||||||
|
}],
|
||||||
|
|
||||||
|
[{
|
||||||
|
landUseClass: ['Animal breeding places'],
|
||||||
|
landUseGroup: ['Agriculture'],
|
||||||
|
landUseOrder: 'Agriculture And Fisheries'
|
||||||
|
}, {
|
||||||
|
landUseClass: ['Animal breeding places', 'Business meeting places']
|
||||||
|
}, {
|
||||||
|
landUseClass: ['Animal breeding places', 'Business meeting places'],
|
||||||
|
landUseGroup: ['Agriculture', 'Offices'],
|
||||||
|
landUseOrder: 'Mixed Use'
|
||||||
|
}]
|
||||||
|
])('Should derive higher level land use classifications from lower level ones',
|
||||||
|
async (landUse: LandUseState, landUseUpdate: Partial<LandUseState>, expectedUpdate: LandUseState) => {
|
||||||
|
const result = await updateLandUse(landUse, landUseUpdate);
|
||||||
|
|
||||||
|
expect(result).toBe(expectedUpdate);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
[{
|
||||||
|
landUseClass: ['Fish farm'],
|
||||||
|
landUseGroup: ['Fisheries'],
|
||||||
|
landUseOrder: 'Agriculture And Fisheries'
|
||||||
|
}, {
|
||||||
|
landUseGroup: []
|
||||||
|
}]
|
||||||
|
])('Should error when update breaks an automatic chain of classifications',
|
||||||
|
async (landUse: LandUseState, landUseUpdate: Partial<LandUseState>) => {
|
||||||
|
const resultPromise = updateLandUse(landUse, landUseUpdate);
|
||||||
|
|
||||||
|
expect(resultPromise).rejects.toBeInstanceOf(DomainLogicError);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
@ -1,9 +1,19 @@
|
|||||||
import * as _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { isNullishOrEmpty } from '../../../helpers';
|
import { isNullishOrEmpty } from '../../../helpers';
|
||||||
import { getLanduseGroupFromClass, getLandUseOrderFromGroup } from '../../dataAccess/landUse';
|
import { getLandUseGroupFromClass, getLandUseOrderFromGroup } from '../../dataAccess/landUse';
|
||||||
import { getCurrentBuildingDataById } from '../building';
|
import { getCurrentBuildingDataById } from '../building';
|
||||||
|
|
||||||
|
export interface LandUseState {
|
||||||
|
landUseClass: string[];
|
||||||
|
landUseGroup: string[];
|
||||||
|
landUseOrder: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateLandUse(landUse: LandUseState, landUseUpdate: Partial<LandUseState>): Promise<LandUseState> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
export async function processCurrentLandUseClassifications(buildingId: number, buildingUpdate: any): Promise<any> {
|
export async function processCurrentLandUseClassifications(buildingId: number, buildingUpdate: any): Promise<any> {
|
||||||
let updateData = _.pick(await getCurrentBuildingDataById(buildingId), [
|
let updateData = _.pick(await getCurrentBuildingDataById(buildingId), [
|
||||||
'current_landuse_class',
|
'current_landuse_class',
|
||||||
@ -16,7 +26,7 @@ export async function processCurrentLandUseClassifications(buildingId: number, b
|
|||||||
const updateFrom = getUpdateStartingStage(buildingUpdate);
|
const updateFrom = getUpdateStartingStage(buildingUpdate);
|
||||||
if(updateFrom === 'class') {
|
if(updateFrom === 'class') {
|
||||||
updateData.current_landuse_class = buildingUpdate.current_landuse_class;
|
updateData.current_landuse_class = buildingUpdate.current_landuse_class;
|
||||||
updateData.current_landuse_group = await getLanduseGroupFromClass(updateData.current_landuse_class);
|
updateData.current_landuse_group = await getLandUseGroupFromClass(updateData.current_landuse_class);
|
||||||
updateData.current_landuse_order = await getLandUseOrderFromGroup(updateData.current_landuse_group);
|
updateData.current_landuse_order = await getLandUseOrderFromGroup(updateData.current_landuse_group);
|
||||||
} else if (updateFrom === 'group') {
|
} else if (updateFrom === 'group') {
|
||||||
if (isNullishOrEmpty(updateData.current_landuse_class)) {
|
if (isNullishOrEmpty(updateData.current_landuse_class)) {
|
@ -1,6 +1,9 @@
|
|||||||
import { hasAnyOwnProperty } from '../../../helpers';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { processCurrentLandUseClassifications } from './currentLandUseClassifications';
|
import { hasAnyOwnProperty } from '../../../helpers';
|
||||||
|
import { getCurrentBuildingDataById } from '../building';
|
||||||
|
|
||||||
|
import { updateLandUse } from './landUse';
|
||||||
|
|
||||||
export async function processBuildingUpdate(buildingId: number, buildingUpdate: any): Promise<any> {
|
export async function processBuildingUpdate(buildingId: number, buildingUpdate: any): Promise<any> {
|
||||||
if(hasAnyOwnProperty(buildingUpdate, ['current_landuse_class', 'current_landuse_group', 'current_landuse_order'])) {
|
if(hasAnyOwnProperty(buildingUpdate, ['current_landuse_class', 'current_landuse_group', 'current_landuse_order'])) {
|
||||||
@ -9,3 +12,25 @@ export async function processBuildingUpdate(buildingId: number, buildingUpdate:
|
|||||||
|
|
||||||
return buildingUpdate;
|
return buildingUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function processCurrentLandUseClassifications(buildingId: number, buildingUpdate: any): Promise<any> {
|
||||||
|
const currentBuildingData = await getCurrentBuildingDataById(buildingId);
|
||||||
|
|
||||||
|
const currentLandUseUpdate = await updateLandUse(
|
||||||
|
{
|
||||||
|
landUseClass: currentBuildingData.current_landuse_class,
|
||||||
|
landUseGroup: currentBuildingData.current_landuse_group,
|
||||||
|
landUseOrder: currentBuildingData.current_landuse_order
|
||||||
|
}, {
|
||||||
|
landUseClass: buildingUpdate.current_landuse_class,
|
||||||
|
landUseGroup: buildingUpdate.current_landuse_group,
|
||||||
|
landUseOrder: buildingUpdate.current_landuse_order
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return Object.assign({}, buildingUpdate, {
|
||||||
|
current_landuse_class: currentLandUseUpdate.landUseClass,
|
||||||
|
current_landuse_group: currentLandUseUpdate.landUseGroup,
|
||||||
|
current_landuse_order: currentLandUseUpdate.landUseOrder,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user