diff --git a/api/apps/api/src/modules/scenarios/marxan-run/cancel.handler.ts b/api/apps/api/src/modules/scenarios/marxan-run/cancel.handler.ts index ab07695e73..0b3bb16e99 100644 --- a/api/apps/api/src/modules/scenarios/marxan-run/cancel.handler.ts +++ b/api/apps/api/src/modules/scenarios/marxan-run/cancel.handler.ts @@ -1,9 +1,11 @@ import { Inject, Injectable } from '@nestjs/common'; import { Job, Queue } from 'bullmq'; -import { Either, left, right } from 'fp-ts/Either'; +import { Either, right } from 'fp-ts/Either'; +import { ApiEventsService } from '@marxan-api/modules/api-events/api-events.service'; import { JobData } from '@marxan/scenario-run-queue'; import { isDefined } from '@marxan/utils'; import { runQueueToken } from './tokens'; +import { API_EVENT_KINDS } from '@marxan/api-events'; export const notFound = Symbol('not found'); export type NotFound = typeof notFound; @@ -13,6 +15,7 @@ export class CancelHandler { constructor( @Inject(runQueueToken) private readonly queue: Queue, + private readonly apiEvents: ApiEventsService, ) {} async cancel(scenarioId: string): Promise> { @@ -23,7 +26,13 @@ export class CancelHandler { const scenarioJob = activeJobs.find( (job) => job.data.scenarioId === scenarioId, ); - if (!isDefined(scenarioJob)) return left(notFound); + if (!isDefined(scenarioJob)) { + await this.apiEvents.create({ + topic: scenarioId, + kind: API_EVENT_KINDS.scenario__run__failed__v1__alpha1, + }); + return right(void 0); + } if (await scenarioJob.isActive()) await scenarioJob.updateProgress({ diff --git a/api/apps/api/src/modules/scenarios/marxan-run/run.service.spec.ts b/api/apps/api/src/modules/scenarios/marxan-run/run.service.spec.ts index ddbac02cc1..6ffebeced6 100644 --- a/api/apps/api/src/modules/scenarios/marxan-run/run.service.spec.ts +++ b/api/apps/api/src/modules/scenarios/marxan-run/run.service.spec.ts @@ -22,7 +22,7 @@ import { RunService } from './run.service'; import { AssetsService } from './assets.service'; import { blmDefaultToken, runEventsToken, runQueueToken } from './tokens'; import { RunHandler } from './run.handler'; -import { CancelHandler, notFound } from './cancel.handler'; +import { CancelHandler } from './cancel.handler'; import { EventsHandler } from './events.handler'; let fixtures: PromiseType>; @@ -99,11 +99,15 @@ test(`canceling job`, async () => { }); test(`canceling job`, async () => { + fixtures.setupForCancelingNotFoundJob(); fixtures.GivenNoJobsInQueue(); const result = await runService.cancel(`scenario-1`); - expect(result).toStrictEqual(left(notFound)); + expect(result).toStrictEqual(right(void 0)); + await fixtures.ThenEventCreated( + API_EVENT_KINDS.scenario__run__failed__v1__alpha1, + ); }); test(`canceling active job`, async () => { @@ -376,6 +380,9 @@ async function getFixtures() { return right({}); }); }, + setupForCancelingNotFoundJob() { + fakeApiEvents.create.mockImplementation(() => ({})); + }, setupMocksForCompletedJob() { fakeApiEvents.createIfNotExists.mockImplementation(() => { return right({});