186 lines
4.9 KiB
TypeScript
186 lines
4.9 KiB
TypeScript
import { describe, expect, it } from 'bun:test';
|
|
import { __financialPageMergeInternals } from './page-merge';
|
|
import type { CompanyFinancialStatementsResponse } from '@/lib/types';
|
|
|
|
function createResponse(partial: Partial<CompanyFinancialStatementsResponse>): CompanyFinancialStatementsResponse {
|
|
return {
|
|
company: {
|
|
ticker: 'MSFT',
|
|
companyName: 'Microsoft Corporation',
|
|
cik: null
|
|
},
|
|
surfaceKind: 'income_statement',
|
|
cadence: 'annual',
|
|
displayModes: ['standardized', 'faithful'],
|
|
defaultDisplayMode: 'standardized',
|
|
periods: [],
|
|
statementRows: {
|
|
faithful: [],
|
|
standardized: []
|
|
},
|
|
statementDetails: null,
|
|
ratioRows: null,
|
|
kpiRows: null,
|
|
trendSeries: [],
|
|
categories: [],
|
|
availability: {
|
|
adjusted: false,
|
|
customMetrics: false
|
|
},
|
|
nextCursor: null,
|
|
facts: null,
|
|
coverage: {
|
|
filings: 0,
|
|
rows: 0,
|
|
dimensions: 0,
|
|
facts: 0
|
|
},
|
|
dataSourceStatus: {
|
|
enabled: true,
|
|
hydratedFilings: 0,
|
|
partialFilings: 0,
|
|
failedFilings: 0,
|
|
pendingFilings: 0,
|
|
queuedSync: false
|
|
},
|
|
metrics: {
|
|
taxonomy: null,
|
|
validation: null
|
|
},
|
|
normalization: {
|
|
parserEngine: 'fiscal-xbrl',
|
|
regime: 'us-gaap',
|
|
fiscalPack: 'core',
|
|
parserVersion: '0.1.0',
|
|
surfaceRowCount: 0,
|
|
detailRowCount: 0,
|
|
kpiRowCount: 0,
|
|
unmappedRowCount: 0,
|
|
materialUnmappedRowCount: 0,
|
|
warnings: []
|
|
},
|
|
dimensionBreakdown: null,
|
|
...partial
|
|
};
|
|
}
|
|
|
|
describe('financial page merge helpers', () => {
|
|
it('merges detail maps safely when legacy detail rows are missing arrays', () => {
|
|
const merged = __financialPageMergeInternals.mergeDetailMaps(
|
|
{
|
|
revenue: [{
|
|
key: 'detail',
|
|
parentSurfaceKey: 'revenue',
|
|
label: 'Detail',
|
|
conceptKey: 'detail',
|
|
qname: 'us-gaap:Detail',
|
|
namespaceUri: 'http://fasb.org/us-gaap/2024',
|
|
localName: 'Detail',
|
|
unit: 'iso4217:USD',
|
|
values: { p1: 1 },
|
|
sourceFactIds: undefined,
|
|
isExtension: false,
|
|
dimensionsSummary: undefined,
|
|
residualFlag: false
|
|
} as never]
|
|
},
|
|
{
|
|
revenue: [{
|
|
key: 'detail',
|
|
parentSurfaceKey: 'revenue',
|
|
label: 'Detail',
|
|
conceptKey: 'detail',
|
|
qname: 'us-gaap:Detail',
|
|
namespaceUri: 'http://fasb.org/us-gaap/2024',
|
|
localName: 'Detail',
|
|
unit: 'iso4217:USD',
|
|
values: { p2: 2 },
|
|
sourceFactIds: [2],
|
|
isExtension: false,
|
|
dimensionsSummary: ['region:americas'],
|
|
residualFlag: false
|
|
}]
|
|
}
|
|
);
|
|
|
|
expect(merged?.revenue?.[0]).toMatchObject({
|
|
values: { p1: 1, p2: 2 },
|
|
sourceFactIds: [2],
|
|
dimensionsSummary: ['region:americas']
|
|
});
|
|
});
|
|
|
|
it('merges paged financial responses safely when row arrays are partially missing', () => {
|
|
const base = createResponse({
|
|
periods: [{
|
|
id: 'p1',
|
|
filingId: 1,
|
|
accessionNumber: '0001',
|
|
filingDate: '2025-01-01',
|
|
periodStart: '2024-01-01',
|
|
periodEnd: '2024-12-31',
|
|
filingType: '10-K',
|
|
periodLabel: 'FY 2024'
|
|
}],
|
|
statementRows: {
|
|
faithful: undefined as never,
|
|
standardized: [{
|
|
key: 'revenue',
|
|
label: 'Revenue',
|
|
category: 'revenue',
|
|
order: 10,
|
|
unit: 'currency',
|
|
values: { p1: 1 },
|
|
sourceConcepts: [],
|
|
sourceRowKeys: [],
|
|
sourceFactIds: [],
|
|
formulaKey: null,
|
|
hasDimensions: false,
|
|
resolvedSourceRowKeys: { p1: 'revenue' }
|
|
}]
|
|
}
|
|
});
|
|
const next = createResponse({
|
|
periods: [{
|
|
id: 'p2',
|
|
filingId: 2,
|
|
accessionNumber: '0002',
|
|
filingDate: '2026-01-01',
|
|
periodStart: '2025-01-01',
|
|
periodEnd: '2025-12-31',
|
|
filingType: '10-K',
|
|
periodLabel: 'FY 2025'
|
|
}],
|
|
statementRows: {
|
|
faithful: [{
|
|
key: 'rev',
|
|
label: 'Revenue',
|
|
conceptKey: 'rev',
|
|
qname: 'us-gaap:Revenue',
|
|
namespaceUri: 'http://fasb.org/us-gaap/2024',
|
|
localName: 'Revenue',
|
|
isExtension: false,
|
|
statement: 'income',
|
|
roleUri: 'income',
|
|
order: 10,
|
|
depth: 0,
|
|
parentKey: null,
|
|
values: { p2: 2 },
|
|
units: { p2: 'iso4217:USD' },
|
|
hasDimensions: false,
|
|
sourceFactIds: []
|
|
}],
|
|
standardized: undefined as never
|
|
}
|
|
});
|
|
|
|
const merged = __financialPageMergeInternals.mergeFinancialPages(base, next);
|
|
|
|
expect(merged.periods.map((period) => period.id)).toEqual(['p1', 'p2']);
|
|
expect(merged.statementRows).toMatchObject({
|
|
faithful: [{ key: 'rev' }],
|
|
standardized: [{ key: 'revenue', values: { p1: 1 } }]
|
|
});
|
|
});
|
|
});
|