home
  • Español
  • English
  • Português
  • Cómo trabajo
  • star Proyectos Destacados
  • Experiencia
  • mail Contacto
arrow_back Volver al proyecto Inicio

Testing del proyecto

Testing · Conciergo

5 archivos markdown (visión, unitarios, integración, e2e, GitHub Actions).

En esta página Testing · visión 0% expand_more
Testing · visión Comandos Por dónde empezar Testing · unitarios El perfil que sale de un token La cabecera Authorization La regla de las conexiones En el front Con qué Testing · integración La cadena del contrato Estado a 20 de octubre de 2026 Lo que el typecheck no ve Un primer test de integración Testing · flujos completos Recorrido como invitado Recorrido con dos cuentas Por qué no está automatizado Cómo sería Testing · CI Lo que hace de puerta hoy Un primer workflow Después

12-testing.md

Testing · visión

Conciergo no tiene tests automatizados: no hay Vitest, Jest ni Playwright instalados y no hay ficheros *.spec.* ni *.test.*. Lo que se comprueba hoy es el typecheck del workspace, la cadena del contrato OpenAPI y un recorrido a mano por la app.

Estado a 20 de octubre de 2026:

CapaHerramientaQué compruebaEstado
Unitarios——No hay
Tipos y contratotsc y OrvalQue contrato, código generado, API y páginas encajanLibrerías, API y scripts pasan; la web da 8 errores
Flujos completosA mano, en el navegadorCartel, mapa, apuntarse, conexiones y chatSin automatizar
CI——No hay workflow de tests; Vercel no ejecuta el typecheck

Comandos

pnpm install
pnpm run typecheck                               # tsc de librerías, apps y scripts
pnpm --filter @workspace/api-spec run codegen    # regenera desde openapi.yaml y compila las librerías

Por dónde empezar

El código tiene piezas fáciles de probar sin red. Cada documento de esta sección señala las que tocaría primero:

  1. Unitarios de las funciones puras de la API: profileFromPayload, readBearerToken y la regla de parejas de las conexiones.
  2. Integración HTTP con Supertest sobre app (se puede importar sin abrir un puerto) y una rama de Neon para cada ejecución.
  3. Un flujo completo con Playwright: dos cuentas de prueba que se apuntan al mismo bolo y se escriben.
  4. Un workflow que ejecute el typecheck en cada push, una vez arreglados los 8 errores.

13-testing-unit.md

Testing · unitarios

No hay tests unitarios ni un runner instalado. Estas son las piezas que no necesitan base de datos ni red y que serían las primeras en tenerlos.

El perfil que sale de un token

profileFromPayload() (artifacts/api-server/src/lib/neonAuth.ts) decide el nombre y el avatar de una cuenta nueva. Es una función pura sobre el payload del JWT:

const name = nameFromClaim || (email ? email.split("@")[0] : "") || "Usuario";
const avatarUrl =
  typeof payload.image === "string"
    ? payload.image
    : typeof payload.picture === "string"
      ? payload.picture
      : null;

Casos que valdría la pena fijar: nombre con espacios alrededor, sin nombre pero con email, sin nada ("Usuario"), y image frente a picture.

La cabecera Authorization

readBearerToken() devuelve el token o null. Casos: sin cabecera, otro esquema (Basic …), Bearer sin token y un token con espacios.

La regla de las conexiones

Al apuntarse, cada pareja se guarda con el id menor primero para que la restricción única la reconozca venga de quien venga:

const u1 = Math.min(user.id, attendee.userId);
const u2 = Math.max(user.id, attendee.userId);

Hoy vive dentro de la ruta. Sacarla a una función (pairFor(a, b)) permitiría probar que pairFor(7, 3) y pairFor(3, 7) dan lo mismo.

En el front

  • getAccessToken() y extractJwt() (src/lib/auth.ts): qué fuente gana cuando hay varias, y que un valor que no es un JWT no se envía.
  • La política de reintentos del QueryClient: tres veces un 401, ninguna un 404.

Con qué

Vitest encaja con el resto del workspace (Vite y ESM) y no necesita navegador para estas funciones.

14-testing-integration.md

Testing · integración

No hay tests de integración que hagan peticiones HTTP. La integración que sí se comprueba es la de los tipos: que el contrato, el código generado, la API y las páginas encajan.

La cadena del contrato

pnpm --filter @workspace/api-spec run codegen
pnpm run typecheck
  1. Orval lee lib/api-spec/openapi.yaml y regenera lib/api-client-react/src/generated y lib/api-zod/src/generated.
  2. tsc --build compila las librerías (db, api-zod, api-client-react).
  3. tsc --noEmit compila cada app (conciergo, api-server, mockup-sandbox) y scripts.

Si una página usa un campo que el contrato ya no tiene, el paso 3 falla. Si cambia una respuesta en el contrato y no se regenera, los tipos generados no coinciden con lo que usan las páginas.

Estado a 20 de octubre de 2026

