* Start scanner-mobile-checkout convoy for the cart-then-commit phone flow. Co-authored-by: Cursor <cursoragent@cursor.com> * Ship a cart-then-commit mobile scanner so phone sessions stay on the camera. Scan matches enqueue locally instead of auto-writing ownership, checkout happens in a sheet, and audit fixes cover stale commit detection, returnUrl open redirects, nested Escape, and ember detection chrome. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
39 lines
1.4 KiB
JavaScript
39 lines
1.4 KiB
JavaScript
// @vitest-environment jsdom
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import { cleanup, render, screen } from '@testing-library/react';
|
|
|
|
import Login, { isSafeAppReturnUrl } from '../../pages/login.js';
|
|
|
|
vi.mock('next/router', () => ({
|
|
useRouter: () => ({ push: vi.fn() }),
|
|
}));
|
|
|
|
vi.mock('../../components/AuthLayout', () => ({
|
|
default: ({ children }) => <div>{children}</div>,
|
|
}));
|
|
|
|
vi.mock('../../components/AnimatedFireLogo', () => ({
|
|
default: () => <div aria-hidden="true">logo</div>,
|
|
}));
|
|
|
|
describe('Login page', () => {
|
|
afterEach(() => cleanup());
|
|
|
|
it('renders the sign-in CTA without dev quick-login credentials', () => {
|
|
render(<Login />);
|
|
|
|
expect(screen.getByRole('button', { name: /sign in to deck hearth/i })).toBeTruthy();
|
|
expect(screen.queryByText(/quick login/i)).toBeNull();
|
|
expect(document.body.textContent).not.toMatch(/alice123|bob123/);
|
|
});
|
|
|
|
it('accepts same-origin relative return URLs and rejects open redirects', () => {
|
|
const origin = 'https://deckhearth.com';
|
|
expect(isSafeAppReturnUrl('/scanner', origin)).toBe(true);
|
|
expect(isSafeAppReturnUrl('/login', origin)).toBe(true);
|
|
expect(isSafeAppReturnUrl('//evil.example', origin)).toBe(false);
|
|
expect(isSafeAppReturnUrl('/\\evil.example', origin)).toBe(false);
|
|
expect(isSafeAppReturnUrl('https://evil.example', origin)).toBe(false);
|
|
expect(isSafeAppReturnUrl(null, origin)).toBe(false);
|
|
});
|
|
});
|