diff --git a/Assets/WebsiteAssets/images/flags/country-squared/pf.png b/Assets/WebsiteAssets/images/flags/country-squared/pf.png deleted file mode 100644 index cecb80e278..0000000000 Binary files a/Assets/WebsiteAssets/images/flags/country-squared/pf.png and /dev/null differ diff --git a/packages/server/src/services/TaskService.test.ts b/packages/server/src/services/TaskService.test.ts new file mode 100644 index 0000000000..295105ace9 --- /dev/null +++ b/packages/server/src/services/TaskService.test.ts @@ -0,0 +1,82 @@ +import config from '../config'; +import { Models } from '../models/factory'; +import { afterAllTests, beforeAllDb, beforeEachDb, expectThrow, models, msleep } from '../utils/testing/testUtils'; +import { Env } from '../utils/types'; +import TaskService, { RunType, Task } from './TaskService'; + +const newService = () => { + return new TaskService(Env.Dev, models(), config()); +}; + +describe('TaskService', function() { + + beforeAll(async () => { + await beforeAllDb('TaskService'); + }); + + afterAll(async () => { + await afterAllTests(); + }); + + beforeEach(async () => { + await beforeEachDb(); + }); + + test('should register a task', async function() { + const service = newService(); + + const task: Task = { + id: 'test', + description: '', + run: (_models: Models) => {}, + schedule: '', + }; + + service.registerTask(task); + + expect(service.tasks['test']).toBeTruthy(); + await expectThrow(async () => service.registerTask(task)); + }); + + test('should run a task', async function() { + const service = newService(); + + let finishTask = false; + let taskHasRan = false; + + const task: Task = { + id: 'test', + description: '', + run: async (_models: Models) => { + const iid = setInterval(() => { + if (finishTask) { + clearInterval(iid); + taskHasRan = true; + } + }, 1); + }, + schedule: '', + }; + + service.registerTask(task); + + expect(service.taskState('test').running).toBe(false); + + const startTime = new Date(); + + void service.runTask('test', RunType.Manual); + expect(service.taskState('test').running).toBe(true); + expect(service.taskState('test').lastCompletionTime).toBeFalsy(); + expect(service.taskState('test').lastRunTime.getTime()).toBeGreaterThanOrEqual(startTime.getTime()); + + await msleep(1); + finishTask = true; + await msleep(3); + + expect(taskHasRan).toBe(true); + expect(service.taskState('test').running).toBe(false); + expect(service.taskState('test').lastCompletionTime.getTime()).toBeGreaterThan(startTime.getTime()); + + }); + +}); diff --git a/packages/server/src/services/TaskService.ts b/packages/server/src/services/TaskService.ts index fff5ddceb1..ae427e7c50 100644 --- a/packages/server/src/services/TaskService.ts +++ b/packages/server/src/services/TaskService.ts @@ -22,7 +22,7 @@ export interface Task { id: TaskId; description: string; schedule: string; - run(models: Models): Promise; + run(models: Models): void; } export type Tasks = Record; @@ -63,6 +63,8 @@ export default class TaskService extends BaseService { return this.taskStates_[id]; } + // TODO: add tests + public async runTask(id: TaskId, runType: RunType) { const state = this.taskState(id); if (state.running) throw new Error(`Task is already running: ${id}`); @@ -93,6 +95,8 @@ export default class TaskService extends BaseService { public async runInBackground() { for (const [taskId, task] of Object.entries(this.tasks_)) { + if (!task.schedule) continue; + logger.info(`Scheduling task "${taskId}": ${task.schedule}`); cron.schedule(task.schedule, async () => {