Misc. doc, test, and qol improvements

This commit is contained in:
Jack Kingsman
2026-02-27 15:17:29 -08:00
parent c40603a36f
commit 6a3510ce2e
12 changed files with 277 additions and 22 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ Types, constants, and pure functions shared across the codebase:
- Types: `NodeType`, `PacketLabel`, `Particle`, `ObservedPath`, `PendingPacket`, `ParsedPacket`, `TrafficObservation`, `RepeaterTrafficData`, `RepeaterSplitAnalysis`
- Constants: `COLORS`, `PARTICLE_COLOR_MAP`, `PARTICLE_SPEED`, `DEFAULT_OBSERVATION_WINDOW_SEC`, traffic thresholds, `PACKET_LEGEND_ITEMS`
- Functions: `simpleHash`, `parsePacket`, `getPacketLabel`, `generatePacketKey`, `getLinkId`, `getNodeType`, `dedupeConsecutive`, `analyzeRepeaterTraffic`, `recordTrafficObservation`
- Functions: `hashString` (from `utils/contactAvatar.ts`), `parsePacket`, `getPacketLabel`, `generatePacketKey`, `getLinkId`, `getNodeType`, `dedupeConsecutive`, `analyzeRepeaterTraffic`, `recordTrafficObservation`
`GraphNode` and `GraphLink` are defined locally in the component — they extend `SimulationNodeDatum3D` and `SimulationLinkDatum` from `d3-force-3d`.
+1
View File
@@ -1,6 +1,7 @@
export { useUnreadCounts } from './useUnreadCounts';
export { useConversationMessages, getMessageContentKey } from './useConversationMessages';
export { useRadioControl } from './useRadioControl';
export { useRepeaterDashboard } from './useRepeaterDashboard';
export { useAppSettings } from './useAppSettings';
export { useConversationRouter } from './useConversationRouter';
export { useContactsAndChannels } from './useContactsAndChannels';
@@ -177,6 +177,32 @@ describe('useWebSocket dispatch', () => {
Object.values(handlers).forEach((fn) => expect(fn).not.toHaveBeenCalled());
});
it('routes raw_packet event to onRawPacket with observation_id', () => {
const onRawPacket = vi.fn();
renderHook(() => useWebSocket({ onRawPacket }));
const rawPacketData = {
id: 5,
observation_id: 42,
timestamp: 1700000000,
data: 'aabbccdd',
payload_type: 'GROUP_TEXT',
snr: 7.5,
rssi: -85,
decrypted: true,
decrypted_info: {
channel_name: '#general',
sender: 'Alice',
},
};
fireMessage({ type: 'raw_packet', data: rawPacketData });
expect(onRawPacket).toHaveBeenCalledOnce();
expect(onRawPacket).toHaveBeenCalledWith(rawPacketData);
expect(onRawPacket.mock.calls[0][0]).toHaveProperty('observation_id', 42);
expect(onRawPacket.mock.calls[0][0]).toHaveProperty('id', 5);
});
it('malformed JSON calls no handlers (catch branch)', () => {
const handlers = {
onHealth: vi.fn(),