Ctrl K
ComunidadGuías…

tests/build-tracking-helpers.unit.test.ts

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

Archivo original ↗Preguntar a KiBot
import { describe, expect, it } from 'vitest'
import { classifyBuildTransition, mapBuildFailureCategory } from '../supabase/functions/_backend/utils/build_tracking.ts'
import { getBuilderXcodeVersion } from '../supabase/functions/_backend/utils/builder_machine.ts'

describe('classifyBuildTransition', () => {
  it.concurrent.each([
    ['pending', 'running', false, 'started'],
    ['queued', 'running', false, 'started'],
    ['running', 'succeeded', false, 'succeeded'],
    ['pending', 'succeeded', false, 'succeeded'],
    ['running', 'failed', false, 'failed'],
    ['running', 'failed', true, 'timed_out'],
    ['running', 'succeeded', true, 'timed_out'],
    // timeout overrides no-change
    ['running', 'running', true, 'timed_out'],
    // previous already terminal (idempotency), even with timeoutApplied
    ['succeeded', 'succeeded', false, null],
    ['failed', 'failed', false, null],
    ['cancelled', 'cancelled', false, null],
    ['expired', 'expired', false, null],
    ['released', 'released', false, null],
    ['failed', 'failed', true, null],
    // no state change
    ['pending', 'pending', false, null],
    ['running', 'running', false, null],
  ] as const)('%s -> %s (timeoutApplied=%s) is %s', (previous, next, timeoutApplied, expected) => {
    expect(classifyBuildTransition({ previous, next, timeoutApplied })).toBe(expected)
  })
})

describe('mapBuildFailureCategory', () => {
  it.concurrent('returns timeout when the timeout flag is set', () => {
    expect(mapBuildFailureCategory({ timeoutApplied: true, errorMessage: null })).toBe('timeout')
  })

  it.concurrent('returns validation_error for validation-style messages', () => {
    expect(mapBuildFailureCategory({ timeoutApplied: false, errorMessage: 'Invalid build_mode value' })).toBe('validation_error')
    expect(mapBuildFailureCategory({ timeoutApplied: false, errorMessage: 'missing credentials' })).toBe('validation_error')
  })

  it.concurrent('returns builder_error when there is any other non-empty error', () => {
    expect(mapBuildFailureCategory({ timeoutApplied: false, errorMessage: 'gradle compile failed' })).toBe('builder_error')
  })

  it.concurrent('returns unknown when timeoutApplied is false and error is empty', () => {
    expect(mapBuildFailureCategory({ timeoutApplied: false, errorMessage: null })).toBe('unknown')
    expect(mapBuildFailureCategory({ timeoutApplied: false, errorMessage: '' })).toBe('unknown')
  })
})

describe('getBuilderXcodeVersion', () => {
  it.concurrent('reads the Xcode version reported by the builder', () => {
    expect(getBuilderXcodeVersion({ backend: 'mac', xcode_version: '26.1', macos_version: '15.6' })).toBe('26.1')
    expect(getBuilderXcodeVersion({ backend: 'linux', xcode_version: '27' })).toBe('27')
  })

  it.concurrent('ignores missing or malformed versions', () => {
    expect(getBuilderXcodeVersion(null)).toBeNull()
    expect(getBuilderXcodeVersion({})).toBeNull()
    expect(getBuilderXcodeVersion({ xcode_version: 26 })).toBeNull()
    expect(getBuilderXcodeVersion({ xcode_version: 'Xcode 26.1' })).toBeNull()
  })
})