mirror of
https://github.com/btouchard/ackify-ce.git
synced 2026-02-08 14:58:36 -06:00
Reorganize GitHub Actions workflows into reusable components and implement complete code coverage tracking across backend, frontend, and E2E tests. **CI/CD Improvements:** - Split monolithic ci.yml into 6 specialized reusable workflows - New workflows: test-backend, test-frontend, test-e2e, build-docker, security, coverage-report - Orchestrated execution with proper dependencies and parallel jobs - Codecov integration with multi-flag coverage (backend/frontend/e2e) **Frontend Testing:** - Add Vitest for unit testing with coverage-v8 provider - Create test setup with window mocks for Ackify globals - Add 34 unit tests for titleExtractor, referenceDetector, and http utils - Configure Istanbul instrumentation for E2E coverage collection - Integrate @cypress/code-coverage for E2E test coverage **Test Infrastructure:** - Create run-tests-suite.sh for local comprehensive test execution - Proper Docker Compose orchestration for integration and E2E tests - Automatic cleanup handlers with trap for test environments - Coverage summary aggregation across all test types **Bug Fixes:** - Fix backend config tests after OAuth/MagicLink validation changes - Update tests from panic expectations to error checking - Ensure OAUTH_COOKIE_SECRET is properly configured in tests **Configuration:** - Add .codecov.yml for coverage reporting with flags - Add .nycrc.json for E2E LCOV generation - Update .gitignore for test artifacts and coverage reports - Configure Vite for test environment and code instrumentation
67 lines
2.5 KiB
TypeScript
67 lines
2.5 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
import { describe, it, expect } from 'vitest'
|
|
import { extractTitleFromPath } from '@/services/titleExtractor'
|
|
|
|
describe('titleExtractor', () => {
|
|
describe('extractTitleFromPath', () => {
|
|
it('should extract title from URL path', () => {
|
|
const result = extractTitleFromPath('https://example.com/my-document.pdf')
|
|
expect(result).toBe('My Document')
|
|
})
|
|
|
|
it('should extract title from nested URL path', () => {
|
|
const result = extractTitleFromPath('https://example.com/docs/user-guide.html')
|
|
expect(result).toBe('User Guide')
|
|
})
|
|
|
|
it('should use hostname when path is empty', () => {
|
|
const result = extractTitleFromPath('https://example.com/')
|
|
// Le code capitalise uniquement la première lettre de chaque mot
|
|
expect(result).toBe('Example')
|
|
})
|
|
|
|
it('should handle underscore separators', () => {
|
|
const result = extractTitleFromPath('https://example.com/product_spec_v2.pdf')
|
|
expect(result).toBe('Product Spec V2')
|
|
})
|
|
|
|
it('should handle mixed separators', () => {
|
|
const result = extractTitleFromPath('https://example.com/user-guide_final.docx')
|
|
expect(result).toBe('User Guide Final')
|
|
})
|
|
|
|
it('should remove file extension', () => {
|
|
const result = extractTitleFromPath('https://example.com/report.2024.pdf')
|
|
expect(result).toBe('Report.2024')
|
|
})
|
|
|
|
it('should capitalize first letter of each word', () => {
|
|
const result = extractTitleFromPath('https://example.com/annual-financial-report.pdf')
|
|
expect(result).toBe('Annual Financial Report')
|
|
})
|
|
|
|
it('should handle local file paths', () => {
|
|
const result = extractTitleFromPath('/home/user/documents/my-file.txt')
|
|
expect(result).toBe('My File')
|
|
})
|
|
|
|
it('should handle Windows file paths', () => {
|
|
// Note: En environnement JS, les backslashes peuvent être interprétés différemment
|
|
// Le code utilise split(/[/\\]/) qui devrait gérer les deux types de séparateurs
|
|
const result = extractTitleFromPath('C:/Users/John/Documents/contract.pdf')
|
|
expect(result).toBe('Contract')
|
|
})
|
|
|
|
it('should handle simple filenames without path', () => {
|
|
const result = extractTitleFromPath('invoice-2024.pdf')
|
|
expect(result).toBe('Invoice 2024')
|
|
})
|
|
|
|
it('should handle empty segments gracefully', () => {
|
|
const result = extractTitleFromPath('https://example.com///')
|
|
// Les segments vides sont filtrés, donc on utilise le hostname
|
|
expect(result).toBe('Example')
|
|
})
|
|
})
|
|
})
|