feat(sprint-3): biblioteca, recursos TO-BE, ROI mejorado e identidad de marca
Sprint 3 completo — 7 etapas: - Etapa 1-2: biblioteca de procesos con agrupación por cliente (Dexie v4, LibraryPage, library-store, groupId/tags en Process) - Etapa 3: modal de configuración global por proceso (horizonte, frecuencia, inversión, moneda) con validación y persistencia - Etapa 4: panel de recursos rediseñado con soporte de unidades y minutos de utilización (utilizationMinutes + units) - Etapa 5: recursos en escenario automatizado — motor de simulación, UI de edición en ActivityPanel, comparación AS-IS/TO-BE en reporte - Etapa 6: PDF recursos automatizados, automatedAssignedResources requerido, 561 tests pasando - Etapa 7: identidad de marca — AppHeader gradiente naranja/magenta con logo InQuality en 5 páginas, favicon con logo real, logo/marca navegan a home Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,7 @@ const mockActivity: Activity = {
|
||||
directCostFixed: 600, executionTimeMinutes: 60,
|
||||
assignedResources: [{ resourceId: 'r1', utilizationMinutes: 60, units: 1 }],
|
||||
automatable: false, automatedCostFixed: 0, automatedTimeMinutes: 0,
|
||||
automatedAssignedResources: [{ resourceId: 'r1', utilizationMinutes: 5, units: 3 }],
|
||||
}
|
||||
|
||||
const activityWithResources: ActivitySimResult = {
|
||||
@@ -122,3 +123,43 @@ describe('drawResourcesSection', () => {
|
||||
expect(autoTableMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
// ─── Escenario automatizado usa automatedAssignedResources ────────────────────
|
||||
|
||||
describe('drawResourcesSection — escenario automatizado', () => {
|
||||
let autoTableMock: ReturnType<typeof vi.fn>
|
||||
|
||||
beforeEach(() => {
|
||||
autoTableMock = vi.fn()
|
||||
})
|
||||
|
||||
it('escenario automatizado: pasa utilizationMinutes y units de automatedAssignedResources', async () => {
|
||||
const { drawResourcesSection } = await import('@/lib/export/pdf-sections')
|
||||
drawResourcesSection(
|
||||
mockDoc, autoTableMock,
|
||||
{ perActivity: [activityWithResources] },
|
||||
[mockResource], [mockActivity], 'USD', 40,
|
||||
'automatizado'
|
||||
)
|
||||
const body = (autoTableMock.mock.calls[0][1] as any).body as any[][]
|
||||
const row = body[0]
|
||||
// Min. (índice 4) y Uds. (índice 5) deben venir de automatedAssignedResources: { utilMin: 5, units: 3 }
|
||||
expect(row[4].content).toBe('5')
|
||||
expect(row[5].content).toBe('3')
|
||||
})
|
||||
|
||||
it('escenario actual: pasa utilizationMinutes y units de assignedResources (sin regresión)', async () => {
|
||||
const { drawResourcesSection } = await import('@/lib/export/pdf-sections')
|
||||
drawResourcesSection(
|
||||
mockDoc, autoTableMock,
|
||||
{ perActivity: [activityWithResources] },
|
||||
[mockResource], [mockActivity], 'USD', 40,
|
||||
'actual'
|
||||
)
|
||||
const body = (autoTableMock.mock.calls[0][1] as any).body as any[][]
|
||||
const row = body[0]
|
||||
// assignedResources: { utilMin: 60, units: 1 }
|
||||
expect(row[4].content).toBe('60')
|
||||
expect(row[5].content).toBe('1')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user