test(07-01): FS1-FS9 fullscreen gates + mock satisfies the grown contract

- telegram-mock gains requestFullscreen/exitFullscreen/lockOrientation/unlockOrientation + __fullscreen* state fields in the SAME change as the contract (contract + fake + test together)
- FS1-FS7: both-halves guard vectors, the throwing-platform path (FS4), the exit mirror (FS5), the event categories (FS6), the old-client fallback (FS7, SC2.e)
- FS8: safeAreaChanged re-resolution through the union authority, with a minimal document stub restored in finally
- FS9: comment-stripped source-scan ban on the DOM-fullscreen/orientation-lock escape hatches (T-07-10) + the guard-is-not-optional assertion
- suite 157 passed, 0 failed (148 baseline + 9); mutation check: neutering the 8.0 guard fails FS2/FS5
This commit is contained in:
araharah-executor
2026-10-25 03:45:49 +08:00
parent 95ad3eab34
commit aec8b07530
2 changed files with 299 additions and 0 deletions
+29
View File
@@ -93,6 +93,11 @@ interface MockWebApp extends TelegramWebAppLike {
__events: Map<string, Array<() => void>>;
__backButtonClicks: Array<() => void>;
__homeScreenAdded: number;
__fullscreenRequested: number;
__fullscreenExited: number;
__orientationLocked: number;
__orientationUnlocked: number;
__isFullscreen: boolean;
}
/* ————— Web-Crypto dev signer (mirror of bot/src/security/initdata.ts's HMAC path) ————— */
@@ -415,6 +420,11 @@ export function installMockWebApp(options: MockOptions = {}): TelegramWebAppLike
__events: events,
__backButtonClicks: backButtonClicks,
__homeScreenAdded: 0,
__fullscreenRequested: 0,
__fullscreenExited: 0,
__orientationLocked: 0,
__orientationUnlocked: 0,
__isFullscreen: false,
isVersionAtLeast(v: string) {
return versionAtLeast(version, v);
},
@@ -428,6 +438,25 @@ export function installMockWebApp(options: MockOptions = {}): TelegramWebAppLike
checkHomeScreenStatus(cb: (status: HomeScreenStatus) => void) {
setTimeout(() => cb(homeScreenStatus), 0);
},
// PX-04/D-03 (07-01): the fullscreen members ship with the contract —
// the mock satisfies the grown contract in the SAME change ("contract +
// fake + test together"). The ?mock= profile's `version` below 8.0 makes
// the fullscreen path a silent no-op via the version guard — never
// hard-coded, the mock's own versionAtLeast drives the guard.
requestFullscreen() {
fake.__fullscreenRequested = (fake.__fullscreenRequested ?? 0) + 1;
fake.__isFullscreen = true;
},
exitFullscreen() {
fake.__fullscreenExited = (fake.__fullscreenExited ?? 0) + 1;
fake.__isFullscreen = false;
},
lockOrientation() {
fake.__orientationLocked = (fake.__orientationLocked ?? 0) + 1;
},
unlockOrientation() {
fake.__orientationUnlocked = (fake.__orientationUnlocked ?? 0) + 1;
},
onEvent(event: string, cb: () => void) {
const list = events.get(event) ?? [];
list.push(cb);