Ctrl K
ComunidadGuías…

tests/analytics-engine-write-volume.unit.test.ts

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

Archivo original ↗Preguntar a KiBot
import { afterEach, describe, expect, it, vi } from 'vitest'

vi.mock('../supabase/functions/_backend/plugin_runtime/utils/logging.ts', () => ({
  cloudlog: vi.fn(),
  cloudlogErr: vi.fn(),
  serializeError: vi.fn(error => error),
}))

vi.mock('../supabase/functions/_backend/plugin_runtime/utils/utils.ts', async (importOriginal) => {
  const actual = await importOriginal<typeof import('../supabase/functions/_backend/plugin_runtime/utils/utils.ts')>()
  return {
    ...actual,
    backgroundTask: vi.fn(() => Promise.resolve()),
  }
})

function createContext(env: Record<string, any>) {
  return {
    env,
    get: (key: string) => (key === 'requestId' ? 'request-id' : undefined),
    header: vi.fn(),
    json: (body: unknown, status?: number) => new Response(JSON.stringify(body), { status }),
    req: {
      raw: {
        cf: {},
        headers: new Headers(),
      },
      url: 'http://localhost/test',
    },
    res: {
      headers: new Headers(),
    },
  } as any
}

const device = {
  app_id: 'com.example.app',
  device_id: 'device-1',
  version_name: '1.0.0',
  platform: 'android',
  plugin_version: '8.0.0',
} as any

function mockRandomUint32(value: number) {
  vi.spyOn(globalThis.crypto, 'getRandomValues').mockImplementation(((array: Uint32Array) => {
    array[0] = value
    return array
  }) as typeof crypto.getRandomValues)
}

afterEach(() => {
  vi.restoreAllMocks()
})

