Files
teknav-bak/app/src/lib/content-api.test.js
T
arsam d6bee5dbca Import source: app/src/lib/content-api
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:24:38 +03:30

82 lines
2.9 KiB
JavaScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
vi.mock('./api.js', () => ({
api: {
get: vi.fn(),
post: vi.fn(),
},
ApiError: class extends Error {
constructor(s, b) { super(); this.status = s; this.body = b; }
},
}));
import { contentApi } from './content-api.js';
import { api } from './api.js';
describe('contentApi', () => {
beforeEach(() => {
vi.restoreAllMocks();
});
it('listArticles calls GET /api/articles', async () => {
api.get.mockResolvedValue({ items: [{ slug: 'test' }], total: 1 });
const res = await contentApi.listArticles({ limit: 10 });
expect(api.get).toHaveBeenCalledWith('/api/articles?limit=10');
expect(res.items).toEqual([{ slug: 'test' }]);
});
it('getArticle calls GET /api/articles/:slug', async () => {
api.get.mockResolvedValue({ article: { slug: 'test', title: 'Test' } });
const res = await contentApi.getArticle('test-unique-slug-1');
expect(api.get).toHaveBeenCalledWith('/api/articles/test-unique-slug-1');
expect(res.article.slug).toBe('test');
});
it('getArticle caches results', async () => {
api.get.mockClear();
api.get.mockResolvedValue({ article: { slug: 'cache-test-slug-999' } });
await contentApi.getArticle('cache-test-slug-999');
const callCount = api.get.mock.calls.length;
await contentApi.getArticle('cache-test-slug-999');
expect(api.get.mock.calls.length).toBe(callCount);
});
it('search calls GET /api/search with query', async () => {
api.get.mockResolvedValue({ items: [] });
await contentApi.search({ q: 'هوش مصنوعی' });
expect(api.get).toHaveBeenCalledWith('/api/search?q=%D9%87%D9%88%D8%B4+%D9%85%D8%B5%D9%86%D9%88%D8%B9%DB%8C');
});
it('listCategories calls GET /api/categories', async () => {
api.get.mockResolvedValue({ items: [{ slug: 'ai', name: 'هوش مصنوعی' }] });
const res = await contentApi.listCategories();
expect(res[0].slug).toBe('ai');
});
it('toggleReaction calls POST with article ID and type', async () => {
api.post.mockResolvedValue({ ok: true });
await contentApi.toggleReaction('art123', 'insightful');
expect(api.post).toHaveBeenCalledWith('/api/articles/art123/reactions', { type: 'insightful' });
});
it('subscribeNewsletter sends email and captcha data', async () => {
api.post.mockResolvedValue({ ok: true });
await contentApi.subscribeNewsletter('test@example.com', 'cap-id', 'ABC');
expect(api.post).toHaveBeenCalledWith('/api/newsletter', {
email: 'test@example.com',
captchaId: 'cap-id',
userSolution: 'ABC',
});
});
it('fallbackArticles returns array from TeknavData', () => {
const result = contentApi.fallbackArticles();
expect(Array.isArray(result)).toBe(true);
});
it('fallbackAuthors returns array from TeknavData', () => {
const result = contentApi.fallbackAuthors();
expect(Array.isArray(result)).toBe(true);
});
});