veza/apps/web/src/components/settings/security/TwoFactorSetup.stories.tsx
senke 95d261b2da style(settings): elevate TwoFactorSetup to SaaS Premium
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:42:45 +01:00

115 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { within, userEvent } from '@storybook/test';
import { http, HttpResponse } from 'msw';
import { TwoFactorSetup, TwoFactorSetupSkeleton } from './TwoFactorSetup';
const meta: Meta<typeof TwoFactorSetup> = {
title: 'Components/Features/Settings/Security/TwoFactorSetup',
component: TwoFactorSetup,
parameters: {
layout: 'padded',
docs: {
description: {
component:
'Assistant de configuration 2FA en 3 étapes: choix de méthode, scan QR code, codes de backup.',
},
},
},
tags: ['autodocs'],
args: {
onBack: fn(),
onComplete: fn(),
},
argTypes: {
onBack: {
description: "Callback appelé quand l'utilisateur revient en arrière",
action: 'onBack',
},
onComplete: {
description: "Callback appelé quand la configuration est terminée",
action: 'onComplete',
},
},
decorators: [
(Story) => (
<div className="max-w-2xl mx-auto p-4 bg-background min-h-layout-page-sm">
<Story />
</div>
),
],
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
name: 'Par défaut',
};
export const Step1_ChooseMethod: Story = {
name: 'Étape 1: Choix de méthode',
parameters: {
docs: {
description: {
story:
'Première étape: choisir entre Authenticator App (TOTP) ou SMS.',
},
},
},
};
export const Step2_QRCode: Story = {
name: 'Étape 2: QR Code',
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const totpOption = canvas.getByText(/authenticator app/i);
await userEvent.click(totpOption);
},
parameters: {
docs: {
description: {
story:
'Deuxième étape: scanner le QR code et entrer le code de vérification.',
},
},
},
};
export const Loading: Story = {
name: 'Chargement',
render: () => <TwoFactorSetupSkeleton />,
parameters: {
docs: {
description: {
story: 'Skeleton de lassistant 2FA (en-tête + cartes méthode).',
},
},
},
};
export const Error: Story = {
name: 'Erreur',
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const totpOption = canvas.getByText(/authenticator app/i);
await userEvent.click(totpOption);
},
parameters: {
msw: {
handlers: [
http.post('*/api/v1/auth/2fa/setup', () =>
HttpResponse.json(
{ success: false, error: { message: 'Setup failed' } },
{ status: 500 },
),
),
],
},
docs: {
description: {
story: 'MSW retourne 500 sur POST /auth/2fa/setup. Toast + onBack.',
},
},
},
};