Skip to content

FakeNativeWorkouts — @gj-kit/expo-workouts

A public interface from @gj-kit/expo-workouts/testing. The signature below is taken directly from the 0.1.1 release declaration.

import { FakeNativeWorkouts } from '@gj-kit/expo-workouts/testing';
/** An in-memory `NativeWorkoutsModule`. THIS is what tests drive; the real JS layer runs on top. */
interface FakeNativeWorkouts extends NativeWorkoutsModule {
setAvailability(availability: Availability): void;
setAuthorization(state: AuthorizationState): void;
/** Grant scopes directly — the shape the fake actually stores. */
authorize(grants: FakeScopeGrants): void;
/** What this build DECLARED. Requesting outside it is `invalidArgument` naming the missing prop. */
setDeclared(declared: FakeScopeGrants): void;
/** How the NEXT `requestPermissions` ends. `'inconclusive'` is f120's onboarding "Go back". */
setNextPermissionOutcome(outcome: FakePermissionOutcome): void;
/** Returns the native id. */
addWorkout(workout: FakeWorkoutInput): string;
/** Platform-faithful replacement: iOS mints a NEW native id and emits `removed{replaced:true}`
* in the same drain batch; Android keeps the SAME id and emits only an upsertion change. */
replaceWorkout(nativeId: string, patch: Partial<FakeWorkoutInput>): string;
removeWorkout(nativeId: string): void;
/** HealthKit purging a deletion record before we drain it — the workout vanishes with no `removed`. */
purgeDeletion(nativeId: string): void;
/** Android: emit an upsertion change carrying an UNCHANGED record — the undetectable stale-version no-op. */
emitNoOpUpsertion(nativeId: string): void;
/** Force `reset: true` with a chosen reason on the next sync — reaches all six `CursorResetReason`s. */
expireCursor(reason?: CursorResetReason | undefined): void;
setRouteAccess(access: RouteAccess): void;
/** Process importance — the only way to reach the background-route path without a device. */
setForeground(foreground: boolean): void;
/** Health Connect first-run onboarding: foreign routes read `consentRequired` while this is false
* even with the permission held and the app in the foreground. */
setOnboarded(onboarded: boolean): void;
/** iOS: protected data unavailable — the `storeLocked` pre-check path. */
setStoreLocked(locked: boolean): void;
/** iOS: make the next save return (nil workout, nil error) — the case Phase 0 could not reproduce. */
nextSaveIsPendingUnlock(): void;
/** f102: every read primitive raises Health Connect's overloaded `errorCode 7` while this is on. */
setRateLimited(rateLimited: boolean): void;
/** f109: `readMetricRecords` returns NOTHING, so every total stays `undefined` — never `0`. */
setMetricsMissing(missing: boolean): void;
/** Make the next call to one seam primitive throw a platform-shaped payload, so the error MAPPING
* (not just the mapped result) is what the test exercises. */
failNext(primitive: keyof NativeWorkoutsModule, payload: NativePayloadDto): void;
/**
* f104: make the next call to one seam primitive **never settle**. The Intent-overflow failure is
* not an error — the ActivityResult callback simply never fires — so the only faithful fake is a
* promise that hangs and lets the caller's timeout be the thing under test.
*/
hangNext(primitive: keyof NativeWorkoutsModule): void;
/** Unreleased route handles. A test asserts this is 0 after every `for await`. */
readonly openRouteHandles: number;
readonly calls: readonly {
readonly fn: keyof NativeWorkoutsModule;
readonly atMs: number;
}[];
}

This declaration is the source of truth for parameters, optionality, generics, return values, and public union/type contracts. Check the package golden path and this subpath’s import conditions for required environment, permission, and error boundaries before calling it.

  • Package: @gj-kit/expo-workouts
  • Version: 0.1.1
  • Public entry: ./testing
  • Source: GitHub