#49 feat: graficos de provenance en columnas por nivel y aristas deduplicadas
This commit is contained in:
@@ -139,4 +139,44 @@ describe('ProductSupplierOrganizationChart', () => {
|
||||
|
||||
expect(wrapper.findComponent(ProvenanceDetailModal).props('visible')).toBe(false)
|
||||
})
|
||||
|
||||
it('alinea los productos en una columna vertical fija y centrada', () => {
|
||||
const provenance = [
|
||||
{ product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'A' } }] },
|
||||
{ product: { id: 2, name: 'Arroz' }, suppliers: [{ supplier: { id: 6, name: 'B' } }] },
|
||||
{ product: { id: 3, name: 'Queso' }, suppliers: [{ supplier: { id: 7, name: 'C' } }] },
|
||||
]
|
||||
const wrapper = mountChart({ provenance })
|
||||
|
||||
const products = visChart(wrapper).props('nodes').filter(node => node.kind === 'product')
|
||||
expect(products).toHaveLength(3)
|
||||
expect(new Set(products.map(node => node.x)).size).toBe(1)
|
||||
expect(products.map(node => node.y)).toEqual([-110, 0, 110])
|
||||
products.forEach(node => {
|
||||
expect(node.fixed).toEqual({ x: true, y: true })
|
||||
})
|
||||
})
|
||||
|
||||
it('alinea proveedores y organizaciones en columnas por nivel', () => {
|
||||
const wrapper = mountChart()
|
||||
|
||||
const supplier = visChart(wrapper).props('nodes').find(node => node.id === 'supplier:5')
|
||||
expect(supplier.x).toBe(0)
|
||||
expect(supplier.fixed).toEqual({ x: true, y: false })
|
||||
expect(supplier.y).toBeUndefined()
|
||||
|
||||
const organization = visChart(wrapper).props('nodes').find(node => node.id === 'organization:3')
|
||||
expect(organization.x).toBe(240)
|
||||
expect(organization.fixed).toEqual({ x: true, y: false })
|
||||
})
|
||||
|
||||
it('el punto de disyunción queda a la misma altura que su producto', () => {
|
||||
const wrapper = mountChart({ provenance: provenanceWithTwoSuppliers })
|
||||
|
||||
const junction = visChart(wrapper).props('nodes').find(node => node.id === 'junction:1')
|
||||
const product = visChart(wrapper).props('nodes').find(node => node.id === 'product:1')
|
||||
expect(junction.x).toBe(-120)
|
||||
expect(junction.y).toBe(product.y)
|
||||
expect(junction.fixed).toEqual({ x: true, y: true })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('ProductTerritoryChart', () => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('renderiza el gráfico con municipio, departamento y país', () => {
|
||||
it('renderiza el gráfico con municipio y departamento, sin país', () => {
|
||||
const wrapper = mountChart()
|
||||
|
||||
const chart = visChart(wrapper)
|
||||
@@ -73,7 +73,7 @@ describe('ProductTerritoryChart', () => {
|
||||
expect(nodeIds).toContain('supplier:5')
|
||||
expect(nodeIds).toContain('municipality:7')
|
||||
expect(nodeIds).toContain('department:2')
|
||||
expect(nodeIds).toContain('country:1')
|
||||
expect(nodeIds).not.toContain('country:1')
|
||||
})
|
||||
|
||||
it('incluye la etiqueta del nodo y el color según el tipo', () => {
|
||||
@@ -96,7 +96,20 @@ describe('ProductTerritoryChart', () => {
|
||||
expect(edges.find(edge => edge.from === 'junction:1' && edge.to === 'supplier:5').dashes).toBe(true)
|
||||
expect(edges.find(edge => edge.from === 'supplier:5' && edge.to === 'municipality:7').dashes).toBe(true)
|
||||
expect(edges.find(edge => edge.from === 'municipality:7' && edge.to === 'department:2').dashes).toBe(true)
|
||||
expect(edges.find(edge => edge.from === 'department:2' && edge.to === 'country:1').dashes).toBe(false)
|
||||
})
|
||||
|
||||
it('con varios productos del mismo proveedor solo traza una línea al municipio', () => {
|
||||
const provenanceWithRepeatedSupplier = [
|
||||
{ product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: { id: 2, name: 'Antioquia' } }] },
|
||||
{ product: { id: 2, name: 'Arroz' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: { id: 2, name: 'Antioquia' } }] },
|
||||
{ product: { id: 3, name: 'Queso' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: { id: 2, name: 'Antioquia' } }] },
|
||||
]
|
||||
const wrapper = mountChart({ provenance: provenanceWithRepeatedSupplier })
|
||||
|
||||
const chart = visChart(wrapper)
|
||||
const edges = chart.props('edges')
|
||||
expect(edges.filter(edge => edge.from === 'supplier:5' && edge.to === 'municipality:7')).toHaveLength(1)
|
||||
expect(chart.props('nodes').filter(node => node.id === 'municipality:7')).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('muestra mensaje de próximamente cuando ningún proveedor tiene territorio', () => {
|
||||
@@ -121,4 +134,13 @@ describe('ProductTerritoryChart', () => {
|
||||
expect(wrapper.findComponent(ProvenanceDetailModal).props('visible')).toBe(true)
|
||||
expect(document.body.textContent).toContain('La Mesa')
|
||||
})
|
||||
|
||||
it('alinea municipios y departamentos en columnas por nivel', () => {
|
||||
const wrapper = mountChart()
|
||||
|
||||
const nodes = visChart(wrapper).props('nodes')
|
||||
expect(nodes.find(node => node.id === 'supplier:5').x).toBe(0)
|
||||
expect(nodes.find(node => node.id === 'municipality:7').x).toBe(240)
|
||||
expect(nodes.find(node => node.id === 'department:2').x).toBe(480)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -87,6 +87,26 @@ describe('hasAnyTerritory', () => {
|
||||
const noSuppliers = [{ product: { id: 1, name: 'Panela' }, suppliers: [] }]
|
||||
expect(hasAnyTerritory(noSuppliers)).toBe(false)
|
||||
})
|
||||
|
||||
it('es true cuando hay municipio aunque el país venga null', () => {
|
||||
const data = [
|
||||
{
|
||||
product: { id: 1, name: 'Panela' },
|
||||
suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: null, country: null }],
|
||||
},
|
||||
]
|
||||
expect(hasAnyTerritory(data)).toBe(true)
|
||||
})
|
||||
|
||||
it('es false cuando solo hay país', () => {
|
||||
const data = [
|
||||
{
|
||||
product: { id: 1, name: 'Panela' },
|
||||
suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: null, department: null, country: { id: 1, name: 'Colombia' } }],
|
||||
},
|
||||
]
|
||||
expect(hasAnyTerritory(data)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('buildSupplierOrganizationGraph', () => {
|
||||
@@ -146,7 +166,7 @@ describe('buildSupplierOrganizationGraph', () => {
|
||||
expect(graph.edges).toEqual([{ from: 'product:1', to: 'supplier:5', certain: true }])
|
||||
})
|
||||
|
||||
it('no duplica nodos que se repiten entre productos', () => {
|
||||
it('no duplica nodos ni aristas cuando 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' } }] },
|
||||
@@ -155,7 +175,19 @@ describe('buildSupplierOrganizationGraph', () => {
|
||||
|
||||
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)
|
||||
expect(graph.edges.filter(e => e.from === 'supplier:5' && e.to === 'organization:3')).toHaveLength(1)
|
||||
expect(graph.edges).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('si el mismo par de nodos repite con distinta certeza, gana la duda', () => {
|
||||
const data = [
|
||||
{ product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'A' }, organization: { id: 3, name: 'Red' } }] },
|
||||
{ product: { id: 2, name: 'Arroz' }, suppliers: [{ supplier: { id: 5, name: 'A' }, organization: { id: 3, name: 'Red' } }, { supplier: { id: 6, name: 'B' }, organization: { id: 4, name: 'Coop' } }] },
|
||||
]
|
||||
const graph = buildSupplierOrganizationGraph(data)
|
||||
|
||||
expect(graph.edges.filter(e => e.from === 'supplier:5' && e.to === 'organization:3')).toHaveLength(1)
|
||||
expect(edgeOf(graph, 'supplier:5', 'organization:3').certain).toBe(false)
|
||||
})
|
||||
|
||||
it('no incluye posiciones de layout', () => {
|
||||
@@ -181,7 +213,25 @@ describe('buildTerritoryGraph', () => {
|
||||
expect(edgeOf(graph, 'product:1', 'supplier:5')).toEqual({ from: 'product:1', to: 'supplier:5', certain: true })
|
||||
expect(edgeOf(graph, 'supplier:5', 'municipality:7')).toEqual({ from: 'supplier:5', to: 'municipality:7', certain: true })
|
||||
expect(edgeOf(graph, 'municipality:7', 'department:2')).toEqual({ from: 'municipality:7', to: 'department:2', certain: true })
|
||||
expect(edgeOf(graph, 'department:2', 'country:1')).toEqual({ from: 'department:2', to: 'country:1', certain: true })
|
||||
})
|
||||
|
||||
it('no incluye nodos ni aristas de país', () => {
|
||||
const graph = buildTerritoryGraph(singleSupplier)
|
||||
|
||||
expect(graph.nodes.map(n => n.id)).not.toContain('country:1')
|
||||
expect(graph.edges.some(edge => edge.from.startsWith('country:') || edge.to.startsWith('country:'))).toBe(false)
|
||||
})
|
||||
|
||||
it('con varios productos del mismo proveedor solo traza una línea hacia el municipio', () => {
|
||||
const data = [
|
||||
{ product: { id: 1, name: 'Panela' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: { id: 2, name: 'Antioquia' } }] },
|
||||
{ product: { id: 2, name: 'Arroz' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: { id: 2, name: 'Antioquia' } }] },
|
||||
{ product: { id: 3, name: 'Queso' }, suppliers: [{ supplier: { id: 5, name: 'La Mesa' }, municipality: { id: 7, name: 'Santa Bárbara' }, department: { id: 2, name: 'Antioquia' } }] },
|
||||
]
|
||||
const graph = buildTerritoryGraph(data)
|
||||
|
||||
expect(graph.edges.filter(e => e.from === 'supplier:5' && e.to === 'municipality:7')).toHaveLength(1)
|
||||
expect(graph.nodes.filter(n => n.id === 'municipality:7')).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('cuando los proveedores comparten municipio, el territorio es cierto desde allí', () => {
|
||||
@@ -194,7 +244,6 @@ describe('buildTerritoryGraph', () => {
|
||||
expect(edgeOf(graph, 'supplier:5', 'municipality:7')).toEqual({ from: 'supplier:5', to: 'municipality:7', certain: true })
|
||||
expect(edgeOf(graph, 'supplier:6', 'municipality:7')).toEqual({ from: 'supplier:6', to: 'municipality:7', certain: true })
|
||||
expect(edgeOf(graph, 'municipality:7', 'department:2').certain).toBe(true)
|
||||
expect(edgeOf(graph, 'department:2', 'country:1').certain).toBe(true)
|
||||
})
|
||||
|
||||
it('municipios distintos pero mismo departamento: dudoso hasta el municipio y cierto desde el departamento', () => {
|
||||
@@ -206,18 +255,15 @@ describe('buildTerritoryGraph', () => {
|
||||
expect(edgeOf(graph, 'supplier:6', 'municipality:8').certain).toBe(false)
|
||||
expect(edgeOf(graph, 'municipality:7', 'department:2')).toEqual({ from: 'municipality:7', to: 'department:2', certain: true })
|
||||
expect(edgeOf(graph, 'municipality:8', 'department:2')).toEqual({ from: 'municipality:8', to: 'department:2', certain: true })
|
||||
expect(edgeOf(graph, 'department:2', 'country:1').certain).toBe(true)
|
||||
})
|
||||
|
||||
it('municipios y departamentos distintos mantienen la duda, y el país común es cierto', () => {
|
||||
it('municipios y departamentos distintos mantienen la duda', () => {
|
||||
const graph = buildTerritoryGraph(twoSuppliers())
|
||||
|
||||
expect(edgeOf(graph, 'supplier:5', 'municipality:7').certain).toBe(false)
|
||||
expect(edgeOf(graph, 'municipality:7', 'department:2').certain).toBe(false)
|
||||
expect(edgeOf(graph, 'supplier:6', 'municipality:8').certain).toBe(false)
|
||||
expect(edgeOf(graph, 'municipality:8', 'department:3').certain).toBe(false)
|
||||
expect(edgeOf(graph, 'department:2', 'country:1')).toEqual({ from: 'department:2', to: 'country:1', certain: true })
|
||||
expect(edgeOf(graph, 'department:3', 'country:1')).toEqual({ from: 'department:3', to: 'country:1', certain: true })
|
||||
})
|
||||
|
||||
it('no crea nodos de territorio cuando el proveedor no tiene municipio', () => {
|
||||
|
||||
Reference in New Issue
Block a user