import { describe, it, expect, beforeEach, vi } from 'vitest';
import { VergeApiClient } from '../../src/client/api';
import {
handleListBlogs,
handleGetBlog,
handleCreateBlog,
handleUpdateBlog,
handleDeleteBlog,
} from '../../src/tools/blogs';
describe('ブログ管理ツール', () => {
let apiClient: VergeApiClient;
beforeEach(() => {
apiClient = new VergeApiClient('https://api.example.com');
});
// ============================================================
// handleListBlogs
// ============================================================
describe('handleListBlogs', () => {
it('正常系: ブログ一覧を取得', async () => {
const mockBlogs = [
{
id: 1,
user_id: 1,
name: 'My Blog',
slug: 'my-blog',
description: 'Blog description',
created_at: '2024-01-01T00:00:00.000Z',
deployment_project_name: null,
deployment_url: null,
last_deployed_at: null,
deployment_in_progress: 0,
},
];
vi.spyOn(apiClient, 'listBlogs').mockResolvedValueOnce(mockBlogs);
const input = {};
const result = await handleListBlogs(input, apiClient);
expect(apiClient.listBlogs).toHaveBeenCalledOnce();
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(true);
expect(parsedContent.count).toBe(1);
expect(parsedContent.blogs).toHaveLength(1);
expect(parsedContent.blogs[0].id).toBe(1);
});
it('異常系: エラーハンドリング', async () => {
vi.spyOn(apiClient, 'listBlogs').mockRejectedValueOnce(new Error('Network error'));
const input = {};
const result = await handleListBlogs(input, apiClient);
expect(result.isError).toBe(true);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(false);
expect(parsedContent.error).toBe('Network error');
});
});
// ============================================================
// handleGetBlog
// ============================================================
describe('handleGetBlog', () => {
it('正常系: ブログ詳細を取得', async () => {
const mockBlog = {
id: 1,
user_id: 1,
name: 'My Blog',
slug: 'my-blog',
description: 'Blog description',
created_at: '2024-01-01T00:00:00.000Z',
deployment_project_name: null,
deployment_url: null,
last_deployed_at: null,
deployment_in_progress: 0,
};
vi.spyOn(apiClient, 'getBlog').mockResolvedValueOnce(mockBlog);
const input = { blog_id: 1 };
const result = await handleGetBlog(input, apiClient);
expect(apiClient.getBlog).toHaveBeenCalledWith(1);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(true);
expect(parsedContent.blog.id).toBe(1);
expect(parsedContent.blog.name).toBe('My Blog');
});
it('異常系: エラーハンドリング', async () => {
vi.spyOn(apiClient, 'getBlog').mockRejectedValueOnce(new Error('Blog not found'));
const input = { blog_id: 999 };
const result = await handleGetBlog(input, apiClient);
expect(result.isError).toBe(true);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(false);
expect(parsedContent.error).toBe('Blog not found');
});
});
// ============================================================
// handleCreateBlog
// ============================================================
describe('handleCreateBlog', () => {
it('正常系: ブログを作成', async () => {
const mockBlog = {
id: 2,
user_id: 1,
name: 'New Blog',
slug: 'new-blog',
description: 'New blog description',
created_at: '2024-01-02T00:00:00.000Z',
deployment_project_name: null,
deployment_url: null,
last_deployed_at: null,
deployment_in_progress: 0,
};
vi.spyOn(apiClient, 'createBlog').mockResolvedValueOnce(mockBlog);
const input = {
name: 'New Blog',
slug: 'new-blog',
description: 'New blog description',
};
const result = await handleCreateBlog(input, apiClient);
expect(apiClient.createBlog).toHaveBeenCalledWith({
name: 'New Blog',
slug: 'new-blog',
description: 'New blog description',
});
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(true);
expect(parsedContent.message).toBe('ブログを作成しました');
expect(parsedContent.blog.id).toBe(2);
});
it('異常系: エラーハンドリング', async () => {
vi.spyOn(apiClient, 'createBlog').mockRejectedValueOnce(new Error('Validation error'));
const input = {
name: 'New Blog',
slug: 'new-blog',
};
const result = await handleCreateBlog(input, apiClient);
expect(result.isError).toBe(true);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(false);
expect(parsedContent.error).toBe('Validation error');
});
});
// ============================================================
// handleUpdateBlog
// ============================================================
describe('handleUpdateBlog', () => {
it('正常系: ブログを更新', async () => {
const mockBlog = {
id: 1,
user_id: 1,
name: 'Updated Blog',
slug: 'updated-blog',
description: 'Updated description',
created_at: '2024-01-01T00:00:00.000Z',
deployment_project_name: null,
deployment_url: null,
last_deployed_at: null,
deployment_in_progress: 0,
};
vi.spyOn(apiClient, 'updateBlog').mockResolvedValueOnce(mockBlog);
const input = {
blog_id: 1,
name: 'Updated Blog',
description: 'Updated description',
};
const result = await handleUpdateBlog(input, apiClient);
expect(apiClient.updateBlog).toHaveBeenCalledWith(1, {
name: 'Updated Blog',
description: 'Updated description',
});
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(true);
expect(parsedContent.message).toBe('ブログを更新しました');
expect(parsedContent.blog.name).toBe('Updated Blog');
});
it('異常系: エラーハンドリング', async () => {
vi.spyOn(apiClient, 'updateBlog').mockRejectedValueOnce(new Error('Update failed'));
const input = {
blog_id: 1,
title: 'Updated Blog Title',
};
const result = await handleUpdateBlog(input, apiClient);
expect(result.isError).toBe(true);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(false);
expect(parsedContent.error).toBe('Update failed');
});
});
// ============================================================
// handleDeleteBlog
// ============================================================
describe('handleDeleteBlog', () => {
it('正常系: ブログを削除', async () => {
vi.spyOn(apiClient, 'deleteBlog').mockResolvedValueOnce(undefined);
const input = { blog_id: 1 };
const result = await handleDeleteBlog(input, apiClient);
expect(apiClient.deleteBlog).toHaveBeenCalledWith(1);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(true);
expect(parsedContent.message).toBe('ブログを削除しました');
expect(parsedContent.blog_id).toBe(1);
});
it('異常系: エラーハンドリング', async () => {
vi.spyOn(apiClient, 'deleteBlog').mockRejectedValueOnce(new Error('Delete failed'));
const input = { blog_id: 1 };
const result = await handleDeleteBlog(input, apiClient);
expect(result.isError).toBe(true);
const parsedContent = JSON.parse(result.content[0].text);
expect(parsedContent.success).toBe(false);
expect(parsedContent.error).toBe('Delete failed');
});
});
});