describe('analytics engine write volume', () => {
  it.each(['download_10', 'download_50', 'download_90'])('drops %s progress from APP_LOG', async (action) => {
    const { createStatsLogs } = await import('../supabase/functions/_backend/plugin_runtime/utils/plugin_stats.ts')
    const writeDataPoint = vi.fn()
    await createStatsLogs(createContext({ APP_LOG: { writeDataPoint } }), 'com.example.app', 'device-1', action as any, '1.0.0')
    expect(writeDataPoint).not.toHaveBeenCalled()
  })

  it.each(['download_0', 'download_complete', 'download_fail', 'get', 'set'])('keeps %s in APP_LOG', async (action) => {
    const { createStatsLogs } = await import('../supabase/functions/_backend/plugin_runtime/utils/plugin_stats.ts')
    const writeDataPoint = vi.fn()
    await createStatsLogs(createContext({ APP_LOG: { writeDataPoint } }), 'com.example.app', 'device-1', action as any, '1.0.0')
    expect(writeDataPoint).toHaveBeenCalledTimes(1)
  })

  it('samples APP_LOG_EXTERNAL and stores the sample rate in double2', async () => {
    const { APP_LOG_EXTERNAL_SAMPLE_RATE, trackLogsCFExternal } = await import('../supabase/functions/_backend/plugin_runtime/utils/cloudflare.ts')
    const writeDataPoint = vi.fn()
    const c = createContext({ APP_LOG_EXTERNAL: { writeDataPoint } })

    mockRandomUint32(1)
    await trackLogsCFExternal(c, 'com.example.app', 'device-1', 'get', '1.0.0')
    expect(writeDataPoint).not.toHaveBeenCalled()

    mockRandomUint32(APP_LOG_EXTERNAL_SAMPLE_RATE * 3)
    await trackLogsCFExternal(c, 'com.example.app', 'device-1', 'get', '1.0.0')
    expect(writeDataPoint).toHaveBeenCalledWith(expect.objectContaining({
      doubles: [0, APP_LOG_EXTERNAL_SAMPLE_RATE],
      indexes: ['com.example.app'],
    }))
  })

  it('only logs real update checks from on-prem apps to APP_LOG_EXTERNAL', async () => {
    const { onPremStats } = await import('../supabase/functions/_backend/plugin_runtime/utils/plugin_stats.ts')
    mockRandomUint32(0)
    const writeDataPoint = vi.fn()
    const c = createContext({ APP_LOG_EXTERNAL: { writeDataPoint } })

    await onPremStats(c, 'com.example.app', 'app_moved_to_foreground', device)
    expect(writeDataPoint).not.toHaveBeenCalled()

    await onPremStats(c, 'com.example.app', 'get', device)
    expect(writeDataPoint).toHaveBeenCalledTimes(1)
    expect(writeDataPoint.mock.calls[0][0].blobs[1]).toBe('get')
  })

  it('omits APP_LOG dimension blobs when device data collection flags are off', async () => {
    const { sendStatsAndDevice } = await import('../supabase/functions/_backend/plugin_runtime/utils/plugin_stats.ts')
    const { DEFAULT_DEVICE_DATA_COLLECTION } = await import('../supabase/functions/_backend/plugin_runtime/utils/deviceDataCollection.ts')
    const writeDataPoint = vi.fn()
    const collection = {
      ...DEFAULT_DEVICE_DATA_COLLECTION,
      country: false,
      platform: false,
      plugin_version: false,
    }
    await sendStatsAndDevice(
      createContext({ APP_LOG: { writeDataPoint } }),
      {
        app_id: 'com.example.app',
        device_id: 'device-1',
        version_name: '1.0.0',
        platform: 'ios',
        plugin_version: '8.0.0',
        os_version: '18.0',
        version_build: '2.0.0',
        custom_id: '',
        is_prod: true,
        is_emulator: false,
        install_source: 'app_store',
        country_code: 'US',
      } as any,
      [{ action: 'set' }],
      true,
      collection,
    )
    expect(writeDataPoint).toHaveBeenCalledWith(expect.objectContaining({
      blobs: ['device-1', 'set', '1.0.0', '', '', '', '', '', ''],
    }))
  })

  it('flags a failure log that was not counted as a version fail in blob10', async () => {
    const { sendStatsAndDevice } = await import('../supabase/functions/_backend/plugin_runtime/utils/plugin_stats.ts')
    const { DEFAULT_DEVICE_DATA_COLLECTION } = await import('../supabase/functions/_backend/plugin_runtime/utils/deviceDataCollection.ts')
    const writeDataPoint = vi.fn()
    await sendStatsAndDevice(
      createContext({ APP_LOG: { writeDataPoint } }),
      {
        app_id: 'com.example.app',
        device_id: 'device-1',
        version_name: '1.0.0',
        platform: 'ios',
        plugin_version: '8.51.16',
        os_version: '18.0',
        version_build: '2.0.0',
        custom_id: '',
        is_prod: true,
        is_emulator: false,
        install_source: 'app_store',
        country_code: 'US',
      } as any,
      [{ action: 'download_fail', uncountedFailure: true }, { action: 'update_fail' }],
      true,
      { ...DEFAULT_DEVICE_DATA_COLLECTION, country: false },
    )
    expect(writeDataPoint.mock.calls.map(([point]) => point.blobs)).toEqual([
      ['device-1', 'download_fail', '1.0.0', '', 'ios', '', '8.51.16', '', '', '1'],
      ['device-1', 'update_fail', '1.0.0', '', 'ios', '', '8.51.16', '', ''],
    ])
  })

  it('omits DEVICE_INFO blobs for disabled collection fields', async () => {
    const { trackDevicesCF } = await import('../supabase/functions/_backend/plugin_runtime/utils/cloudflare.ts')
    const { applyDeviceDataCollectionToDevice, DEFAULT_DEVICE_DATA_COLLECTION } = await import('../supabase/functions/_backend/plugin_runtime/utils/deviceDataCollection.ts')
    const writeDataPoint = vi.fn()
    const source = {
      app_id: 'com.example.app',
      device_id: 'device-1',
      version_name: '1.0.0',
      platform: 'ios',
      plugin_version: '8.0.0',
      os_version: '18.0',
      custom_id: 'cid',
      version_build: '2.0.0',
      default_channel: 'production',
      key_id: '',
      install_source: 'app_store',
      country_code: 'US',
      is_prod: true,
      is_emulator: false,
    }
    const stored = applyDeviceDataCollectionToDevice(source, {
      ...DEFAULT_DEVICE_DATA_COLLECTION,
      country: false,
      platform: false,
      os_version: false,
      plugin_version: false,
      version_build: false,
      is_emulator: false,
      is_prod: false,
      install_source: false,
    }) as typeof source

    await trackDevicesCF(createContext({ DEVICE_INFO: { writeDataPoint } }), stored as any)
    expect(writeDataPoint).toHaveBeenCalledWith(expect.objectContaining({
      blobs: ['device-1', '1.0.0', '', '', 'cid', 'builtin', 'production', '', '', ''],
      doubles: [-1, -1, -1],
      indexes: ['com.example.app'],
    }))
  })

  it('scales the external update count by the stored sample rate', async () => {
    const { countUpdatesFromLogsExternalCF } = await import('../supabase/functions/_backend/utils/cloudflare.ts')
    const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response(JSON.stringify({ meta: [{ name: 'count', type: 'Float64' }], data: [{ count: 1236.7 }] })))
    const c = createContext({ CF_ACCOUNT_ANALYTICS_ID: 'account', CF_ANALYTICS_TOKEN: 'token' })

    await expect(countUpdatesFromLogsExternalCF(c)).resolves.toBe(1237)
    const body = String(fetchMock.mock.calls[0][1]?.body)
    expect(body).toContain('SUM(_sample_interval * if(double2 > 0, double2, 1.0))')
  })
})