import { describe, it, expect } from 'vitest';
import { createTestHarness } from './utils/testHarness.js';
import { setupMockApi, MOCK_BLOG_ID } from './utils/mockApi.js';
/**
* エラーハンドリングの統合テスト
* 様々なエラーケースでMCPレスポンスが適切に処理されることを確認
*/
describe('エラーハンドリング統合テスト', () => {
setupMockApi();
describe('認証エラー', () => {
it('未認証状態で記事一覧を取得しようとするとエラーになる', async () => {
const harness = await createTestHarness();
try {
const result = await harness.client.callTool({
name: 'verge_list_articles',
arguments: {
blog_id: MOCK_BLOG_ID,
},
});
expect(result.isError).toBe(true);
const response = JSON.parse((result.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toContain('No authentication token');
} finally {
await harness.close();
}
});
it('未認証状態で記事を作成しようとするとエラーになる', async () => {
const harness = await createTestHarness();
try {
const result = await harness.client.callTool({
name: 'verge_create_article',
arguments: {
blog_id: MOCK_BLOG_ID,
title: 'テスト記事',
content: '本文',
slug: 'test',
},
});
expect(result.isError).toBe(true);
const response = JSON.parse((result.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toContain('No authentication token');
} finally {
await harness.close();
}
});
});
describe('リソース不在エラー', () => {
it('存在しない記事IDを指定すると404エラーになる', async () => {
const harness = await createTestHarness();
try {
// ログイン
await harness.client.callTool({
name: 'verge_login',
arguments: {
email: 'test@example.com',
password: 'password123',
},
});
// 存在しない記事IDを取得
const result = await harness.client.callTool({
name: 'verge_get_article',
arguments: {
article_id: 99999,
blog_id: MOCK_BLOG_ID,
},
});
expect(result.isError).toBe(true);
const response = JSON.parse((result.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toContain('Article not found');
} finally {
await harness.close();
}
});
it('存在しない記事IDを更新しようとすると404エラーになる', async () => {
const harness = await createTestHarness();
try {
// ログイン
await harness.client.callTool({
name: 'verge_login',
arguments: {
email: 'test@example.com',
password: 'password123',
},
});
// 存在しない記事IDを更新
const result = await harness.client.callTool({
name: 'verge_update_article',
arguments: {
article_id: 99999,
blog_id: MOCK_BLOG_ID,
title: '更新',
},
});
expect(result.isError).toBe(true);
const response = JSON.parse((result.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toContain('Article not found');
} finally {
await harness.close();
}
});
it('存在しない記事IDを削除しようとすると404エラーになる', async () => {
const harness = await createTestHarness();
try {
// ログイン
await harness.client.callTool({
name: 'verge_login',
arguments: {
email: 'test@example.com',
password: 'password123',
},
});
// 存在しない記事IDを削除
const result = await harness.client.callTool({
name: 'verge_delete_article',
arguments: {
article_id: 99999,
blog_id: MOCK_BLOG_ID,
},
});
expect(result.isError).toBe(true);
const response = JSON.parse((result.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toContain('Article not found');
} finally {
await harness.close();
}
});
});
describe('バリデーションエラー', () => {
it('必須フィールドが欠けている場合はバリデーションエラーになる', async () => {
const harness = await createTestHarness();
try {
// ログイン
await harness.client.callTool({
name: 'verge_login',
arguments: {
email: 'test@example.com',
password: 'password123',
},
});
// titleフィールドを省略して記事作成
const result = await harness.client.callTool({
name: 'verge_create_article',
arguments: {
blog_id: MOCK_BLOG_ID,
// title: 省略
content: '本文',
slug: 'test',
},
});
expect(result.isError).toBe(true);
const response = JSON.parse((result.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toBeTruthy();
} finally {
await harness.close();
}
});
});
describe('複数ツールのエラー連鎖', () => {
it('ログイン失敗後に記事操作を試みるとエラーになる', async () => {
const harness = await createTestHarness();
try {
// 誤った認証情報でログイン試行
const loginResult = await harness.client.callTool({
name: 'verge_login',
arguments: {
email: 'test@example.com',
password: 'wrong-password',
},
});
expect(loginResult.isError).toBe(true);
// ログイン失敗後に記事作成を試みる
const createResult = await harness.client.callTool({
name: 'verge_create_article',
arguments: {
blog_id: MOCK_BLOG_ID,
title: 'テスト記事',
content: '本文',
slug: 'test',
},
});
expect(createResult.isError).toBe(true);
const response = JSON.parse((createResult.content[0] as any).text);
expect(response.success).toBe(false);
expect(response.error).toContain('No authentication token');
} finally {
await harness.close();
}
});
it('記事削除後に同じ記事に対する操作がエラーになる', async () => {
const harness = await createTestHarness();
try {
// ログイン
await harness.client.callTool({
name: 'verge_login',
arguments: {
email: 'test@example.com',
password: 'password123',
},
});
// 記事作成
const createResult = await harness.client.callTool({
name: 'verge_create_article',
arguments: {
blog_id: MOCK_BLOG_ID,
title: 'テスト記事',
content: '本文',
slug: 'test',
},
});
const createResponse = JSON.parse((createResult.content[0] as any).text);
const articleId = createResponse.article.id;
// 記事削除
const deleteResult = await harness.client.callTool({
name: 'verge_delete_article',
arguments: {
article_id: articleId,
blog_id: MOCK_BLOG_ID,
},
});
expect(deleteResult.isError).toBeFalsy();
// 削除後に取得を試みる
const getResult = await harness.client.callTool({
name: 'verge_get_article',
arguments: {
article_id: articleId,
blog_id: MOCK_BLOG_ID,
},
});
expect(getResult.isError).toBe(true);
// 削除後に更新を試みる
const updateResult = await harness.client.callTool({
name: 'verge_update_article',
arguments: {
article_id: articleId,
blog_id: MOCK_BLOG_ID,
title: '更新',
},
});
expect(updateResult.isError).toBe(true);
// 削除後に再度削除を試みる
const deleteAgainResult = await harness.client.callTool({
name: 'verge_delete_article',
arguments: {
article_id: articleId,
blog_id: MOCK_BLOG_ID,
},
});
expect(deleteAgainResult.isError).toBe(true);
} finally {
await harness.close();
}
});
});
});