import { describe, expect, it } from 'vitest' import { buildSupplierOrganizationGraph, buildTerritoryGraph, hasAnySupplier, hasAnyTerritory, } from '@/components/provenance/provenance-graph' const provenance = [ { product: { id: 1, name: 'Panela regional por Kg', catalogue_images: ['http://localhost/media/panela.jpg'], }, suppliers: [ { supplier: { id: 5, name: 'Asociación Agropecuaria La Mesa', description: 'Cooperativa' }, organization: { id: 3, name: 'Red de Economía Solidaria', description: 'Red' }, municipality: { id: 7, name: 'La Mesa' }, department: { id: 2, name: 'Cundinamarca' }, country: { id: 1, name: 'Colombia', code: 'CO' }, }, ], }, ] describe('hasAnySupplier', () => { it('es true cuando algún producto tiene proveedores', () => { expect(hasAnySupplier(provenance)).toBe(true) }) it('es false cuando todos los productos están sin proveedores', () => { const empty = [{ product: { id: 1, name: 'Panela' }, suppliers: [] }] expect(hasAnySupplier(empty)).toBe(false) }) it('es false cuando no hay provenance', () => { expect(hasAnySupplier([])).toBe(false) }) }) describe('hasAnyTerritory', () => { it('es true cuando algún proveedor tiene territorio', () => { expect(hasAnyTerritory(provenance)).toBe(true) }) it('es false cuando todos los territorios vienen en null', () => { const noTerritory = [ { product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, organization: null, municipality: null, department: null, country: null }], }, ] expect(hasAnyTerritory(noTerritory)).toBe(false) }) it('es false cuando no hay suppliers', () => { const noSuppliers = [{ product: { id: 1, name: 'Panela' }, suppliers: [] }] expect(hasAnyTerritory(noSuppliers)).toBe(false) }) }) describe('buildSupplierOrganizationGraph', () => { it('crea nodos de producto, proveedor y organización con sus aristas', () => { const graph = buildSupplierOrganizationGraph(provenance) const ids = graph.nodes.map(n => n.id) expect(ids).toContain('product:1') expect(ids).toContain('supplier:5') expect(ids).toContain('organization:3') expect(graph.edges).toContainEqual({ from: 'product:1', to: 'supplier:5' }) expect(graph.edges).toContainEqual({ from: 'supplier:5', to: 'organization:3' }) }) it('incluye la imagen del producto y el detalle de la entidad', () => { const graph = buildSupplierOrganizationGraph(provenance) const product = graph.nodes.find(n => n.id === 'product:1') expect(product.image).toBe('http://localhost/media/panela.jpg') expect(product.label).toBe('Panela regional por Kg') expect(product.entity.kind).toBe('product') expect(product.entity.name).toBe('Panela regional por Kg') }) it('omite el nodo de organización cuando la relación es null', () => { const data = [ { product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, organization: null }], }, ] const graph = buildSupplierOrganizationGraph(data) expect(graph.nodes.map(n => n.id)).not.toContain('organization:') expect(graph.edges).toEqual([{ from: 'product:1', to: 'supplier:5' }]) }) it('no duplica nodos que se repiten entre productos', () => { const data = [ { product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, organization: { id: 3, name: 'Red' } }] }, { product: { id: 2, name: 'Arroz' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, organization: { id: 3, name: 'Red' } }] }, ] const graph = buildSupplierOrganizationGraph(data) expect(graph.nodes.filter(n => n.id === 'supplier:5')).toHaveLength(1) expect(graph.nodes.filter(n => n.id === 'organization:3')).toHaveLength(1) expect(graph.edges).toHaveLength(4) }) it('ubica producto, proveedor y organización en columnas crecientes', () => { const graph = buildSupplierOrganizationGraph(provenance) const product = graph.nodes.find(n => n.id === 'product:1') const supplier = graph.nodes.find(n => n.id === 'supplier:5') const organization = graph.nodes.find(n => n.id === 'organization:3') expect(product.x).toBeLessThan(supplier.x) expect(supplier.x).toBeLessThan(organization.x) }) it('devuelve un grafo vacío cuando no hay provenance', () => { const graph = buildSupplierOrganizationGraph([]) expect(graph.nodes).toEqual([]) expect(graph.edges).toEqual([]) }) }) describe('buildTerritoryGraph', () => { it('crea la cadena producto → proveedor → municipio → departamento → país', () => { const graph = buildTerritoryGraph(provenance) const ids = graph.nodes.map(n => n.id) expect(ids).toContain('product:1') expect(ids).toContain('supplier:5') expect(ids).toContain('municipality:7') expect(ids).toContain('department:2') expect(ids).toContain('country:1') expect(graph.edges).toContainEqual({ from: 'supplier:5', to: 'municipality:7' }) expect(graph.edges).toContainEqual({ from: 'municipality:7', to: 'department:2' }) expect(graph.edges).toContainEqual({ from: 'department:2', to: 'country:1' }) }) it('no crea nodos de territorio cuando el proveedor no tiene municipio', () => { const data = [ { product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: null, department: null, country: null }], }, ] const graph = buildTerritoryGraph(data) expect(graph.nodes.map(n => n.id)).toEqual(['product:1', 'supplier:5']) expect(graph.edges).toEqual([{ from: 'product:1', to: 'supplier:5' }]) }) })