186 lines
5.7 KiB
TypeScript
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];
|
|
}
|
|
}
|