diff --git a/.vscode/settings.json b/.vscode/settings.json index 9bf4d12..82bf02b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,10 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true + "editor.formatOnSave": true, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/src/__tests__/ClientHandler.test.ts b/src/__tests__/ClientHandler.test.ts index afc4f0f..294af5e 100644 --- a/src/__tests__/ClientHandler.test.ts +++ b/src/__tests__/ClientHandler.test.ts @@ -1,34 +1,34 @@ -import GRPCClientHandler from '../implementations/GRPCClientHandler'; -import { AISServiceClientImpl } from '../../proto/AIS-protobuf/ais'; +import GRPCClientHandler from '../implementations/GRPCClientHandler' +import { AISServiceClientImpl, VesselInfoResponse } from '../../proto/AIS-protobuf/ais' // Create a mock implementation of Rpc const mockClient: jest.Mocked = { - GetVesselInfo: jest.fn(), -} as unknown as jest.Mocked; + GetVesselInfo: jest.fn(), +} as unknown as jest.Mocked -jest.mock('../../proto/AIS-protobuf/ais'); +jest.mock('../../proto/AIS-protobuf/ais') describe('GRPCClientHandler', () => { - let clientHandler: GRPCClientHandler; + let clientHandler: GRPCClientHandler - beforeEach(() => { - clientHandler = new GRPCClientHandler(mockClient); - }); + beforeEach(() => { + clientHandler = new GRPCClientHandler(mockClient) + }) - it('should return detailed vessel information', async () => { - const mockResponse = { mmsi: 123456789, name: 'Test Vessel', shipType: 'Cargo' } as any; // Mock the actual response - mockClient.GetVesselInfo.mockResolvedValue(mockResponse); + it('should return detailed vessel information', async () => { + const mockResponse = { mmsi: 123456789, name: 'Test Vessel', shipType: 'Cargo' } as VesselInfoResponse // Mock the actual response + mockClient.GetVesselInfo.mockResolvedValue(mockResponse) - const result = await clientHandler.getVesselInfo({ mmsi: 123456789, timestamp: 1609459200 }); - expect(result).toEqual({ - mmsi: 123456789, - name: 'Test Vessel', - shipType: 'Cargo', - imo: undefined, - callSign: undefined, - width: undefined, - length: undefined, - positionFixingDevice: undefined, - }); - }); -}); \ No newline at end of file + const result = await clientHandler.getVesselInfo({ mmsi: 123456789, timestamp: 1609459200 }) + expect(result).toEqual({ + mmsi: 123456789, + name: 'Test Vessel', + shipType: 'Cargo', + imo: undefined, + callSign: undefined, + width: undefined, + length: undefined, + positionFixingDevice: undefined, + }) + }) +}) diff --git a/src/__tests__/StreamManager.test.ts b/src/__tests__/StreamManager.test.ts index 7d4d6f3..43f1a5e 100644 --- a/src/__tests__/StreamManager.test.ts +++ b/src/__tests__/StreamManager.test.ts @@ -1,46 +1,61 @@ -import StreamManager, { SIMPLE_FETCH_INTERVAL, MONITORED_FETCH_INTERVAL } from '../implementations/StreamManager'; -import { IClientHandler } from '../interfaces/IClientHandler'; -import { ISimpleVessel } from '../models/simpleVessel'; -import { IMonitoredVessel } from '../models/monitoredVessel'; -import { RefObject } from 'react'; +import StreamManager from '../implementations/StreamManager' +import { IClientHandler } from '../interfaces/IClientHandler' +import { ISimpleVessel } from '../models/simpleVessel' +import { IMonitoredVessel } from '../models/monitoredVessel' +import { RefObject } from 'react' -jest.mock('../interfaces/IClientHandler'); +jest.mock('../interfaces/IClientHandler') describe('StreamManager', () => { - let mockClientHandler: jest.Mocked; - let setAllVessels: jest.Mock>>; - let setMonitoredVessels: jest.Mock>>; - let dateTimeRef: RefObject; - let streamManager: StreamManager; - - beforeEach(() => { - mockClientHandler = { - getSimpleVessles: jest.fn().mockResolvedValue([{ mmsi: 123456, location: { point: { lon: 1, lat: 2 }, timestamp: new Date(), heading: 45 } }]), - getMonitoredVessels: jest.fn().mockResolvedValue([{ mmsi: 123456, trustworthiness: 0.9, reason: 'Test' }]), - } as unknown as jest.Mocked; - - setAllVessels = jest.fn(); - setMonitoredVessels = jest.fn(); - dateTimeRef = { current: new Date() } as RefObject; - - streamManager = new StreamManager(mockClientHandler, setAllVessels, setMonitoredVessels, dateTimeRef); - }); - - it('should start and stop simple vessel fetching', async () => { - jest.useFakeTimers(); - jest.spyOn(global, 'setTimeout') - streamManager.startSimpleVesselFetching(); - expect(mockClientHandler.getSimpleVessles).toHaveBeenCalledTimes(1); // Called once - - // jest.advanceTimersByTime(SIMPLE_FETCH_INTERVAL); // Simulate 5 seconds for the next call - // expect(mockClientHandler.getSimpleVessles).toHaveBeenCalledTimes(2); // Called in loop - - streamManager.stopSimpleVesselFetching(); // Stop the loop - // jest.clearAllTimers(); - }); - - it('should handle monitoring zone change and stop fetching if zone is invalid', () => { - streamManager.onMonitoringZoneChange(undefined); - expect(setMonitoredVessels).toHaveBeenCalledWith([]); - }); -}); \ No newline at end of file + let mockClientHandler: jest.Mocked + let setAllVessels: jest.Mock>> + let setMonitoredVessels: jest.Mock>> + let dateTimeRef: RefObject + let streamManager: StreamManager + + beforeEach(() => { + mockClientHandler = { + getSimpleVessles: jest + .fn() + .mockResolvedValue([ + { mmsi: 123456, location: { point: { lon: 1, lat: 2 }, timestamp: new Date(), heading: 45 } }, + ]), + getMonitoredVessels: jest.fn().mockResolvedValue([{ mmsi: 123456, trustworthiness: 0.9, reason: 'Test' }]), + } as unknown as jest.Mocked + + setAllVessels = jest.fn() + setMonitoredVessels = jest.fn() + dateTimeRef = { current: new Date() } as RefObject + + streamManager = new StreamManager(mockClientHandler, setAllVessels, setMonitoredVessels, dateTimeRef) + }) + + it('should start and stop simple vessel fetching', async () => { + streamManager.startSimpleVesselFetching() + expect(mockClientHandler.getSimpleVessles).toHaveBeenCalledTimes(1) // Called once + streamManager.stopSimpleVesselFetching() // Stop the loop + }) + + it('should start and stop monitored vessel fetching', async () => { + // Start fetching + streamManager.onMonitoringZoneChange([ + { lon: 1, lat: 2 }, + { lon: 3, lat: 4 }, + { lon: 5, lat: 6 }, + { lon: 7, lat: 8 }, + ]) + expect(mockClientHandler.getMonitoredVessels).toHaveBeenCalledTimes(1) + + // Clear call count + mockClientHandler.getMonitoredVessels.mockClear() + + // Stop fetching + streamManager.onMonitoringZoneChange(undefined) + expect(mockClientHandler.getMonitoredVessels).not.toHaveBeenCalled() + }) + + it('should handle monitoring zone change and stop fetching if zone is invalid', () => { + streamManager.onMonitoringZoneChange(undefined) + expect(setMonitoredVessels).toHaveBeenCalledWith([]) + }) +}) diff --git a/src/implementations/GRPCClientHandler.ts b/src/implementations/GRPCClientHandler.ts index d0fade6..b6c6938 100644 --- a/src/implementations/GRPCClientHandler.ts +++ b/src/implementations/GRPCClientHandler.ts @@ -15,7 +15,7 @@ import { ILocation } from '../models/location' import { IVesselPath } from '../models/vesselPath' export default class GRPCClientHandler implements IClientHandler { - constructor(private readonly client: AISServiceClientImpl) { } + constructor(private readonly client: AISServiceClientImpl) {} async getVesselInfo(request: { mmsi: number; timestamp: number }): Promise { const grpcReq: VesselInfoRequest = { diff --git a/src/implementations/StreamManager.ts b/src/implementations/StreamManager.ts index 34a65a1..20a6609 100644 --- a/src/implementations/StreamManager.ts +++ b/src/implementations/StreamManager.ts @@ -27,7 +27,7 @@ export default class StreamManager implements IStreamManager { timestamp: Math.round(this.myDateTimeRef.current!.getTime() / 1000), }) - this.manageNewSimpleVessels(simpleVessels) + this.setAllVessels(simpleVessels) } private async simpleVesselLoop() { @@ -62,7 +62,7 @@ export default class StreamManager implements IStreamManager { timestamp: Math.round(this.myDateTimeRef.current!.getTime() / 1000), selection: { points: this.zone }, }) - this.manageNewMonitoredVessels(monitoredvessels) + this.setMonitoredVessels(monitoredvessels) } private async startMonitoredVesselFetching() { @@ -77,12 +77,4 @@ export default class StreamManager implements IStreamManager { private async stopMonitoredVesselFetching() { clearTimeout(this.monitoredVesselTimeout) } - - private manageNewSimpleVessels(vessels: ISimpleVessel[]) { - this.setAllVessels(vessels) - } - - private manageNewMonitoredVessels(vessels: IMonitoredVessel[]) { - this.setMonitoredVessels(vessels) - } }