import { describe, expect, test } from 'bun:test'; import { availabilityChange, iapAttributeChanges, iapLocalizationChanges } from '../cli/apple/iap'; describe('iapLocalizationChanges', () => { const store = [{ id: 'l1', locale: 'en-US', name: 'Coins', description: 'A pile of coins' }, { id: 'l2', locale: 'de-DE', name: 'Muenzen', description: 'Viele' }]; test('no difference means no change', () => { expect(iapLocalizationChanges(store, [{ locale: 'en-US', name: 'Coins', description: 'A pile of coins' }])).toEqual([]); }); test('only the changed attribute is patched', () => { const r = iapLocalizationChanges(store, [{ locale: 'en-US', name: 'Coins', description: 'More coins' }]); expect(r).toHaveLength(1); expect(r[0]!.id).toBe('l1'); expect(r[0]!.attrs).toEqual({ description: 'More coins' }); expect(r[0]!.note).toBe('localization en-US: description "A pile of coins" -> "More coins"'); }); test('name and description, long text truncated, missing locales skipped', () => { const long = 'x'.repeat(100); const r = iapLocalizationChanges(store, [{ locale: 'de-DE', name: 'Gold', description: long }, { locale: 'fr-FR', name: 'a', description: 'b' }]); expect(r).toHaveLength(1); expect(r[0]!.attrs).toEqual({ name: 'Gold', description: long }); expect(r[0]!.note).toContain('name "Muenzen" -> "Gold"'); expect(r[0]!.note.length).toBeLessThan(120); }); }); describe('iapAttributeChanges', () => { test('equal attributes: nothing', () => { const r = iapAttributeChanges({ name: 'com.example.coins', reviewNote: 'n', familySharable: false }, { name: 'com.example.coins', reviewNote: 'n', familySharable: false }); expect(r.patch).toEqual({}); expect(r.notes).toEqual([]); expect(r.familyMismatch).toBeNull(); }); test('referenceName and reviewNote differ', () => { const r = iapAttributeChanges({ name: 'Old', reviewNote: 'a' }, { name: 'New', reviewNote: 'b' }); expect(r.patch).toEqual({ name: 'New', reviewNote: 'b' }); expect(r.notes).toHaveLength(2); }); test('reviewNote not set in the config is not compared', () => { expect(iapAttributeChanges({ name: 'A', reviewNote: 'kept' }, { name: 'A' }).patch).toEqual({}); }); test('familySharable can be turned on, never off', () => { expect(iapAttributeChanges({ name: 'A', familySharable: false }, { name: 'A', familySharable: true }).patch).toEqual({ familySharable: true }); const off = iapAttributeChanges({ name: 'A', familySharable: true }, { name: 'A', familySharable: false }); expect(off.patch).toEqual({}); expect(off.familyMismatch).toContain('familySharable'); }); }); describe('availabilityChange', () => { const all = ['USA', 'DEU', 'FRA']; test('complete availability with new territories: no change', () => { expect(availabilityChange({ territories: ['USA', 'DEU', 'FRA', 'ITA'], newTerritories: true }, all)).toBeNull(); }); test('fewer territories', () => { const r = availabilityChange({ territories: ['USA'], newTerritories: true }, all); expect(r?.note).toBe('availability: 1 -> 3 territories'); }); test('new territories off', () => { expect(availabilityChange({ territories: all, newTerritories: false }, all)?.note).toContain('new territories on'); }); test('no availability at all', () => { expect(availabilityChange(null, all)).toMatchObject({ from: 0, to: 3 }); }); });