213 lines
6.2 KiB
TypeScript
213 lines
6.2 KiB
TypeScript
/**
|
|
* PartyShare Repository Integration Tests
|
|
*/
|
|
|
|
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { PartyShareRepositoryImpl } from '../../src/infrastructure/persistence/repositories/party-share.repository.impl';
|
|
import { PartyShareMapper } from '../../src/infrastructure/persistence/mappers/party-share.mapper';
|
|
import { PrismaService } from '../../src/infrastructure/persistence/prisma/prisma.service';
|
|
import { PartyShare } from '../../src/domain/entities/party-share.entity';
|
|
import {
|
|
ShareId,
|
|
PartyId,
|
|
SessionId,
|
|
Threshold,
|
|
ShareData,
|
|
PublicKey,
|
|
} from '../../src/domain/value-objects';
|
|
import { PartyShareType, PartyShareStatus } from '../../src/domain/enums';
|
|
|
|
describe('PartyShareRepository (Integration)', () => {
|
|
let repository: PartyShareRepositoryImpl;
|
|
let prismaService: any;
|
|
let mapper: PartyShareMapper;
|
|
|
|
const createMockShare = (): PartyShare => {
|
|
return PartyShare.create({
|
|
partyId: PartyId.create('user123-server'),
|
|
sessionId: SessionId.generate(),
|
|
shareType: PartyShareType.WALLET,
|
|
shareData: ShareData.create(
|
|
Buffer.from('encrypted-test-share-data'),
|
|
Buffer.from('123456789012'),
|
|
Buffer.from('1234567890123456'),
|
|
),
|
|
publicKey: PublicKey.fromHex('03' + '0'.repeat(64)),
|
|
threshold: Threshold.create(3, 2),
|
|
});
|
|
};
|
|
|
|
beforeEach(async () => {
|
|
prismaService = {
|
|
partyShare: {
|
|
findUnique: jest.fn(),
|
|
findFirst: jest.fn(),
|
|
findMany: jest.fn(),
|
|
create: jest.fn(),
|
|
update: jest.fn(),
|
|
delete: jest.fn(),
|
|
count: jest.fn(),
|
|
},
|
|
$transaction: jest.fn((fn: any) => fn(prismaService)),
|
|
};
|
|
|
|
mapper = new PartyShareMapper();
|
|
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
providers: [
|
|
PartyShareRepositoryImpl,
|
|
{ provide: PrismaService, useValue: prismaService },
|
|
PartyShareMapper,
|
|
],
|
|
}).compile();
|
|
|
|
repository = module.get<PartyShareRepositoryImpl>(PartyShareRepositoryImpl);
|
|
});
|
|
|
|
describe('save', () => {
|
|
it('should save a new share', async () => {
|
|
const share = createMockShare();
|
|
const persistenceData = mapper.toPersistence(share);
|
|
|
|
prismaService.partyShare.create.mockResolvedValue({
|
|
...persistenceData,
|
|
id: share.id.value,
|
|
});
|
|
|
|
await repository.save(share);
|
|
|
|
expect(prismaService.partyShare.create).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('update', () => {
|
|
it('should update an existing share', async () => {
|
|
const share = createMockShare();
|
|
const persistenceData = mapper.toPersistence(share);
|
|
|
|
prismaService.partyShare.update.mockResolvedValue({
|
|
...persistenceData,
|
|
id: share.id.value,
|
|
});
|
|
|
|
await repository.update(share);
|
|
|
|
expect(prismaService.partyShare.update).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('findById', () => {
|
|
it('should return share when found', async () => {
|
|
const share = createMockShare();
|
|
const persistenceData = mapper.toPersistence(share);
|
|
|
|
prismaService.partyShare.findUnique.mockResolvedValue({
|
|
...persistenceData,
|
|
id: share.id.value,
|
|
});
|
|
|
|
const result = await repository.findById(share.id);
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result).toBeInstanceOf(PartyShare);
|
|
});
|
|
|
|
it('should return null when not found', async () => {
|
|
prismaService.partyShare.findUnique.mockResolvedValue(null);
|
|
|
|
const result = await repository.findById(ShareId.generate());
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findByPartyId', () => {
|
|
it('should return all shares for party', async () => {
|
|
const share = createMockShare();
|
|
const persistenceData = mapper.toPersistence(share);
|
|
|
|
prismaService.partyShare.findMany.mockResolvedValue([
|
|
{ ...persistenceData, id: share.id.value },
|
|
]);
|
|
|
|
const result = await repository.findByPartyId(PartyId.create('user123-server'));
|
|
|
|
expect(result).toHaveLength(1);
|
|
result.forEach((s) => {
|
|
expect(s).toBeInstanceOf(PartyShare);
|
|
});
|
|
});
|
|
|
|
it('should return empty array when no shares', async () => {
|
|
prismaService.partyShare.findMany.mockResolvedValue([]);
|
|
|
|
const result = await repository.findByPartyId(PartyId.create('nonexistent-party'));
|
|
|
|
expect(result).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('findByPublicKey', () => {
|
|
it('should return share when found', async () => {
|
|
const share = createMockShare();
|
|
const persistenceData = mapper.toPersistence(share);
|
|
|
|
prismaService.partyShare.findFirst.mockResolvedValue({
|
|
...persistenceData,
|
|
id: share.id.value,
|
|
});
|
|
|
|
const result = await repository.findByPublicKey(
|
|
PublicKey.fromHex('03' + '0'.repeat(64)),
|
|
);
|
|
|
|
expect(result).toBeDefined();
|
|
expect(result).toBeInstanceOf(PartyShare);
|
|
});
|
|
|
|
it('should return null when not found', async () => {
|
|
prismaService.partyShare.findFirst.mockResolvedValue(null);
|
|
|
|
const result = await repository.findByPublicKey(
|
|
PublicKey.fromHex('03' + '1'.repeat(64)),
|
|
);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('findBySessionId', () => {
|
|
it('should return shares for session', async () => {
|
|
const share = createMockShare();
|
|
const persistenceData = mapper.toPersistence(share);
|
|
|
|
prismaService.partyShare.findMany.mockResolvedValue([
|
|
{ ...persistenceData, id: share.id.value },
|
|
]);
|
|
|
|
const result = await repository.findBySessionId(share.sessionId);
|
|
|
|
expect(result).toHaveLength(1);
|
|
});
|
|
});
|
|
|
|
describe('delete', () => {
|
|
it('should soft delete share by updating status to revoked', async () => {
|
|
const shareId = ShareId.generate();
|
|
|
|
prismaService.partyShare.update.mockResolvedValue({});
|
|
|
|
await repository.delete(shareId);
|
|
|
|
expect(prismaService.partyShare.update).toHaveBeenCalledWith({
|
|
where: { id: shareId.value },
|
|
data: {
|
|
status: PartyShareStatus.REVOKED,
|
|
updatedAt: expect.any(Date),
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
});
|