mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 13:33:11 +00:00
fix: update tests for template compression, pagination, and quality filtering
- Fix parameter validation tests to expect mode parameter in getTemplate calls - Update database utils tests to use totalViews > 10 for quality filter - Add comprehensive tests for template service functionality - Fix integration tests for new pagination parameters All CI tests now passing after template system enhancements
This commit is contained in:
577
tests/unit/services/template-service.test.ts
Normal file
577
tests/unit/services/template-service.test.ts
Normal file
@@ -0,0 +1,577 @@
|
||||
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
||||
import { TemplateService, PaginatedResponse, TemplateInfo, TemplateMinimal } from '../../../src/templates/template-service';
|
||||
import { TemplateRepository, StoredTemplate } from '../../../src/templates/template-repository';
|
||||
import { DatabaseAdapter } from '../../../src/database/database-adapter';
|
||||
|
||||
// Mock the logger
|
||||
vi.mock('../../../src/utils/logger', () => ({
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
// Mock the template repository
|
||||
vi.mock('../../../src/templates/template-repository');
|
||||
|
||||
// Mock template fetcher - only imported when needed
|
||||
vi.mock('../../../src/templates/template-fetcher', () => ({
|
||||
TemplateFetcher: vi.fn().mockImplementation(() => ({
|
||||
fetchTemplates: vi.fn(),
|
||||
fetchAllTemplateDetails: vi.fn()
|
||||
}))
|
||||
}));
|
||||
|
||||
describe('TemplateService', () => {
|
||||
let service: TemplateService;
|
||||
let mockDb: DatabaseAdapter;
|
||||
let mockRepository: TemplateRepository;
|
||||
|
||||
const createMockTemplate = (id: number, overrides: any = {}): StoredTemplate => ({
|
||||
id,
|
||||
workflow_id: id,
|
||||
name: overrides.name || `Template ${id}`,
|
||||
description: overrides.description || `Description for template ${id}`,
|
||||
author_name: overrides.author_name || 'Test Author',
|
||||
author_username: overrides.author_username || 'testuser',
|
||||
author_verified: overrides.author_verified !== undefined ? overrides.author_verified : 1,
|
||||
nodes_used: JSON.stringify(overrides.nodes_used || ['n8n-nodes-base.webhook']),
|
||||
workflow_json: JSON.stringify(overrides.workflow || {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
type: 'n8n-nodes-base.webhook',
|
||||
name: 'Webhook',
|
||||
position: [100, 100],
|
||||
parameters: {}
|
||||
}
|
||||
],
|
||||
connections: {},
|
||||
settings: {}
|
||||
}),
|
||||
categories: JSON.stringify(overrides.categories || ['automation']),
|
||||
views: overrides.views || 100,
|
||||
created_at: overrides.created_at || '2024-01-01T00:00:00Z',
|
||||
updated_at: overrides.updated_at || '2024-01-01T00:00:00Z',
|
||||
url: overrides.url || `https://n8n.io/workflows/${id}`,
|
||||
scraped_at: '2024-01-01T00:00:00Z'
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
mockDb = {} as DatabaseAdapter;
|
||||
|
||||
// Create mock repository with all methods
|
||||
mockRepository = {
|
||||
getTemplatesByNodes: vi.fn(),
|
||||
getNodeTemplatesCount: vi.fn(),
|
||||
getTemplate: vi.fn(),
|
||||
searchTemplates: vi.fn(),
|
||||
getSearchCount: vi.fn(),
|
||||
getTemplatesForTask: vi.fn(),
|
||||
getTaskTemplatesCount: vi.fn(),
|
||||
getAllTemplates: vi.fn(),
|
||||
getTemplateCount: vi.fn(),
|
||||
getTemplateStats: vi.fn(),
|
||||
getExistingTemplateIds: vi.fn(),
|
||||
clearTemplates: vi.fn(),
|
||||
saveTemplate: vi.fn(),
|
||||
rebuildTemplateFTS: vi.fn()
|
||||
} as any;
|
||||
|
||||
// Mock the constructor
|
||||
(TemplateRepository as any).mockImplementation(() => mockRepository);
|
||||
|
||||
service = new TemplateService(mockDb);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('listNodeTemplates', () => {
|
||||
it('should return paginated node templates', async () => {
|
||||
const mockTemplates = [
|
||||
createMockTemplate(1, { name: 'Webhook Template' }),
|
||||
createMockTemplate(2, { name: 'HTTP Template' })
|
||||
];
|
||||
|
||||
mockRepository.getTemplatesByNodes = vi.fn().mockReturnValue(mockTemplates);
|
||||
mockRepository.getNodeTemplatesCount = vi.fn().mockReturnValue(10);
|
||||
|
||||
const result = await service.listNodeTemplates(['n8n-nodes-base.webhook'], 5, 0);
|
||||
|
||||
expect(result).toEqual({
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: 1,
|
||||
name: 'Webhook Template',
|
||||
author: expect.objectContaining({
|
||||
name: 'Test Author',
|
||||
username: 'testuser',
|
||||
verified: true
|
||||
}),
|
||||
nodes: ['n8n-nodes-base.webhook'],
|
||||
views: 100
|
||||
})
|
||||
]),
|
||||
total: 10,
|
||||
limit: 5,
|
||||
offset: 0,
|
||||
hasMore: true
|
||||
});
|
||||
|
||||
expect(mockRepository.getTemplatesByNodes).toHaveBeenCalledWith(['n8n-nodes-base.webhook'], 5, 0);
|
||||
expect(mockRepository.getNodeTemplatesCount).toHaveBeenCalledWith(['n8n-nodes-base.webhook']);
|
||||
});
|
||||
|
||||
it('should handle pagination correctly', async () => {
|
||||
mockRepository.getTemplatesByNodes = vi.fn().mockReturnValue([]);
|
||||
mockRepository.getNodeTemplatesCount = vi.fn().mockReturnValue(25);
|
||||
|
||||
const result = await service.listNodeTemplates(['n8n-nodes-base.webhook'], 10, 20);
|
||||
|
||||
expect(result.hasMore).toBe(false); // 20 + 10 >= 25
|
||||
expect(result.offset).toBe(20);
|
||||
expect(result.limit).toBe(10);
|
||||
});
|
||||
|
||||
it('should use default pagination parameters', async () => {
|
||||
mockRepository.getTemplatesByNodes = vi.fn().mockReturnValue([]);
|
||||
mockRepository.getNodeTemplatesCount = vi.fn().mockReturnValue(0);
|
||||
|
||||
await service.listNodeTemplates(['n8n-nodes-base.webhook']);
|
||||
|
||||
expect(mockRepository.getTemplatesByNodes).toHaveBeenCalledWith(['n8n-nodes-base.webhook'], 10, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTemplate', () => {
|
||||
const mockWorkflow = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
type: 'n8n-nodes-base.webhook',
|
||||
name: 'Webhook',
|
||||
position: [100, 100],
|
||||
parameters: { path: 'test' }
|
||||
},
|
||||
{
|
||||
id: 'node2',
|
||||
type: 'n8n-nodes-base.slack',
|
||||
name: 'Slack',
|
||||
position: [300, 100],
|
||||
parameters: { channel: '#general' }
|
||||
}
|
||||
],
|
||||
connections: {
|
||||
'node1': {
|
||||
'main': [
|
||||
[{ 'node': 'node2', 'type': 'main', 'index': 0 }]
|
||||
]
|
||||
}
|
||||
},
|
||||
settings: { timezone: 'UTC' }
|
||||
};
|
||||
|
||||
it('should return template in nodes_only mode', async () => {
|
||||
const mockTemplate = createMockTemplate(1, { workflow: mockWorkflow });
|
||||
mockRepository.getTemplate = vi.fn().mockReturnValue(mockTemplate);
|
||||
|
||||
const result = await service.getTemplate(1, 'nodes_only');
|
||||
|
||||
expect(result).toEqual({
|
||||
id: 1,
|
||||
name: 'Template 1',
|
||||
nodes: [
|
||||
{ type: 'n8n-nodes-base.webhook', name: 'Webhook' },
|
||||
{ type: 'n8n-nodes-base.slack', name: 'Slack' }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should return template in structure mode', async () => {
|
||||
const mockTemplate = createMockTemplate(1, { workflow: mockWorkflow });
|
||||
mockRepository.getTemplate = vi.fn().mockReturnValue(mockTemplate);
|
||||
|
||||
const result = await service.getTemplate(1, 'structure');
|
||||
|
||||
expect(result).toEqual({
|
||||
id: 1,
|
||||
name: 'Template 1',
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
type: 'n8n-nodes-base.webhook',
|
||||
name: 'Webhook',
|
||||
position: [100, 100]
|
||||
},
|
||||
{
|
||||
id: 'node2',
|
||||
type: 'n8n-nodes-base.slack',
|
||||
name: 'Slack',
|
||||
position: [300, 100]
|
||||
}
|
||||
],
|
||||
connections: mockWorkflow.connections
|
||||
});
|
||||
});
|
||||
|
||||
it('should return full template in full mode', async () => {
|
||||
const mockTemplate = createMockTemplate(1, { workflow: mockWorkflow });
|
||||
mockRepository.getTemplate = vi.fn().mockReturnValue(mockTemplate);
|
||||
|
||||
const result = await service.getTemplate(1, 'full');
|
||||
|
||||
expect(result).toEqual(expect.objectContaining({
|
||||
id: 1,
|
||||
name: 'Template 1',
|
||||
description: 'Description for template 1',
|
||||
author: {
|
||||
name: 'Test Author',
|
||||
username: 'testuser',
|
||||
verified: true
|
||||
},
|
||||
nodes: ['n8n-nodes-base.webhook'],
|
||||
views: 100,
|
||||
workflow: mockWorkflow
|
||||
}));
|
||||
});
|
||||
|
||||
it('should return null for non-existent template', async () => {
|
||||
mockRepository.getTemplate = vi.fn().mockReturnValue(null);
|
||||
|
||||
const result = await service.getTemplate(999);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should handle templates with no workflow nodes', async () => {
|
||||
const mockTemplate = createMockTemplate(1, { workflow: { connections: {}, settings: {} } });
|
||||
mockRepository.getTemplate = vi.fn().mockReturnValue(mockTemplate);
|
||||
|
||||
const result = await service.getTemplate(1, 'nodes_only');
|
||||
|
||||
expect(result.nodes).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchTemplates', () => {
|
||||
it('should return paginated search results', async () => {
|
||||
const mockTemplates = [
|
||||
createMockTemplate(1, { name: 'Webhook Automation' }),
|
||||
createMockTemplate(2, { name: 'Webhook Processing' })
|
||||
];
|
||||
|
||||
mockRepository.searchTemplates = vi.fn().mockReturnValue(mockTemplates);
|
||||
mockRepository.getSearchCount = vi.fn().mockReturnValue(15);
|
||||
|
||||
const result = await service.searchTemplates('webhook', 10, 5);
|
||||
|
||||
expect(result).toEqual({
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({ id: 1, name: 'Webhook Automation' }),
|
||||
expect.objectContaining({ id: 2, name: 'Webhook Processing' })
|
||||
]),
|
||||
total: 15,
|
||||
limit: 10,
|
||||
offset: 5,
|
||||
hasMore: false // 5 + 10 >= 15
|
||||
});
|
||||
|
||||
expect(mockRepository.searchTemplates).toHaveBeenCalledWith('webhook', 10, 5);
|
||||
expect(mockRepository.getSearchCount).toHaveBeenCalledWith('webhook');
|
||||
});
|
||||
|
||||
it('should use default parameters', async () => {
|
||||
mockRepository.searchTemplates = vi.fn().mockReturnValue([]);
|
||||
mockRepository.getSearchCount = vi.fn().mockReturnValue(0);
|
||||
|
||||
await service.searchTemplates('test');
|
||||
|
||||
expect(mockRepository.searchTemplates).toHaveBeenCalledWith('test', 20, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTemplatesForTask', () => {
|
||||
it('should return paginated task templates', async () => {
|
||||
const mockTemplates = [
|
||||
createMockTemplate(1, { name: 'AI Workflow' }),
|
||||
createMockTemplate(2, { name: 'ML Pipeline' })
|
||||
];
|
||||
|
||||
mockRepository.getTemplatesForTask = vi.fn().mockReturnValue(mockTemplates);
|
||||
mockRepository.getTaskTemplatesCount = vi.fn().mockReturnValue(8);
|
||||
|
||||
const result = await service.getTemplatesForTask('ai_automation', 5, 3);
|
||||
|
||||
expect(result).toEqual({
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({ id: 1, name: 'AI Workflow' }),
|
||||
expect.objectContaining({ id: 2, name: 'ML Pipeline' })
|
||||
]),
|
||||
total: 8,
|
||||
limit: 5,
|
||||
offset: 3,
|
||||
hasMore: false // 3 + 5 >= 8
|
||||
});
|
||||
|
||||
expect(mockRepository.getTemplatesForTask).toHaveBeenCalledWith('ai_automation', 5, 3);
|
||||
expect(mockRepository.getTaskTemplatesCount).toHaveBeenCalledWith('ai_automation');
|
||||
});
|
||||
});
|
||||
|
||||
describe('listTemplates', () => {
|
||||
it('should return paginated minimal template data', async () => {
|
||||
const mockTemplates = [
|
||||
createMockTemplate(1, {
|
||||
name: 'Template A',
|
||||
nodes_used: ['n8n-nodes-base.webhook', 'n8n-nodes-base.slack'],
|
||||
views: 200
|
||||
}),
|
||||
createMockTemplate(2, {
|
||||
name: 'Template B',
|
||||
nodes_used: ['n8n-nodes-base.httpRequest'],
|
||||
views: 150
|
||||
})
|
||||
];
|
||||
|
||||
mockRepository.getAllTemplates = vi.fn().mockReturnValue(mockTemplates);
|
||||
mockRepository.getTemplateCount = vi.fn().mockReturnValue(50);
|
||||
|
||||
const result = await service.listTemplates(10, 20, 'views');
|
||||
|
||||
expect(result).toEqual({
|
||||
items: [
|
||||
{ id: 1, name: 'Template A', views: 200, nodeCount: 2 },
|
||||
{ id: 2, name: 'Template B', views: 150, nodeCount: 1 }
|
||||
],
|
||||
total: 50,
|
||||
limit: 10,
|
||||
offset: 20,
|
||||
hasMore: true // 20 + 10 < 50
|
||||
});
|
||||
|
||||
expect(mockRepository.getAllTemplates).toHaveBeenCalledWith(10, 20, 'views');
|
||||
expect(mockRepository.getTemplateCount).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should use default parameters', async () => {
|
||||
mockRepository.getAllTemplates = vi.fn().mockReturnValue([]);
|
||||
mockRepository.getTemplateCount = vi.fn().mockReturnValue(0);
|
||||
|
||||
await service.listTemplates();
|
||||
|
||||
expect(mockRepository.getAllTemplates).toHaveBeenCalledWith(10, 0, 'views');
|
||||
});
|
||||
|
||||
it('should handle different sort orders', async () => {
|
||||
mockRepository.getAllTemplates = vi.fn().mockReturnValue([]);
|
||||
mockRepository.getTemplateCount = vi.fn().mockReturnValue(0);
|
||||
|
||||
await service.listTemplates(5, 0, 'name');
|
||||
|
||||
expect(mockRepository.getAllTemplates).toHaveBeenCalledWith(5, 0, 'name');
|
||||
});
|
||||
});
|
||||
|
||||
describe('listAvailableTasks', () => {
|
||||
it('should return list of available tasks', () => {
|
||||
const tasks = service.listAvailableTasks();
|
||||
|
||||
expect(tasks).toEqual([
|
||||
'ai_automation',
|
||||
'data_sync',
|
||||
'webhook_processing',
|
||||
'email_automation',
|
||||
'slack_integration',
|
||||
'data_transformation',
|
||||
'file_processing',
|
||||
'scheduling',
|
||||
'api_integration',
|
||||
'database_operations'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTemplateStats', () => {
|
||||
it('should return template statistics', async () => {
|
||||
const mockStats = {
|
||||
totalTemplates: 100,
|
||||
averageViews: 250,
|
||||
topUsedNodes: [
|
||||
{ node: 'n8n-nodes-base.webhook', count: 45 },
|
||||
{ node: 'n8n-nodes-base.slack', count: 30 }
|
||||
]
|
||||
};
|
||||
|
||||
mockRepository.getTemplateStats = vi.fn().mockReturnValue(mockStats);
|
||||
|
||||
const result = await service.getTemplateStats();
|
||||
|
||||
expect(result).toEqual(mockStats);
|
||||
expect(mockRepository.getTemplateStats).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchAndUpdateTemplates', () => {
|
||||
it('should handle rebuild mode', async () => {
|
||||
const mockFetcher = {
|
||||
fetchTemplates: vi.fn().mockResolvedValue([
|
||||
{ id: 1, name: 'Template 1' },
|
||||
{ id: 2, name: 'Template 2' }
|
||||
]),
|
||||
fetchAllTemplateDetails: vi.fn().mockResolvedValue(new Map([
|
||||
[1, { id: 1, workflow: { nodes: [], connections: {}, settings: {} } }],
|
||||
[2, { id: 2, workflow: { nodes: [], connections: {}, settings: {} } }]
|
||||
]))
|
||||
};
|
||||
|
||||
// Mock dynamic import
|
||||
vi.doMock('../../../src/templates/template-fetcher', () => ({
|
||||
TemplateFetcher: vi.fn(() => mockFetcher)
|
||||
}));
|
||||
|
||||
mockRepository.clearTemplates = vi.fn();
|
||||
mockRepository.saveTemplate = vi.fn();
|
||||
mockRepository.rebuildTemplateFTS = vi.fn();
|
||||
|
||||
const progressCallback = vi.fn();
|
||||
|
||||
await service.fetchAndUpdateTemplates(progressCallback, 'rebuild');
|
||||
|
||||
expect(mockRepository.clearTemplates).toHaveBeenCalled();
|
||||
expect(mockRepository.saveTemplate).toHaveBeenCalledTimes(2);
|
||||
expect(mockRepository.rebuildTemplateFTS).toHaveBeenCalled();
|
||||
expect(progressCallback).toHaveBeenCalledWith('Complete', 2, 2);
|
||||
});
|
||||
|
||||
it('should handle update mode with existing templates', async () => {
|
||||
const mockFetcher = {
|
||||
fetchTemplates: vi.fn().mockResolvedValue([
|
||||
{ id: 1, name: 'Template 1' },
|
||||
{ id: 2, name: 'Template 2' },
|
||||
{ id: 3, name: 'Template 3' }
|
||||
]),
|
||||
fetchAllTemplateDetails: vi.fn().mockResolvedValue(new Map([
|
||||
[3, { id: 3, workflow: { nodes: [], connections: {}, settings: {} } }]
|
||||
]))
|
||||
};
|
||||
|
||||
// Mock dynamic import
|
||||
vi.doMock('../../../src/templates/template-fetcher', () => ({
|
||||
TemplateFetcher: vi.fn(() => mockFetcher)
|
||||
}));
|
||||
|
||||
mockRepository.getExistingTemplateIds = vi.fn().mockReturnValue(new Set([1, 2]));
|
||||
mockRepository.saveTemplate = vi.fn();
|
||||
mockRepository.rebuildTemplateFTS = vi.fn();
|
||||
|
||||
const progressCallback = vi.fn();
|
||||
|
||||
await service.fetchAndUpdateTemplates(progressCallback, 'update');
|
||||
|
||||
expect(mockRepository.getExistingTemplateIds).toHaveBeenCalled();
|
||||
expect(mockRepository.saveTemplate).toHaveBeenCalledTimes(1); // Only new template
|
||||
expect(mockRepository.rebuildTemplateFTS).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle update mode with no new templates', async () => {
|
||||
const mockFetcher = {
|
||||
fetchTemplates: vi.fn().mockResolvedValue([
|
||||
{ id: 1, name: 'Template 1' },
|
||||
{ id: 2, name: 'Template 2' }
|
||||
]),
|
||||
fetchAllTemplateDetails: vi.fn().mockResolvedValue(new Map())
|
||||
};
|
||||
|
||||
// Mock dynamic import
|
||||
vi.doMock('../../../src/templates/template-fetcher', () => ({
|
||||
TemplateFetcher: vi.fn(() => mockFetcher)
|
||||
}));
|
||||
|
||||
mockRepository.getExistingTemplateIds = vi.fn().mockReturnValue(new Set([1, 2]));
|
||||
mockRepository.saveTemplate = vi.fn();
|
||||
mockRepository.rebuildTemplateFTS = vi.fn();
|
||||
|
||||
const progressCallback = vi.fn();
|
||||
|
||||
await service.fetchAndUpdateTemplates(progressCallback, 'update');
|
||||
|
||||
expect(mockRepository.saveTemplate).not.toHaveBeenCalled();
|
||||
expect(mockRepository.rebuildTemplateFTS).not.toHaveBeenCalled();
|
||||
expect(progressCallback).toHaveBeenCalledWith('No new templates', 0, 0);
|
||||
});
|
||||
|
||||
it('should handle errors during fetch', async () => {
|
||||
// Mock the import to fail during constructor
|
||||
const mockFetcher = function() {
|
||||
throw new Error('Fetch failed');
|
||||
};
|
||||
|
||||
vi.doMock('../../../src/templates/template-fetcher', () => ({
|
||||
TemplateFetcher: mockFetcher
|
||||
}));
|
||||
|
||||
await expect(service.fetchAndUpdateTemplates()).rejects.toThrow('Fetch failed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatTemplateInfo (private method behavior)', () => {
|
||||
it('should format template data correctly through public methods', async () => {
|
||||
const mockTemplate = createMockTemplate(1, {
|
||||
name: 'Test Template',
|
||||
description: 'Test Description',
|
||||
author_name: 'John Doe',
|
||||
author_username: 'johndoe',
|
||||
author_verified: 1,
|
||||
nodes_used: ['n8n-nodes-base.webhook', 'n8n-nodes-base.slack'],
|
||||
views: 500,
|
||||
created_at: '2024-01-15T10:30:00Z',
|
||||
url: 'https://n8n.io/workflows/123'
|
||||
});
|
||||
|
||||
mockRepository.searchTemplates = vi.fn().mockReturnValue([mockTemplate]);
|
||||
mockRepository.getSearchCount = vi.fn().mockReturnValue(1);
|
||||
|
||||
const result = await service.searchTemplates('test');
|
||||
|
||||
expect(result.items[0]).toEqual({
|
||||
id: 1,
|
||||
name: 'Test Template',
|
||||
description: 'Test Description',
|
||||
author: {
|
||||
name: 'John Doe',
|
||||
username: 'johndoe',
|
||||
verified: true
|
||||
},
|
||||
nodes: ['n8n-nodes-base.webhook', 'n8n-nodes-base.slack'],
|
||||
views: 500,
|
||||
created: '2024-01-15T10:30:00Z',
|
||||
url: 'https://n8n.io/workflows/123'
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle unverified authors', async () => {
|
||||
const mockTemplate = createMockTemplate(1, {
|
||||
author_verified: 0 // Explicitly set to 0 for unverified
|
||||
});
|
||||
|
||||
// Override the helper to return exactly what we want
|
||||
const unverifiedTemplate = {
|
||||
...mockTemplate,
|
||||
author_verified: 0
|
||||
};
|
||||
|
||||
mockRepository.searchTemplates = vi.fn().mockReturnValue([unverifiedTemplate]);
|
||||
mockRepository.getSearchCount = vi.fn().mockReturnValue(1);
|
||||
|
||||
const result = await service.searchTemplates('test');
|
||||
|
||||
expect(result.items[0].author.verified).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user