2026-05-14 10:05:17 +00:00
|
|
|
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
|
|
|
import * as feeSchedules from '../ts/index.js';
|
|
|
|
|
|
2026-05-14 12:41:31 +00:00
|
|
|
const getGermanyCatalog = () => {
|
|
|
|
|
const catalog = feeSchedules.FEE_SCHEDULE_CATALOGS.find((item) => item.countryCode === 'DE');
|
|
|
|
|
if (!catalog) {
|
|
|
|
|
throw new Error('Expected Germany catalog in generated fee schedule payload.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return catalog;
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-14 10:05:17 +00:00
|
|
|
tap.test('exports Germany fee schedules and API helpers', async () => {
|
2026-05-14 12:41:31 +00:00
|
|
|
expect(feeSchedules.FEE_SCHEDULE_CATALOGS).toBeArray();
|
|
|
|
|
expect(feeSchedules.FEE_SCHEDULE_DATA).toBeArray();
|
|
|
|
|
expect(feeSchedules.SUPPORTED_COUNTRY_CODES).toContain('DE');
|
2026-05-14 10:05:17 +00:00
|
|
|
expect(feeSchedules.FEE_SCHEDULE_CATALOGS).toHaveLength(1);
|
|
|
|
|
expect(feeSchedules.FeeSchedules).toBeTypeOf('function');
|
|
|
|
|
expect(feeSchedules.feeSchedules).toBeInstanceOf(feeSchedules.FeeSchedules);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('contains the initial German schedule catalog', async () => {
|
2026-05-14 12:41:31 +00:00
|
|
|
const germanyCatalog = getGermanyCatalog();
|
|
|
|
|
|
|
|
|
|
expect(germanyCatalog.schedules).toHaveLength(21);
|
|
|
|
|
expect(feeSchedules.FEE_SCHEDULE_DATA).toHaveLength(21);
|
2026-05-14 10:05:17 +00:00
|
|
|
|
2026-05-14 12:41:31 +00:00
|
|
|
for (const schedule of germanyCatalog.schedules) {
|
2026-05-14 10:05:17 +00:00
|
|
|
expect(schedule.id).toBeTypeofString();
|
|
|
|
|
expect(schedule.countryCode).toEqual('DE');
|
|
|
|
|
expect(schedule.area).toBeTypeofString();
|
|
|
|
|
expect(schedule.abbreviation).toBeTypeofString();
|
|
|
|
|
expect(schedule.description).toBeTypeofString();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('contains actual imported fee rows for federal German schedules', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
const goae = api.getDataByScheduleId('de-goae');
|
|
|
|
|
const goz = api.getDataByScheduleId('de-goz');
|
|
|
|
|
const rvg = api.getDataByScheduleId('de-rvg');
|
|
|
|
|
const gvkostg = api.getDataByScheduleId('de-gvkostg');
|
|
|
|
|
|
|
|
|
|
expect(goae?.dataStatus).toEqual('federal-law-fee-data');
|
|
|
|
|
expect(goae?.feeRows.length).toBeGreaterThan(2000);
|
|
|
|
|
expect(goz?.feeRows.length).toBeGreaterThan(200);
|
|
|
|
|
expect(rvg?.feeRows.length).toBeGreaterThan(200);
|
|
|
|
|
expect(gvkostg?.feeRows.length).toBeGreaterThan(50);
|
|
|
|
|
|
|
|
|
|
expect(api.getFeeRow('de-goae', '1')?.cells).toEqual([
|
|
|
|
|
'1',
|
|
|
|
|
'Beratung - auch mittels Fernsprecher -',
|
|
|
|
|
'80',
|
|
|
|
|
'9,12',
|
|
|
|
|
]);
|
|
|
|
|
expect(api.getFeeRow('de-goae', '1')?.points).toEqual(80);
|
|
|
|
|
expect(api.getFeeRow('de-goae', '1')?.amountEur).toEqual(9.12);
|
|
|
|
|
expect(api.getFeeRow('de-goz', '0010')?.points).toEqual(100);
|
|
|
|
|
expect(api.getFeeRow('de-rvg', '1000')?.description).toContain('Einigungsgebühr');
|
|
|
|
|
expect(api.getFeeRow('de-gvkostg', '100')?.amountEur).toEqual(12);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('contains rule sections for formula-based federal schedules', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
const gop = api.getDataByScheduleId('de-gop');
|
|
|
|
|
const ampreisv = api.getDataByScheduleId('de-ampreisv');
|
|
|
|
|
const insvv = api.getDataByScheduleId('de-insvv');
|
|
|
|
|
|
|
|
|
|
expect(gop?.dataStatus).toEqual('federal-law-rules-only');
|
|
|
|
|
expect(ampreisv?.dataStatus).toEqual('federal-law-rules-only');
|
|
|
|
|
expect(insvv?.dataStatus).toEqual('federal-law-rules-only');
|
|
|
|
|
expect(api.getRuleSections('de-gop').length).toBeGreaterThan(0);
|
|
|
|
|
expect(api.searchRuleSections('Gebührenordnung für Ärzte', 'de-gop').length).toBeGreaterThan(0);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('looks up schedules by country and abbreviation', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
const germany = api.getByCountry('de');
|
|
|
|
|
const goae = api.findByAbbreviation('GOÄ');
|
|
|
|
|
const bema = api.findByAbbreviation('bema', 'DE');
|
|
|
|
|
const gnotkg = api.findByAbbreviation('GNotKG');
|
|
|
|
|
const gebueh = api.findByAbbreviation('GebüH');
|
|
|
|
|
|
|
|
|
|
expect(germany).toHaveLength(21);
|
|
|
|
|
expect(goae?.area).toEqual('Ärzte privat');
|
|
|
|
|
expect(bema?.area).toEqual('Zahnärzte GKV');
|
|
|
|
|
expect(gnotkg?.description).toContain('Notarkosten');
|
|
|
|
|
expect(gebueh?.description).toContain('keine amtliche verbindliche Gebührenordnung');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('searches schedules across searchable fields', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
const legalResults = api.search('Rechtsanwälte');
|
|
|
|
|
const hospitalResults = api.search('Krankenhausfälle');
|
|
|
|
|
const gkvResults = api.search('GKV', 'DE');
|
|
|
|
|
|
|
|
|
|
expect(legalResults.map((schedule) => schedule.abbreviation)).toEqual(['RVG']);
|
|
|
|
|
expect(hospitalResults.map((schedule) => schedule.abbreviation)).toEqual(['aG-DRG / FPV']);
|
|
|
|
|
expect(gkvResults.length).toBeGreaterThan(3);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('searches imported fee rows', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
const goaeConsultations = api.searchFeeRows('Fernsprecher', 'de-goae');
|
|
|
|
|
const courtDelivery = api.searchFeeRows('Persönliche Zustellung', 'de-gvkostg');
|
|
|
|
|
|
|
|
|
|
expect(goaeConsultations.length).toBeGreaterThan(1);
|
|
|
|
|
expect(courtDelivery.map((row) => row.code)).toContain('100');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('marks non-federal external sources explicitly', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
const ebm = api.getDataByScheduleId('de-ebm');
|
|
|
|
|
const bema = api.getDataByScheduleId('de-bema');
|
|
|
|
|
|
|
|
|
|
expect(ebm?.dataStatus).toEqual('external-source-pending');
|
|
|
|
|
expect(bema?.dataStatus).toEqual('external-source-pending');
|
|
|
|
|
expect(ebm?.source.url).toContain('kbv');
|
|
|
|
|
expect(bema?.source.url).toContain('kzbv');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tap.test('returns empty results for unknown lookups', async () => {
|
|
|
|
|
const api = new feeSchedules.FeeSchedules();
|
|
|
|
|
|
|
|
|
|
expect(api.getByCountry('AT')).toHaveLength(0);
|
|
|
|
|
expect(api.findByAbbreviation('UNKNOWN')).toBeUndefined();
|
|
|
|
|
expect(api.search('')).toHaveLength(0);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default tap.start();
|