import { describe, it, expect, beforeEach, vi } from 'vitest' import { createPieDownloadConfig } from './download' import type { PieWidgetData } from './types' const single: PieWidgetData = [ [ { name: 'a', value: 1 }, { name: 'b', value: 2 }, ], ] const multi: PieWidgetData = [ [{ name: 'a', value: 1 }], [{ name: 'c', value: 3 }], ] let csvText = '' let revokeSpy: ReturnType beforeEach(() => { csvText = '' vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock') revokeSpy = vi .spyOn(URL, 'revokeObjectURL') .mockImplementation(() => undefined) const RealBlob = global.Blob vi.stubGlobal( 'Blob', class extends RealBlob { constructor(parts: BlobPart[], opts?: BlobPropertyBag) { csvText = typeof parts[0] === 'string' ? parts[0] : '' super(parts, opts) } }, ) }) describe('createPieDownloadConfig', () => { it('returns CSV-only items by default', () => { const items = createPieDownloadConfig({ filename: 'p', getData: () => single, }) expect(items.map((i) => i.id)).toEqual(['csv']) }) it('prepends PNG when getCaptureEl provided and rejects when null', async () => { const items = createPieDownloadConfig({ filename: 'p', getData: () => single, getCaptureEl: () => null, }) expect(items.map((i) => i.id)).toEqual(['png', 'csv']) await expect(items[0]!.resolve()).rejects.toThrow(/No PNG capture element/) }) it('CSV resolve uses default series_ when seriesNames is absent', async () => { const items = createPieDownloadConfig({ filename: 'p', getData: () => multi, }) const handle = await items.find((i) => i.id === 'csv')!.resolve() expect(handle.filename).toBe('p.csv') expect(csvText).toBe('series,name,value\nseries_1,a,1\nseries_2,c,3') handle.revoke?.() expect(revokeSpy).toHaveBeenCalled() }) it('CSV resolve uses provided seriesNames when supplied', async () => { const items = createPieDownloadConfig({ filename: 'p', getData: () => multi, seriesNames: ['alpha', 'beta'], }) await items.find((i) => i.id === 'csv')!.resolve() expect(csvText).toBe('series,name,value\nalpha,a,1\nbeta,c,3') }) })