feat(admin): overview dashboard sections + system temperature/load sensors (0.85.0) (#11)
This commit was merged in pull request #11.
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
listAdminMangas,
|
||||
listAdminChapters,
|
||||
getSystemStats,
|
||||
getOverviewStats,
|
||||
getStorageStats,
|
||||
backfillStorage,
|
||||
resyncManga,
|
||||
@@ -88,7 +89,14 @@ const systemFixture = {
|
||||
percent_used: 50.0
|
||||
},
|
||||
memory: { total_bytes: 8_000_000, used_bytes: 4_000_000, percent_used: 50.0 },
|
||||
cpu: { percent_used: 12.3 },
|
||||
cpu: {
|
||||
percent_used: 12.3,
|
||||
load_avg: { one: 0.81, five: 0.66, fifteen: 0.59 },
|
||||
per_core: [10.0, 14.5, 8.2, 20.1]
|
||||
},
|
||||
temperatures: [
|
||||
{ label: 'CPU Package', celsius: 52.0, max_celsius: 71.0, critical_celsius: 100.0 }
|
||||
],
|
||||
alerts: []
|
||||
};
|
||||
|
||||
@@ -258,6 +266,10 @@ describe('admin api client', () => {
|
||||
expect(s.disk?.percent_used).toBe(50);
|
||||
expect(s.memory.percent_used).toBe(50);
|
||||
expect(s.cpu.percent_used).toBe(12.3);
|
||||
expect(s.cpu.load_avg.one).toBe(0.81);
|
||||
expect(s.cpu.per_core).toHaveLength(4);
|
||||
expect(s.temperatures[0].label).toBe('CPU Package');
|
||||
expect(s.temperatures[0].critical_celsius).toBe(100);
|
||||
expect(s.alerts).toEqual([]);
|
||||
const url = fetchSpy.mock.calls[0][0] as string;
|
||||
expect(url).toMatch(/\/v1\/admin\/system$/);
|
||||
@@ -269,6 +281,43 @@ describe('admin api client', () => {
|
||||
expect(s.disk).toBeNull();
|
||||
});
|
||||
|
||||
it('getSystemStats tolerates an empty temperatures array (sensors unavailable)', async () => {
|
||||
fetchSpy.mockResolvedValueOnce(ok({ ...systemFixture, temperatures: [] }));
|
||||
const s = await getSystemStats();
|
||||
expect(s.temperatures).toEqual([]);
|
||||
});
|
||||
|
||||
it('getOverviewStats GETs /v1/admin/overview and parses the nested envelope', async () => {
|
||||
const fixture = {
|
||||
users: {
|
||||
total: 7,
|
||||
admins: 2,
|
||||
newest_username: 'kenji',
|
||||
newest_created_at: '2026-06-15T00:00:00Z'
|
||||
},
|
||||
mangas: {
|
||||
total: 12,
|
||||
synced: 10,
|
||||
in_progress: 1,
|
||||
dropped: 1,
|
||||
total_chapters: 340,
|
||||
total_pages: 9001,
|
||||
newest_title: 'Sakamoto Days',
|
||||
newest_seen_at: '2026-06-16T00:00:00Z'
|
||||
},
|
||||
analysis: { analyzed_pages: 5760, total_pages: 9001 }
|
||||
};
|
||||
fetchSpy.mockResolvedValueOnce(ok(fixture));
|
||||
const s = await getOverviewStats();
|
||||
expect(s.users.total).toBe(7);
|
||||
expect(s.users.admins).toBe(2);
|
||||
expect(s.mangas.synced).toBe(10);
|
||||
expect(s.mangas.total_pages).toBe(9001);
|
||||
expect(s.analysis.analyzed_pages).toBe(5760);
|
||||
const url = fetchSpy.mock.calls[0][0] as string;
|
||||
expect(url).toMatch(/\/v1\/admin\/overview$/);
|
||||
});
|
||||
|
||||
// ---- force resync ----
|
||||
|
||||
it('resyncManga POSTs to /v1/admin/mangas/{id}/resync and returns the envelope', async () => {
|
||||
|
||||
Reference in New Issue
Block a user