afff6fdbdf
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
122 lines
4.1 KiB
TypeScript
122 lines
4.1 KiB
TypeScript
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { AccountsService } from './accounts.service';
|
|
import { PrismaService } from '../../prisma/prisma.service';
|
|
import * as QRCode from 'qrcode';
|
|
|
|
jest.mock('qrcode', () => ({
|
|
toDataURL: jest.fn().mockResolvedValue('data:image/png;base64,fakedata'),
|
|
}));
|
|
|
|
const mockAccounts = [
|
|
{ id: 'acc_1', platform: 'whatsapp', jid: '111@s.whatsapp.net', displayName: 'Test Account', status: 'ACTIVE' },
|
|
];
|
|
|
|
const mockCreatedAccount = {
|
|
id: 'acc_new',
|
|
platform: 'whatsapp',
|
|
jid: 'pending_uuid@placeholder',
|
|
displayName: 'My Number',
|
|
status: 'ACTIVE',
|
|
};
|
|
|
|
const mockPrisma = {
|
|
account: {
|
|
findMany: jest.fn().mockResolvedValue(mockAccounts),
|
|
findUnique: jest.fn(),
|
|
create: jest.fn().mockResolvedValue(mockCreatedAccount),
|
|
},
|
|
};
|
|
|
|
const mockConfig = {
|
|
get: jest.fn().mockImplementation((key: string, def: string) =>
|
|
key === 'WHATSAPP_SESSION_PATH' ? './sessions' : def,
|
|
),
|
|
};
|
|
|
|
describe('AccountsService', () => {
|
|
let service: AccountsService;
|
|
|
|
beforeEach(async () => {
|
|
jest.clearAllMocks();
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
providers: [
|
|
AccountsService,
|
|
{ provide: PrismaService, useValue: mockPrisma },
|
|
{ provide: ConfigService, useValue: mockConfig },
|
|
],
|
|
}).compile();
|
|
service = module.get<AccountsService>(AccountsService);
|
|
});
|
|
|
|
describe('list()', () => {
|
|
it('returns accounts from Prisma without qrCode field', async () => {
|
|
const result = await service.list();
|
|
expect(result).toEqual(mockAccounts);
|
|
expect(mockPrisma.account.findMany).toHaveBeenCalledWith(
|
|
expect.objectContaining({ select: expect.not.objectContaining({ qrCode: true }) }),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('getQr()', () => {
|
|
it('returns null qrDataUrl when account has no qrCode', async () => {
|
|
mockPrisma.account.findUnique.mockResolvedValue({ status: 'ACTIVE', qrCode: null });
|
|
const result = await service.getQr('acc_1');
|
|
expect(result).toEqual({ status: 'ACTIVE', qrDataUrl: null });
|
|
expect(QRCode.toDataURL).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('converts qrCode string to data URL when qrCode is present', async () => {
|
|
mockPrisma.account.findUnique.mockResolvedValue({ status: 'DISCONNECTED', qrCode: 'raw-qr-string' });
|
|
const result = await service.getQr('acc_1');
|
|
expect(QRCode.toDataURL).toHaveBeenCalledWith('raw-qr-string');
|
|
expect(result).toEqual({ status: 'DISCONNECTED', qrDataUrl: 'data:image/png;base64,fakedata' });
|
|
});
|
|
|
|
it('returns not_found status when account does not exist', async () => {
|
|
mockPrisma.account.findUnique.mockResolvedValue(null);
|
|
const result = await service.getQr('nonexistent');
|
|
expect(result).toEqual({ status: 'not_found', qrDataUrl: null });
|
|
});
|
|
});
|
|
|
|
describe('create()', () => {
|
|
it('creates account with platform whatsapp and status ACTIVE', async () => {
|
|
await service.create('My Number');
|
|
expect(mockPrisma.account.create).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
data: expect.objectContaining({
|
|
platform: 'whatsapp',
|
|
status: 'ACTIVE',
|
|
displayName: 'My Number',
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('generates a unique sessionPath under WHATSAPP_SESSION_PATH', async () => {
|
|
await service.create();
|
|
const call = mockPrisma.account.create.mock.calls[0][0];
|
|
expect(call.data.sessionPath).toMatch(/^\.\/sessions\/.+/);
|
|
});
|
|
|
|
it('generates a placeholder jid prefixed with pending_', async () => {
|
|
await service.create();
|
|
const call = mockPrisma.account.create.mock.calls[0][0];
|
|
expect(call.data.jid).toMatch(/^pending_/);
|
|
});
|
|
|
|
it('sets displayName to null when not provided', async () => {
|
|
await service.create();
|
|
const call = mockPrisma.account.create.mock.calls[0][0];
|
|
expect(call.data.displayName).toBeNull();
|
|
});
|
|
|
|
it('returns the created account summary', async () => {
|
|
const result = await service.create('My Number');
|
|
expect(result).toEqual(mockCreatedAccount);
|
|
});
|
|
});
|
|
});
|