mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 15:18:18 -05:00
Remove navigationRef from provingMachine (#1011)
This commit is contained in:
committed by
GitHub
parent
5de4aa8c9e
commit
99c5612e04
@@ -21,8 +21,6 @@ export type {
|
||||
ProofRequest,
|
||||
RegistrationInput,
|
||||
RegistrationStatus,
|
||||
SDKEvent,
|
||||
SDKEventMap,
|
||||
ScanMode,
|
||||
ScanOpts,
|
||||
ScanResult,
|
||||
@@ -43,9 +41,11 @@ export type { QRProofOptions } from './qr';
|
||||
export type { SdkErrorCategory } from './errors';
|
||||
|
||||
export { SCANNER_ERROR_CODES, notImplemented, sdkError } from './errors';
|
||||
export { SdkEvents } from './types/events';
|
||||
|
||||
export { SelfClientContext, SelfClientProvider, useSelfClient } from './context';
|
||||
|
||||
export { createSelfClient } from './client';
|
||||
export { createListenersMap, createSelfClient } from './client';
|
||||
|
||||
export { defaultConfig } from './config/defaults';
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { defaultConfig } from './config/defaults';
|
||||
import { mergeConfig } from './config/merge';
|
||||
import { notImplemented } from './errors';
|
||||
import { extractMRZInfo as parseMRZInfo } from './processing/mrz';
|
||||
import { SDKEvent, SDKEventMap, SdkEvents } from './types/events';
|
||||
import type {
|
||||
Adapters,
|
||||
Config,
|
||||
@@ -18,15 +19,12 @@ import type {
|
||||
RegistrationStatus,
|
||||
ScanOpts,
|
||||
ScanResult,
|
||||
SDKEvent,
|
||||
SDKEventMap,
|
||||
SelfClient,
|
||||
Unsubscribe,
|
||||
ValidationInput,
|
||||
ValidationResult,
|
||||
} from './types/public';
|
||||
import { TrackEventParams } from './types/public';
|
||||
|
||||
/**
|
||||
* Optional adapter implementations used when a consumer does not provide their
|
||||
* own. These defaults are intentionally minimal no-ops suitable for tests and
|
||||
@@ -51,6 +49,21 @@ const optionalDefaults: Required<Pick<Adapters, 'storage' | 'clock' | 'logger'>>
|
||||
|
||||
const REQUIRED_ADAPTERS = ['auth', 'scanner', 'network', 'crypto', 'documents'] as const;
|
||||
|
||||
export const createListenersMap = (): {
|
||||
map: Map<SDKEvent, Set<(p: any) => void>>;
|
||||
addListener: <E extends SDKEvent>(event: E, cb: (payload: SDKEventMap[E]) => any) => void;
|
||||
} => {
|
||||
const map = new Map<SDKEvent, Set<(p: any) => void>>();
|
||||
|
||||
const addListener = <E extends SDKEvent>(event: E, cb: (payload: SDKEventMap[E]) => void) => {
|
||||
const set = map.get(event) ?? new Set();
|
||||
set.add(cb as any);
|
||||
map.set(event, set);
|
||||
};
|
||||
|
||||
return { map, addListener };
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a fully configured {@link SelfClient} instance.
|
||||
*
|
||||
@@ -58,7 +71,15 @@ const REQUIRED_ADAPTERS = ['auth', 'scanner', 'network', 'crypto', 'documents']
|
||||
* provided configuration with sensible defaults. Missing optional adapters are
|
||||
* filled with benign no-op implementations.
|
||||
*/
|
||||
export function createSelfClient({ config, adapters }: { config: Config; adapters: Adapters }): SelfClient {
|
||||
export function createSelfClient({
|
||||
config,
|
||||
adapters,
|
||||
listeners,
|
||||
}: {
|
||||
config: Config;
|
||||
adapters: Adapters;
|
||||
listeners: Map<SDKEvent, Set<(p: any) => void>>;
|
||||
}): SelfClient {
|
||||
const cfg = mergeConfig(defaultConfig, config);
|
||||
|
||||
for (const name of REQUIRED_ADAPTERS) {
|
||||
@@ -66,17 +87,17 @@ export function createSelfClient({ config, adapters }: { config: Config; adapter
|
||||
}
|
||||
|
||||
const _adapters = { ...optionalDefaults, ...adapters };
|
||||
const listeners = new Map<SDKEvent, Set<(p: any) => void>>();
|
||||
const _listeners = new Map<SDKEvent, Set<(p: any) => void>>();
|
||||
|
||||
function on<E extends SDKEvent>(event: E, cb: (payload: SDKEventMap[E]) => void): Unsubscribe {
|
||||
const set = listeners.get(event) ?? new Set();
|
||||
const set = _listeners.get(event) ?? new Set();
|
||||
set.add(cb as any);
|
||||
listeners.set(event, set);
|
||||
_listeners.set(event, set);
|
||||
return () => set.delete(cb as any);
|
||||
}
|
||||
|
||||
function emit<E extends SDKEvent>(event: E, payload: SDKEventMap[E]): void {
|
||||
const set = listeners.get(event);
|
||||
const set = _listeners.get(event);
|
||||
if (!set) return;
|
||||
for (const cb of Array.from(set)) {
|
||||
try {
|
||||
@@ -87,6 +108,12 @@ export function createSelfClient({ config, adapters }: { config: Config; adapter
|
||||
}
|
||||
}
|
||||
|
||||
for (const [event, set] of listeners ?? []) {
|
||||
for (const cb of Array.from(set)) {
|
||||
on(event, cb);
|
||||
}
|
||||
}
|
||||
|
||||
async function scanDocument(opts: ScanOpts & { signal?: AbortSignal }): Promise<ScanResult> {
|
||||
return _adapters.scanner.scan(opts);
|
||||
}
|
||||
@@ -114,7 +141,7 @@ export function createSelfClient({ config, adapters }: { config: Config; adapter
|
||||
if (!adapters.network) throw notImplemented('network');
|
||||
if (!adapters.crypto) throw notImplemented('crypto');
|
||||
const timeoutMs = opts.timeoutMs ?? cfg.timeouts?.proofMs ?? defaultConfig.timeouts.proofMs;
|
||||
void _adapters.clock.sleep(timeoutMs!, opts.signal).then(() => emit('error', new Error('timeout')));
|
||||
void _adapters.clock.sleep(timeoutMs!, opts.signal).then(() => emit(SdkEvents.ERROR, new Error('timeout')));
|
||||
return {
|
||||
id: 'stub',
|
||||
status: 'pending',
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { createContext, type PropsWithChildren, useContext, useMemo } from 'react';
|
||||
|
||||
import { createSelfClient } from './client';
|
||||
import { SdkEvents } from './types/events';
|
||||
import type { Adapters, Config, SelfClient } from './types/public';
|
||||
|
||||
/**
|
||||
@@ -29,6 +30,10 @@ export interface SelfClientProviderProps {
|
||||
* be replaced with default no-op implementations.
|
||||
*/
|
||||
adapters: Adapters;
|
||||
/**
|
||||
* Map of event listeners.
|
||||
*/
|
||||
listeners: Map<SdkEvents, Set<(p: any) => void>>;
|
||||
}
|
||||
|
||||
export { SelfClientContext };
|
||||
@@ -40,8 +45,13 @@ export { SelfClientContext };
|
||||
* Consumers should ensure that `config` and `adapters` are referentially stable
|
||||
* (e.g. wrapped in `useMemo`) to avoid recreating the client on every render.
|
||||
*/
|
||||
export function SelfClientProvider({ config, adapters, children }: PropsWithChildren<SelfClientProviderProps>) {
|
||||
const client = useMemo(() => createSelfClient({ config, adapters }), [config, adapters]);
|
||||
export function SelfClientProvider({
|
||||
config,
|
||||
adapters,
|
||||
listeners,
|
||||
children,
|
||||
}: PropsWithChildren<SelfClientProviderProps>) {
|
||||
const client = useMemo(() => createSelfClient({ config, adapters, listeners }), [config, adapters, listeners]);
|
||||
|
||||
return <SelfClientContext.Provider value={client}>{children}</SelfClientContext.Provider>;
|
||||
}
|
||||
|
||||
@@ -5,16 +5,18 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import { SelfClientProvider } from '../context';
|
||||
import { SDKEvent } from '../types/events';
|
||||
import type { Adapters, Config } from '../types/public';
|
||||
|
||||
export interface SelfMobileSdkProps {
|
||||
config: Config;
|
||||
adapters: Adapters;
|
||||
listeners: Map<SDKEvent, Set<(p: any) => void>>;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const SelfMobileSdk = ({ config, adapters, children }: SelfMobileSdkProps) => (
|
||||
<SelfClientProvider config={config} adapters={adapters}>
|
||||
export const SelfMobileSdk = ({ config, adapters, listeners, children }: SelfMobileSdkProps) => (
|
||||
<SelfClientProvider config={config} adapters={adapters} listeners={listeners}>
|
||||
{children}
|
||||
</SelfClientProvider>
|
||||
);
|
||||
|
||||
@@ -22,8 +22,6 @@ export type {
|
||||
ProofRequest,
|
||||
RegistrationInput,
|
||||
RegistrationStatus,
|
||||
SDKEvent,
|
||||
SDKEventMap,
|
||||
ScanMode,
|
||||
ScanOpts,
|
||||
ScanResult,
|
||||
@@ -71,13 +69,15 @@ export { PassportCameraScreen } from './components/screens/PassportCameraScreen'
|
||||
|
||||
export { QRCodeScreen } from './components/screens/QRCodeScreen';
|
||||
|
||||
export { SdkEvents } from './types/events';
|
||||
|
||||
// Context and Client
|
||||
export { SelfClientContext, SelfClientProvider, useSelfClient } from './context';
|
||||
|
||||
// Components
|
||||
export { SelfMobileSdk } from './entry';
|
||||
|
||||
export { createSelfClient } from './client';
|
||||
export { createListenersMap, createSelfClient } from './client';
|
||||
|
||||
export { defaultConfig } from './config/defaults';
|
||||
|
||||
|
||||
35
packages/mobile-sdk-alpha/src/types/events.ts
Normal file
35
packages/mobile-sdk-alpha/src/types/events.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
|
||||
|
||||
import type { PassportData, Progress } from './public';
|
||||
|
||||
export enum SdkEvents {
|
||||
ERROR = 'ERROR',
|
||||
PROGRESS = 'PROGRESS',
|
||||
STATE = 'STATE',
|
||||
|
||||
PROVING_PASSPORT_DATA_NOT_FOUND = 'PROVING_PASSPORT_DATA_NOT_FOUND',
|
||||
PROVING_ACCOUNT_VERIFIED_SUCCESS = 'PROVING_ACCOUNT_VERIFIED_SUCCESS',
|
||||
PROVING_REGISTER_ERROR_OR_FAILURE = 'PROVING_REGISTER_ERROR_OR_FAILURE',
|
||||
PROVING_PASSPORT_NOT_SUPPORTED = 'PROVING_PASSPORT_NOT_SUPPORTED',
|
||||
PROVING_ACCOUNT_RECOVERY_REQUIRED = 'PROVING_ACCOUNT_RECOVERY_REQUIRED',
|
||||
}
|
||||
|
||||
export interface SDKEventMap {
|
||||
[SdkEvents.PROVING_PASSPORT_DATA_NOT_FOUND]: undefined;
|
||||
[SdkEvents.PROVING_ACCOUNT_VERIFIED_SUCCESS]: undefined;
|
||||
[SdkEvents.PROVING_REGISTER_ERROR_OR_FAILURE]: {
|
||||
hasValidDocument: boolean;
|
||||
};
|
||||
[SdkEvents.PROVING_PASSPORT_NOT_SUPPORTED]: {
|
||||
passportData: PassportData;
|
||||
};
|
||||
[SdkEvents.PROVING_ACCOUNT_RECOVERY_REQUIRED]: undefined;
|
||||
|
||||
[SdkEvents.PROGRESS]: Progress;
|
||||
[SdkEvents.STATE]: string;
|
||||
[SdkEvents.ERROR]: Error;
|
||||
}
|
||||
|
||||
export type SDKEvent = keyof SDKEventMap;
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
import type { DocumentCatalog, PassportData } from '@selfxyz/common/utils/types';
|
||||
|
||||
import { SDKEvent, SDKEventMap } from './events';
|
||||
|
||||
export type { PassportValidationCallbacks } from '../validation/document';
|
||||
export type { DocumentCatalog, PassportData };
|
||||
export interface Config {
|
||||
@@ -134,13 +136,6 @@ export interface RegistrationStatus {
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface SDKEventMap {
|
||||
progress: Progress;
|
||||
state: string;
|
||||
error: Error;
|
||||
}
|
||||
export type SDKEvent = keyof SDKEventMap;
|
||||
|
||||
export type ScanMode = 'mrz' | 'nfc' | 'qr';
|
||||
|
||||
export type ScanOpts =
|
||||
@@ -202,8 +197,8 @@ export interface SelfClient {
|
||||
trackEvent(event: string, payload?: TrackEventParams): void;
|
||||
getPrivateKey(): Promise<string | null>;
|
||||
hasPrivateKey(): Promise<boolean>;
|
||||
on<E extends SDKEvent>(event: E, cb: (payload: SDKEventMap[E]) => void): Unsubscribe;
|
||||
emit<E extends SDKEvent>(event: E, payload: SDKEventMap[E]): void;
|
||||
on<E extends SDKEvent>(event: E, cb: (payload?: SDKEventMap[E]) => void): Unsubscribe;
|
||||
emit<E extends SDKEvent>(event: E, payload?: SDKEventMap[E]): void;
|
||||
|
||||
loadDocumentCatalog(): Promise<DocumentCatalog>;
|
||||
loadDocumentById(id: string): Promise<PassportData | null>;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { badCheckDigitsMRZ, expectedMRZResult, invalidMRZ, mockAdapters, sampleM
|
||||
|
||||
describe('createSelfClient API', () => {
|
||||
it('creates a client instance with expected methods', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters });
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters, listeners: new Map() });
|
||||
|
||||
expect(typeof client.extractMRZInfo).toBe('function');
|
||||
expect(typeof client.registerDocument).toBe('function');
|
||||
@@ -17,7 +17,7 @@ describe('createSelfClient API', () => {
|
||||
});
|
||||
|
||||
it('parses MRZ data correctly', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters });
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters, listeners: new Map() });
|
||||
const info = client.extractMRZInfo(sampleMRZ);
|
||||
|
||||
expect(info.documentNumber).toBe(expectedMRZResult.documentNumber);
|
||||
@@ -28,6 +28,7 @@ describe('createSelfClient API', () => {
|
||||
const clientWithAllAdapters = createSelfClient({
|
||||
config: {},
|
||||
adapters: mockAdapters,
|
||||
listeners: new Map(),
|
||||
});
|
||||
|
||||
expect(clientWithAllAdapters).toBeDefined();
|
||||
@@ -35,12 +36,12 @@ describe('createSelfClient API', () => {
|
||||
});
|
||||
|
||||
it('throws MrzParseError for malformed MRZ input', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters });
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters, listeners: new Map() });
|
||||
expect(() => client.extractMRZInfo(invalidMRZ)).toThrowError(MrzParseError);
|
||||
});
|
||||
|
||||
it('flags invalid check digits', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters });
|
||||
const client = createSelfClient({ config: {}, adapters: mockAdapters, listeners: new Map() });
|
||||
const info = client.extractMRZInfo(badCheckDigitsMRZ);
|
||||
expect(info.validation?.overall).toBe(false);
|
||||
});
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { CryptoAdapter, DocumentsAdapter, NetworkAdapter, ScannerAdapter } from '../src';
|
||||
import { createSelfClient } from '../src/index';
|
||||
import { AuthAdapter } from '../src/types/public';
|
||||
import { createListenersMap, createSelfClient, SdkEvents } from '../src/index';
|
||||
import { AuthAdapter, PassportData } from '../src/types/public';
|
||||
|
||||
describe('createSelfClient', () => {
|
||||
// Test eager validation during client creation
|
||||
@@ -47,7 +47,11 @@ describe('createSelfClient', () => {
|
||||
});
|
||||
|
||||
it('creates client successfully with all required adapters', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: { scanner, network, crypto, documents, auth } });
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner, network, crypto, documents, auth },
|
||||
listeners: new Map(),
|
||||
});
|
||||
expect(client).toBeTruthy();
|
||||
});
|
||||
|
||||
@@ -56,6 +60,7 @@ describe('createSelfClient', () => {
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner: { scan: scanMock }, network, crypto, documents, auth },
|
||||
listeners: new Map(),
|
||||
});
|
||||
const result = await client.scanDocument({ mode: 'qr' });
|
||||
expect(result).toEqual({ mode: 'qr', data: 'self://ok' });
|
||||
@@ -68,6 +73,7 @@ describe('createSelfClient', () => {
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner: { scan: scanMock }, network, crypto, documents, auth },
|
||||
listeners: new Map(),
|
||||
});
|
||||
await expect(client.scanDocument({ mode: 'qr' })).rejects.toBe(err);
|
||||
});
|
||||
@@ -76,7 +82,11 @@ describe('createSelfClient', () => {
|
||||
const network = { http: { fetch: vi.fn() }, ws: { connect: vi.fn() } } as any;
|
||||
const crypto = { hash: vi.fn(), sign: vi.fn() } as any;
|
||||
const scanner = { scan: vi.fn() } as any;
|
||||
const client = createSelfClient({ config: {}, adapters: { network, crypto, scanner, documents, auth } });
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { network, crypto, scanner, documents, auth },
|
||||
listeners: new Map(),
|
||||
});
|
||||
const handle = await client.generateProof({ type: 'register', payload: {} });
|
||||
expect(handle.id).toBe('stub');
|
||||
expect(handle.status).toBe('pending');
|
||||
@@ -85,26 +95,49 @@ describe('createSelfClient', () => {
|
||||
});
|
||||
|
||||
it('emits and unsubscribes events', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: { scanner, network, crypto, documents, auth } });
|
||||
const cb = vi.fn();
|
||||
const originalSet = Map.prototype.set;
|
||||
let eventSet: Set<(p: any) => void> | undefined;
|
||||
Map.prototype.set = function (key: any, value: any) {
|
||||
if (key === 'progress') eventSet = value;
|
||||
return originalSet.call(this, key, value);
|
||||
};
|
||||
const unsub = client.on('progress', cb);
|
||||
Map.prototype.set = originalSet;
|
||||
const listeners = createListenersMap();
|
||||
|
||||
eventSet?.forEach(fn => fn({ step: 'one' }));
|
||||
expect(cb).toHaveBeenCalledWith({ step: 'one' });
|
||||
unsub();
|
||||
eventSet?.forEach(fn => fn({ step: 'two' }));
|
||||
expect(cb).toHaveBeenCalledTimes(1);
|
||||
const passportNotSupportedListener = vi.fn();
|
||||
const accountRecoveryChoiceListener = vi.fn();
|
||||
const anotherAccountRecoveryChoiceListener = vi.fn();
|
||||
|
||||
listeners.addListener(SdkEvents.PROVING_PASSPORT_NOT_SUPPORTED, passportNotSupportedListener);
|
||||
listeners.addListener(SdkEvents.PROVING_ACCOUNT_RECOVERY_REQUIRED, accountRecoveryChoiceListener);
|
||||
listeners.addListener(SdkEvents.PROVING_ACCOUNT_RECOVERY_REQUIRED, anotherAccountRecoveryChoiceListener);
|
||||
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner, network, crypto, documents, auth },
|
||||
listeners: listeners.map,
|
||||
});
|
||||
|
||||
client.emit(SdkEvents.PROVING_PASSPORT_NOT_SUPPORTED, { passportData: { mrz: 'test' } as PassportData });
|
||||
client.emit(SdkEvents.PROVING_ACCOUNT_RECOVERY_REQUIRED);
|
||||
client.emit(SdkEvents.PROVING_REGISTER_ERROR_OR_FAILURE, { hasValidDocument: true });
|
||||
|
||||
expect(accountRecoveryChoiceListener).toHaveBeenCalledTimes(1);
|
||||
expect(accountRecoveryChoiceListener).toHaveBeenCalledWith(undefined);
|
||||
expect(anotherAccountRecoveryChoiceListener).toHaveBeenCalledTimes(1);
|
||||
expect(anotherAccountRecoveryChoiceListener).toHaveBeenCalledWith(undefined);
|
||||
|
||||
expect(passportNotSupportedListener).toHaveBeenCalledWith({ passportData: { mrz: 'test' } });
|
||||
expect(passportNotSupportedListener).toHaveBeenCalledTimes(1);
|
||||
|
||||
client.emit(SdkEvents.PROVING_PASSPORT_NOT_SUPPORTED, { passportData: { mrz: 'test' } as PassportData });
|
||||
client.emit(SdkEvents.PROVING_ACCOUNT_RECOVERY_REQUIRED);
|
||||
client.emit(SdkEvents.PROVING_REGISTER_ERROR_OR_FAILURE, { hasValidDocument: true });
|
||||
|
||||
expect(passportNotSupportedListener).toHaveBeenCalledTimes(2);
|
||||
expect(accountRecoveryChoiceListener).toHaveBeenCalledTimes(2);
|
||||
expect(anotherAccountRecoveryChoiceListener).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('parses MRZ via client', () => {
|
||||
const client = createSelfClient({ config: {}, adapters: { scanner, network, crypto, documents, auth } });
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner, network, crypto, documents, auth },
|
||||
listeners: new Map(),
|
||||
});
|
||||
const sample = `P<UTOERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<\nL898902C36UTO7408122F1204159ZE184226B<<<<<10`;
|
||||
const info = client.extractMRZInfo(sample);
|
||||
expect(info.documentNumber).toBe('L898902C3');
|
||||
@@ -112,7 +145,11 @@ describe('createSelfClient', () => {
|
||||
});
|
||||
|
||||
it('returns stub registration status', async () => {
|
||||
const client = createSelfClient({ config: {}, adapters: { scanner, network, crypto, documents, auth } });
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner, network, crypto, documents, auth },
|
||||
listeners: new Map(),
|
||||
});
|
||||
await expect(client.registerDocument({} as any)).resolves.toEqual({
|
||||
registered: false,
|
||||
reason: 'SELF_REG_STATUS_STUB',
|
||||
@@ -131,6 +168,7 @@ describe('createSelfClient', () => {
|
||||
analytics: { trackEvent },
|
||||
auth: { getPrivateKey: () => Promise.resolve('stubbed-private-key') },
|
||||
},
|
||||
listeners: new Map(),
|
||||
});
|
||||
|
||||
client.trackEvent('test_event');
|
||||
@@ -146,6 +184,7 @@ describe('createSelfClient', () => {
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner, network, crypto, documents, auth: { getPrivateKey } },
|
||||
listeners: new Map(),
|
||||
});
|
||||
|
||||
await expect(client.getPrivateKey()).resolves.toBe('stubbed-private-key');
|
||||
@@ -155,6 +194,7 @@ describe('createSelfClient', () => {
|
||||
const client = createSelfClient({
|
||||
config: {},
|
||||
adapters: { scanner, network, crypto, documents, auth: { getPrivateKey } },
|
||||
listeners: new Map(),
|
||||
});
|
||||
await expect(client.hasPrivateKey()).resolves.toBe(true);
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ import { createSelfClient, defaultConfig, DocumentsAdapter, loadSelectedDocument
|
||||
const createMockSelfClientWithDocumentsAdapter = (documentsAdapter: DocumentsAdapter): SelfClient => {
|
||||
return createSelfClient({
|
||||
config: defaultConfig,
|
||||
listeners: new Map(),
|
||||
adapters: {
|
||||
auth: {
|
||||
getPrivateKey: async () => null,
|
||||
|
||||
@@ -20,7 +20,7 @@ function Consumer() {
|
||||
describe('SelfMobileSdk Entry Component', () => {
|
||||
it('provides client to children and enables MRZ parsing', () => {
|
||||
render(
|
||||
<SelfMobileSdk config={{}} adapters={mockAdapters}>
|
||||
<SelfMobileSdk config={{}} adapters={mockAdapters} listeners={new Map()}>
|
||||
<Consumer />
|
||||
</SelfMobileSdk>,
|
||||
);
|
||||
@@ -31,7 +31,7 @@ describe('SelfMobileSdk Entry Component', () => {
|
||||
it('renders children correctly', () => {
|
||||
const testMessage = 'Test Child Component';
|
||||
render(
|
||||
<SelfMobileSdk config={{}} adapters={mockAdapters}>
|
||||
<SelfMobileSdk config={{}} adapters={mockAdapters} listeners={new Map()}>
|
||||
<div>{testMessage}</div>
|
||||
</SelfMobileSdk>,
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ import { renderHook } from '@testing-library/react';
|
||||
describe('SelfClientProvider Context', () => {
|
||||
it('provides client through context with MRZ parsing capability', () => {
|
||||
const wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<SelfClientProvider config={{}} adapters={mockAdapters}>
|
||||
<SelfClientProvider config={{}} adapters={mockAdapters} listeners={new Map()}>
|
||||
{children}
|
||||
</SelfClientProvider>
|
||||
);
|
||||
@@ -38,8 +38,10 @@ describe('SelfClientProvider Context', () => {
|
||||
const spy = vi.spyOn(clientModule, 'createSelfClient');
|
||||
const config = {};
|
||||
const adapters = mockAdapters;
|
||||
const listeners = new Map();
|
||||
|
||||
const wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<SelfClientProvider config={config} adapters={adapters}>
|
||||
<SelfClientProvider config={config} adapters={adapters} listeners={listeners}>
|
||||
{children}
|
||||
</SelfClientProvider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user