mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-06-08 07:13:53 +02:00
668ce16dc7
Gate messages now propagate via the Infonet hashchain as encrypted blobs — every node syncs them through normal chain sync while only Gate members with MLS keys can decrypt. Added mesh reputation system, peer push workers, voluntary Wormhole opt-in for node participation, fork recovery, killwormhole scripts, obfuscated terminology, and hardened the self-updater to protect encryption keys and chain state during updates. New features: Shodan search, train tracking, Sentinel Hub imagery, 8 new intelligence layers, CCTV expansion to 11,000+ cameras across 6 countries, Mesh Terminal CLI, prediction markets, desktop-shell scaffold, and comprehensive mesh test suite (215 frontend + backend tests passing). Community contributors: @wa1id, @AlborzNazari, @adust09, @Xpirix, @imqdcr, @csysp, @suranyami, @chr0n1x, @johan-martensson, @singularfailure, @smithbh, @OrfeoTerkuci, @deuza, @tm-const, @Elhard1, @ttulttul
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { spreadAlertItems } from '@/utils/alertSpread';
|
|
|
|
describe('spreadAlertItems', () => {
|
|
const makeAlert = (title: string, lat: number, lng: number, cluster_count = 1) => ({
|
|
title,
|
|
coords: [lat, lng],
|
|
cluster_count,
|
|
alert_level: 3,
|
|
});
|
|
|
|
it('returns empty array for empty input', () => {
|
|
expect(spreadAlertItems([], 4, new Set())).toEqual([]);
|
|
});
|
|
|
|
it('throws on null input (caller must null-check)', () => {
|
|
expect(() => spreadAlertItems(null as any, 4, new Set())).toThrow();
|
|
});
|
|
|
|
it('filters out items without coords', () => {
|
|
const items = [{ title: 'No coords', alert_level: 1 }, makeAlert('Has coords', 40, -74)];
|
|
const result = spreadAlertItems(items, 4, new Set());
|
|
expect(result.length).toBe(1);
|
|
expect(result[0].title).toBe('Has coords');
|
|
});
|
|
|
|
it('filters dismissed alerts by alertKey', () => {
|
|
const items = [makeAlert('Fire in NYC', 40.7, -74.0), makeAlert('Floods in LA', 34.0, -118.2)];
|
|
const dismissed = new Set(['Fire in NYC|40.7,-74']);
|
|
const result = spreadAlertItems(items, 4, dismissed);
|
|
expect(result.length).toBe(1);
|
|
expect(result[0].title).toBe('Floods in LA');
|
|
});
|
|
|
|
it('preserves originalIdx for popup selection', () => {
|
|
const items = [
|
|
{ title: 'Skip me', alert_level: 1 }, // no coords
|
|
makeAlert('Alert A', 10, 20),
|
|
makeAlert('Alert B', 30, 40),
|
|
];
|
|
const result = spreadAlertItems(items, 4, new Set());
|
|
expect(result[0].originalIdx).toBe(1);
|
|
expect(result[1].originalIdx).toBe(2);
|
|
});
|
|
|
|
it('adds alertKey and showLine properties', () => {
|
|
const items = [makeAlert('Test Alert', 51.5, -0.1)];
|
|
const result = spreadAlertItems(items, 4, new Set());
|
|
expect(result[0]).toHaveProperty('alertKey');
|
|
expect(result[0]).toHaveProperty('showLine');
|
|
expect(result[0].alertKey).toContain('Test Alert');
|
|
});
|
|
|
|
it('spreads overlapping alerts apart (offsets are non-zero for stacked items)', () => {
|
|
// Place 5 alerts at the exact same location — they should be spread apart
|
|
const items = Array.from({ length: 5 }, (_, i) => makeAlert(`Alert ${i}`, 40.0, -74.0));
|
|
const result = spreadAlertItems(items, 8, new Set()); // zoom 8 = close enough to overlap
|
|
const hasNonZeroOffset = result.some(
|
|
(r: any) => Math.abs(r.offsetX) > 1 || Math.abs(r.offsetY) > 1,
|
|
);
|
|
expect(hasNonZeroOffset).toBe(true);
|
|
});
|
|
});
|