import type { Context } from 'hono' import { beforeEach, describe, expect, it, vi } from 'vitest' import { buildReadDevicesCFQuery as buildPluginReadDevicesCFQuery } from '../supabase/functions/_backend/plugin_runtime/utils/cloudflare.ts' import { buildDeviceIdsByInstallSourcesQuery, buildReadDevicesCFQuery, countDevicesCF, countInstallSourcesCF, formatDateCF, readBandwidthUsageCF, readDeviceUsageCF, readDevicesCF } from '../supabase/functions/_backend/utils/cloudflare.ts' import { readDevicesSB } from '../supabase/functions/_backend/utils/supabase.ts' const pgMocks = vi.hoisted(() => ({ getPgClient: vi.fn(), })) vi.mock('../supabase/functions/_backend/utils/pg.ts', async importOriginal => ({ ...await importOriginal(), getPgClient: pgMocks.getPgClient, closeClient: vi.fn(), })) function createContextMock() { return { env: { SUPABASE_URL: 'http://localhost:54321', SUPABASE_SERVICE_ROLE_KEY: 'service-role-key', CF_ANALYTICS_TOKEN: 'cf-analytics-token', CF_ACCOUNT_ANALYTICS_ID: 'cf-account-id', BANDWIDTH_USAGE: {}, }, req: { url: 'http://localhost/private/devices' }, get: vi.fn((key: string) => key === 'requestId' ? 'test-request' : undefined), } } beforeEach(() => { pgMocks.getPgClient.mockReset() vi.unstubAllGlobals() }) describe('buildReadDevicesCFQuery', () => { it.concurrent('applies default device_id cursor pagination when no order is provided', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', cursor: '2026-04-04 03:05:59|11111111-1111-4111-8111-111111111111', limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') const cursorIndex = query.indexOf(`WHERE device_id > '11111111-1111-4111-8111-111111111111'`) expect(groupByIndex).toBeGreaterThan(-1) expect(cursorIndex).toBeGreaterThan(groupByIndex) expect(query).toContain('ORDER BY device_id ASC') }) const installSourceArgMax = 'argMax(blob9, if(blob9 != \'\', timestamp, toDateTime(\'1970-01-01 00:00:00\'))) AS install_source' it.concurrent('reads install_source from blob9 on default device listing', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', limit: 1, }, false) expect(query).toContain(installSourceArgMax) expect(query).not.toContain('blob10') }) it.concurrent('reads install_source from blob9 in plugin-runtime device listing', () => { const query = buildPluginReadDevicesCFQuery({ app_id: 'com.example.app', limit: 1, }, false) expect(query).toContain(installSourceArgMax) }) it.concurrent('does not read country code for custom id listing without device ids', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', limit: 1, }, true) expect(query).toContain('custom_id != \'\'') expect(query).not.toContain('blob5 != \'\'') expect(query).not.toContain('blob10') }) it.concurrent('reads country code when devices are requested by id', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', deviceIds: ['11111111-1111-4111-8111-111111111111'], limit: 1, }, false) expect(query).toContain('argMax(blob10, if(blob10 != \'\', timestamp, toDateTime(\'1970-01-01 00:00:00\'))) AS country_code') }) it.concurrent('applies descending cursor pagination after device grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', cursor: '2026-04-04 03:05:59|11111111-1111-4111-8111-111111111111', limit: 1, order: [{ key: 'updated_at', sortable: 'desc' }], }, false) const groupByIndex = query.indexOf('GROUP BY blob1') const cursorIndex = query.indexOf(`WHERE (updated_at < toDateTime('2026-04-04 03:05:59')`) const tiebreakerIndex = query.indexOf(`AND device_id > '11111111-1111-4111-8111-111111111111'`) expect(groupByIndex).toBeGreaterThan(-1) expect(cursorIndex).toBeGreaterThan(groupByIndex) expect(tiebreakerIndex).toBeGreaterThan(cursorIndex) expect(query).not.toContain(`AND (timestamp < toDateTime('2026-04-04 03:05:59')`) expect(query).toContain(`ORDER BY updated_at DESC, device_id ASC`) }) it.concurrent('applies ascending cursor pagination after device grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', cursor: '2026-04-04 03:05:59|11111111-1111-4111-8111-111111111111', limit: 1, order: [{ key: 'updated_at', sortable: 'asc' }], }, false) const cursorIndex = query.indexOf(`WHERE (updated_at > toDateTime('2026-04-04 03:05:59')`) const tiebreakerIndex = query.indexOf(`AND device_id > '11111111-1111-4111-8111-111111111111'`) expect(query).toContain(`WHERE (updated_at > toDateTime('2026-04-04 03:05:59')`) expect(tiebreakerIndex).toBeGreaterThan(cursorIndex) expect(query).toContain(`ORDER BY updated_at ASC, device_id ASC`) }) it.concurrent('builds install source device lookup from non-empty blob9 rows', () => { const query = buildDeviceIdsByInstallSourcesQuery('com.example.app', ['app_store', 'amazon_appstore']) expect(query).toContain(`WHERE index1 = 'com.example.app' AND blob9 != ''`) expect(query).toContain('GROUP BY blob1') expect(query).toContain(`install_source IN ('app_store', 'amazon_appstore')`) }) it.concurrent('filters devices with updated_at greater than the provided timestamp', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', updated_at_gt: '2026-04-04T03:05:59.000Z', limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') const innerFilterIndex = query.indexOf(`timestamp > toDateTime('2026-04-04 03:05:59')`) const outerFilterIndex = query.indexOf(`WHERE updated_at > toDateTime('2026-04-04 03:05:59')`) expect(groupByIndex).toBeGreaterThan(-1) expect(innerFilterIndex).toBeGreaterThan(-1) expect(innerFilterIndex).toBeLessThan(groupByIndex) expect(outerFilterIndex).toBeGreaterThan(groupByIndex) }) it.concurrent('filters devices by latest aggregated platform and version after grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', platform: 'ios', version_name: '1.2.3', limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') const outerWhereIndex = query.indexOf('WHERE platform = 1 AND version_name = \'1.2.3\'') const altOuterWhereIndex = query.indexOf('WHERE version_name = \'1.2.3\' AND platform = 1') expect(query).not.toContain(`blob2 = '1.2.3'`) expect(Math.max(outerWhereIndex, altOuterWhereIndex)).toBeGreaterThan(groupByIndex) }) it.concurrent('filters devices by latest aggregated default_channel after grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', default_channel: 'beta\'s', limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') expect(query).not.toContain(`blob7 = `) expect(query.indexOf(`default_channel = 'beta''s'`)).toBeGreaterThan(groupByIndex) }) it.concurrent('filters devices by os_version gte after grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', platform: 'android', os_version_compare: { op: 'gte', value: '14' }, version_name_compare: { op: 'lte', value: '1.2.3' }, limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') expect(query).toContain('argMax(blob4, timestamp) AS os_version') expect(query.indexOf('>= 14')).toBeGreaterThan(groupByIndex) expect(query.indexOf('splitByChar(\'.\', os_version)')).toBeGreaterThan(groupByIndex) expect(query.indexOf('splitByChar(\'.\', version_name)')).toBeGreaterThan(groupByIndex) expect(query).not.toContain('concat(') }) it.concurrent('filters devices by multiple version names after grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', version_name: ['1.2.3', '2.0.0'], limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') const outerWhereIndex = query.indexOf(`WHERE version_name IN ('1.2.3', '2.0.0')`) expect(query).not.toContain(`blob2 IN ('1.2.3', '2.0.0')`) expect(outerWhereIndex).toBeGreaterThan(groupByIndex) }) it.concurrent('filters plugin-runtime devices by multiple version names', () => { const query = buildPluginReadDevicesCFQuery({ app_id: 'com.example.app', version_name: ['1.2.3', '2.0.0'], limit: 1, }, false) expect(query).toContain(`blob2 IN ('1.2.3', '2.0.0')`) }) it.concurrent('applies search against latest aggregated device fields after grouping', () => { const query = buildReadDevicesCFQuery({ app_id: 'com.example.app', platform: 'android', search: 'abc', limit: 1, }, false) const groupByIndex = query.indexOf('GROUP BY blob1') const searchIndex = query.indexOf(`position('abc' IN toLower(device_id))`) expect(query).not.toContain(`toLower(blob1)`) expect(searchIndex).toBeGreaterThan(groupByIndex) expect(query.indexOf('platform = 0')).toBeGreaterThan(groupByIndex) }) it('maps install_source from Analytics Engine rows in readDevicesCF', async () => { let query = '' const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => { query = String(init?.body ?? '') return new Response(JSON.stringify({ meta: [ { name: 'device_id', type: 'String' }, { name: 'version_name', type: 'String' }, { name: 'plugin_version', type: 'String' }, { name: 'os_version', type: 'String' }, { name: 'custom_id', type: 'String' }, { name: 'version_build', type: 'String' }, { name: 'default_channel', type: 'String' }, { name: 'key_id', type: 'String' }, { name: 'install_source', type: 'String' }, { name: 'platform', type: 'Float64' }, { name: 'is_prod', type: 'Float64' }, { name: 'is_emulator', type: 'Float64' }, { name: 'updated_at', type: 'DateTime' }, ], data: [{ device_id: '11111111-1111-4111-8111-111111111111', version_name: '1.0.0', plugin_version: '8.0.0', os_version: '17.0', custom_id: '', version_build: '1', default_channel: 'production', key_id: '', install_source: 'app_store', platform: 1, is_prod: 1, is_emulator: 0, updated_at: '2026-04-04 03:05:59', }], }), { status: 200, headers: { 'content-type': 'application/json' }, }) }) vi.stubGlobal('fetch', fetchMock) const devices = await readDevicesCF(createContextMock() as unknown as Context, { app_id: 'com.example.app', limit: 1, }, false) expect(query).toContain(installSourceArgMax) expect(devices).toHaveLength(1) expect(devices[0]?.install_source).toBe('app_store') }) }) describe('countDevicesCF', () => { it('does not read install source blob on default device counts', async () => { let query = '' const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => { query = String(init?.body ?? '') return new Response(JSON.stringify({ meta: [{ name: 'total', type: 'UInt64' }], data: [{ total: 12 }], }), { status: 200, headers: { 'content-type': 'application/json' }, }) }) vi.stubGlobal('fetch', fetchMock) const count = await countDevicesCF( createContextMock() as unknown as Context, 'com.example.app', false, ) expect(count).toBe(12) expect(query).toContain('COUNT(DISTINCT blob1) AS total') expect(query).not.toContain('blob9') expect(query).not.toContain('install_source') }) }) describe('countDevicesCF default channel', () => { it('filters counts by latest aggregated default_channel', async () => { let query = '' const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => { query = String(init?.body ?? '') return new Response(JSON.stringify({ meta: [{ name: 'total', type: 'UInt64' }], data: [{ total: 3 }], }), { status: 200, headers: { 'content-type': 'application/json' }, }) }) vi.stubGlobal('fetch', fetchMock) const count = await countDevicesCF( createContextMock() as unknown as Context, 'com.example.app', false, [], undefined, undefined, { defaultChannel: 'beta' }, ) expect(count).toBe(3) expect(query).toContain('argMax(blob7, timestamp) AS default_channel') expect(query.indexOf(`default_channel = 'beta'`)).toBeGreaterThan(query.indexOf('GROUP BY blob1')) }) }) describe('readBandwidthUsageCF', () => { it('throws strict bandwidth read failures instead of returning empty usage', async () => { const fetchMock = vi.fn(async () => { throw new Error('analytics unavailable') }) vi.stubGlobal('fetch', fetchMock) await expect(readBandwidthUsageCF( createContextMock() as unknown as Context, 'com.example.app', '2026-06-01', '2026-07-01', { throwOnError: true }, )).rejects.toThrow('runQueryToCFA encountered an error') expect(fetchMock).toHaveBeenCalledTimes(1) }) it('includes Cloudflare Analytics HTTP error details in strict bandwidth failures', async () => { const fetchMock = vi.fn(async () => new Response(JSON.stringify({ errors: [{ message: 'bad Analytics Engine query' }], }), { status: 400, headers: { 'content-type': 'application/json' }, })) vi.stubGlobal('fetch', fetchMock) await expect(readBandwidthUsageCF( createContextMock() as unknown as Context, 'com.example.app', '2026-06-01', '2026-07-01', { throwOnError: true }, )).rejects.toThrow('runQueryToCFA HTTP 400: {"errors":[{"message":"bad Analytics Engine query"}]}') }) }) describe('countInstallSourcesCF', () => { it('counts latest install sources in a dedicated aggregate query', async () => { let query = '' const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => { query = String(init?.body ?? '') return new Response(JSON.stringify({ meta: [ { name: 'install_source', type: 'String' }, { name: 'total', type: 'UInt64' }, ], data: [ { install_source: 'app_store', total: 3 }, { install_source: 'testflight', total: 2 }, ], }), { status: 200, headers: { 'content-type': 'application/json' }, }) }) vi.stubGlobal('fetch', fetchMock) const counts = await countInstallSourcesCF(createContextMock() as unknown as Context, 'com.example.app') expect(counts).toEqual({ app_store: 3, testflight: 2 }) expect(fetchMock).toHaveBeenCalledTimes(1) expect(query).toContain('GROUP BY install_source') expect(query).toContain('argMax(blob9, timestamp) AS install_source') expect(query).toContain('COUNT() AS total') expect(query).not.toContain('COUNT(DISTINCT blob1) AS total') expect(query).not.toContain('CASE WHEN blob9') }) it('reuses cached install source counts for the same app', async () => { const cachedResponses = new Map() vi.stubGlobal('caches', { open: vi.fn(async () => ({ match: vi.fn(async (request: Request) => cachedResponses.get(request.url)), put: vi.fn(async (request: Request, response: Response) => { cachedResponses.set(request.url, response) }), })), }) const fetchMock = vi.fn(async () => new Response(JSON.stringify({ meta: [ { name: 'install_source', type: 'String' }, { name: 'total', type: 'UInt64' }, ], data: [{ install_source: 'app_store', total: 3 }], }), { status: 200, headers: { 'content-type': 'application/json' }, })) vi.stubGlobal('fetch', fetchMock) const context = createContextMock() as unknown as Context await expect(countInstallSourcesCF(context, 'com.example.app')).resolves.toEqual({ app_store: 3 }) await expect(countInstallSourcesCF(context, 'com.example.app')).resolves.toEqual({ app_store: 3 }) expect(fetchMock).toHaveBeenCalledTimes(1) }) }) describe('readDevicesSB', () => { async function readDevicesQuery(params: Parameters[1], customIdMode = false) { const query = vi.fn(async (_text: string, _values: unknown[]) => ({ rows: [] })) pgMocks.getPgClient.mockResolvedValueOnce({ query }) await readDevicesSB(createContextMock() as unknown as Context, params, customIdMode) expect(query).toHaveBeenCalledTimes(1) const [text, values] = query.mock.calls[0]! return { text, values } } it('applies default device_id cursor pagination when no order is provided', async () => { const { text, values } = await readDevicesQuery({ app_id: 'com.example.app', cursor: '2026-04-04 03:05:59|11111111-1111-4111-8111-111111111111', limit: 1, }) expect(text).toContain('FROM public.devices WHERE app_id = $1 AND device_id > $2 ORDER BY device_id ASC LIMIT $3') expect(values).toEqual(['com.example.app', '11111111-1111-4111-8111-111111111111', 2]) expect(pgMocks.getPgClient).toHaveBeenLastCalledWith(expect.anything(), false) }) it('applies install source filters', async () => { const { text, values } = await readDevicesQuery({ app_id: 'com.example.app', installSources: ['app_store', 'testflight'], limit: 1, }) expect(text).toContain('install_source = ANY($2::text[])') expect(values).toContainEqual(['app_store', 'testflight']) }) it('applies platform and version_name filters together', async () => { const { text, values } = await readDevicesQuery({ app_id: 'com.example.app', platform: 'android', version_name: '2.0.0', limit: 1, }) expect(text).toContain('version_name = $2') expect(text).toContain('platform = $3::public.platform_os') expect(values).toEqual(['com.example.app', '2.0.0', 'android', 2]) }) it('applies default_channel filter', async () => { const { text, values } = await readDevicesQuery({ app_id: 'com.example.app', default_channel: 'beta', limit: 1, }) expect(text).toContain('default_channel = $2') expect(values).toEqual(['com.example.app', 'beta', 2]) }) it('filters devices with updated_at greater than the provided timestamp', async () => { const { text, values } = await readDevicesQuery({ app_id: 'com.example.app', updated_at_gt: '2026-04-04T03:05:59.000Z', limit: 1, }) expect(text).toContain('updated_at > $2::timestamptz') expect(values).toEqual(['com.example.app', '2026-04-04T03:05:59.000Z', 2]) }) it('orders devices by updated_at when requested', async () => { const { text } = await readDevicesQuery({ app_id: 'com.example.app', order: [{ key: 'updated_at', sortable: 'desc' }], limit: 1, }) expect(text).toContain('ORDER BY updated_at DESC, device_id ASC') }) it('returns rows as PostgREST JSON', async () => { const { text } = await readDevicesQuery({ app_id: 'com.example.app', limit: 1 }) expect(text).toContain('pg_catalog.to_json(q.*)') }) }) describe('formatDateCF', () => { it.concurrent.each([ ['Date objects', new Date('2026-03-17T09:08:07.654Z')], ['ISO strings with offsets', '2026-03-17T10:08:07+01:00'], ] as const)('normalizes %s to a stable UTC SQL timestamp', (_name, input) => { expect(formatDateCF(input)).toBe('2026-03-17 09:08:07') }) }) function createDeviceUsageContext() { return { env: { CF_ANALYTICS_TOKEN: 'cf-analytics-token', CF_ACCOUNT_ANALYTICS_ID: 'cf-account-id', DEVICE_USAGE: {}, }, get: (key: string) => key === 'requestId' ? 'device-usage-test' : undefined, } as unknown as Context } describe('readDeviceUsageCF', () => { it('aggregates daily MAU inside Analytics Engine instead of returning one row per device', async () => { const queries: string[] = [] vi.stubGlobal('fetch', vi.fn(async (_url: string, init?: RequestInit) => { queries.push(String(init?.body)) return new Response(JSON.stringify({ meta: [ { name: 'date', type: 'String' }, { name: 'app_id', type: 'String' }, { name: 'org_id', type: 'String' }, { name: 'mau', type: 'UInt64' }, ], data: [ { date: '2026-09-01', app_id: 'com.example.app', org_id: 'org-new', mau: '600000' }, { date: '2026-09-01', app_id: 'com.example.app', org_id: 'org-old', mau: '5' }, { date: '2026-09-02', app_id: 'com.example.app', org_id: 'org-new', mau: '328104' }, ], rows: 3, }), { status: 200, headers: { 'content-type': 'application/json' } }) })) const usage = await readDeviceUsageCF(createDeviceUsageContext(), 'com.example.app', '2026-09-01T00:00:00Z', '2026-10-01T00:00:00Z', { throwOnError: true }) expect(queries).toHaveLength(1) // Device ids stay inside the inner GROUP BY; the result is one row per day/org. expect(queries[0]).toMatch(/count\(\) AS mau/) expect(queries[0]).toMatch(/GROUP BY date, app_id, org_id/) expect(queries[0]!.split('\n')[1]!.trim()).toBe('date,') expect(usage).toEqual([ { date: '2026-09-01', app_id: 'com.example.app', org_id: 'org-new', mau: 600005 }, { date: '2026-09-02', app_id: 'com.example.app', org_id: 'org-new', mau: 328104 }, ]) }) })