74 lines
4.4 KiB
TypeScript
74 lines
4.4 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
import { campaignDiff } from '../cli/apple/offer-codes';
|
|
import { winBackDiff } from '../cli/apple/win-back';
|
|
import { cppDeepLinkReq, type AppEventDef, eventAttrDiff, eventPatchReq, extraCppLocales } from '../cli/lib/cpp-events';
|
|
import { missingVersionLocales } from '../cli/apple/screenshots';
|
|
import { dataSafetyDryNote } from '../cli/play/data-safety';
|
|
|
|
describe('offer code campaign drift', () => {
|
|
const cur = { eligibility: ['NON_SPENDER'], prices: [{ territory: 'USA', pointId: 'p1' }, { territory: 'DEU', pointId: 'p2' }] };
|
|
test('equal: no differences', () => {
|
|
expect(campaignDiff(cur, { eligibility: ['NON_SPENDER'], free: false, prices: cur.prices })).toEqual([]);
|
|
});
|
|
test('eligibility, territories, price and mode differ', () => {
|
|
const d = campaignDiff(cur, { eligibility: ['NON_SPENDER', 'CHURNED_SPENDER'], free: false, prices: [{ territory: 'USA', pointId: 'p9' }, { territory: 'FRA', pointId: 'p3' }] });
|
|
expect(d.join('|')).toContain('eligibility');
|
|
expect(d.join('|')).toContain('+1 (FRA)');
|
|
expect(d.join('|')).toContain('-1 (DEU)');
|
|
expect(d.join('|')).toContain('prices differ in 1 territory');
|
|
expect(campaignDiff(cur, { eligibility: ['NON_SPENDER'], free: true, prices: cur.prices }).join()).toContain('mode paid -> free');
|
|
});
|
|
});
|
|
|
|
describe('win-back drift', () => {
|
|
const want = { id: 'wb', type: 'pay-as-you-go', usd: 2.99, paidMonths: 3, lapsedMonths: { min: 1, max: 12 }, start: '2027-01-01', end: '2027-02-01' } as const;
|
|
test('equal', () => expect(winBackDiff({ offerMode: 'PAY_AS_YOU_GO', startDate: '2027-01-01', endDate: '2027-02-01' }, 2.99, want)).toEqual([]));
|
|
test('mode, price, dates', () => {
|
|
const d = winBackDiff({ offerMode: 'FREE_TRIAL', startDate: '2027-01-05', endDate: null }, 1.99, want);
|
|
expect(d.length).toBe(4);
|
|
expect(winBackDiff({ offerMode: 'PAY_AS_YOU_GO', startDate: '2027-01-01', endDate: '2027-02-01' }, undefined, want)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('event attribute drift', () => {
|
|
const ev: AppEventDef = { referenceName: 'Spring', badge: 'CHALLENGE', priority: 'high', schedule: { publishStart: '2027-03-01T00:00:00Z', eventStart: '2027-03-05T00:00:00Z', eventEnd: '2027-03-10T00:00:00Z' }, listings: {} };
|
|
const now = { badge: 'CHALLENGE', priority: 'HIGH', purpose: 'APPROPRIATE_FOR_ALL_USERS', territorySchedules: [{ territories: ['USA'], publishStart: '2027-03-01T00:00:00.000Z', eventStart: '2027-03-05T00:00:00.000Z', eventEnd: '2027-03-10T00:00:00.000Z' }] };
|
|
test('same instants in another format: no drift', () => {
|
|
const d = eventAttrDiff(ev, now);
|
|
expect(d.lines).toEqual([]);
|
|
expect(eventPatchReq('e1', 'Spring', d.attrs, d.lines)).toBeNull();
|
|
});
|
|
test('badge, priority and end differ: one PATCH', () => {
|
|
const d = eventAttrDiff({ ...ev, badge: 'MAJOR_UPDATE', priority: 'normal', schedule: { ...ev.schedule, eventEnd: '2027-03-12T00:00:00Z' } }, now);
|
|
expect(d.lines.length).toBe(3);
|
|
const r = eventPatchReq('e1', 'Spring', d.attrs, d.lines)!;
|
|
expect(r.method).toBe('PATCH');
|
|
expect(r.path).toBe('/v1/appEvents/e1');
|
|
expect((r.body as { data: { attributes: Record<string, unknown> } }).data.attributes.territorySchedules).toHaveLength(1);
|
|
});
|
|
});
|
|
|
|
describe('custom product page drift', () => {
|
|
test('deep link removed is cleared', () => {
|
|
const r = cppDeepLinkReq('v1', 'Page', undefined, 'example://old')!;
|
|
expect(r.note).toContain('removed');
|
|
expect((r.body as { data: { attributes: { deepLink: unknown } } }).data.attributes.deepLink).toBeNull();
|
|
});
|
|
test('equal or both empty: nothing', () => {
|
|
expect(cppDeepLinkReq('v1', 'Page', 'example://a', 'example://a')).toBeNull();
|
|
expect(cppDeepLinkReq('v1', 'Page', undefined, null)).toBeNull();
|
|
});
|
|
test('extra locales on the page', () => expect(extraCppLocales(['en-US', 'fr-FR'], ['en-US'])).toEqual(['fr-FR']));
|
|
});
|
|
|
|
describe('screenshots and data safety notes', () => {
|
|
test('version without a localization for a config language', () => {
|
|
expect(missingVersionLocales([{ apple: 'en-US' }, { apple: 'tr' }, {}], ['en-US'])).toEqual(['tr']);
|
|
});
|
|
test('data safety dry note says Play cannot be read and --force re-sends', () => {
|
|
const n = dataSafetyDryNote({ at: '2027-01-01T10:00:00Z' });
|
|
expect(n).toContain('no read API');
|
|
expect(n).toContain('--force');
|
|
expect(dataSafetyDryNote(null)).toContain('none recorded');
|
|
});
|
|
});
|