// A macOS App Store version is checked against the Mac screenshot set only (APP_DESKTOP), never the iPhone / iPad // sets: validate / release plan showed 2 false blockers per locale for an app whose editable version was macOS. // Also: a non-macOS machine without the certificates' keys must not be told to create another certificate. import { describe, expect, test } from 'bun:test'; import { requiredDisplayTypes } from '../cli/apple/screenshots'; import { pickCertificate, type ApiCert } from '../cli/lib/signing'; import { appleRules, type AppleSnapshot } from '../cli/lib/validate-rules'; const snap = (platform: string, apple: Parameters[0], shots: Record): AppleSnapshot => ({ version: { versionString: '1.0.0', state: 'PREPARE_FOR_SUBMISSION', platform }, build: null, expectedLocales: ['en-US', 'de-DE'], locales: ['en-US', 'de-DE'].map(locale => ({ locale, name: 'n', subtitle: 's', description: 'd', keywords: 'k', screenshots: shots })), requiredDisplayTypes: requiredDisplayTypes(apple, platform), mac: !!apple?.mac, macVersion: platform === 'MAC_OS', reviewDetail: null, ageRating: null, priceSchedule: true, availability: true, iaps: [], expectedProducts: [], privacyUrl: { url: 'https://example.com/privacy', status: 200 }, } as AppleSnapshot); const shotBlockers = (s: AppleSnapshot) => appleRules(s).filter(x => x.level === 'blocker' && x.code.startsWith('screenshots')); describe('required screenshot types per platform', () => { test('macOS: the Mac set with apple.mac, nothing else; apple.screenshotTypes stays the iOS list', () => { expect(requiredDisplayTypes({ ipad: true, mac: true }, 'MAC_OS')).toEqual(['APP_DESKTOP']); expect(requiredDisplayTypes({ ipad: true, mac: true, screenshotTypes: ['APP_IPHONE_67'] }, 'MAC_OS')).toEqual(['APP_DESKTOP']); expect(requiredDisplayTypes({ ipad: true }, 'MAC_OS')).toEqual([]); expect(requiredDisplayTypes({ ipad: true, mac: true, screenshotTypes: ['APP_IPHONE_67'] })).toEqual(['APP_IPHONE_67']); expect(requiredDisplayTypes({ ipad: true })).toEqual(['APP_IPHONE_61', 'APP_IPAD_PRO_3GEN_129']); expect(requiredDisplayTypes({ ipad: true }, 'TV_OS')).toEqual([]); }); test('a macOS version with Mac screenshots and no iPhone / iPad ones has no screenshot blocker', () => { expect(shotBlockers(snap('MAC_OS', { ipad: true, mac: true }, { APP_DESKTOP: 3 }))).toEqual([]); }); test('a macOS version without the Mac set is missing APP_DESKTOP only', () => { const b = shotBlockers(snap('MAC_OS', { ipad: true, mac: true }, {})); expect(b.map(x => x.msg)).toEqual(['en-US: no APP_DESKTOP screenshots', 'de-DE: no APP_DESKTOP screenshots']); }); test('an iOS version still needs the iPhone and iPad sets', () => { expect(shotBlockers(snap('IOS', { ipad: true, mac: true }, { APP_DESKTOP: 3 })).length).toBe(4); }); }); describe('certificate without a local key', () => { const c = (id: string): ApiCert => ({ id, attributes: { certificateType: 'DISTRIBUTION', activated: true, expirationDate: new Date(Date.now() + 400 * 864e5).toISOString() } }); test('macOS: a new one or the .p12 import', () => { expect(pickCertificate([c('a')], 'DISTRIBUTION', () => false, Date.now(), 'darwin').why).toContain('a new one is needed'); }); test('Windows / Linux: build on the Mac, never a new certificate', () => { for (const p of ['win32', 'linux']) { const why = pickCertificate([c('a')], 'DISTRIBUTION', () => false, Date.now(), p).why; expect(why).toContain('none of their private keys'); expect(why).toContain('cannot build or sign for Apple'); expect(why).toContain('Do not create another certificate'); expect(why).not.toContain('a new one is needed'); } }); });