// // HTMLImageExtractorTests.swift // readeckTests // // Created by Ilyas Hallak on 30.11.25. // import Testing import Foundation @testable import readeck @Suite("HTMLImageExtractor Tests") struct HTMLImageExtractorTests { // MARK: - Test Data private let htmlWithImages = """
"""
private let htmlWithMixedURLs = """
"""
private let htmlWithoutImages = """
This is just text content with no images.
"""
let extractor = HTMLImageExtractor()
let imageURLs = extractor.extract(from: htmlWithRelative)
#expect(imageURLs.count == 1)
#expect(imageURLs.first == "https://valid.com/image.jpg")
}
@Test("Extract handles empty HTML string")
func testExtractHandlesEmptyHTML() {
let extractor = HTMLImageExtractor()
let imageURLs = extractor.extract(from: htmlEmpty)
#expect(imageURLs.isEmpty)
}
@Test("Extract ignores data URI images")
func testExtractIgnoresDataURIs() {
let htmlWithDataURI = """
"""
let extractor = HTMLImageExtractor()
let imageURLs = extractor.extract(from: htmlWithDataURI)
#expect(imageURLs.count == 1)
#expect(imageURLs.first == "https://example.com/real-image.jpg")
// Verify no data URIs are included
for url in imageURLs {
#expect(!url.hasPrefix("data:"))
}
}
// MARK: - Hero/Thumbnail Tests
@Test("Extract with hero image prepends it to array")
func testExtractWithHeroImagePrependsToArray() {
let extractor = HTMLImageExtractor()
let heroURL = "https://example.com/hero.jpg"
let imageURLs = extractor.extract(
from: htmlWithImages,
heroImageURL: heroURL,
thumbnailURL: nil
)
#expect(imageURLs.count == 4) // 3 from HTML + 1 hero
#expect(imageURLs.first == heroURL) // Hero should be at position 0
#expect(imageURLs.contains("https://example.com/image1.jpg"))
}
@Test("Extract with thumbnail prepends it when no hero image")
func testExtractWithThumbnailPrependsWhenNoHero() {
let extractor = HTMLImageExtractor()
let thumbnailURL = "https://example.com/thumbnail.jpg"
let imageURLs = extractor.extract(
from: htmlWithImages,
heroImageURL: nil,
thumbnailURL: thumbnailURL
)
#expect(imageURLs.count == 4) // 3 from HTML + 1 thumbnail
#expect(imageURLs.first == thumbnailURL) // Thumbnail should be at position 0
}
@Test("Extract prefers hero image over thumbnail when both provided")
func testExtractPrefersHeroOverThumbnail() {
let extractor = HTMLImageExtractor()
let heroURL = "https://example.com/hero.jpg"
let thumbnailURL = "https://example.com/thumbnail.jpg"
let imageURLs = extractor.extract(
from: htmlWithImages,
heroImageURL: heroURL,
thumbnailURL: thumbnailURL
)
#expect(imageURLs.count == 4) // 3 from HTML + 1 hero (thumbnail ignored)
#expect(imageURLs.first == heroURL) // Hero takes precedence
#expect(!imageURLs.contains(thumbnailURL)) // Thumbnail should NOT be added
}
@Test("Extract with hero and thumbnail but no HTML images")
func testExtractWithHeroAndNoHTMLImages() {
let extractor = HTMLImageExtractor()
let heroURL = "https://example.com/hero.jpg"
let imageURLs = extractor.extract(
from: htmlWithoutImages,
heroImageURL: heroURL,
thumbnailURL: nil
)
#expect(imageURLs.count == 1)
#expect(imageURLs.first == heroURL)
}
}