84 lines
No EOL
2.8 KiB
TypeScript
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')
|
|
})
|
|
}) |