-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #196 from Vizzuality/feat/MARXAN-413-cost-surface-…
…application feat(api): cost-surface: application logic
- Loading branch information
Showing
17 changed files
with
423 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { MigrationInterface, QueryRunner } from 'typeorm'; | ||
|
||
export class CostSurfaceEvents1621341638168 implements MigrationInterface { | ||
public async up(queryRunner: QueryRunner): Promise<void> { | ||
await queryRunner.query(` | ||
INSERT INTO api_event_kinds (id) values | ||
('scenario.costSurface.submitted/v1alpha1'), | ||
('scenario.costSurface.shapeConverted/v1alpha1'), | ||
('scenario.costSurface.shapeConversionFailed/v1alpha1'), | ||
('scenario.costSurface.costUpdateFailed/v1alpha1'), | ||
('scenario.costSurface.finished/v1alpha1'); | ||
`); | ||
} | ||
|
||
public async down(queryRunner: QueryRunner): Promise<void> { | ||
await queryRunner.query( | ||
`DELETE FROM api_event_kinds WHERE id like 'scenario.costSurface.%';`, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
api/src/modules/scenarios/cost-surface/__mocks__/adjust-cost-service-fake.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { AdjustCostSurface } from '../../../analysis/entry-points/adjust-cost-surface'; | ||
import { CostSurfaceInputDto } from '../../../analysis/entry-points/adjust-cost-surface-input'; | ||
|
||
@Injectable() | ||
export class AdjustCostServiceFake implements AdjustCostSurface { | ||
mock = jest.fn(); | ||
|
||
async update( | ||
scenarioId: string, | ||
constraints: CostSurfaceInputDto, | ||
): Promise<true> { | ||
return this.mock(scenarioId, constraints); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
api/src/modules/scenarios/cost-surface/__mocks__/cost-surface-events-fake.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Injectable, Scope } from '@nestjs/common'; | ||
import { | ||
CostSurfaceEventsPort, | ||
CostSurfaceState, | ||
} from '../cost-surface-events.port'; | ||
|
||
@Injectable() | ||
export class CostSurfaceEventsFake implements CostSurfaceEventsPort { | ||
mock = jest.fn(); | ||
events: [string, CostSurfaceState][] = []; | ||
|
||
async event( | ||
scenarioId: string, | ||
state: CostSurfaceState, | ||
context?: Record<string, unknown> | Error, | ||
): Promise<void> { | ||
this.events.push([scenarioId, state]); | ||
return this.mock(scenarioId, state, context); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
api/src/modules/scenarios/cost-surface/__mocks__/shapefile-converter-fake.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { ResolvePuWithCost } from '../resolve-pu-with-cost'; | ||
import { CostSurfaceInputDto } from '../../../analysis/entry-points/adjust-cost-surface-input'; | ||
|
||
@Injectable() | ||
export class ShapefileConverterFake implements ResolvePuWithCost { | ||
mock = jest.fn(); | ||
|
||
async fromShapefile(file: Express.Multer.File): Promise<CostSurfaceInputDto> { | ||
return this.mock(file); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
api/src/modules/scenarios/cost-surface/__mocks__/surface-cost.data.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { CostSurfaceInputDto } from '../../../analysis/entry-points/adjust-cost-surface-input'; | ||
|
||
export const getValidSurfaceCost = (): CostSurfaceInputDto => ({ | ||
planningUnits: [ | ||
{ | ||
id: 'pu-id-1', | ||
cost: 300, | ||
}, | ||
{ | ||
id: 'pu-id-2', | ||
cost: 2000, | ||
}, | ||
], | ||
}); |
76 changes: 76 additions & 0 deletions
76
api/src/modules/scenarios/cost-surface/adapters/cost-surface-api-events.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { getRepositoryToken } from '@nestjs/typeorm'; | ||
import { Test } from '@nestjs/testing'; | ||
import { Repository } from 'typeorm'; | ||
|
||
import { | ||
API_EVENT_KINDS, | ||
ApiEvent, | ||
} from '../../../api-events/api-event.api.entity'; | ||
|
||
import { CostSurfaceApiEvents } from './cost-surface-api-events'; | ||
import { CostSurfaceState } from '../cost-surface-events.port'; | ||
|
||
import { fakeQueryBuilder } from '../../../../utils/__mocks__/fake-query-builder'; | ||
import { LatestApiEventByTopicAndKind } from '../../../api-events/api-event.topic+kind.api.entity'; | ||
|
||
const scenarioId = 'scenario-uuid'; | ||
const cases: [CostSurfaceState, API_EVENT_KINDS][] = [ | ||
[ | ||
CostSurfaceState.Submitted, | ||
API_EVENT_KINDS.scenario__costSurface__submitted__v1_alpha1, | ||
], | ||
[ | ||
CostSurfaceState.ShapefileConverted, | ||
API_EVENT_KINDS.scenario__costSurface__shapeConverted__v1_alpha1, | ||
], | ||
[ | ||
CostSurfaceState.ShapefileConversionFailed, | ||
API_EVENT_KINDS.scenario__costSurface__shapeConversionFailed__v1_alpha1, | ||
], | ||
[ | ||
CostSurfaceState.CostUpdateFailed, | ||
API_EVENT_KINDS.scenario__costSurface__costUpdateFailed__v1_alpha1, | ||
], | ||
[ | ||
CostSurfaceState.Finished, | ||
API_EVENT_KINDS.scenario__costSurface__finished__v1_alpha1, | ||
], | ||
]; | ||
|
||
let sut: CostSurfaceApiEvents; | ||
let repoMock: jest.Mocked<Repository<ApiEvent>>; | ||
|
||
beforeEach(async () => { | ||
const apiEventsToken = getRepositoryToken(ApiEvent); | ||
const sandbox = await Test.createTestingModule({ | ||
providers: [ | ||
CostSurfaceApiEvents, | ||
{ | ||
provide: apiEventsToken, | ||
useValue: { | ||
metadata: { | ||
name: 'required-by-base-service-for-logging', | ||
}, | ||
createQueryBuilder: () => fakeQueryBuilder(jest.fn()), | ||
save: jest.fn().mockResolvedValue({}), | ||
}, | ||
}, | ||
{ | ||
provide: getRepositoryToken(LatestApiEventByTopicAndKind), | ||
useValue: jest.fn(), | ||
}, | ||
], | ||
}).compile(); | ||
|
||
sut = sandbox.get(CostSurfaceApiEvents); | ||
repoMock = sandbox.get(apiEventsToken); | ||
}); | ||
|
||
test.each(cases)(`emits %p as %p`, async (event, kind) => { | ||
await sut.event(scenarioId, event); | ||
expect(repoMock.save.mock.calls[0][0]).toEqual({ | ||
data: {}, | ||
topic: scenarioId, | ||
kind, | ||
}); | ||
}); |
33 changes: 33 additions & 0 deletions
33
api/src/modules/scenarios/cost-surface/adapters/cost-surface-api-events.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { | ||
CostSurfaceEventsPort, | ||
CostSurfaceState, | ||
} from '../cost-surface-events.port'; | ||
import { ApiEventsService } from '../../../api-events/api-events.service'; | ||
import { API_EVENT_KINDS } from '../../../api-events/api-event.api.entity'; | ||
|
||
@Injectable() | ||
export class CostSurfaceApiEvents | ||
extends ApiEventsService | ||
implements CostSurfaceEventsPort { | ||
private readonly eventsMap: Record<CostSurfaceState, API_EVENT_KINDS> = { | ||
[CostSurfaceState.Submitted]: | ||
API_EVENT_KINDS.scenario__costSurface__submitted__v1_alpha1, | ||
[CostSurfaceState.ShapefileConverted]: | ||
API_EVENT_KINDS.scenario__costSurface__shapeConverted__v1_alpha1, | ||
[CostSurfaceState.ShapefileConversionFailed]: | ||
API_EVENT_KINDS.scenario__costSurface__shapeConversionFailed__v1_alpha1, | ||
[CostSurfaceState.CostUpdateFailed]: | ||
API_EVENT_KINDS.scenario__costSurface__costUpdateFailed__v1_alpha1, | ||
[CostSurfaceState.Finished]: | ||
API_EVENT_KINDS.scenario__costSurface__finished__v1_alpha1, | ||
}; | ||
|
||
async event(scenarioId: string, state: CostSurfaceState): Promise<void> { | ||
await this.create({ | ||
data: {}, | ||
topic: scenarioId, | ||
kind: this.eventsMap[state], | ||
}); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
api/src/modules/scenarios/cost-surface/adapters/geoprocessing-cost-from-shapefile.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { ResolvePuWithCost } from '../resolve-pu-with-cost'; | ||
import { CostSurfaceInputDto } from '../../../analysis/entry-points/adjust-cost-surface-input'; | ||
|
||
@Injectable() | ||
export class GeoprocessingCostFromShapefile implements ResolvePuWithCost { | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
async fromShapefile(file: Express.Multer.File): Promise<CostSurfaceInputDto> { | ||
return { | ||
planningUnits: [], | ||
}; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
api/src/modules/scenarios/cost-surface/cost-surface-events.port.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export enum CostSurfaceState { | ||
Submitted = 'submitted', | ||
ShapefileConverted = 'shapefile-converted', | ||
ShapefileConversionFailed = 'shapefile-conversion-failed', | ||
CostUpdateFailed = 'cost-update-failed', | ||
Finished = 'finished', | ||
} | ||
|
||
export abstract class CostSurfaceEventsPort { | ||
abstract event( | ||
scenarioId: string, | ||
state: CostSurfaceState, | ||
context?: Record<string, unknown> | Error, | ||
): Promise<void>; | ||
} |
Oops, something went wrong.