rwadurian/backend/services/admin-service/test/unit/infrastructure/mappers/app-version.mapper.spec.ts

141 lines
6.0 KiB
TypeScript

import { Test, TestingModule } from '@nestjs/testing';
import { AppVersionMapper } from '../../../../src/infrastructure/persistence/mappers/app-version.mapper';
import { AppVersion } from '../../../../src/domain/entities/app-version.entity';
import { Platform } from '../../../../src/domain/enums/platform.enum';
import { Platform as PrismaPlatform } from '@prisma/client';
import { VersionCode } from '../../../../src/domain/value-objects/version-code.vo';
import { VersionName } from '../../../../src/domain/value-objects/version-name.vo';
import { BuildNumber } from '../../../../src/domain/value-objects/build-number.vo';
import { DownloadUrl } from '../../../../src/domain/value-objects/download-url.vo';
import { FileSize } from '../../../../src/domain/value-objects/file-size.vo';
import { FileSha256 } from '../../../../src/domain/value-objects/file-sha256.vo';
import { Changelog } from '../../../../src/domain/value-objects/changelog.vo';
describe('AppVersionMapper', () => {
let mapper: AppVersionMapper;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AppVersionMapper],
}).compile();
mapper = module.get<AppVersionMapper>(AppVersionMapper);
});
const createDomainVersion = () => {
return AppVersion.create({
platform: Platform.ANDROID,
versionCode: VersionCode.create(100),
versionName: VersionName.create('1.0.0'),
buildNumber: BuildNumber.create('100'),
downloadUrl: DownloadUrl.create('https://example.com/app.apk'),
fileSize: FileSize.create(10485760n),
fileSha256: FileSha256.create('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'),
changelog: Changelog.create('Initial release'),
isForceUpdate: false,
createdBy: 'admin',
});
};
const createPrismaVersion = () => ({
id: 'test-id',
platform: PrismaPlatform.ANDROID,
versionCode: 100,
versionName: '1.0.0',
buildNumber: '100',
downloadUrl: 'https://example.com/app.apk',
fileSize: 10485760n,
fileSha256: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
changelog: 'Initial release',
minOsVersion: null,
isEnabled: true,
isForceUpdate: false,
releaseDate: null,
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
createdBy: 'admin',
updatedBy: null,
});
describe('toDomain', () => {
it('should map Prisma model to domain entity', () => {
const prismaVersion = createPrismaVersion();
const domainVersion = mapper.toDomain(prismaVersion);
expect(domainVersion).toBeInstanceOf(AppVersion);
expect(domainVersion.id).toBe(prismaVersion.id);
expect(domainVersion.platform).toBe(Platform.ANDROID);
expect(domainVersion.versionCode.value).toBe(100);
expect(domainVersion.versionName.value).toBe('1.0.0');
expect(domainVersion.buildNumber.value).toBe('100');
expect(domainVersion.downloadUrl.value).toBe('https://example.com/app.apk');
expect(domainVersion.fileSize.bytes).toBe(10485760n);
expect(domainVersion.fileSha256.value).toBe('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
expect(domainVersion.changelog.value).toBe('Initial release');
expect(domainVersion.isEnabled).toBe(true);
expect(domainVersion.isForceUpdate).toBe(false);
});
it('should map iOS platform correctly', () => {
const prismaVersion = { ...createPrismaVersion(), platform: PrismaPlatform.IOS };
const domainVersion = mapper.toDomain(prismaVersion);
expect(domainVersion.platform).toBe(Platform.IOS);
});
it('should handle null minOsVersion', () => {
const prismaVersion = { ...createPrismaVersion(), minOsVersion: null };
const domainVersion = mapper.toDomain(prismaVersion);
expect(domainVersion.minOsVersion).toBeNull();
});
it('should handle null releaseDate', () => {
const prismaVersion = { ...createPrismaVersion(), releaseDate: null };
const domainVersion = mapper.toDomain(prismaVersion);
expect(domainVersion.releaseDate).toBeNull();
});
});
describe('toPersistence', () => {
it('should map domain entity to Prisma model', () => {
const domainVersion = createDomainVersion();
const persistenceModel = mapper.toPersistence(domainVersion);
expect(persistenceModel.id).toBe(domainVersion.id);
expect(persistenceModel.platform).toBe(Platform.ANDROID);
expect(persistenceModel.versionCode).toBe(100);
expect(persistenceModel.versionName).toBe('1.0.0');
expect(persistenceModel.buildNumber).toBe('100');
expect(persistenceModel.downloadUrl).toBe('https://example.com/app.apk');
expect(persistenceModel.fileSize).toBe(10485760n);
expect(persistenceModel.fileSha256).toBe('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
expect(persistenceModel.changelog).toBe('Initial release');
expect(persistenceModel.isEnabled).toBe(true);
expect(persistenceModel.isForceUpdate).toBe(false);
});
it('should exclude createdAt and updatedAt from output', () => {
const domainVersion = createDomainVersion();
const persistenceModel = mapper.toPersistence(domainVersion);
expect(persistenceModel).not.toHaveProperty('createdAt');
expect(persistenceModel).not.toHaveProperty('updatedAt');
});
});
describe('round-trip conversion', () => {
it('should maintain data integrity through round-trip conversion', () => {
const originalPrisma = createPrismaVersion();
const domain = mapper.toDomain(originalPrisma);
const backToPersistence = mapper.toPersistence(domain);
expect(backToPersistence.id).toBe(originalPrisma.id);
expect(backToPersistence.versionCode).toBe(originalPrisma.versionCode);
expect(backToPersistence.versionName).toBe(originalPrisma.versionName);
expect(backToPersistence.platform).toBe(originalPrisma.platform);
});
});
});