test: harden business boundary conditions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Subject, Observable } from 'rxjs';
|
||||
@@ -18,7 +18,10 @@ export class NotificationsService {
|
||||
) {}
|
||||
|
||||
async create(dto: CreateNotificationDto): Promise<Notification[]> {
|
||||
const notifications = dto.recipientIds.map((recipientId) => ({
|
||||
const recipientIds = [...new Set(dto.recipientIds)];
|
||||
if (recipientIds.length === 0) throw new BadRequestException('通知接收人不能为空');
|
||||
|
||||
const notifications = recipientIds.map((recipientId) => ({
|
||||
recipientId,
|
||||
type: dto.type,
|
||||
title: dto.title,
|
||||
@@ -36,16 +39,13 @@ export class NotificationsService {
|
||||
return saved;
|
||||
}
|
||||
|
||||
async findByUser(
|
||||
userId: number,
|
||||
after?: number,
|
||||
limit: number = 20,
|
||||
): Promise<Notification[]> {
|
||||
async findByUser(userId: number, after?: number, limit: number = 20): Promise<Notification[]> {
|
||||
const safeLimit = Math.min(Math.max(limit, 1), 100);
|
||||
const qb = this.repo
|
||||
.createQueryBuilder('n')
|
||||
.where('n.recipientId = :userId', { userId })
|
||||
.orderBy('n.createdAt', 'DESC')
|
||||
.take(limit);
|
||||
.take(safeLimit);
|
||||
|
||||
if (after !== undefined) {
|
||||
qb.andWhere('n.id < :after', { after });
|
||||
@@ -61,10 +61,10 @@ export class NotificationsService {
|
||||
}
|
||||
|
||||
async markRead(id: number, userId: number): Promise<void> {
|
||||
await this.repo.update(
|
||||
{ id, recipientId: userId },
|
||||
{ isRead: true, readAt: new Date() },
|
||||
);
|
||||
const notification = await this.repo.findOne({ where: { id, recipientId: userId } });
|
||||
if (!notification) throw new NotFoundException('通知不存在');
|
||||
if (notification.isRead) return;
|
||||
await this.repo.update({ id, recipientId: userId }, { isRead: true, readAt: new Date() });
|
||||
}
|
||||
|
||||
async markAllRead(userId: number): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user