Ctrl K
ComunidadGuías…

tests/bundle-get-filter.test.ts

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

Archivo original ↗Preguntar a KiBot
import { randomUUID } from 'node:crypto'
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
import {
  BASE_URL,
  createAppVersions,
  createDirectApiKeyWithBindings,
  getSupabaseClient,
  headers,
  ORG_ID_2,
  resetAndSeedAppData,
  resetAppData,
  USER_ID_2,
} from './test-utils.ts'

const fixtureId = randomUUID()
const APP_A = `com.test.bundle.lookup.a.${fixtureId}`
const APP_B = `com.test.bundle.lookup.b.${fixtureId}`
const VERSION_NAME = `9.8.7-lookup-${fixtureId}`

let versionIdOnA: number
let deniedHeaders: typeof headers
let deniedKeyId: number

async function getBundles(query: Record<string, string>, requestHeaders: typeof headers = headers) {
  const params = new URLSearchParams(query)
  const response = await fetch(`${BASE_URL}/bundle?${params.toString()}`, {
    method: 'GET',
    headers: requestHeaders,
  })
  const data = await response.json()
  return { response, data }
}

beforeAll(async () => {
  await resetAndSeedAppData(APP_A)
  await resetAndSeedAppData(APP_B)

  const version = await createAppVersions(VERSION_NAME, APP_A)
  versionIdOnA = version.id

  const deniedKey = await createDirectApiKeyWithBindings({
    userId: USER_ID_2,
    key: randomUUID(),
    name: `bundle-lookup-denied-${fixtureId}`,
    orgId: ORG_ID_2,
    roleName: 'org_admin',
  })
  if (!deniedKey.key)
    throw new Error('Failed to create denied API key')

  deniedKeyId = deniedKey.id
  deniedHeaders = {
    'Content-Type': 'application/json',
    Authorization: deniedKey.key,
  }
})

afterAll(async () => {
  await resetAppData(APP_A)
  await resetAppData(APP_B)
  if (deniedKeyId)
    await getSupabaseClient().from('apikeys').delete().eq('id', deniedKeyId)
})

describe('[GET] /bundle version and id filters', () => {
  it.concurrent('returns one bundle when version exists on the app', async () => {
    const { response, data } = await getBundles({ app_id: APP_A, version: VERSION_NAME })
    expect(response.status).toBe(200)
    expect(Array.isArray(data)).toBe(true)
    expect(data).toHaveLength(1)
    expect((data as { id: number, name: string }[])[0].id).toBe(versionIdOnA)
    expect((data as { name: string }[])[0].name).toBe(VERSION_NAME)
  })

  it.concurrent('returns empty array when version does not exist', async () => {
    const { response, data } = await getBundles({
      app_id: APP_A,
      version: `missing-${fixtureId}`,
    })
    expect(response.status).toBe(200)
    expect(data).toEqual([])
  })

  it.concurrent('returns empty array when version exists on another app', async () => {
    const { response, data } = await getBundles({ app_id: APP_B, version: VERSION_NAME })
    expect(response.status).toBe(200)
    expect(data).toEqual([])
  })

  it.concurrent('rejects unsafe bundle id query values', async () => {
    const { response, data } = await getBundles({
      app_id: APP_A,
      id: '99999999999999999999',
    })
    expect(response.status).toBe(400)
    expect((data as { error: string }).error).toBe('invalid_query')
  })

  it.concurrent('returns one bundle when id exists on the app', async () => {
    const { response, data } = await getBundles({
      app_id: APP_A,
      id: String(versionIdOnA),
    })
    expect(response.status).toBe(200)
    expect(data).toHaveLength(1)
    expect((data as { id: number }[])[0].id).toBe(versionIdOnA)
  })

  it.concurrent('rejects API key without access to the app', async () => {
    const { response, data } = await getBundles({ app_id: APP_A, version: VERSION_NAME }, deniedHeaders)
    expect(response.status).toBe(404)
    expect((data as { error: string }).error).toBe('app_not_found')
  })

  it.concurrent('keeps unpaginated list paging behavior unchanged', async () => {
    const { response, data } = await getBundles({ app_id: APP_A, page: '99' })
    expect(response.status).toBe(200)
    expect(data).toEqual([])
  })

  it.concurrent('fields=summary leaves out manifest and native_packages', async () => {
    const { response, data } = await getBundles({ app_id: APP_A, version: VERSION_NAME, fields: 'summary' })
    expect(response.status).toBe(200)
    const row = (data as Record<string, unknown>[])[0]
    expect(row.id).toBe(versionIdOnA)
    expect(row).toHaveProperty('checksum')
    expect(row).not.toHaveProperty('native_packages')
    expect(row).not.toHaveProperty('manifest')
  })

  it.concurrent('limit returns larger list pages', async () => {
    const [{ response: small, data: smallPage }, { response: large, data: largePage }] = await Promise.all([
      getBundles({ app_id: APP_A, limit: '1', fields: 'summary' }),
      getBundles({ app_id: APP_A, limit: '1000', fields: 'summary' }),
    ])
    expect(small.status).toBe(200)
    expect(large.status).toBe(200)
    expect(smallPage).toHaveLength(1)
    expect((largePage as unknown[]).length).toBeGreaterThan(1)
    expect((largePage as { id: number }[]).map(row => row.id)).toContain(versionIdOnA)
  })

  it.concurrent('rejects limits above the PostgREST page cap', async () => {
    const { response, data } = await getBundles({ app_id: APP_A, limit: '1001' })
    expect(response.status).toBe(400)
    expect((data as { error: string }).error).toBe('invalid_query')
  })
})