3 changed files with 52 additions and 7 deletions
@ -0,0 +1,20 @@ |
|||||||
|
import { describe, expect, it } from 'vitest' |
||||||
|
import { |
||||||
|
isFaviconLoadFailed, |
||||||
|
markFaviconLoadFailed, |
||||||
|
normalizeFaviconDomain |
||||||
|
} from '@/lib/favicon-fail-cache' |
||||||
|
|
||||||
|
describe('favicon-fail-cache', () => { |
||||||
|
it('normalizes domain casing and trailing dot', () => { |
||||||
|
expect(normalizeFaviconDomain(' Example.COM. ')).toBe('example.com') |
||||||
|
}) |
||||||
|
|
||||||
|
it('remembers failed domains for the session', () => { |
||||||
|
const host = `fail-cache-test-${Date.now()}.example` |
||||||
|
expect(isFaviconLoadFailed(host)).toBe(false) |
||||||
|
markFaviconLoadFailed(host) |
||||||
|
expect(isFaviconLoadFailed(host)).toBe(true) |
||||||
|
expect(isFaviconLoadFailed(host.toUpperCase())).toBe(true) |
||||||
|
}) |
||||||
|
}) |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
import { LRUCache } from 'lru-cache' |
||||||
|
|
||||||
|
/** Domains whose `https://{host}/favicon.ico` already failed — skip repeat network requests. */ |
||||||
|
const FAILED_FAVICON_DOMAINS = new LRUCache<string, true>({ max: 512 }) |
||||||
|
|
||||||
|
export function normalizeFaviconDomain(domain: string): string { |
||||||
|
return domain.trim().toLowerCase().replace(/\.$/, '') |
||||||
|
} |
||||||
|
|
||||||
|
export function isFaviconLoadFailed(domain: string): boolean { |
||||||
|
const key = normalizeFaviconDomain(domain) |
||||||
|
if (!key) return true |
||||||
|
return FAILED_FAVICON_DOMAINS.has(key) |
||||||
|
} |
||||||
|
|
||||||
|
export function markFaviconLoadFailed(domain: string): void { |
||||||
|
const key = normalizeFaviconDomain(domain) |
||||||
|
if (!key) return |
||||||
|
FAILED_FAVICON_DOMAINS.set(key, true) |
||||||
|
} |
||||||
Loading…
Reference in new issue