121 lines
4.1 KiB
TypeScript
121 lines
4.1 KiB
TypeScript
import type { Issue, IssueColumn } from '../types'
|
||
import { describe, expect, it } from 'vitest'
|
||
import { isColumnId, resolveKanbanDrag } from './kanbanDrag'
|
||
|
||
function issue(
|
||
number: number,
|
||
column: IssueColumn,
|
||
extra: Partial<Issue> = {},
|
||
): Issue {
|
||
return {
|
||
id: `repo#${number}`,
|
||
number,
|
||
title: `issue ${number}`,
|
||
column,
|
||
htmlUrl: '',
|
||
...extra,
|
||
}
|
||
}
|
||
|
||
describe('isColumnId', () => {
|
||
it('识别四列 id', () => {
|
||
expect(isColumnId('todo')).toBe(true)
|
||
expect(isColumnId('in-progress')).toBe(true)
|
||
expect(isColumnId('review')).toBe(true)
|
||
expect(isColumnId('done')).toBe(true)
|
||
})
|
||
|
||
it('拒绝卡片 id', () => {
|
||
expect(isColumnId('repo#1')).toBe(false)
|
||
})
|
||
})
|
||
|
||
describe('resolveKanbanDrag', () => {
|
||
it('active===over → none', () => {
|
||
const issues = [issue(1, 'todo')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#1' }))
|
||
.toEqual({ type: 'none' })
|
||
})
|
||
|
||
it('丢到另一张待办卡片 = set(over 为前置)', () => {
|
||
const issues = [issue(1, 'todo'), issue(2, 'todo')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#2' }))
|
||
.toEqual({ type: 'dependency-set', issueNumber: 1, prerequisiteNumber: 2 })
|
||
})
|
||
|
||
it('丢到待办列空白且已有依赖 = clear', () => {
|
||
const issues = [issue(1, 'todo', { prerequisite: 2 }), issue(2, 'todo')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'todo' }))
|
||
.toEqual({ type: 'dependency-clear', issueNumber: 1, prerequisiteNumber: 2 })
|
||
})
|
||
|
||
it('over 是列且已在 todo 且无依赖 = none', () => {
|
||
const issues = [issue(1, 'todo')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'todo' }))
|
||
.toEqual({ type: 'none' })
|
||
})
|
||
|
||
it('跨列仍是 column', () => {
|
||
const issues = [issue(1, 'in-progress'), issue(2, 'todo')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'todo' }))
|
||
.toEqual({ type: 'column', issueNumber: 1, toColumn: 'todo' })
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#2' }))
|
||
.toEqual({ type: 'column', issueNumber: 1, toColumn: 'todo' })
|
||
})
|
||
|
||
it('跨列带上 source / externalId', () => {
|
||
const issues = [issue(1, 'review', { source: 'youtrack', externalId: 'LXF-1' })]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'todo' }))
|
||
.toEqual({
|
||
type: 'column',
|
||
issueNumber: 1,
|
||
toColumn: 'todo',
|
||
source: 'youtrack',
|
||
externalId: 'LXF-1',
|
||
})
|
||
})
|
||
|
||
it('环拒绝:不能把祖先挂到自己的后代下', () => {
|
||
const issues = [
|
||
issue(1, 'todo'),
|
||
issue(2, 'todo', { prerequisite: 1 }),
|
||
issue(3, 'todo', { prerequisite: 2 }),
|
||
]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#3' }))
|
||
.toEqual({ type: 'none' })
|
||
})
|
||
|
||
it('已经是这个 parent → none', () => {
|
||
const issues = [issue(1, 'todo', { prerequisite: 2 }), issue(2, 'todo')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#2' }))
|
||
.toEqual({ type: 'none' })
|
||
})
|
||
|
||
it('换 parent 也是 dependency-set,不先 clear', () => {
|
||
const issues = [
|
||
issue(1, 'todo', { prerequisite: 2 }),
|
||
issue(2, 'todo'),
|
||
issue(3, 'todo'),
|
||
]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#3' }))
|
||
.toEqual({ type: 'dependency-set', issueNumber: 1, prerequisiteNumber: 3 })
|
||
})
|
||
|
||
it('同列非 todo → reorder', () => {
|
||
const issues = [issue(1, 'in-progress'), issue(2, 'in-progress')]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#2' }))
|
||
.toEqual({ type: 'reorder', fromIndex: 0, toIndex: 1 })
|
||
})
|
||
|
||
it('锁定:todo 且前置未完成,目标列不是 todo → none', () => {
|
||
const issues = [
|
||
issue(1, 'todo', { prerequisite: 2 }),
|
||
issue(2, 'in-progress'),
|
||
]
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'in-progress' }))
|
||
.toEqual({ type: 'none' })
|
||
expect(resolveKanbanDrag({ issues, activeId: 'repo#1', overId: 'repo#2' }))
|
||
.toEqual({ type: 'none' })
|
||
})
|
||
})
|