refactor: resolve remaining field audit issues

This commit is contained in:
2026-07-13 15:12:36 +08:00
parent 0533c30ece
commit aa1ed7db56
34 changed files with 953 additions and 263 deletions

View File

@@ -1,7 +1,19 @@
import 'reflect-metadata';
import { ValidationPipe } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import { UpsertProfileDto } from './archive.dto';
import {
UpdateEnrollmentDto,
UpdateExamScoreDto,
UpdateLearningRecordDto,
UpsertProfileDto,
} from './archive.dto';
const pipe = new ValidationPipe({ transform: true, whitelist: true });
async function transform<T extends object>(metatype: new () => T, value: unknown) {
return pipe.transform(value, { type: 'body', metatype });
}
describe('UpsertProfileDto retired fields', () => {
it('removes the retired campusLocation field under whitelist validation', async () => {
@@ -16,3 +28,30 @@ describe('UpsertProfileDto retired fields', () => {
expect(dto).not.toHaveProperty('campusLocation');
});
});
describe('archive update DTOs', () => {
it('allows partial enrollment updates and strips unknown fields', async () => {
await expect(
transform(UpdateEnrollmentDto, { className: '新班级', ignored: 'value' }),
).resolves.toEqual(expect.objectContaining({ className: '新班级' }));
const result = await transform(UpdateEnrollmentDto, {
className: '新班级',
ignored: 'value',
});
expect(result).not.toHaveProperty('ignored');
});
it('retains create DTO validation rules for exam scores', async () => {
await expect(transform(UpdateExamScoreDto, { score: '90' })).rejects.toThrow();
await expect(transform(UpdateExamScoreDto, { score: 90 })).resolves.toMatchObject({
score: 90,
});
});
it('retains create DTO date validation for learning records', async () => {
await expect(
transform(UpdateLearningRecordDto, { recordDate: 'not-a-date' }),
).rejects.toThrow();
await expect(transform(UpdateLearningRecordDto, {})).resolves.toEqual({});
});
});

View File

@@ -1,3 +1,4 @@
import { PartialType } from '@nestjs/mapped-types';
import { IsOptional, IsString, IsNumber, IsDateString } from 'class-validator';
export class UpsertProfileDto {
@@ -20,6 +21,8 @@ export class CreateEnrollmentDto {
@IsOptional() @IsString() status?: string;
}
export class UpdateEnrollmentDto extends PartialType(CreateEnrollmentDto) {}
export class CreateExamScoreDto {
@IsString() examType: string;
@IsOptional() @IsString() examName?: string;
@@ -31,6 +34,8 @@ export class CreateExamScoreDto {
@IsOptional() @IsNumber() enrollmentId?: number;
}
export class UpdateExamScoreDto extends PartialType(CreateExamScoreDto) {}
export class CreateLearningRecordDto {
@IsDateString() recordDate: string;
@IsString() recordType: string;
@@ -39,6 +44,8 @@ export class CreateLearningRecordDto {
@IsOptional() @IsString() nextStep?: string;
}
export class UpdateLearningRecordDto extends PartialType(CreateLearningRecordDto) {}
export class UpsertResultDto {
@IsOptional() @IsNumber() cultureFinalScore?: number;
@IsOptional() @IsNumber() professionalFinalScore?: number;