このコミットが含まれているのは:
@@ -1,9 +1,11 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { apiPost } from '@/lib/api'
|
||||
import { apiGet, apiPost } from '@/lib/api'
|
||||
import {
|
||||
buildGekanatorQuestions,
|
||||
expectedAnswerForQuestion,
|
||||
fetchGekanatorPosts,
|
||||
fetchGekanatorQuestions,
|
||||
learnedSemanticSideForPost,
|
||||
questionIdForCondition,
|
||||
restoreGekanatorQuestion,
|
||||
@@ -24,6 +26,7 @@ vi.mock('@/lib/api', () => ({
|
||||
}))
|
||||
|
||||
const mockedApiPost = vi.mocked(apiPost)
|
||||
const mockedApiGet = vi.mocked(apiGet)
|
||||
|
||||
const post = (overrides: Partial<Post> = {}): Post => ({
|
||||
id: 1,
|
||||
@@ -43,6 +46,24 @@ const post = (overrides: Partial<Post> = {}): Post => ({
|
||||
...overrides,
|
||||
})
|
||||
|
||||
describe('Gekanator API functions', () => {
|
||||
it('returns posts from the Gekanator posts endpoint', async () => {
|
||||
const posts = [post()]
|
||||
mockedApiGet.mockResolvedValueOnce({ posts })
|
||||
|
||||
await expect(fetchGekanatorPosts()).resolves.toEqual(posts)
|
||||
expect(mockedApiGet).toHaveBeenCalledWith('/gekanator/posts')
|
||||
})
|
||||
|
||||
it('returns questions from the Gekanator questions endpoint', async () => {
|
||||
const questions: StoredGekanatorQuestion[] = []
|
||||
mockedApiGet.mockResolvedValueOnce({ questions })
|
||||
|
||||
await expect(fetchGekanatorQuestions()).resolves.toEqual(questions)
|
||||
expect(mockedApiGet).toHaveBeenCalledWith('/gekanator/questions')
|
||||
})
|
||||
})
|
||||
|
||||
describe('expectedAnswerForQuestion', () => {
|
||||
it('returns a direct example answer when present', () => {
|
||||
const question: StoredGekanatorQuestion = {
|
||||
@@ -126,6 +147,7 @@ describe('expectedAnswerForQuestion', () => {
|
||||
postCount: 1,
|
||||
createdAt: '2026-06-10T00:00:00.000Z',
|
||||
updatedAt: '2026-06-10T00:00:00.000Z',
|
||||
deprecatedAt: null,
|
||||
hasWiki: false,
|
||||
hasDeerjikists: false,
|
||||
materialId: null,
|
||||
|
||||
@@ -58,6 +58,20 @@ describe ('tags API functions', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it.each ([
|
||||
[true, '1'],
|
||||
[false, '0'],
|
||||
] as const) ('maps deprecated=%s to %s', async (deprecated, expected) => {
|
||||
api.apiGet.mockResolvedValueOnce ({ tags: [], count: 0 })
|
||||
|
||||
await fetchTags ({ ...baseParams, deprecated })
|
||||
|
||||
expect (api.apiGet).toHaveBeenCalledWith (
|
||||
'/tags',
|
||||
{ params: expect.objectContaining ({ deprecated: expected }) },
|
||||
)
|
||||
})
|
||||
|
||||
it ('returns null when tag fetches fail', async () => {
|
||||
api.apiGet.mockRejectedValueOnce (new Error ('missing'))
|
||||
api.apiGet.mockRejectedValueOnce (new Error ('missing'))
|
||||
|
||||
@@ -14,13 +14,22 @@ vi.mock ('@/lib/tags', () => tagsApi)
|
||||
describe ('TagListPage', () => {
|
||||
it ('loads tags from URL filters and renders the results table', async () => {
|
||||
tagsApi.fetchTags.mockResolvedValueOnce ({
|
||||
tags: [buildTag ({ id: 7, name: '虹夏', category: 'character', postCount: 99 })],
|
||||
tags: [buildTag ({
|
||||
id: 7,
|
||||
name: '虹夏',
|
||||
category: 'character',
|
||||
postCount: 99,
|
||||
deprecatedAt: '2026-06-01T00:00:00.000Z',
|
||||
})],
|
||||
count: 1,
|
||||
})
|
||||
|
||||
renderWithProviders (
|
||||
<TagListPage/>,
|
||||
{ route: '/tags?name=%E8%99%B9&category=character&page=3&post_count_gte=5' },
|
||||
{
|
||||
route:
|
||||
'/tags?name=%E8%99%B9&category=character&page=3&post_count_gte=5&deprecated=1',
|
||||
},
|
||||
)
|
||||
|
||||
await waitFor (() => {
|
||||
@@ -30,6 +39,7 @@ describe ('TagListPage', () => {
|
||||
category: 'character',
|
||||
page: 3,
|
||||
postCountGTE: 5,
|
||||
deprecated: true,
|
||||
}),
|
||||
)
|
||||
})
|
||||
@@ -38,6 +48,8 @@ describe ('TagListPage', () => {
|
||||
'/tags/7',
|
||||
)
|
||||
expect (screen.getAllByText ('キャラクター').length).toBeGreaterThan (0)
|
||||
expect (screen.getAllByRole ('combobox')[1]).toHaveValue ('1')
|
||||
expect (screen.getAllByText ('廃止')).toHaveLength (2)
|
||||
})
|
||||
|
||||
it ('navigates to a normalized search URL on submit', async () => {
|
||||
@@ -46,7 +58,9 @@ describe ('TagListPage', () => {
|
||||
renderWithProviders (<TagListPage/>, { route: '/tags' })
|
||||
|
||||
fireEvent.change (screen.getByRole ('textbox'), { target: { value: '虹夏' } })
|
||||
fireEvent.change (screen.getByRole ('combobox'), { target: { value: 'character' } })
|
||||
fireEvent.change (screen.getAllByRole ('combobox')[0], {
|
||||
target: { value: 'character' },
|
||||
})
|
||||
fireEvent.submit (screen.getByRole ('button', { name: '検索' }).closest ('form')!)
|
||||
|
||||
await waitFor (() => {
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
"@/*": ["*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
"include": ["src"],
|
||||
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx", "src/test"]
|
||||
}
|
||||
|
||||
新しい課題から参照
ユーザをブロックする