import { describe, expect, it } from 'vitest' import type { KbxGridColumn, KbxSelectionState } from '@kbx/contracts' import { normalizeKbxGridClipboardData, toKbxBulkSelectionRequest } from '@kbx/ui' type Row={code:string;qty:number;price:number;date:string;active:boolean} const columns:KbxGridColumn[]=[ {field:'code',header:'코드',type:'code'}, {field:'qty',header:'수량',type:'quantity'}, {field:'price',header:'단가',type:'money'}, {field:'date',header:'일자',type:'date'}, {field:'active',header:'사용',type:'boolean'}, ] describe('KBX grid productivity contract',()=>{ it('normalizes Excel-like pasted values before cell validation',()=>{ const {data,result}=normalizeKbxGridClipboardData([[' ABC001 ','1,200','3,500','20260808','Y']],columns,0) expect(data[0]).toEqual(['ABC001',1200,3500,'2026-08-08',true]) expect(result.cellCount).toBe(5) expect(result.rejectedCount).toBe(0) }) it('keeps invalid pasted values visible for inline validation',()=>{ const {data,result}=normalizeKbxGridClipboardData([['ABC001','not-number']],columns,0) expect(data[0][1]).toBe('not-number') expect(result.issues[0]).toMatchObject({field:'qty',code:'INVALID_NUMBER'}) }) it('does not expand all-filtered selection into browser ids',()=>{ const state:KbxSelectionState={mode:'all-filtered',selectedIds:[],excludedIds:['ORDER-9']} expect(toKbxBulkSelectionRequest(state,{status:'READY'})).toEqual({mode:'filter',filter:{status:'READY'},excludedIds:['ORDER-9']}) }) })