Files
portal/app/tests/Frontend/auth-api.spec.ts
T

144 lines
6.3 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 { describe, it, expect, beforeEach, vi } from 'vitest';
vi.mock('../../resources/js/api/client', () => ({
apiClient: {
get: vi.fn(),
post: vi.fn(),
patch: vi.fn(),
delete: vi.fn(),
},
ensureCsrfCookie: vi.fn(),
}));
import {
login,
registerStart,
me,
logout,
verifyTwoFactor,
useRecoveryCode,
twoFactorInit,
twoFactorConfirm,
twoFactorDisable,
twoFactorRegenerateRecoveryCodes,
forgotPassword,
resetPassword,
updateNotificationPreferences,
} from '../../resources/js/api/auth';
import { apiClient, ensureCsrfCookie } from '../../resources/js/api/client';
const FAKE_USER = {
id: 1,
email: 'demo@x.ru',
first_name: 'D',
last_name: 'U',
tenant_id: 1,
totp_enabled: false,
last_login_at: null,
};
describe('api/auth', () => {
beforeEach(() => vi.clearAllMocks());
it('login() POSTs /api/auth/login + calls ensureCsrfCookie + unwraps data', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { user: FAKE_USER, requires_2fa: false } });
const result = await login({ email: 'a@x.ru', password: 'pw' });
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/login', { email: 'a@x.ru', password: 'pw' });
expect(result.requires_2fa).toBe(false);
expect(result.user.email).toBe('demo@x.ru');
});
it('registerStart() POSTs /api/auth/register/start с email+phone+accept-флагами', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { message: 'ok', email: 'a@x.ru' } });
await registerStart({ email: 'a@x.ru', phone: '79991234567', password: 'pw', accept_offer: true, accept_pdn: true }); // gitleaks:allow
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/register/start', {
email: 'a@x.ru',
phone: '79991234567', // gitleaks:allow
password: 'pw',
accept_offer: true,
accept_pdn: true,
});
});
it('me() GETs /api/auth/me + unwraps data.user', async () => {
vi.mocked(apiClient.get).mockResolvedValue({ data: { user: FAKE_USER } });
const result = await me();
expect(apiClient.get).toHaveBeenCalledWith('/api/auth/me');
expect(result.id).toBe(1);
});
it('logout() POSTs /api/auth/logout + ensureCsrfCookie', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: {} });
await logout();
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/logout');
});
it('verifyTwoFactor() POSTs /api/auth/2fa/verify с code', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { user: FAKE_USER, requires_2fa: false } });
await verifyTwoFactor('123456');
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/2fa/verify', { code: '123456' });
});
it('useRecoveryCode() POSTs /api/auth/2fa/recovery-use с code + возвращает remaining', async () => {
vi.mocked(apiClient.post).mockResolvedValue({
data: { user: FAKE_USER, requires_2fa: false, recovery_codes_remaining: 7 },
});
const r = await useRecoveryCode('xxxx-yyyy');
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/2fa/recovery-use', { code: 'xxxx-yyyy' });
expect(r.recovery_codes_remaining).toBe(7);
});
it('twoFactorInit() POSTs /api/2fa/init + возвращает secret+qr_url', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { secret: 'JBSW', qr_url: 'otpauth://...' } });
const r = await twoFactorInit();
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.post).toHaveBeenCalledWith('/api/2fa/init');
expect(r.secret).toBe('JBSW');
});
it('twoFactorConfirm() POSTs /api/2fa/confirm с code', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { recovery_codes: ['a', 'b'], message: 'ok' } });
await twoFactorConfirm('000000');
expect(apiClient.post).toHaveBeenCalledWith('/api/2fa/confirm', { code: '000000' });
});
it('twoFactorDisable() POSTs /api/2fa/disable с паролем', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { message: 'disabled' } });
await twoFactorDisable('current-pw');
expect(apiClient.post).toHaveBeenCalledWith('/api/2fa/disable', { password: 'current-pw' });
});
it('twoFactorRegenerateRecoveryCodes() POSTs /api/2fa/regenerate-recovery-codes', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { recovery_codes: ['x', 'y', 'z'], message: 'ok' } });
const r = await twoFactorRegenerateRecoveryCodes('pw');
expect(apiClient.post).toHaveBeenCalledWith('/api/2fa/regenerate-recovery-codes', { password: 'pw' });
expect(r.recovery_codes.length).toBe(3);
});
it('forgotPassword() POSTs /api/auth/forgot с email', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { message: 'sent' } });
await forgotPassword('a@x.ru');
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/forgot', { email: 'a@x.ru' });
});
it('resetPassword() POSTs /api/auth/reset-password с token+email+password', async () => {
vi.mocked(apiClient.post).mockResolvedValue({ data: { message: 'reset' } });
const payload = { token: 't', email: 'a@x.ru', password: 'newpw', password_confirmation: 'newpw' };
await resetPassword(payload);
expect(apiClient.post).toHaveBeenCalledWith('/api/auth/reset-password', payload);
});
it('updateNotificationPreferences() PATCH /api/auth/me/notification-preferences', async () => {
vi.mocked(apiClient.patch).mockResolvedValue({ data: { user: FAKE_USER } });
const payload = { prefs: { new_lead: { inapp: true } }, sound_enabled: false };
await updateNotificationPreferences(payload);
expect(ensureCsrfCookie).toHaveBeenCalledOnce();
expect(apiClient.patch).toHaveBeenCalledWith('/api/auth/me/notification-preferences', payload);
});
});