diff --git a/src/app/routes/AppRoutes.tsx b/src/app/routes/AppRoutes.tsx new file mode 100644 index 0000000..4bc1825 --- /dev/null +++ b/src/app/routes/AppRoutes.tsx @@ -0,0 +1,15 @@ +import { Route, Routes } from 'react-router'; +import { AppPage } from '@/pages/app'; +import { MapPage } from '@/pages/map'; +import { NotFoundPage } from '@/pages/not-found'; + +export function AppRoutes() { + return ( + + } /> + } /> + } /> + } /> + + ); +} diff --git a/src/main.test.tsx b/src/main.test.tsx new file mode 100644 index 0000000..6a90a12 --- /dev/null +++ b/src/main.test.tsx @@ -0,0 +1,17 @@ +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router'; +import { describe, expect, it } from 'vitest'; +import { AppRoutes } from '@/app/routes/AppRoutes'; + +describe('application routing', () => { + it('shows a not-found page for an unknown path', () => { + render( + + + , + ); + + expect(screen.getByRole('heading', { name: 'Страница не найдена' })).toBeVisible(); + expect(screen.getByRole('link', { name: 'Вернуться к карте' })).toHaveAttribute('href', '/map'); + }); +}); diff --git a/src/main.tsx b/src/main.tsx index 6b510ed..e4cd43a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,9 +1,8 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; -import { BrowserRouter, Routes, Route } from 'react-router'; +import { BrowserRouter } from 'react-router'; import { AppProviders } from '@/app/providers'; -import { AppPage } from '@/pages/app'; -import { MapPage } from '@/pages/map'; +import { AppRoutes } from '@/app/routes/AppRoutes'; import '@/index.css'; // VITE_API_MODE controls MSW registration. @@ -25,11 +24,7 @@ function renderApp() { - - } /> - } /> - } /> - + , diff --git a/src/pages/not-found/NotFoundPage.tsx b/src/pages/not-found/NotFoundPage.tsx new file mode 100644 index 0000000..8950a72 --- /dev/null +++ b/src/pages/not-found/NotFoundPage.tsx @@ -0,0 +1,28 @@ +import { ArrowLeft, MapPinned } from 'lucide-react'; +import { Link } from 'react-router'; + +export function NotFoundPage() { + return ( + + + + + + Ошибка 404 + + Страница не найдена + + + Возможно, ссылка устарела или адрес был введён с ошибкой. + + + + Вернуться к карте + + + + ); +} diff --git a/src/pages/not-found/index.ts b/src/pages/not-found/index.ts new file mode 100644 index 0000000..642c600 --- /dev/null +++ b/src/pages/not-found/index.ts @@ -0,0 +1 @@ +export { NotFoundPage } from './NotFoundPage'; diff --git a/tests/e2e/not-found.spec.ts b/tests/e2e/not-found.spec.ts new file mode 100644 index 0000000..5760e72 --- /dev/null +++ b/tests/e2e/not-found.spec.ts @@ -0,0 +1,8 @@ +import { expect, test } from '@playwright/test'; + +test('unknown paths show the not-found page and a way back to the map', async ({ page }) => { + await page.goto('/missing-page'); + + await expect(page.getByRole('heading', { name: 'Страница не найдена' })).toBeVisible(); + await expect(page.getByRole('link', { name: 'Вернуться к карте' })).toHaveAttribute('href', '/map'); +});
Ошибка 404
+ Возможно, ссылка устарела или адрес был введён с ошибкой. +