PaqueteResultado
Librerías (tsc --build)Sin errores
artifacts/api-serverSin errores
artifacts/mockup-sandboxSin errores
scriptsSin errores
artifacts/conciergo8 errores

Los 8 errores de la web tienen tres causas:

ErroresDóndeCausa
3chat.tsx (2) y user-profile.tsxLos hooks generados piden queryKey cuando se les pasan opciones de consulta, y esas páginas pasan solo { enabled }
4event-map.tsxNo están instalados los tipos de Google Maps (@types/google.maps), así que google.maps no existe para TypeScript
1event-map.tsxsetOptions({ key, version: "weekly" }): la versión 2 del loader ya no acepta version

Ninguno rompe el build: Vite compila sin comprobar tipos y Vercel no ejecuta typecheck. Pero pnpm run build, que empieza por el typecheck, sí falla.

Lo que el typecheck no ve

  • El servidor no valida lo que recibe. Los tipos del cliente garantizan que el front envía bien los cuerpos, pero la API no los pasa por los esquemas Zod. Una petición hecha a mano con campos raros llega a Drizzle tal cual.
  • Nada ejecuta SQL. Que una consulta de Drizzle compile no dice que devuelva lo esperado.

Un primer test de integración

app.ts exporta la app sin abrir un puerto, así que Supertest puede llamarla directamente. Con una rama de Neon creada para cada ejecución (o un Postgres local) y un JWKS de prueba con su propia clave, el primer caso sería el corazón del producto: dos personas se apuntan al mismo bolo y GET /matches devuelve una conexión para cada una; si una se borra, la conexión y sus mensajes desaparecen.

15-testing-e2e.md

Testing · flujos completos

No hay Playwright ni otra herramienta de navegador. Los flujos se recorren a mano en producción.

Recorrido como invitado

  1. /: el titular «No dejes que un gran bolo se pierda» y los botones Entrar, Unirse y Explorar eventos.
  2. /events: los bolos con sus géneros; tocar un género filtra la lista.
  3. /events/map: un marcador por bolo; al tocarlo, su ficha con Inicia sesión para apuntarte.
  4. /events/:id: la ficha completa con el número de asistentes.
  5. La navegación solo enseña Eventos y Mapa.

Recorrido con dos cuentas

Hacen falta dos navegadores (o una ventana privada) con cuentas distintas:

  1. Cada cuenta se registra en /auth/sign-up; la primera petición crea su fila en users.
  2. La cuenta A se apunta a un bolo. La B se apunta al mismo.
  3. Las dos ven la conexión en /matches (como mucho 20 segundos después).
  4. A escribe en el chat. B ve el mensaje al volver a la pestaña o al abrir el chat; en producción no llega al instante (ver Arquitectura).
  5. B se borra del bolo: la conexión desaparece para las dos y el chat ya no abre.

Por qué no está automatizado

  • El login real pasa por Neon Auth y Google; un test necesita cuentas de prueba y un proyecto de Neon Auth que no sea el de producción.
  • El mapa necesita una clave de Google Maps con facturación.
  • Producción tiene una sola base de datos: un test que se apunta a bolos dejaría conexiones reales.

Cómo sería

Playwright contra la app en local (API con Socket.io y Vite), una rama de Neon nueva para cada ejecución y dos contextos de navegador con cuentas de prueba. El mapa se puede dejar fuera al principio: el flujo que importa es apuntarse, conectar y chatear.

16-testing-ci.md

Testing · CI

No hay ningún workflow que compile o pruebe el código. El único fichero en .github/workflows es portfolio-docs.yml, que pide al portfolio que se reconstruya cuando cambia docs/.

Lo que hace de puerta hoy

El build de Vercel en cada push a main. Si Vite o esbuild no pueden compilar, el deploy falla y producción sigue con la versión anterior. Un error de tipos no lo para, porque ese build no ejecuta tsc.

Un primer workflow

Sin secretos ni base de datos, solo con lo que ya existe:

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  typecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm run typecheck

pnpm/action-setup toma la versión de pnpm de packageManager. El job fallaría hoy por los 8 errores de la web (ver integración): arreglarlos es el paso previo.

Después

Cuando existan tests unitarios, un paso más en el mismo job. Los de integración y los flujos completos necesitarían una rama de Neon por ejecución y cuentas de prueba de Neon Auth guardadas como secretos.

En esta página

Testing · visión Comandos Por dónde empezar Testing · unitarios El perfil que sale de un token La cabecera Authorization La regla de las conexiones En el front Con qué Testing · integración La cadena del contrato Estado a 20 de octubre de 2026 Lo que el typecheck no ve Un primer test de integración Testing · flujos completos Recorrido como invitado Recorrido con dos cuentas Por qué no está automatizado Cómo sería Testing · CI Lo que hace de puerta hoy Un primer workflow Después

0% leído

folder_zip Descargar todos (ZIP)
Pregunta sobre Cristian Asistente con IA, solo datos públicos

Es un asistente automático y puede equivocarse. Para algo importante, escribe a Cristian.