feat: Migrate from Socket.IO to Server-Sent Events (SSE)
- Replace Socket.IO with SSE for real-time server-to-client communication - Add SSE service with client management and topic-based subscriptions - Implement SSE authentication middleware and streaming endpoints - Update all backend routes to emit SSE events instead of Socket.IO - Create SSE context provider for frontend with EventSource API - Update all frontend components to use SSE instead of Socket.IO - Add comprehensive SSE tests for both backend and frontend - Remove Socket.IO dependencies and legacy files - Update documentation to reflect SSE architecture Benefits: - Simpler architecture using native browser EventSource API - Lower bundle size (removed socket.io-client dependency) - Better compatibility with reverse proxies and load balancers - Reduced resource usage for Raspberry Pi deployment - Standard HTTP-based real-time communication 🤖 Generated with [AI Assistant] Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { AuthContext } from '../../context/AuthContext';
|
||||
import { SocketContext } from '../../context/SocketContext';
|
||||
import { SSEContext } from '../../context/SSEContext';
|
||||
import Events from '../Events';
|
||||
import axios from 'axios';
|
||||
|
||||
@@ -13,13 +13,15 @@ const mockAuthContext = {
|
||||
logout: jest.fn(),
|
||||
};
|
||||
|
||||
const mockSocketContext = {
|
||||
socket: null,
|
||||
const mockSSEContext = {
|
||||
connected: true,
|
||||
notifications: [],
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
joinEvent: jest.fn(),
|
||||
leaveEvent: jest.fn(),
|
||||
subscribe: jest.fn().mockResolvedValue({ subscribed: [] }),
|
||||
unsubscribe: jest.fn().mockResolvedValue({ unsubscribed: [] }),
|
||||
clearNotification: jest.fn(),
|
||||
clearAllNotifications: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock('axios');
|
||||
@@ -83,9 +85,9 @@ describe('Events Component', () => {
|
||||
return render(
|
||||
<BrowserRouter>
|
||||
<AuthContext.Provider value={mockAuthContext}>
|
||||
<SocketContext.Provider value={mockSocketContext}>
|
||||
<SSEContext.Provider value={mockSSEContext}>
|
||||
<Events />
|
||||
</SocketContext.Provider>
|
||||
</SSEContext.Provider>
|
||||
</AuthContext.Provider>
|
||||
</BrowserRouter>
|
||||
);
|
||||
@@ -296,19 +298,19 @@ describe('Events Component', () => {
|
||||
});
|
||||
|
||||
it('handles real-time updates', async () => {
|
||||
const { on } = mockSocketContext;
|
||||
const { on } = mockSSEContext;
|
||||
|
||||
renderEvents();
|
||||
|
||||
await waitFor(() => {
|
||||
// Simulate receiving a new event via socket
|
||||
const socketCallback = on.mock.calls[0][1];
|
||||
// Simulate receiving a new event via SSE
|
||||
const sseCallback = on.mock.calls[0][1];
|
||||
const newEventData = {
|
||||
type: 'new_event',
|
||||
data: { ...mockEvents[0], _id: 'event5' }
|
||||
event: { ...mockEvents[0], _id: 'event5' }
|
||||
};
|
||||
|
||||
socketCallback(newEventData);
|
||||
sseCallback(newEventData);
|
||||
|
||||
// Verify new event appears in the list
|
||||
expect(screen.getByText('Community Cleanup Day')).toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user