feat(devices): compute effective online status with stale heartbeat ttl
This commit is contained in:
60
Backend/tests/device-status.test.ts
Normal file
60
Backend/tests/device-status.test.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
|
||||
import { getEffectiveDeviceStatus } from '../utils/device-status';
|
||||
|
||||
describe('device status helper', () => {
|
||||
test('reports online when status is online and heartbeat is fresh', () => {
|
||||
const now = new Date('2026-02-25T12:00:00.000Z');
|
||||
const lastSeenAt = new Date('2026-02-25T11:59:45.000Z');
|
||||
|
||||
const status = getEffectiveDeviceStatus({
|
||||
status: 'online',
|
||||
lastSeenAt,
|
||||
now,
|
||||
staleAfterSeconds: 30,
|
||||
});
|
||||
|
||||
expect(status).toBe('online');
|
||||
});
|
||||
|
||||
test('reports offline when heartbeat is stale', () => {
|
||||
const now = new Date('2026-02-25T12:00:00.000Z');
|
||||
const lastSeenAt = new Date('2026-02-25T11:59:00.000Z');
|
||||
|
||||
const status = getEffectiveDeviceStatus({
|
||||
status: 'online',
|
||||
lastSeenAt,
|
||||
now,
|
||||
staleAfterSeconds: 30,
|
||||
});
|
||||
|
||||
expect(status).toBe('offline');
|
||||
});
|
||||
|
||||
test('reports offline when stored status is not online', () => {
|
||||
const now = new Date('2026-02-25T12:00:00.000Z');
|
||||
const lastSeenAt = new Date('2026-02-25T11:59:55.000Z');
|
||||
|
||||
const status = getEffectiveDeviceStatus({
|
||||
status: 'offline',
|
||||
lastSeenAt,
|
||||
now,
|
||||
staleAfterSeconds: 30,
|
||||
});
|
||||
|
||||
expect(status).toBe('offline');
|
||||
});
|
||||
|
||||
test('reports offline when lastSeenAt is missing', () => {
|
||||
const now = new Date('2026-02-25T12:00:00.000Z');
|
||||
|
||||
const status = getEffectiveDeviceStatus({
|
||||
status: 'online',
|
||||
lastSeenAt: null,
|
||||
now,
|
||||
staleAfterSeconds: 30,
|
||||
});
|
||||
|
||||
expect(status).toBe('offline');
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, test } from 'bun:test';
|
||||
|
||||
import { getBetterAuthBaseUrl, getFirstDefinedEnv } from '../utils/env';
|
||||
import { getBetterAuthBaseUrl, getDeviceOnlineStaleSeconds, getFirstDefinedEnv } from '../utils/env';
|
||||
|
||||
const ORIGINAL_ENV = { ...process.env };
|
||||
|
||||
@@ -22,4 +22,25 @@ describe('env helpers', () => {
|
||||
|
||||
expect(getBetterAuthBaseUrl()).toBe('http://base-url:4000');
|
||||
});
|
||||
|
||||
test('getDeviceOnlineStaleSeconds defaults to 30', () => {
|
||||
delete process.env.DEVICE_ONLINE_STALE_SECONDS;
|
||||
expect(getDeviceOnlineStaleSeconds()).toBe(30);
|
||||
});
|
||||
|
||||
test('getDeviceOnlineStaleSeconds parses valid positive integer values', () => {
|
||||
process.env.DEVICE_ONLINE_STALE_SECONDS = '45';
|
||||
expect(getDeviceOnlineStaleSeconds()).toBe(45);
|
||||
});
|
||||
|
||||
test('getDeviceOnlineStaleSeconds falls back to default on invalid values', () => {
|
||||
process.env.DEVICE_ONLINE_STALE_SECONDS = '0';
|
||||
expect(getDeviceOnlineStaleSeconds()).toBe(30);
|
||||
|
||||
process.env.DEVICE_ONLINE_STALE_SECONDS = '-2';
|
||||
expect(getDeviceOnlineStaleSeconds()).toBe(30);
|
||||
|
||||
process.env.DEVICE_ONLINE_STALE_SECONDS = 'abc';
|
||||
expect(getDeviceOnlineStaleSeconds()).toBe(30);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user