/**
* WordPress Posts Service Unit Tests
*/
import { PostsService } from '../../src/services/wordpress/posts-service.js';
import { WordPressConfig } from '../../src/types/wordpress.js';
describe('PostsService', () => {
let postsService: PostsService;
let mockAxios: any;
beforeEach(() => {
const config: WordPressConfig = {
baseUrl: 'https://test-site.com',
username: 'testuser',
applicationPassword: 'testpass'
};
// Mock axios instance
mockAxios = {
get: jest.fn(),
post: jest.fn(),
put: jest.fn(),
delete: jest.fn()
};
postsService = new PostsService(mockAxios);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('listPosts', () => {
it('should fetch posts with default parameters', async () => {
const mockResponse = {
data: [
{ id: 1, title: { rendered: 'Test Post 1' } },
{ id: 2, title: { rendered: 'Test Post 2' } }
]
};
mockAxios.get.mockResolvedValue(mockResponse);
const result = await postsService.listPosts({});
expect(mockAxios.get).toHaveBeenCalledWith('/wp-json/wp/v2/posts', {
params: {
per_page: 10,
status: 'publish'
}
});
expect(result).toEqual(mockResponse.data);
});
it('should fetch posts with custom parameters', async () => {
const mockResponse = {
data: [{ id: 1, title: { rendered: 'Search Result' } }]
};
mockAxios.get.mockResolvedValue(mockResponse);
const params = {
per_page: 5,
status: 'draft',
search: 'test',
author: 1
};
const result = await postsService.listPosts(params);
expect(mockAxios.get).toHaveBeenCalledWith('/wp-json/wp/v2/posts', {
params
});
expect(result).toEqual(mockResponse.data);
});
it('should handle API errors', async () => {
const mockError = new Error('API Error');
mockAxios.get.mockRejectedValue(mockError);
await expect(postsService.listPosts({})).rejects.toThrow('API Error');
});
});
describe('getPost', () => {
it('should fetch single post by ID', async () => {
const mockResponse = {
data: { id: 1, title: { rendered: 'Test Post' } }
};
mockAxios.get.mockResolvedValue(mockResponse);
const result = await postsService.getPost(1);
expect(mockAxios.get).toHaveBeenCalledWith('/wp-json/wp/v2/posts/1');
expect(result).toEqual(mockResponse.data);
});
it('should handle post not found', async () => {
const mockError = {
response: { status: 404, data: { message: 'Post not found' } }
};
mockAxios.get.mockRejectedValue(mockError);
await expect(postsService.getPost(999)).rejects.toEqual(mockError);
});
});
describe('createPost', () => {
it('should create new post', async () => {
const postData = {
title: 'New Post',
content: 'Post content',
status: 'publish'
};
const mockResponse = {
data: { id: 3, title: { rendered: 'New Post' } }
};
mockAxios.post.mockResolvedValue(mockResponse);
const result = await postsService.createPost(postData);
expect(mockAxios.post).toHaveBeenCalledWith('/wp-json/wp/v2/posts', postData);
expect(result).toEqual(mockResponse.data);
});
it('should validate required fields', async () => {
const invalidData = { status: 'publish' }; // Missing title
await expect(postsService.createPost(invalidData)).rejects.toThrow();
});
});
describe('updatePost', () => {
it('should update existing post', async () => {
const postId = 1;
const updateData = {
title: 'Updated Post',
content: 'Updated content'
};
const mockResponse = {
data: { id: 1, title: { rendered: 'Updated Post' } }
};
mockAxios.put.mockResolvedValue(mockResponse);
const result = await postsService.updatePost(postId, updateData);
expect(mockAxios.put).toHaveBeenCalledWith(`/wp-json/wp/v2/posts/${postId}`, updateData);
expect(result).toEqual(mockResponse.data);
});
});
describe('deletePost', () => {
it('should delete post', async () => {
const postId = 1;
const mockResponse = {
data: { deleted: true }
};
mockAxios.delete.mockResolvedValue(mockResponse);
const result = await postsService.deletePost(postId, false);
expect(mockAxios.delete).toHaveBeenCalledWith(`/wp-json/wp/v2/posts/${postId}`, {
params: { force: false }
});
expect(result).toEqual(mockResponse.data);
});
it('should force delete post', async () => {
const postId = 1;
const mockResponse = {
data: { deleted: true }
};
mockAxios.delete.mockResolvedValue(mockResponse);
const result = await postsService.deletePost(postId, true);
expect(mockAxios.delete).toHaveBeenCalledWith(`/wp-json/wp/v2/posts/${postId}`, {
params: { force: true }
});
expect(result).toEqual(mockResponse.data);
});
});
describe('searchPosts', () => {
it('should search posts by term', async () => {
const searchTerm = 'test';
const mockResponse = {
data: [
{ id: 1, title: { rendered: 'Test Post 1' } },
{ id: 2, title: { rendered: 'Test Post 2' } }
]
};
mockAxios.get.mockResolvedValue(mockResponse);
const result = await postsService.searchPosts(searchTerm);
expect(mockAxios.get).toHaveBeenCalledWith('/wp-json/wp/v2/posts', {
params: { search: searchTerm, per_page: 10 }
});
expect(result).toEqual(mockResponse.data);
});
});
});