import { describe, expect, it } from 'vitest' import { resolveMessage, renderTemplate, resolveSetting, type MessageRow, type SettingRow } from '@sims/config' const CTX = { tenantId: 't1', storeId: 's1', counterId: 'c1', userId: 'u1' } describe('settings hierarchy — nearest scope wins', () => { const rows: SettingRow[] = [ { scopeType: 'system', scopeId: '', key: 'discount.capBp', value: '1000' }, { scopeType: 'tenant', scopeId: 't1', key: 'discount.capBp', value: '1500' }, { scopeType: 'store', scopeId: 's1', key: 'discount.capBp', value: '500' }, ] it('store overrides tenant overrides system', () => { expect(resolveSetting(rows, 'discount.capBp', CTX, '2026-07-09')).toEqual({ value: '500', scope: 'store', }) }) it('falls through when the nearer scope has no row', () => { const noStore = { ...CTX, storeId: 's-other' } expect(resolveSetting(rows, 'discount.capBp', noStore, '2026-07-09')?.value).toBe('1500') }) it('system default applies when nothing overrides', () => { expect(resolveSetting(rows, 'discount.capBp', { tenantId: 'tx' }, '2026-07-09')?.value).toBe('1000') }) it('returns undefined for unknown keys', () => { expect(resolveSetting(rows, 'nope', CTX, '2026-07-09')).toBeUndefined() }) }) describe('settings — effective dating', () => { const rows: SettingRow[] = [ { scopeType: 'system', scopeId: '', key: 'gst.roundToRupee', value: 'true' }, { scopeType: 'system', scopeId: '', key: 'gst.roundToRupee', value: 'false', effectiveFrom: '2026-08-01' }, ] it('picks the latest row not after the target date', () => { expect(resolveSetting(rows, 'gst.roundToRupee', {}, '2026-07-31')?.value).toBe('true') expect(resolveSetting(rows, 'gst.roundToRupee', {}, '2026-08-01')?.value).toBe('false') }) }) describe('message catalog — language fallback chain', () => { const rows: MessageRow[] = [ { code: 'BILL_ESHARE', channel: 'whatsapp', lang: 'en', template: 'Hi {name}, your bill of {amount}' }, { code: 'BILL_ESHARE', channel: 'whatsapp', lang: 'hi', template: 'नमस्ते {name}, आपका बिल {amount}' }, { code: 'BILL_ESHARE', channel: 'whatsapp', lang: 'ml', template: 'നമസ്കാരം {name}, ബിൽ {amount}' }, ] it('prefers user language, then store, then English', () => { expect(resolveMessage(rows, 'BILL_ESHARE', 'whatsapp', { userLang: 'ml' })?.lang).toBe('ml') expect(resolveMessage(rows, 'BILL_ESHARE', 'whatsapp', { userLang: 'ta', storeLang: 'hi' })?.lang).toBe('hi') expect(resolveMessage(rows, 'BILL_ESHARE', 'whatsapp', { userLang: 'ta' })?.lang).toBe('en') }) it('returns undefined for unknown codes (caller surfaces the raw key in dev)', () => { expect(resolveMessage(rows, 'NOPE', 'whatsapp', {})).toBeUndefined() }) it('renders placeholders; missing vars stay visible', () => { expect(renderTemplate('Hi {name}, bill {amount}', { name: 'Lakshmi', amount: '₹1,431.00' })).toBe( 'Hi Lakshmi, bill ₹1,431.00', ) expect(renderTemplate('Hi {name}', {})).toBe('Hi {name}') }) })