Ctrl K
ComunidadGuías…

tests/console-image-fallback.unit.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// @vitest-environment happy-dom
import { beforeEach, describe, expect, it, vi } from 'vitest'

const USER_ID = '11111111-1111-4111-8111-111111111111'
const mockGetSession = vi.fn()
const mockInvoke = vi.fn()

vi.mock('../src/services/console.ts', () => ({
  defaultApiHost: 'https://api.example.com',
  useConsole: () => ({
    auth: { getSession: mockGetSession },
    functions: { invoke: mockInvoke },
    storage: { from: vi.fn() },
  }),
}))

const RELAY = 'https://api.example.com/private/console/images/read'

function relayUrl(path: string, token: string) {
  const url = new URL(RELAY)
  url.searchParams.set('path', path)
  url.searchParams.set('t', token)
  return url.href
}

function fail(image: HTMLImageElement) {
  image.dispatchEvent(new Event('error'))
}

describe('console image fallback', () => {
  beforeEach(async () => {
    vi.clearAllMocks()
    vi.resetModules()
    document.body.innerHTML = ''
    mockGetSession.mockResolvedValue({ data: { session: { user: { id: USER_ID } } }, error: null })
    mockInvoke.mockResolvedValue({ data: { data: { token: 'fresh', expiresAt: Math.floor(Date.now() / 1000) + 12 * 3600 }, error: null }, error: null })
    const { installConsoleImageFallback } = await import('../src/services/storage.ts')
    installConsoleImageFallback()
  })

  it('retries an expired relay URL once with a current token', async () => {
    const image = document.createElement('img')
    image.src = relayUrl('org/o/logo/a.png', 'expired')
    document.body.appendChild(image)

    fail(image)
    await vi.waitFor(() => expect(image.src).toBe(relayUrl('org/o/logo/a.png', 'fresh')))
    expect(image.style.visibility).toBe('')

    // The retried URL failing too means the image is really unavailable.
    fail(image)
    expect(image.style.visibility).toBe('hidden')
  })

  it('hides a missing image instead of looping when the token is already current', async () => {
    const image = document.createElement('img')
    image.src = relayUrl('org/o/logo/missing.png', 'fresh')
    document.body.appendChild(image)

    fail(image)
    await vi.waitFor(() => expect(image.style.visibility).toBe('hidden'))
    expect(image.src).toBe(relayUrl('org/o/logo/missing.png', 'fresh'))
  })

  it('shows a reused element again once it loads a working image', async () => {
    const image = document.createElement('img')
    image.src = relayUrl('org/o/logo/missing.png', 'fresh')
    document.body.appendChild(image)
    fail(image)
    await vi.waitFor(() => expect(image.style.visibility).toBe('hidden'))

    image.src = relayUrl('org/o/logo/present.png', 'fresh')
    image.dispatchEvent(new Event('load'))
    expect(image.style.visibility).toBe('')
  })

  it('drops a pending retry when the element moved to another image', async () => {
    let releaseToken!: () => void
    mockInvoke.mockImplementation(() => new Promise((resolve) => {
      releaseToken = () => resolve({ data: { data: { token: 'fresh', expiresAt: Math.floor(Date.now() / 1000) + 12 * 3600 }, error: null }, error: null })
    }))
    const image = document.createElement('img')
    image.src = relayUrl('org/o/logo/old.png', 'expired')
    document.body.appendChild(image)

    fail(image)
    await vi.waitFor(() => expect(mockInvoke).toHaveBeenCalled())
    const replacement = relayUrl('org/o/logo/new.png', 'fresh')
    image.src = replacement
    releaseToken()
    await new Promise(resolve => setTimeout(resolve, 0))

    expect(image.src).toBe(replacement)
    expect(image.style.visibility).toBe('')
  })

  it('ignores images that are not served by the console relay', async () => {
    const image = document.createElement('img')
    image.src = 'https://cdn.example.org/logo.png'
    document.body.appendChild(image)

    fail(image)
    await Promise.resolve()
    expect(image.style.visibility).toBe('')
    expect(mockInvoke).not.toHaveBeenCalled()
  })
})