Skip to content

Commit 92b6986

Browse files
committed
fix(api-headless-cms-scheduler): executor
1 parent 2e35600 commit 92b6986

File tree

3 files changed

+77
-45
lines changed

3 files changed

+77
-45
lines changed

packages/api-headless-cms-scheduler/__tests__/scheduler/ScheduleExecutor.test.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@ import { createMockService } from "~tests/mocks/service.js";
33
import { createMockScheduleModel } from "~tests/mocks/scheduleModel.js";
44
import { createMockCms } from "~tests/mocks/cms.js";
55
import { createMockFetcher } from "~tests/mocks/fetcher.js";
6+
import { type IScheduleRecord, ScheduleType } from "~/scheduler/types.js";
7+
import { createScheduleRecord } from "~/scheduler/ScheduleRecord.js";
8+
import { createMockGetIdentity } from "~tests/mocks/getIdentity.js";
69

710
describe("ScheduleExecutor", () => {
811
const service = createMockService();
912
const scheduleModel = createMockScheduleModel();
1013
const cms = createMockCms();
11-
const fetcher = createMockFetcher();
1214

1315
it("should execute not find action for publishing", async () => {
16+
const fetcher = createMockFetcher({
17+
async getScheduled(targetId: string): Promise<IScheduleRecord> {
18+
return createScheduleRecord({
19+
id: `schedule-record-id-${targetId}`,
20+
targetId,
21+
scheduledOn: new Date(),
22+
dateOn: new Date(),
23+
type: ScheduleType.publish,
24+
title: `Scheduled for ${targetId}`,
25+
scheduledBy: createMockGetIdentity()(),
26+
model: {} as any
27+
});
28+
}
29+
});
1430
const executor = new ScheduleExecutor({
1531
actions: [],
1632
scheduleModel,
@@ -21,13 +37,31 @@ describe("ScheduleExecutor", () => {
2137

2238
await expect(
2339
executor.schedule("target-id#0001", {
24-
type: "publish",
25-
dateOn: new Date()
40+
type: ScheduleType.publish,
41+
scheduleOn: new Date()
2642
})
27-
).rejects.toThrow(`No action found for input type "publish"`);
43+
).rejects.toThrow(`No action found for input type "${ScheduleType.publish}"`);
44+
45+
await expect(executor.cancel("target-id#0001")).rejects.toThrow(
46+
`No action found for input type "${ScheduleType.publish}"`
47+
);
2848
});
2949

3050
it("should execute not find action for unpublishing", async () => {
51+
const fetcher = createMockFetcher({
52+
async getScheduled(targetId: string): Promise<IScheduleRecord> {
53+
return createScheduleRecord({
54+
id: `schedule-record-id-${targetId}`,
55+
targetId,
56+
scheduledOn: new Date(),
57+
dateOn: new Date(),
58+
type: ScheduleType.unpublish,
59+
title: `Scheduled for ${targetId}`,
60+
scheduledBy: createMockGetIdentity()(),
61+
model: {} as any
62+
});
63+
}
64+
});
3165
const executor = new ScheduleExecutor({
3266
actions: [],
3367
scheduleModel,
@@ -38,9 +72,13 @@ describe("ScheduleExecutor", () => {
3872

3973
await expect(
4074
executor.schedule("target-id#0001", {
41-
type: "unpublish",
42-
dateOn: new Date()
75+
type: ScheduleType.unpublish,
76+
scheduleOn: new Date()
4377
})
44-
).rejects.toThrow(`No action found for input type "unpublish"`);
78+
).rejects.toThrow(`No action found for input type "${ScheduleType.unpublish}"`);
79+
80+
await expect(executor.cancel("target-id#0001")).rejects.toThrow(
81+
`No action found for input type "${ScheduleType.unpublish}"`
82+
);
4583
});
4684
});
Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import type { CmsModel } from "@webiny/api-headless-cms/types";
2-
import type {
3-
IScheduleAction,
4-
IScheduleExecutor,
5-
IScheduleFetcher,
6-
IScheduleRecord,
7-
ISchedulerInput
2+
import {
3+
type IScheduleAction,
4+
type IScheduleExecutor,
5+
type IScheduleFetcher,
6+
type IScheduleRecord,
7+
type ISchedulerInput,
8+
ScheduleType
89
} from "~/scheduler/types.js";
910
import { createScheduleRecordId } from "~/scheduler/createScheduleRecordId.js";
10-
import { convertException } from "@webiny/utils";
11-
import { NotFoundError } from "@webiny/handler-graphql";
1211
import type { ISchedulerService } from "~/service/types.js";
1312
import type { PublishScheduleActionCms } from "~/scheduler/actions/PublishScheduleAction.js";
1413
import type { UnpublishScheduleActionCms } from "~/scheduler/actions/UnpublishScheduleAction.js";
@@ -43,16 +42,7 @@ export class ScheduleExecutor implements IScheduleExecutor {
4342
const scheduleRecordId = createScheduleRecordId(targetId);
4443
const original = await this.fetcher.getScheduled(targetId);
4544

46-
const action = this.actions.find(action => action.canHandle(input));
47-
if (!action) {
48-
throw new WebinyError(
49-
`No action found for input type "${input.type}".`,
50-
"NO_ACTION_FOUND",
51-
{
52-
type: input.type
53-
}
54-
);
55-
}
45+
const action = this.getAction(input.type);
5646

5747
if (original) {
5848
return action.reschedule(original, input);
@@ -66,28 +56,32 @@ export class ScheduleExecutor implements IScheduleExecutor {
6656
}
6757

6858
public async cancel(id: string): Promise<void> {
69-
const record = await this.fetcher.getScheduled(id);
70-
if (!record) {
71-
return;
59+
const original = await this.fetcher.getScheduled(id);
60+
if (!original) {
61+
throw new WebinyError(
62+
`No scheduled record found for ID "${id}".`,
63+
"SCHEDULED_RECORD_NOT_FOUND",
64+
{
65+
id
66+
}
67+
);
7268
}
7369

74-
try {
75-
await this.cms.deleteEntry(this.scheduleModel, record.id);
76-
} catch (ex) {
77-
if (ex.code === "NOT_FOUND" || ex instanceof NotFoundError) {
78-
return;
79-
}
80-
console.error(`Error while deleting scheduled record: ${id}.`);
81-
console.log(convertException(ex));
82-
throw ex;
83-
}
70+
const action = this.getAction(original.type);
71+
return action.cancel(original.id);
72+
}
8473

85-
const result = await this.service.delete(record.id);
86-
if (!result.error) {
87-
return;
88-
} else if (result.error.code === "NOT_FOUND" || result.error instanceof NotFoundError) {
89-
return;
74+
private getAction(type: ScheduleType): IScheduleAction {
75+
const action = this.actions.find(action => {
76+
return action.canHandle({
77+
type
78+
});
79+
});
80+
if (action) {
81+
return action;
9082
}
91-
throw result.error;
83+
throw new WebinyError(`No action found for input type "${type}".`, "NO_ACTION_FOUND", {
84+
type
85+
});
9286
}
9387
}

packages/api-headless-cms-scheduler/src/scheduler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export interface IScheduleActionScheduleParams {
9494
input: ISchedulerInput;
9595
}
9696
export interface IScheduleAction {
97-
canHandle(input: ISchedulerInput): boolean;
97+
canHandle(input: Pick<ISchedulerInput, "type">): boolean;
9898
schedule(params: IScheduleActionScheduleParams): Promise<IScheduleRecord>;
9999
cancel(id: string): Promise<void>;
100100
reschedule(original: IScheduleRecord, input: ISchedulerInput): Promise<IScheduleRecord>;

0 commit comments

Comments
 (0)