mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
[SELF-1952] UI: Create KYC verified screen; prompt to enter proving flow (#1681)
* first pass at kyc verified screen * finalize kyc verified design * add queue buffer
This commit is contained in:
@@ -85,6 +85,7 @@ describe('navigation', () => {
|
||||
'Home',
|
||||
'IDPicker',
|
||||
'IdDetails',
|
||||
'KYCVerified',
|
||||
'KycSuccess',
|
||||
'Loading',
|
||||
'ManageDocuments',
|
||||
|
||||
511
app/tests/src/providers/notificationTrackingProvider.test.tsx
Normal file
511
app/tests/src/providers/notificationTrackingProvider.test.tsx
Normal file
@@ -0,0 +1,511 @@
|
||||
// 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 React from 'react';
|
||||
import type { FirebaseMessagingTypes } from '@react-native-firebase/messaging';
|
||||
import { render, waitFor } from '@testing-library/react-native';
|
||||
|
||||
import { navigationRef } from '@/navigation';
|
||||
import { NotificationTrackingProvider } from '@/providers/notificationTrackingProvider';
|
||||
import * as analytics from '@/services/analytics';
|
||||
|
||||
// Mock Firebase messaging
|
||||
const mockOnNotificationOpenedApp = jest.fn();
|
||||
const mockGetInitialNotification = jest.fn();
|
||||
|
||||
jest.mock('@react-native-firebase/messaging', () => {
|
||||
return jest.fn(() => ({
|
||||
onNotificationOpenedApp: mockOnNotificationOpenedApp,
|
||||
getInitialNotification: mockGetInitialNotification,
|
||||
}));
|
||||
});
|
||||
|
||||
// Mock navigation
|
||||
jest.mock('@/navigation', () => ({
|
||||
navigationRef: {
|
||||
isReady: jest.fn(),
|
||||
navigate: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock analytics
|
||||
jest.mock('@/services/analytics', () => ({
|
||||
trackEvent: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock analytics constants
|
||||
jest.mock('@selfxyz/mobile-sdk-alpha/constants/analytics', () => ({
|
||||
NotificationEvents: {
|
||||
BACKGROUND_NOTIFICATION_OPENED: 'BACKGROUND_NOTIFICATION_OPENED',
|
||||
COLD_START_NOTIFICATION_OPENED: 'COLD_START_NOTIFICATION_OPENED',
|
||||
},
|
||||
}));
|
||||
|
||||
const mockNavigationRef = navigationRef as jest.Mocked<typeof navigationRef>;
|
||||
|
||||
describe('NotificationTrackingProvider', () => {
|
||||
const mockUserId = '19f21362-856a-4606-88e1-fa306036978f';
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockNavigationRef.isReady.mockReturnValue(true);
|
||||
});
|
||||
|
||||
it('should render children without errors', () => {
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
const { getByTestId } = render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test Child</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
expect(getByTestId('child')).toHaveTextContent('Test Child');
|
||||
});
|
||||
|
||||
describe('Background notification (onNotificationOpenedApp)', () => {
|
||||
it('should navigate to KYCVerified when notification type is kyc_result and status is approved', async () => {
|
||||
let notificationHandler:
|
||||
| ((message: FirebaseMessagingTypes.RemoteMessage) => void)
|
||||
| null = null;
|
||||
|
||||
mockOnNotificationOpenedApp.mockImplementation(handler => {
|
||||
notificationHandler = handler;
|
||||
return jest.fn(); // Return unsubscribe function
|
||||
});
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
expect(mockOnNotificationOpenedApp).toHaveBeenCalled();
|
||||
|
||||
// Simulate notification tap
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'approved',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
if (notificationHandler) {
|
||||
notificationHandler(remoteMessage);
|
||||
}
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalledWith(
|
||||
'BACKGROUND_NOTIFICATION_OPENED',
|
||||
{
|
||||
messageId: 'test-message-id',
|
||||
type: 'kyc_result',
|
||||
actionId: undefined,
|
||||
},
|
||||
);
|
||||
|
||||
expect(mockNavigationRef.navigate).toHaveBeenCalledWith('KYCVerified', {
|
||||
status: 'approved',
|
||||
userId: mockUserId,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not navigate when status is retry', async () => {
|
||||
let notificationHandler:
|
||||
| ((message: FirebaseMessagingTypes.RemoteMessage) => void)
|
||||
| null = null;
|
||||
|
||||
mockOnNotificationOpenedApp.mockImplementation(handler => {
|
||||
notificationHandler = handler;
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'retry',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
if (notificationHandler) {
|
||||
notificationHandler(remoteMessage);
|
||||
}
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should not navigate for retry status
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not navigate when status is rejected', async () => {
|
||||
let notificationHandler:
|
||||
| ((message: FirebaseMessagingTypes.RemoteMessage) => void)
|
||||
| null = null;
|
||||
|
||||
mockOnNotificationOpenedApp.mockImplementation(handler => {
|
||||
notificationHandler = handler;
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'rejected',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
if (notificationHandler) {
|
||||
notificationHandler(remoteMessage);
|
||||
}
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should not navigate for rejected status
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle missing notification data gracefully', async () => {
|
||||
let notificationHandler:
|
||||
| ((message: FirebaseMessagingTypes.RemoteMessage) => void)
|
||||
| null = null;
|
||||
|
||||
mockOnNotificationOpenedApp.mockImplementation(handler => {
|
||||
notificationHandler = handler;
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: undefined,
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
if (notificationHandler) {
|
||||
notificationHandler(remoteMessage);
|
||||
}
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should not navigate when data is missing
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not navigate when navigation is not ready', async () => {
|
||||
mockNavigationRef.isReady.mockReturnValue(false);
|
||||
|
||||
let notificationHandler:
|
||||
| ((message: FirebaseMessagingTypes.RemoteMessage) => void)
|
||||
| null = null;
|
||||
|
||||
mockOnNotificationOpenedApp.mockImplementation(handler => {
|
||||
notificationHandler = handler;
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'approved',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
if (notificationHandler) {
|
||||
notificationHandler(remoteMessage);
|
||||
}
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should not navigate when navigationRef is not ready
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Cold start notification (getInitialNotification)', () => {
|
||||
it('should navigate to KYCVerified when notification type is kyc_result and status is approved', async () => {
|
||||
mockOnNotificationOpenedApp.mockReturnValue(jest.fn());
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'approved',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(remoteMessage);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalledWith(
|
||||
'COLD_START_NOTIFICATION_OPENED',
|
||||
{
|
||||
messageId: 'test-message-id',
|
||||
type: 'kyc_result',
|
||||
actionId: undefined,
|
||||
},
|
||||
);
|
||||
|
||||
expect(mockNavigationRef.navigate).toHaveBeenCalledWith('KYCVerified', {
|
||||
status: 'approved',
|
||||
userId: mockUserId,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not navigate when getInitialNotification returns null', async () => {
|
||||
mockOnNotificationOpenedApp.mockReturnValue(jest.fn());
|
||||
mockGetInitialNotification.mockResolvedValue(null);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockGetInitialNotification).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should not track or navigate when there's no initial notification
|
||||
expect(analytics.trackEvent).not.toHaveBeenCalledWith(
|
||||
'COLD_START_NOTIFICATION_OPENED',
|
||||
expect.anything(),
|
||||
);
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not navigate when status is retry on cold start', async () => {
|
||||
mockOnNotificationOpenedApp.mockReturnValue(jest.fn());
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'retry',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(remoteMessage);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalledWith(
|
||||
'COLD_START_NOTIFICATION_OPENED',
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
// Should not navigate for retry status
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should queue navigation when navigationRef is not ready on cold start', async () => {
|
||||
// Start with navigation not ready
|
||||
mockNavigationRef.isReady.mockReturnValue(false);
|
||||
mockOnNotificationOpenedApp.mockReturnValue(jest.fn());
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'approved',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(remoteMessage);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
// Wait for initial notification to be processed
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalledWith(
|
||||
'COLD_START_NOTIFICATION_OPENED',
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
// Navigation should not have been called yet
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
|
||||
// Simulate navigation becoming ready
|
||||
mockNavigationRef.isReady.mockReturnValue(true);
|
||||
|
||||
// Wait for the polling interval to detect navigation is ready
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(mockNavigationRef.navigate).toHaveBeenCalledWith(
|
||||
'KYCVerified',
|
||||
{
|
||||
status: 'approved',
|
||||
userId: mockUserId,
|
||||
},
|
||||
);
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
});
|
||||
|
||||
it('should process pending navigation immediately if navigation becomes ready', async () => {
|
||||
// Start with navigation not ready
|
||||
mockNavigationRef.isReady.mockReturnValue(false);
|
||||
mockOnNotificationOpenedApp.mockReturnValue(jest.fn());
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'kyc_result',
|
||||
status: 'approved',
|
||||
user_id: mockUserId,
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(remoteMessage);
|
||||
|
||||
const { rerender } = render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
// Wait for initial notification to be processed
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalledWith(
|
||||
'COLD_START_NOTIFICATION_OPENED',
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
// Navigation should not have been called yet
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
|
||||
// Make navigation ready
|
||||
mockNavigationRef.isReady.mockReturnValue(true);
|
||||
|
||||
// Trigger a re-render to simulate React's update cycle
|
||||
rerender(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
// Navigation should be called after navigation becomes ready
|
||||
await waitFor(
|
||||
() => {
|
||||
expect(mockNavigationRef.navigate).toHaveBeenCalledWith(
|
||||
'KYCVerified',
|
||||
{
|
||||
status: 'approved',
|
||||
userId: mockUserId,
|
||||
},
|
||||
);
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
});
|
||||
|
||||
it('should not queue navigation for non-KYC notifications when navigation is not ready', async () => {
|
||||
mockNavigationRef.isReady.mockReturnValue(false);
|
||||
mockOnNotificationOpenedApp.mockReturnValue(jest.fn());
|
||||
|
||||
const remoteMessage = {
|
||||
messageId: 'test-message-id',
|
||||
data: {
|
||||
type: 'other_notification',
|
||||
status: 'some_status',
|
||||
},
|
||||
} as FirebaseMessagingTypes.RemoteMessage;
|
||||
|
||||
mockGetInitialNotification.mockResolvedValue(remoteMessage);
|
||||
|
||||
render(
|
||||
<NotificationTrackingProvider>
|
||||
<mock-text testID="child">Test</mock-text>
|
||||
</NotificationTrackingProvider>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(analytics.trackEvent).toHaveBeenCalledWith(
|
||||
'COLD_START_NOTIFICATION_OPENED',
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
// Make navigation ready
|
||||
mockNavigationRef.isReady.mockReturnValue(true);
|
||||
|
||||
// Wait a bit to ensure no navigation happens
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
|
||||
// Should not navigate for non-KYC notifications
|
||||
expect(mockNavigationRef.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
156
app/tests/src/screens/kyc/KYCVerifiedScreen.test.tsx
Normal file
156
app/tests/src/screens/kyc/KYCVerifiedScreen.test.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
// 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 React from 'react';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { fireEvent, render } from '@testing-library/react-native';
|
||||
|
||||
import * as haptics from '@/integrations/haptics';
|
||||
import KYCVerifiedScreen from '@/screens/kyc/KYCVerifiedScreen';
|
||||
|
||||
// Note: While jest.setup.js provides comprehensive React Native mocking,
|
||||
// react-test-renderer requires component-based mocks (functions) rather than
|
||||
// string-based mocks for proper rendering. This minimal mock provides the
|
||||
// specific components needed for this test without using requireActual to
|
||||
// avoid memory issues (see .cursor/rules/test-memory-optimization.mdc).
|
||||
jest.mock('react-native', () => ({
|
||||
__esModule: true,
|
||||
Platform: { OS: 'ios', select: jest.fn() },
|
||||
StyleSheet: {
|
||||
create: (styles: any) => styles,
|
||||
flatten: (style: any) => style,
|
||||
},
|
||||
View: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
Text: ({ children, ...props }: any) => <span {...props}>{children}</span>,
|
||||
}));
|
||||
|
||||
jest.mock('react-native-edge-to-edge', () => ({
|
||||
SystemBars: () => null,
|
||||
}));
|
||||
|
||||
jest.mock('react-native-safe-area-context', () => ({
|
||||
useSafeAreaInsets: jest.fn(() => ({ top: 0, bottom: 0 })),
|
||||
}));
|
||||
|
||||
jest.mock('@react-navigation/native', () => ({
|
||||
useNavigation: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock Tamagui components
|
||||
jest.mock('tamagui', () => ({
|
||||
__esModule: true,
|
||||
YStack: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
View: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
Text: ({ children, ...props }: any) => <span {...props}>{children}</span>,
|
||||
}));
|
||||
|
||||
jest.mock('@selfxyz/mobile-sdk-alpha/constants/colors', () => ({
|
||||
black: '#000000',
|
||||
white: '#FFFFFF',
|
||||
}));
|
||||
|
||||
jest.mock('@selfxyz/mobile-sdk-alpha/components', () => ({
|
||||
AbstractButton: ({ children, onPress, testID, ...props }: any) => (
|
||||
<button
|
||||
onClick={onPress}
|
||||
type="button"
|
||||
data-testid={testID || 'generate-proof-button'}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
),
|
||||
Title: ({ children, style, testID, ...props }: any) => (
|
||||
<div data-testid={testID || 'title'} style={style} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
Description: ({ children, style, testID, ...props }: any) => (
|
||||
<div data-testid={testID || 'description'} style={style} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
jest.mock('@/integrations/haptics', () => ({
|
||||
buttonTap: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/config/sentry', () => ({
|
||||
captureException: jest.fn(),
|
||||
}));
|
||||
|
||||
const mockUseNavigation = useNavigation as jest.MockedFunction<
|
||||
typeof useNavigation
|
||||
>;
|
||||
|
||||
describe('KYCVerifiedScreen', () => {
|
||||
const mockNavigate = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockUseNavigation.mockReturnValue({
|
||||
navigate: mockNavigate,
|
||||
} as any);
|
||||
});
|
||||
|
||||
it('should render the screen without errors', () => {
|
||||
const { root } = render(<KYCVerifiedScreen />);
|
||||
expect(root).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display the correct title', () => {
|
||||
const { root } = render(<KYCVerifiedScreen />);
|
||||
// Title is the first div child
|
||||
const titleElement = root.findAll(
|
||||
node =>
|
||||
node.type === 'div' &&
|
||||
node.props.children === 'Your ID has been verified',
|
||||
)[0];
|
||||
expect(titleElement).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display the correct description text', () => {
|
||||
const { root } = render(<KYCVerifiedScreen />);
|
||||
// Description is a div with the description text
|
||||
const descriptionElement = root.findAll(
|
||||
node =>
|
||||
node.type === 'div' &&
|
||||
node.props.children ===
|
||||
'Next Self will generate a zk proof specifically for this device that you can use to proof your identity.',
|
||||
)[0];
|
||||
expect(descriptionElement).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have a "Generate proof" button that is visible', () => {
|
||||
const { root } = render(<KYCVerifiedScreen />);
|
||||
const buttons = root.findAllByType('button');
|
||||
expect(buttons.length).toBeGreaterThan(0);
|
||||
expect(buttons[0].props.children).toBe('Generate proof');
|
||||
});
|
||||
|
||||
it('should trigger haptic feedback when "Generate proof" is pressed', () => {
|
||||
const { root } = render(<KYCVerifiedScreen />);
|
||||
const button = root.findAllByType('button')[0];
|
||||
|
||||
fireEvent.press(button);
|
||||
|
||||
expect(haptics.buttonTap).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should navigate to ProvingScreenRouter when "Generate proof" is pressed', () => {
|
||||
const { root } = render(<KYCVerifiedScreen />);
|
||||
const button = root.findAllByType('button')[0];
|
||||
|
||||
fireEvent.press(button);
|
||||
|
||||
expect(mockNavigate).toHaveBeenCalledWith('ProvingScreenRouter');
|
||||
});
|
||||
|
||||
it('should have navigation available', () => {
|
||||
render(<KYCVerifiedScreen />);
|
||||
expect(mockUseNavigation).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user