Unregister & Unsubscribe vom SSE für Keys eingebaut

This commit is contained in:
Bastian Wagner
2026-03-09 12:59:59 +01:00
parent b3fd7fbf03
commit 1480e8d7b2
4 changed files with 40 additions and 5 deletions

View File

@@ -6,6 +6,7 @@ import { JwtService } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config'; import { ConfigModule, ConfigService } from '@nestjs/config';
import { AuthService } from 'src/modules/auth/auth.service'; import { AuthService } from 'src/modules/auth/auth.service';
import { SseService } from './sse.service'; import { SseService } from './sse.service';
import { Subject } from 'rxjs';
describe('SseController', () => { describe('SseController', () => {
let controller: SseController; let controller: SseController;
@@ -18,7 +19,6 @@ describe('SseController', () => {
ConfigService, ConfigService,
{ provide: JwtService, useClass: MockJwTService }, { provide: JwtService, useClass: MockJwTService },
{ provide: SseTicketService, useClass: MockSseTicketService }, { provide: SseTicketService, useClass: MockSseTicketService },
{ provide: UserService, useClass: MockUserService },
{ provide: AuthService, useClass: MockAuthService }, { provide: AuthService, useClass: MockAuthService },
{ provide: SseService, useClass: MockSSEService } { provide: SseService, useClass: MockSSEService }
@@ -56,11 +56,10 @@ class MockSseTicketService {
class MockSSEService { class MockSSEService {
register = jest.fn().mockImplementation( (id) => { register = jest.fn().mockImplementation( (id) => {
return new Promise(resolve => resolve(null)) return new Subject()
}) })
} }
class MockUserService { }
class MockJwTService {} class MockJwTService {}
class MockAuthService {} class MockAuthService {}

View File

@@ -2,7 +2,7 @@ import { Controller, Get, Param, Query, Req, Sse, UnauthorizedException, UseGuar
import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface'; import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface';
import { SseTicketService } from './sse-ticket.service'; import { SseTicketService } from './sse-ticket.service';
import { AuthGuard } from 'src/core/guards/auth.guard'; import { AuthGuard } from 'src/core/guards/auth.guard';
import { Observable } from 'rxjs'; import { finalize, Observable } from 'rxjs';
import { SseService } from './sse.service'; import { SseService } from './sse.service';
@Controller('sse') @Controller('sse')
@@ -23,6 +23,10 @@ export class SseController {
if (!userId) throw new UnauthorizedException('Invalid/expired ticket'); if (!userId) throw new UnauthorizedException('Invalid/expired ticket');
return this.sseService.register(userId); return this.sseService.register(userId).pipe(
finalize(() => {
this.sseService.unregister(userId)
})
);
} }
} }

View File

@@ -1,8 +1,10 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { SseService } from './sse.service'; import { SseService } from './sse.service';
import { Key } from 'src/model/entitites';
describe('SseService', () => { describe('SseService', () => {
let service: SseService; let service: SseService;
const userId = 'testuserid-54';
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
@@ -15,4 +17,26 @@ describe('SseService', () => {
it('should be defined', () => { it('should be defined', () => {
expect(service).toBeDefined(); expect(service).toBeDefined();
}); });
it('should register new SSE clients', () => {
const res = service.register(userId);
expect(service["clients"].has(userId)).toBeTruthy();
});
it('should send keys to User', () => {
const sub = service.register(userId);
const key = new Key();
const keyId = 'testkey-123';
key.id = keyId;
sub.subscribe({
next: val => {
expect(val.data).toBeTruthy();
expect(val.data[0]?.id).toBe(keyId)
}
})
service.sendKeysToUsers(userId, [key]);
})
}); });

View File

@@ -19,4 +19,12 @@ export class SseService {
this.clients.set(userId, subj); this.clients.set(userId, subj);
return subj; return subj;
} }
unregister(userId: string) {
if (!this.clients.has(userId)) { return; }
const sub = this.clients.get(userId);
sub.unsubscribe();
this.clients.delete(userId);
}
} }