jobhunt-platform/apps/web/src/views/Applications.test.ts

84 lines
No EOL
2.8 KiB
TypeScript

import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import Applications from '@/views/Applications.vue'
import type { Application } from '@/types'
vi.mock('@/api', () => ({
getApplications: vi.fn(),
transitionApplication: vi.fn(),
batchScore: vi.fn().mockResolvedValue({ results: [] }),
getToday: vi.fn().mockResolvedValue({ digest: [], nudges: [], pending_approvals: 0 }),
HttpError: class HttpError extends Error {
status: number
body: unknown
constructor(status: number, body: unknown, msg?: string) {
super(msg ?? `HTTP ${status}`)
this.status = status
this.body = body
}
}
}))
function fixture(): Application[] {
return [
{
id: 'app-1',
job_posting_id: 'j-1',
state: 'discovered',
score: null,
score_rationale: null,
notes: '',
state_changed_at: '2026-01-01T00:00:00Z',
created_at: '2026-01-01T00:00:00Z',
posting: {
id: 'j-1', source: 'manual_url', external_id: null, url: 'http://x',
company: 'Acme', title: 'Engineer', location: 'Remote', description: '',
raw: {}, fetched_at: '2026-01-01T00:00:00Z'
}
},
{
id: 'app-2',
job_posting_id: 'j-2',
state: 'scored',
score: 85,
score_rationale: null,
notes: '',
state_changed_at: '2026-01-01T00:00:00Z',
created_at: '2026-01-01T00:00:00Z',
posting: {
id: 'j-2', source: 'linkedin', external_id: null, url: 'http://y',
company: 'Globex', title: 'Manager', location: 'Malmo', description: '',
raw: {}, fetched_at: '2026-01-01T00:00:00Z'
}
}
]
}
describe('Applications kanban', () => {
it('groups cards by state from fixture', async () => {
setActivePinia(createPinia())
const { getApplications } = await import('@/api')
;(getApplications as ReturnType<typeof vi.fn>).mockResolvedValue(fixture())
const wrapper = mount(Applications)
// Wait for onMounted load
await vi.waitFor(() => {
expect(wrapper.text()).toContain('Acme')
expect(wrapper.text()).toContain('Globex')
})
// "discovered" column should contain Acme
const discoveredCol = wrapper.findAll('.font-semibold').find((el) => el.text() === 'discovered')
expect(discoveredCol).toBeTruthy()
const discoveredColumn = discoveredCol!.element.parentElement!
expect(discoveredColumn.textContent).toContain('Acme')
expect(discoveredColumn.textContent).not.toContain('Globex')
// "scored" column should contain Globex
const scoredCol = wrapper.findAll('.font-semibold').find((el) => el.text() === 'scored')
expect(scoredCol).toBeTruthy()
const scoredColumn = scoredCol!.element.parentElement!
expect(scoredColumn.textContent).toContain('Globex')
})
})