ReviewOS

also looking at this

craft-native/craft

test(ios): install the Watch-enabled app and read the APNs environment it signs

#218
Merged glennmichael123 wants to merge fix/ios-apns-environment-resolved into main
6 files +248 -12
packages/ios/scripts/watch-bundle.test.tsadded+61-0
Changes to packages/ios/scripts/watch-bundle.test.ts
@@ -0,0 +1,61 @@
1import { afterEach, describe, expect, it } from 'bun:test'
2import { mkdirSync, mkdtempSync, rmSync } from 'node:fs'
3import { tmpdir } from 'node:os'
4import { join } from 'node:path'
5import { watchCompanionProblems } from './watch-bundle'
6
7const roots: string[] = []
8afterEach(() => {
9 for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
10})
11
12/** A built app's directory shape, with plists served from memory. */
13function bundle(parts: { watch?: boolean, extension?: boolean }) {
14 const root = mkdtempSync(join(tmpdir(), 'craft-watch-bundle-'))
15 roots.push(root)
16 const app = join(root, 'Probe.app')
17 mkdirSync(app, { recursive: true })
18 if (parts.watch) mkdirSync(join(app, 'Watch', 'ProbeWatch.app'), { recursive: true })
19 if (parts.extension) mkdirSync(join(app, 'Watch', 'ProbeWatch.app', 'PlugIns', 'ProbeWatchExtension.appex'), { recursive: true })
20 return app
21}
22
23const complete = (path: string): Record<string, unknown> | null =>
24 path.includes('.appex')
25 ? { NSExtension: { NSExtensionPointIdentifier: 'com.apple.watchkit' } }
26 : { WKWatchKitApp: true, WKCompanionAppBundleIdentifier: 'dev.craft.probe' }
27
28describe('watchCompanionProblems', () => {
29 it('passes the WatchKit 2 companion the generator now emits', () => {
30 expect(watchCompanionProblems(bundle({ watch: true, extension: true }), 'Probe', complete)).toEqual([])
31 })
32
33 it('names #194: a Watch app with no WatchKit marker', () => {
34 const noMarker = (path: string) => (path.includes('.appex') ? complete(path) : { WKCompanionAppBundleIdentifier: 'dev.craft.probe' })
35 expect(watchCompanionProblems(bundle({ watch: true, extension: true }), 'Probe', noMarker)).toEqual([
36 'Watch/ProbeWatch.app sets neither WKWatchKitApp nor WKApplication to true, so iOS will not install it (#194)',
37 ])
38 })
39
40 it('accepts WKApplication, the single-target marker, in place of WKWatchKitApp', () => {
41 const modern = (path: string) => (path.includes('.appex') ? complete(path) : { WKApplication: true })
42 expect(watchCompanionProblems(bundle({ watch: true, extension: true }), 'Probe', modern)).toEqual([])
43 })
44
45 it('names #195: a Watch app with no extension inside it', () => {
46 expect(watchCompanionProblems(bundle({ watch: true }), 'Probe', complete)).toEqual([
47 'Watch/ProbeWatch.app has no PlugIns/ProbeWatchExtension.appex, so it is not a WatchKit 2 app (#195)',
48 ])
49 })
50
51 it('says when there is no Watch app to check at all', () => {
52 expect(watchCompanionProblems(bundle({}), 'Probe', complete)).toEqual(['Probe.app embeds no Watch/ProbeWatch.app'])
53 })
54
55 it('checks the extension is a WatchKit extension, not merely present', () => {
56 const wrongPoint = (path: string) => (path.includes('.appex') ? { NSExtension: { NSExtensionPointIdentifier: 'com.apple.widgetkit-extension' } } : complete(path))
57 expect(watchCompanionProblems(bundle({ watch: true, extension: true }), 'Probe', wrongPoint)).toEqual([
58 'ProbeWatchExtension.appex declares extension point "com.apple.widgetkit-extension", not com.apple.watchkit',
59 ])
60 })
61})