import 'reflect-metadata';
import { ValidationPipe } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
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 () => {
    const dto = plainToInstance(UpsertProfileDto, {
      grade: '高三',
      campusLocation: '旧校区',
    });

    await validate(dto, { whitelist: true });

    expect(dto).toMatchObject({ grade: '高三' });
    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({});
  });
});
