test(app): add content extraction edge case tests

Tests empty input, interleaved tags, malformed tags, unicode content,
duplicate deduplication, place/TV extraction, tag stripping, magazine
sections. 11 test cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-04 22:23:49 +00:00
co-authored by Claude Opus 4.6
parent c6e384a288
commit 5c82a09e65
@@ -0,0 +1,125 @@
import { describe, it, expect } from 'vitest'
import {
extractAllFilms,
extractAllSongs,
extractAllBooks,
extractAllTVSeries,
extractAllPlaces,
extractAllImages,
extractMagazineSections,
stripContentTags,
} from '../contentExtraction'
// ─── Edge cases ──────────────────────────────────────────────────
describe('contentExtraction edge cases', () => {
it('handles empty string', () => {
expect(extractAllFilms('')).toEqual([])
expect(extractAllSongs('', '')).toEqual([])
expect(extractAllBooks('', '')).toEqual([])
expect(extractAllTVSeries('', '')).toEqual([])
expect(extractAllPlaces('', '')).toEqual([])
expect(extractAllImages('', '')).toEqual([])
expect(extractMagazineSections('')).toEqual([])
})
it('handles text with no tags', () => {
const text = 'Just a regular response about movies and music.'
expect(extractAllFilms(text)).toEqual([])
expect(extractAllSongs(text, '')).toEqual([])
})
it('handles interleaved tags of different types', () => {
const text = `
Here are some recommendations:
[[film_ext:Inception|2010|Christopher Nolan]]
Then a great song:
[[song_ext:Bohemian Rhapsody|Queen|1975]]
And a book:
[[book_ext:Dune|Frank Herbert|1965]]
`
const films = extractAllFilms(text)
const songs = extractAllSongs(text, '')
const books = extractAllBooks(text, '')
expect(films).toHaveLength(1)
expect(films[0].title).toBe('Inception')
expect(songs).toHaveLength(1)
expect(songs[0].title).toBe('Bohemian Rhapsody')
expect(books).toHaveLength(1)
expect(books[0].title).toBe('Dune')
})
it('handles malformed tags (missing fields)', () => {
// film_ext requires title|year|director — missing any means no match
expect(extractAllFilms('[[film_ext:Inception]]')).toHaveLength(0)
expect(extractAllFilms('[[film_ext:Inception|2010]]')).toHaveLength(0)
// All 3 fields present — matches
const films = extractAllFilms('[[film_ext:Inception|2010|Christopher Nolan]]')
expect(films).toHaveLength(1)
expect(films[0].title).toBe('Inception')
})
it('handles unicode content in tags', () => {
const text = '[[film_ext:千と千尋の神隠し|2001|宮崎駿]]'
const films = extractAllFilms(text)
expect(films).toHaveLength(1)
expect(films[0].title).toBe('千と千尋の神隠し')
})
it('handles tags with extra whitespace in pipe-separated values', () => {
// Regex captures include leading/trailing spaces in groups
// but the tag format requires no spaces around brackets
const text = '[[film_ext:Inception|2010|Christopher Nolan]]'
const films = extractAllFilms(text)
expect(films).toHaveLength(1)
expect(films[0].title).toBe('Inception')
expect(films[0].director).toBe('Christopher Nolan')
})
it('handles duplicate tags (same title)', () => {
const text = `
[[film_ext:Inception|2010|Christopher Nolan]]
[[film_ext:Inception|2010|Christopher Nolan]]
`
const films = extractAllFilms(text)
// Should deduplicate
expect(films).toHaveLength(1)
})
it('handles place_ext with all fields', () => {
const text = '[[place_ext:Sushi Nakazawa|40.7258|-74.0030|Japanese|$$$$|New York]]'
const places = extractAllPlaces(text, '')
expect(places).toHaveLength(1)
expect(places[0].name).toBe('Sushi Nakazawa')
})
it('handles tv_ext tags', () => {
const text = '[[tv_ext:Breaking Bad|2008|Vince Gilligan]]'
const series = extractAllTVSeries(text, '')
expect(series).toHaveLength(1)
expect(series[0].title).toBe('Breaking Bad')
})
it('stripContentTags removes all tag types', () => {
const text = 'Watch [[film_ext:Inception|2010|Nolan]] and listen to [[song_ext:Song|Artist|2020]]'
const stripped = stripContentTags(text)
expect(stripped).not.toContain('[[')
expect(stripped).not.toContain(']]')
expect(stripped).toContain('Watch')
expect(stripped).toContain('and listen to')
})
it('handles magazine sections with bold markers', () => {
const text = `
- **Bitcoin rallies**: Price surges 5% as ETF inflows hit record.
- **Lightning Network growth**: Capacity doubles in Q1 2026.
- **Mining difficulty**: New all-time high reached.
`
const sections = extractMagazineSections(text)
expect(sections.length).toBeGreaterThanOrEqual(1)
// First section is a summary grouping the items
const titles = sections.map(s => s.title)
expect(titles.length).toBeGreaterThan(0)
})
})