mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
storing last run in database
This commit is contained in:
110
test/services/jobs/dashboardRouter.test.js
Normal file
110
test/services/jobs/dashboardRouter.test.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2026 by Christian Kellner.
|
||||
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||
import path from 'node:path';
|
||||
import Fastify from 'fastify';
|
||||
|
||||
describe('api/routes/dashboardRouter.js', () => {
|
||||
let app;
|
||||
let state;
|
||||
|
||||
async function buildApp() {
|
||||
const ROOT = path.resolve('.');
|
||||
const jobStoragePath = path.join(ROOT, 'lib', 'services', 'storage', 'jobStorage.js');
|
||||
const listingsStoragePath = path.join(ROOT, 'lib', 'services', 'storage', 'listingsStorage.js');
|
||||
const settingsStoragePath = path.join(ROOT, 'lib', 'services', 'storage', 'settingsStorage.js');
|
||||
const securityPath = path.join(ROOT, 'lib', 'api', 'security.js');
|
||||
|
||||
vi.resetModules();
|
||||
vi.doMock(jobStoragePath, () => ({
|
||||
getJobs: () => state.jobs.slice(),
|
||||
}));
|
||||
vi.doMock(listingsStoragePath, () => ({
|
||||
getListingsKpisForJobIds: () => ({ numberOfActiveListings: 0, medianPriceOfListings: 0 }),
|
||||
getProviderDistributionForJobIds: () => [],
|
||||
}));
|
||||
vi.doMock(settingsStoragePath, () => ({
|
||||
getSettings: async () => ({ interval: 30 }),
|
||||
}));
|
||||
vi.doMock(securityPath, () => ({
|
||||
isAdmin: () => state.admin,
|
||||
}));
|
||||
|
||||
const mod = await import(path.join(ROOT, 'lib', 'api', 'routes', 'dashboardRouter.js'));
|
||||
const plugin = mod.default;
|
||||
const instance = Fastify({ logger: false });
|
||||
instance.addHook('onRequest', async (request) => {
|
||||
request.session = { currentUser: state.currentUser, createdAt: Date.now() };
|
||||
});
|
||||
await instance.register(plugin, { prefix: '/api/dashboard' });
|
||||
await instance.ready();
|
||||
return instance;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
currentUser: 'u1',
|
||||
admin: false,
|
||||
jobs: [],
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (app) await app.close();
|
||||
app = null;
|
||||
});
|
||||
|
||||
it('derives lastRun from the most recent accessible job for a regular user', async () => {
|
||||
state.jobs = [
|
||||
{ id: 'a', userId: 'u1', shared_with_user: [], lastRunAt: 1000 },
|
||||
{ id: 'b', userId: 'u1', shared_with_user: [], lastRunAt: 5000 },
|
||||
{ id: 'c', userId: 'someone-else', shared_with_user: [], lastRunAt: 9999 },
|
||||
];
|
||||
app = await buildApp();
|
||||
|
||||
const res = await app.inject({ method: 'GET', url: '/api/dashboard/' });
|
||||
expect(res.statusCode).toBe(200);
|
||||
const body = res.json();
|
||||
expect(body.general.lastRun).toBe(5000);
|
||||
expect(body.general.nextRun).toBe(5000 + 30 * 60000);
|
||||
});
|
||||
|
||||
it('includes shared jobs in the lastRun calculation', async () => {
|
||||
state.jobs = [
|
||||
{ id: 'mine', userId: 'u1', shared_with_user: [], lastRunAt: 1000 },
|
||||
{ id: 'shared', userId: 'someone-else', shared_with_user: ['u1'], lastRunAt: 4000 },
|
||||
];
|
||||
app = await buildApp();
|
||||
|
||||
const res = await app.inject({ method: 'GET', url: '/api/dashboard/' });
|
||||
expect(res.json().general.lastRun).toBe(4000);
|
||||
});
|
||||
|
||||
it('admins see lastRun across all jobs', async () => {
|
||||
state.admin = true;
|
||||
state.jobs = [
|
||||
{ id: 'a', userId: 'someone', shared_with_user: [], lastRunAt: 1000 },
|
||||
{ id: 'b', userId: 'another', shared_with_user: [], lastRunAt: 7000 },
|
||||
];
|
||||
app = await buildApp();
|
||||
|
||||
const res = await app.inject({ method: 'GET', url: '/api/dashboard/' });
|
||||
expect(res.json().general.lastRun).toBe(7000);
|
||||
});
|
||||
|
||||
it('returns null lastRun and 0 nextRun when no accessible job has ever run', async () => {
|
||||
state.jobs = [
|
||||
{ id: 'a', userId: 'u1', shared_with_user: [], lastRunAt: null },
|
||||
{ id: 'b', userId: 'someone-else', shared_with_user: [], lastRunAt: 9999 },
|
||||
];
|
||||
app = await buildApp();
|
||||
|
||||
const res = await app.inject({ method: 'GET', url: '/api/dashboard/' });
|
||||
const body = res.json();
|
||||
expect(body.general.lastRun).toBeNull();
|
||||
expect(body.general.nextRun).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user