272 lines
9.4 KiB
TypeScript
272 lines
9.4 KiB
TypeScript
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { ConfigModule } from '@nestjs/config';
|
|
import { PrismaService } from '../../../src/infrastructure/persistence/prisma/prisma.service';
|
|
import { AppVersionRepositoryImpl } from '../../../src/infrastructure/persistence/repositories/app-version.repository.impl';
|
|
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 { 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('AppVersionRepository Integration Tests', () => {
|
|
let repository: AppVersionRepositoryImpl;
|
|
let prisma: PrismaService;
|
|
|
|
beforeAll(async () => {
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
imports: [
|
|
ConfigModule.forRoot({
|
|
isGlobal: true,
|
|
envFilePath: '.env.test',
|
|
}),
|
|
],
|
|
providers: [
|
|
PrismaService,
|
|
AppVersionMapper,
|
|
AppVersionRepositoryImpl,
|
|
],
|
|
}).compile();
|
|
|
|
repository = module.get<AppVersionRepositoryImpl>(AppVersionRepositoryImpl);
|
|
prisma = module.get<PrismaService>(PrismaService);
|
|
|
|
// Connect to test database
|
|
await prisma.$connect();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await prisma.$disconnect();
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
// Clean up test data
|
|
await prisma.appVersion.deleteMany({});
|
|
});
|
|
|
|
const createTestVersion = () => {
|
|
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('Test version for integration testing'),
|
|
isForceUpdate: false,
|
|
createdBy: 'test-user',
|
|
});
|
|
};
|
|
|
|
describe('save', () => {
|
|
it('should save new app version', async () => {
|
|
const version = createTestVersion();
|
|
|
|
const saved = await repository.save(version);
|
|
|
|
expect(saved.id).toBe(version.id);
|
|
expect(saved.versionCode.value).toBe(100);
|
|
expect(saved.versionName.value).toBe('1.0.0');
|
|
});
|
|
|
|
it('should save version and retrieve it from database', async () => {
|
|
const version = createTestVersion();
|
|
await repository.save(version);
|
|
|
|
const found = await repository.findById(version.id);
|
|
|
|
expect(found).not.toBeNull();
|
|
expect(found!.id).toBe(version.id);
|
|
expect(found!.versionCode.value).toBe(version.versionCode.value);
|
|
});
|
|
});
|
|
|
|
describe('findById', () => {
|
|
it('should find version by id', async () => {
|
|
const version = createTestVersion();
|
|
await repository.save(version);
|
|
|
|
const found = await repository.findById(version.id);
|
|
|
|
expect(found).not.toBeNull();
|
|
expect(found!.id).toBe(version.id);
|
|
});
|
|
|
|
it('should return null for non-existent id', async () => {
|
|
const found = await repository.findById('non-existent-id');
|
|
|
|
expect(found).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findLatestByPlatform', () => {
|
|
it('should find latest enabled version by platform', async () => {
|
|
const v1 = createTestVersion();
|
|
const v2 = AppVersion.create({
|
|
platform: Platform.ANDROID,
|
|
versionCode: VersionCode.create(200),
|
|
versionName: VersionName.create('2.0.0'),
|
|
buildNumber: BuildNumber.create('200'),
|
|
downloadUrl: DownloadUrl.create('https://example.com/app-v2.apk'),
|
|
fileSize: FileSize.create(20971520n),
|
|
fileSha256: FileSha256.create('0000000000000000000000000000000000000000000000000000000000000000'),
|
|
changelog: Changelog.create('Version 2.0.0 with new features'),
|
|
isForceUpdate: false,
|
|
createdBy: 'test-user',
|
|
});
|
|
|
|
await repository.save(v1);
|
|
await repository.save(v2);
|
|
|
|
const latest = await repository.findLatestByPlatform(Platform.ANDROID);
|
|
|
|
expect(latest).not.toBeNull();
|
|
expect(latest!.versionCode.value).toBe(200);
|
|
});
|
|
|
|
it('should return null if no enabled versions exist', async () => {
|
|
const latest = await repository.findLatestByPlatform(Platform.ANDROID);
|
|
|
|
expect(latest).toBeNull();
|
|
});
|
|
|
|
it('should not return disabled versions', async () => {
|
|
const version = createTestVersion();
|
|
version.disable('test-user');
|
|
await repository.save(version);
|
|
|
|
const latest = await repository.findLatestByPlatform(Platform.ANDROID);
|
|
|
|
expect(latest).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findByPlatformAndVersionCode', () => {
|
|
it('should find version by platform and version code', async () => {
|
|
const version = createTestVersion();
|
|
await repository.save(version);
|
|
|
|
const found = await repository.findByPlatformAndVersionCode(
|
|
Platform.ANDROID,
|
|
VersionCode.create(100),
|
|
);
|
|
|
|
expect(found).not.toBeNull();
|
|
expect(found!.versionCode.value).toBe(100);
|
|
});
|
|
|
|
it('should return null if version not found', async () => {
|
|
const found = await repository.findByPlatformAndVersionCode(
|
|
Platform.ANDROID,
|
|
VersionCode.create(999),
|
|
);
|
|
|
|
expect(found).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findAllByPlatform', () => {
|
|
it('should find all enabled versions by default', async () => {
|
|
const v1 = createTestVersion();
|
|
const v2 = AppVersion.create({
|
|
platform: Platform.ANDROID,
|
|
versionCode: VersionCode.create(200),
|
|
versionName: VersionName.create('2.0.0'),
|
|
buildNumber: BuildNumber.create('200'),
|
|
downloadUrl: DownloadUrl.create('https://example.com/app-v2.apk'),
|
|
fileSize: FileSize.create(20971520n),
|
|
fileSha256: FileSha256.create('0000000000000000000000000000000000000000000000000000000000000000'),
|
|
changelog: Changelog.create('Version 2.0.0'),
|
|
isForceUpdate: false,
|
|
createdBy: 'test-user',
|
|
});
|
|
v2.disable('test-user');
|
|
|
|
await repository.save(v1);
|
|
await repository.save(v2);
|
|
|
|
const versions = await repository.findAllByPlatform(Platform.ANDROID);
|
|
|
|
expect(versions).toHaveLength(1);
|
|
expect(versions[0].versionCode.value).toBe(100);
|
|
});
|
|
|
|
it('should find all versions including disabled when requested', async () => {
|
|
const v1 = createTestVersion();
|
|
const v2 = AppVersion.create({
|
|
platform: Platform.ANDROID,
|
|
versionCode: VersionCode.create(200),
|
|
versionName: VersionName.create('2.0.0'),
|
|
buildNumber: BuildNumber.create('200'),
|
|
downloadUrl: DownloadUrl.create('https://example.com/app-v2.apk'),
|
|
fileSize: FileSize.create(20971520n),
|
|
fileSha256: FileSha256.create('0000000000000000000000000000000000000000000000000000000000000000'),
|
|
changelog: Changelog.create('Version 2.0.0'),
|
|
isForceUpdate: false,
|
|
createdBy: 'test-user',
|
|
});
|
|
v2.disable('test-user');
|
|
|
|
await repository.save(v1);
|
|
await repository.save(v2);
|
|
|
|
const versions = await repository.findAllByPlatform(Platform.ANDROID, true);
|
|
|
|
expect(versions).toHaveLength(2);
|
|
});
|
|
});
|
|
|
|
describe('update', () => {
|
|
it('should update existing version', async () => {
|
|
const version = createTestVersion();
|
|
await repository.save(version);
|
|
|
|
version.setForceUpdate(true, 'test-user');
|
|
await repository.update(version.id, version);
|
|
|
|
const updated = await repository.findById(version.id);
|
|
|
|
expect(updated).not.toBeNull();
|
|
expect(updated!.isForceUpdate).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('toggleEnabled', () => {
|
|
it('should toggle enabled status', async () => {
|
|
const version = createTestVersion();
|
|
await repository.save(version);
|
|
|
|
await repository.toggleEnabled(version.id, false);
|
|
|
|
const disabled = await repository.findById(version.id);
|
|
expect(disabled!.isEnabled).toBe(false);
|
|
|
|
await repository.toggleEnabled(version.id, true);
|
|
|
|
const enabled = await repository.findById(version.id);
|
|
expect(enabled!.isEnabled).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('delete', () => {
|
|
it('should delete version', async () => {
|
|
const version = createTestVersion();
|
|
await repository.save(version);
|
|
|
|
await repository.delete(version.id);
|
|
|
|
const found = await repository.findById(version.id);
|
|
expect(found).toBeNull();
|
|
});
|
|
|
|
it('should not throw when deleting non-existent version', async () => {
|
|
await expect(repository.delete('non-existent-id')).resolves.not.toThrow();
|
|
});
|
|
});
|
|
});
|