rwadurian/backend/services/backup-service/test/utils/mock-prisma.service.ts

186 lines
5.7 KiB
TypeScript

import { Injectable } from '@nestjs/common';
interface MockBackupShare {
shareId: bigint;
userId: bigint;
accountSequence: bigint;
publicKey: string;
partyIndex: number;
threshold: number;
totalParties: number;
encryptedShareData: string;
encryptionKeyId: string;
status: string;
accessCount: number;
lastAccessedAt: Date | null;
createdAt: Date;
updatedAt: Date;
revokedAt: Date | null;
}
interface MockShareAccessLog {
logId: bigint;
shareId: bigint;
userId: bigint;
action: string;
sourceService: string;
sourceIp: string;
success: boolean;
errorMessage: string | null;
createdAt: Date;
}
@Injectable()
export class MockPrismaService {
private backupShares: MockBackupShare[] = [];
private shareAccessLogs: MockShareAccessLog[] = [];
private shareIdCounter = 1n;
private logIdCounter = 1n;
backupShare = {
create: jest.fn().mockImplementation(({ data }) => {
const share: MockBackupShare = {
shareId: this.shareIdCounter++,
userId: data.userId,
accountSequence: data.accountSequence,
publicKey: data.publicKey,
partyIndex: data.partyIndex ?? 2,
threshold: data.threshold ?? 2,
totalParties: data.totalParties ?? 3,
encryptedShareData: data.encryptedShareData,
encryptionKeyId: data.encryptionKeyId,
status: data.status ?? 'ACTIVE',
accessCount: data.accessCount ?? 0,
lastAccessedAt: data.lastAccessedAt ?? null,
createdAt: new Date(),
updatedAt: new Date(),
revokedAt: data.revokedAt ?? null,
};
this.backupShares.push(share);
return Promise.resolve(share);
}),
update: jest.fn().mockImplementation(({ where, data }) => {
const index = this.backupShares.findIndex(s => s.shareId === where.shareId);
if (index === -1) return Promise.resolve(null);
this.backupShares[index] = {
...this.backupShares[index],
...data,
updatedAt: new Date(),
};
return Promise.resolve(this.backupShares[index]);
}),
findUnique: jest.fn().mockImplementation(({ where }) => {
let share: MockBackupShare | undefined;
if (where.shareId) {
share = this.backupShares.find(s => s.shareId === where.shareId);
} else if (where.userId) {
share = this.backupShares.find(s => s.userId === where.userId);
} else if (where.publicKey) {
share = this.backupShares.find(s => s.publicKey === where.publicKey);
} else if (where.accountSequence) {
share = this.backupShares.find(s => s.accountSequence === where.accountSequence);
}
return Promise.resolve(share ?? null);
}),
findFirst: jest.fn().mockImplementation(({ where }) => {
const share = this.backupShares.find(s =>
s.userId === where.userId && s.publicKey === where.publicKey
);
return Promise.resolve(share ?? null);
}),
delete: jest.fn().mockImplementation(({ where }) => {
const index = this.backupShares.findIndex(s => s.shareId === where.shareId);
if (index === -1) return Promise.resolve(null);
const deleted = this.backupShares.splice(index, 1)[0];
return Promise.resolve(deleted);
}),
deleteMany: jest.fn().mockImplementation(() => {
const count = this.backupShares.length;
this.backupShares = [];
return Promise.resolve({ count });
}),
};
shareAccessLog = {
create: jest.fn().mockImplementation(({ data }) => {
const log: MockShareAccessLog = {
logId: this.logIdCounter++,
shareId: data.shareId,
userId: data.userId,
action: data.action,
sourceService: data.sourceService,
sourceIp: data.sourceIp,
success: data.success ?? true,
errorMessage: data.errorMessage ?? null,
createdAt: new Date(),
};
this.shareAccessLogs.push(log);
return Promise.resolve(log);
}),
findMany: jest.fn().mockImplementation(({ where, orderBy, take }) => {
let logs = [...this.shareAccessLogs];
if (where?.shareId) {
logs = logs.filter(l => l.shareId === where.shareId);
}
if (where?.userId) {
logs = logs.filter(l => l.userId === where.userId);
}
if (orderBy?.createdAt === 'desc') {
logs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
}
if (take) {
logs = logs.slice(0, take);
}
return Promise.resolve(logs);
}),
count: jest.fn().mockImplementation(({ where }) => {
let logs = [...this.shareAccessLogs];
if (where?.userId) {
logs = logs.filter(l => l.userId === where.userId);
}
if (where?.action) {
logs = logs.filter(l => l.action === where.action);
}
if (where?.createdAt?.gte) {
logs = logs.filter(l => l.createdAt >= where.createdAt.gte);
}
return Promise.resolve(logs.length);
}),
deleteMany: jest.fn().mockImplementation(() => {
const count = this.shareAccessLogs.length;
this.shareAccessLogs = [];
return Promise.resolve({ count });
}),
};
$connect = jest.fn().mockResolvedValue(undefined);
$disconnect = jest.fn().mockResolvedValue(undefined);
$queryRaw = jest.fn().mockResolvedValue([{ '?column?': 1 }]);
// Helper methods for testing
reset(): void {
this.backupShares = [];
this.shareAccessLogs = [];
this.shareIdCounter = 1n;
this.logIdCounter = 1n;
jest.clearAllMocks();
}
getBackupShares(): MockBackupShare[] {
return [...this.backupShares];
}
getShareAccessLogs(): MockShareAccessLog[] {
return [...this.shareAccessLogs];
}
}