Repository navigation
feat: RSS-CORE-00 video and testing - #42
Conversation
- Configure Vitest environment and coverage exclusions - Cover authentication flow with unit and integration tests - Verify form validations, server actions, and middleware redirects
- Add unit tests for Swagger Editor and Viewer components - Cover try-it-out form and curl command generation with tests - Implement testing for Proxy API and SSR routing - Refactor codemirror-linter and add validation logic tests - Achieve over 92% overall code coverage
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughДобавлены тесты для proxy API, OpenAPI endpoint-компонентов, Try It Out, аутентификации, Supabase, CodeMirror linter и UI. Также обновлены настройки Vitest и тип возвращаемого значения ChangesТестовое покрытие приложения
Estimated code review effort: 3 (Moderate) | ~30 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (8)
src/shared/api/supabase/server.test.ts (1)
16-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winОбщий мок
mockCookieStoreне сбрасывается между тестами полностью.
vi.clearAllMocks()вbeforeEachочищает только историю вызовов, но не удаляет пользовательские реализации, заданные черезmockImplementation/mockReturnValue. Тест на Line 55-57 задаётmockCookieStore.setбросающим исключение, а тест на Line 37 задаётmockCookieStore.getAllс кастомным возвратом — оба изменения переживутclearAllMocks()и «утекут» в любой добавленный впоследствии тест, вызывая непредсказуемые падения. Сейчас проблема не проявляется только потому, что это последние использования моков в файле.♻️ Предлагаемое исправление
beforeEach(() => { - vi.clearAllMocks(); + vi.resetAllMocks(); vi.mocked(cookies).mockResolvedValue(mockCookieStore as any); });Also applies to: 46-62
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/shared/api/supabase/server.test.ts` around lines 16 - 24, Reset mock implementations as well as call history in the beforeEach for mockCookieStore, replacing vi.clearAllMocks() with the appropriate full mock reset. Ensure cookies, mockCookieStore.getAll, and mockCookieStore.set start each test with their default behavior so custom implementations from individual tests cannot leak.src/features/auth-form/ui/auth-form.test.tsx (1)
108-146: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winОтсутствует тест на отображение серверной ошибки для режима регистрации.
Для Login-режима есть тест
should display server error if signInWithPassword fails(строки 93-105), но для Register-режима аналогичного теста на ошибкуsignUpнет — покрытие несимметрично, хотя оба флоу используют одинаковый механизм отображенияserverErrorчерезt(\errors.${result.error}`)(см.src/features/auth-form/ui/auth-form.tsx:47-51`).♻️ Предлагаемый тест
it('should call signUp on successful submit', async () => { ... }); + + it('should display server error if signUp fails', async () => { + const user = userEvent.setup(); + vi.mocked(signUp).mockResolvedValue({ error: 'userAlreadyExists' }); + + render(<AuthForm variant="register" />); + + await user.type(screen.getByLabelText('Register.emailLabel'), 'test@domain.com'); + await user.type(screen.getByLabelText('Register.passcodeLabel'), 'ValidPass123!'); + await user.type(screen.getByLabelText('Register.confirmPasscodeLabel'), 'ValidPass123!'); + + await user.click(screen.getByRole('button', { name: /Register.submitButton/i })); + + expect(await screen.findByText('Register.errors.userAlreadyExists')).toBeInTheDocument(); + }); }); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/auth-form/ui/auth-form.test.tsx` around lines 108 - 146, Add a Register Mode test alongside the existing successful-submit test that mocks signUp to return a failure result, submits valid registration credentials, and asserts the translated server error is rendered via the existing error-message mechanism. Reuse the same symbols and setup as the Login server-error test and preserve the current success-path coverage.src/entities/endpoint/ui/try-it-out-form/try-it-out-form.test.tsx (1)
71-103: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winНе проверяется передача заголовка X-Token в запросе.
В тесте заполняется поле
X-Token (header)(строка 85), но assertion на вызовfetchViaProxy(строки 90-96) проверяет толькоmethodиbody, игнорируяheaders. Часть покрытия для передачи кастомных заголовков через форму фактически не проверяется этим тестом.Пример дополнения проверки
expect(fetchViaProxy).toHaveBeenCalledWith( 'https://api.example.com/users/123?q=search', expect.objectContaining({ method: 'POST', body: JSON.stringify({ name: 'Alice' }, null, 2), + headers: expect.objectContaining({ 'X-Token': 'secret' }), }) );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/endpoint/ui/try-it-out-form/try-it-out-form.test.tsx` around lines 71 - 103, Расширьте assertion на вызов fetchViaProxy в тесте “should submit the form successfully and render the response details”, добавив проверку headers с переданным значением X-Token: secret. Сохраните существующие проверки URL, method и body без изменений.src/entities/endpoint/ui/try-it-out-form/build-headers.test.ts (1)
15-27: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winНе покрыта ветка
if (value)вbuildHeaders.Оба теста используют непустые значения в FormData, поэтому ветка пропуска установки заголовка при falsy-значении (
getFormStringValueвернул пустую строку) не проверяется.♻️ Предлагаемый дополнительный тест-кейс
it('should filter and set headers from form parameters', () => { const parameters: IOpenApiParameter[] = [ { name: 'X-Test-Header', in: 'header', required: false, schema: { type: 'string' } }, { name: 'query-param', in: 'query', required: false, schema: { type: 'string' } }, ]; const formData = new FormData(); formData.append('header:X-Test-Header', 'hello'); formData.append('query:query-param', 'world'); const headers = buildHeaders({ parameters, formData }); expect(headers.get('X-Test-Header')).toBe('hello'); expect(headers.get('query-param')).toBeNull(); }); + + it('should skip setting header when value is empty', () => { + const parameters: IOpenApiParameter[] = [ + { name: 'X-Empty-Header', in: 'header', required: false, schema: { type: 'string' } }, + ]; + const formData = new FormData(); + formData.append('header:X-Empty-Header', ''); + + const headers = buildHeaders({ parameters, formData }); + expect(headers.has('X-Empty-Header')).toBe(false); + });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/endpoint/ui/try-it-out-form/build-headers.test.ts` around lines 15 - 27, Extend the buildHeaders test coverage to include a header form parameter whose FormData value is an empty string, then assert that no header is set for it. Keep the existing non-empty header and non-header parameter assertions unchanged.src/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsx (1)
1-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winДублирование хелпера
renderWithTranslationsв трёх тестовых файлах.Идентичный код (импорт
messages/en.json+ обёрткаNextIntlClientProvider) повторяется без изменений в трёх файлах. Общий корень — отсутствие общего test-utils хелпера для i18n-рендеринга.
src/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsx#L1-L14: заменить локальныйrenderWithTranslationsна импорт из общего test-utils модуля.src/entities/endpoint/ui/request-body/request-body.test.tsx#L1-L14: то же самое.src/entities/endpoint/ui/response-list/response-list.test.tsx#L1-L15: то же самое.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsx` around lines 1 - 14, Создайте общий test-utils хелпер для i18n-рендеринга, инкапсулирующий messages/en.json и NextIntlClientProvider, затем замените локальные renderWithTranslations в src/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsx#L1-L14, src/entities/endpoint/ui/request-body/request-body.test.tsx#L1-L14 и src/entities/endpoint/ui/response-list/response-list.test.tsx#L1-L15 импортом общего хелпера и удалите дублирующиеся импорты и реализации.vitest.config.ts (2)
14-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
coverage.excludeполностью заменяет дефолтные исключения Vitest.Документация Vitest явно указывает:
coverage.excludeперезаписывает встроенный список исключений, а не расширяет его. В v4 риск невелик, так как в отчёт по умолчанию попадают только реально импортированные файлы (coverage.includeне задан) и паттерны тестовых файлов добавляются автоматически, но остальные встроенные исключения (например,**/*.d.ts, служебные конфиги других инструментов) теряются. Рекомендуется расширять дефолтный список черезcoverageConfigDefaults.exclude, чтобы не потерять эти исключения при будущих изменениях (новые конфиги/инструменты,.d.ts-файлы, попавшие в граф импортов).♻️ Предлагаемый рефакторинг
+import { coverageConfigDefaults } from 'vitest/config'; + coverage: { provider: 'v8', reporter: ['text', 'json', 'html'], exclude: [ - 'node_modules/**', - '.next/**', - 'coverage/**', 'vitest.config.ts', 'vitest.setup.ts', 'next.config.ts', 'proxy.ts', '**/index.ts', '**/*.module.scss', '**/*.scss', + ...coverageConfigDefaults.exclude, ], },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@vitest.config.ts` around lines 14 - 25, Update the coverage configuration in vitest.config.ts to extend Vitest’s built-in exclusions via coverageConfigDefaults.exclude instead of replacing them with a standalone exclude array. Preserve all existing project-specific patterns while retaining default exclusions such as declaration files and tool configuration files.
37-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueАлиас
server-onlyуказывает наvitest.setup.ts— смешивает два несвязанных назначения одного файла.Технически рабочее решение (модуль кэшируется один раз, так как
vitest.setup.tsуже загружен черезsetupFiles), но использование тестового setup-файла как заглушки для стороннего пакетаserver-onlyснижает читаемость конфигурации: последующий разработчик, дополняяvitest.setup.tsреальной логикой инициализации, рискует незаметно повлиять на разрешение импортаserver-only. Отдельный пустой stub-модуль был бы более явным.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@vitest.config.ts` at line 37, Разделите назначения алиаса server-only и файла vitest.setup.ts: создайте отдельный пустой stub-модуль для подмены server-only и укажите его в конфигурации Vitest вместо vitest.setup.ts, сохранив vitest.setup.ts только в setupFiles.vitest.setup.ts (1)
16-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueМок
@uiw/react-codemirrorвыглядит корректно.
onChange/onUpdateэмулируют реальное поведение достаточно для нужд тестов (диагностика черезforEachDiagnosticмокается отдельно вswagger-editor.test.tsx). Замечу лишь, что реальныйonChangeв@uiw/react-codemirrorпередаёт такжеViewUpdateвторым аргументом — сейчас мок его не передаёт; текущим тестам это не мешает, но может ограничить будущие тест-кейсы, которым понадобится второй аргумент.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@vitest.setup.ts` around lines 16 - 36, Extend the mocked CodeMirror onChange invocation in the default mock component to provide the expected second ViewUpdate argument, while preserving the existing value propagation and onUpdate behavior. Use the existing update object shape or a compatible mock value so future tests can consume the second argument.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/schema-validator/lib/codemirror-linter.test.ts`:
- Around line 1-6: Ensure every test creating an EditorView in the
codemirror-linter test suite destroys it after execution. Add afterEach cleanup
or try/finally around the relevant tests, tracking each view and calling its
destroy() method so DOM handlers and observers are released.
---
Nitpick comments:
In `@src/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsx`:
- Around line 1-14: Создайте общий test-utils хелпер для i18n-рендеринга,
инкапсулирующий messages/en.json и NextIntlClientProvider, затем замените
локальные renderWithTranslations в
src/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsx#L1-L14,
src/entities/endpoint/ui/request-body/request-body.test.tsx#L1-L14 и
src/entities/endpoint/ui/response-list/response-list.test.tsx#L1-L15 импортом
общего хелпера и удалите дублирующиеся импорты и реализации.
In `@src/entities/endpoint/ui/try-it-out-form/build-headers.test.ts`:
- Around line 15-27: Extend the buildHeaders test coverage to include a header
form parameter whose FormData value is an empty string, then assert that no
header is set for it. Keep the existing non-empty header and non-header
parameter assertions unchanged.
In `@src/entities/endpoint/ui/try-it-out-form/try-it-out-form.test.tsx`:
- Around line 71-103: Расширьте assertion на вызов fetchViaProxy в тесте “should
submit the form successfully and render the response details”, добавив проверку
headers с переданным значением X-Token: secret. Сохраните существующие проверки
URL, method и body без изменений.
In `@src/features/auth-form/ui/auth-form.test.tsx`:
- Around line 108-146: Add a Register Mode test alongside the existing
successful-submit test that mocks signUp to return a failure result, submits
valid registration credentials, and asserts the translated server error is
rendered via the existing error-message mechanism. Reuse the same symbols and
setup as the Login server-error test and preserve the current success-path
coverage.
In `@src/shared/api/supabase/server.test.ts`:
- Around line 16-24: Reset mock implementations as well as call history in the
beforeEach for mockCookieStore, replacing vi.clearAllMocks() with the
appropriate full mock reset. Ensure cookies, mockCookieStore.getAll, and
mockCookieStore.set start each test with their default behavior so custom
implementations from individual tests cannot leak.
In `@vitest.config.ts`:
- Around line 14-25: Update the coverage configuration in vitest.config.ts to
extend Vitest’s built-in exclusions via coverageConfigDefaults.exclude instead
of replacing them with a standalone exclude array. Preserve all existing
project-specific patterns while retaining default exclusions such as declaration
files and tool configuration files.
- Line 37: Разделите назначения алиаса server-only и файла vitest.setup.ts:
создайте отдельный пустой stub-модуль для подмены server-only и укажите его в
конфигурации Vitest вместо vitest.setup.ts, сохранив vitest.setup.ts только в
setupFiles.
In `@vitest.setup.ts`:
- Around line 16-36: Extend the mocked CodeMirror onChange invocation in the
default mock component to provide the expected second ViewUpdate argument, while
preserving the existing value propagation and onUpdate behavior. Use the
existing update object shape or a compatible mock value so future tests can
consume the second argument.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 102801f0-179d-4395-834f-42efe588603f
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (31)
app/api/proxy/getProxyHeaders.test.tsapp/api/proxy/route.test.tssrc/entities/endpoint/lib/generate-example.test.tssrc/entities/endpoint/lib/group-endpoints.test.tssrc/entities/endpoint/ui/endpoint-list/endpoint-list.test.tsxsrc/entities/endpoint/ui/method-badge/method-badge.test.tsxsrc/entities/endpoint/ui/request-body/request-body.test.tsxsrc/entities/endpoint/ui/response-list/response-list.test.tsxsrc/entities/endpoint/ui/try-it-out-form/build-headers.test.tssrc/entities/endpoint/ui/try-it-out-form/build-url.test.tssrc/entities/endpoint/ui/try-it-out-form/format-response-body.test.tssrc/entities/endpoint/ui/try-it-out-form/generate-curl-command.test.tssrc/entities/endpoint/ui/try-it-out-form/get-form-string-value.test.tssrc/entities/endpoint/ui/try-it-out-form/get-parameter-field-name.test.tssrc/entities/endpoint/ui/try-it-out-form/try-it-out-form.test.tsxsrc/features/auth-form/ui/auth-form.test.tsxsrc/features/auth/model/action.test.tssrc/features/auth/model/action.tssrc/features/auth/model/auth-provider.test.tsxsrc/features/schema-validator/lib/codemirror-linter.test.tssrc/features/schema-validator/lib/codemirror-linter.tssrc/shared/api/supabase/client.test.tssrc/shared/api/supabase/get-current-user.test.tssrc/shared/api/supabase/middleware.test.tssrc/shared/api/supabase/server.test.tssrc/shared/ui/input/input.module.scsssrc/widgets/header/ui/header.test.tsxsrc/widgets/swagger-editor/ui/swagger-editor.test.tsxsrc/widgets/swagger-viewer/ui/swagger-viewer.test.tsxvitest.config.tsvitest.setup.ts
| import { describe, it, expect, vi } from 'vitest'; | ||
| import { runOpenapiLinter } from './codemirror-linter'; | ||
| import { EditorState } from '@codemirror/state'; | ||
| import { EditorView } from '@codemirror/view'; | ||
| import { validateSchema } from './validate-schema'; | ||
| import { DiagnosticSeverity } from '@stoplight/types'; |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the test file and any global test teardown/setup that might already destroy views.
git ls-files | rg 'src/features/schema-validator/lib/codemirror-linter\.test\.ts|vitest|setup|teardown|test'
echo
echo '--- file outline ---'
ast-grep outline src/features/schema-validator/lib/codemirror-linter.test.ts --view expanded
echo
echo '--- file contents (numbered) ---'
cat -n src/features/schema-validator/lib/codemirror-linter.test.ts
echo
echo '--- search for destroy() / afterEach around EditorView in tests ---'
rg -n "destroy\(\)|afterEach\(|EditorView" src/features/schema-validator -g '!**/dist/**' -g '!**/build/**'
echo
echo '--- search for global test setup ---'
rg -n "setupFiles|setup\.ts|setupTests|afterEach|beforeEach" . -g 'vitest.config.*' -g 'vite.config.*' -g 'src/**' -g '!**/dist/**' -g '!**/build/**'Repository: FierceSloth/swagger-editor-app
Length of output: 7176
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- vitest.setup.ts ---'
cat -n vitest.setup.ts
echo
echo '--- vitest.config.ts ---'
cat -n vitest.config.ts
echo
echo '--- schema linter implementation ---'
cat -n src/features/schema-validator/lib/codemirror-linter.tsRepository: FierceSloth/swagger-editor-app
Length of output: 4604
Освобождайте EditorView после каждого теста
Оба теста создают EditorView, но не вызывают destroy(). Добавьте afterEach или try/finally, чтобы не оставлять DOM-обработчики и внутренние наблюдатели между тестами.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/schema-validator/lib/codemirror-linter.test.ts` around lines 1 -
6, Ensure every test creating an EditorView in the codemirror-linter test suite
destroys it after execution. Add afterEach cleanup or try/finally around the
relevant tests, tracking each view and calling its destroy() method so DOM
handlers and observers are released.
📋 Trello Task ID
feature/videoAndTesting→develop)⚡️ Summary
Merge the Video & Testing epic into
develop. This includes setting up the testing environment with Vitest and React Testing Library, and writing comprehensive unit and integration tests across the application to achieve high code coverage (>95%). Tests cover the authentication flow, form validation, Swagger Editor and Viewer logic, proxy server, and header navigation.Included stories:
🛠 Type of change
feat(New feature)fix(Bug fix)refactor(Code improvement / Refactoring without changing logic)style(Formatting, CSS)docs(Documentation)chore(Configs, Build)test(Testing)Summary by CodeRabbit