UDT-011: Localización Temporal Argentina (infra transversal) #25

Merged
dmolinari merged 24 commits from feature/UDT-011 into main 2026-04-18 13:57:49 +00:00
10 changed files with 16 additions and 49 deletions
Showing only changes of commit a5fd3e90fb - Show all commits

View File

@@ -2,7 +2,8 @@ import * as React from "react"
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
import { cn } from "@/lib/utils"
import { ButtonProps, buttonVariants } from "@/components/ui/button"
import type { ButtonProps } from "@/components/ui/button"
import { buttonVariants } from "@/components/ui/button"
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav

View File

@@ -34,11 +34,10 @@ const medioFormSchema = z.object({
.string()
.min(1, 'El nombre es requerido')
.max(100, 'Máximo 100 caracteres'),
tipo: z.coerce.number().refine((v) => v >= 1, 'Seleccioná un tipo válido'),
tipo: z.coerce.number<number>().refine((v) => v >= 1, 'Seleccioná un tipo válido'),
plataformaEmpresaId: z
.union([z.coerce.number().int().positive('Debe ser un número positivo'), z.literal('')])
.optional()
.transform((v) => (v === '' || v === undefined ? null : Number(v))),
.union([z.coerce.number<number>().int().positive('Debe ser un número positivo'), z.literal('')])
.optional(),
})
export type MedioFormValues = z.infer<typeof medioFormSchema>

View File

@@ -29,7 +29,7 @@ import type { SeccionDetail, TipoSeccion } from '../types'
const TIPO_SECCION_VALUES = ['clasificados', 'notables', 'suplementos'] as const
const seccionFormSchema = z.object({
medioId: z.coerce.number().refine((v) => v >= 1, 'Seleccioná un medio'),
medioId: z.coerce.number<number>().refine((v) => v >= 1, 'Seleccioná un medio'),
codigo: z
.string()
.min(1, 'El código es requerido')
@@ -38,7 +38,7 @@ const seccionFormSchema = z.object({
.string()
.min(1, 'El nombre es requerido')
.max(100, 'Máximo 100 caracteres'),
tipo: z.enum(TIPO_SECCION_VALUES, { errorMap: () => ({ message: 'Seleccioná un tipo válido' }) }),
tipo: z.enum(TIPO_SECCION_VALUES, { error: 'Seleccioná un tipo válido' }),
})
export type SeccionFormValues = z.infer<typeof seccionFormSchema>

View File

@@ -5,42 +5,10 @@ import { useAuthStore } from '../../../stores/authStore'
import { ProtectedRoute } from '../../../components/routing/ProtectedRoute'
// Helper components for testing
function HomePage() {
return <div>Home Page</div>
}
function SecurePage() {
return <div>Secure Page</div>
}
// Renders ProtectedRoute at a given path with optional navigation target capture
function renderProtected(
props: {
requiredRoles?: string[]
requiredPermissions?: string[]
children?: React.ReactNode
},
{ initialPath = '/' }: { initialPath?: string } = {},
) {
const { children, ...routeProps } = props
return render(
<MemoryRouter initialEntries={[initialPath]}>
<Routes>
<Route path="/login" element={<div>Login Page</div>} />
<Route path="/" element={<div>Root</div>} />
<Route
path="/secure"
element={
<ProtectedRoute {...routeProps}>
{children ?? <SecurePage />}
</ProtectedRoute>
}
/>
</Routes>
</MemoryRouter>,
)
}
beforeEach(() => {
useAuthStore.setState({ user: null, accessToken: null, refreshToken: null, expiresAt: null })
})

View File

@@ -1,7 +1,7 @@
// T600.5 — TDD: TipoDeIvaFormModal
// CRÍTICO: verifica que el modal de Editar NO tiene campo Porcentaje [REQ-UI-003]
// T600.10 — BUG-FE-03 regression: default vigenciaDesde usa todayArgentina (no UTC)
import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'
import { describe, it, expect, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

View File

@@ -1,4 +1,4 @@
import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'
import { describe, it, expect, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

View File

@@ -80,7 +80,7 @@ describe('SeccionForm — create mode', () => {
await userEvent.type(screen.getByLabelText(/nombre/i), 'Mi Sección')
await userEvent.click(screen.getByRole('button', { name: /crear sección/i }))
await waitFor(() =>
expect(screen.getByText(/seleccioná un tipo/i)).toBeInTheDocument(),
expect(screen.getByText(/seleccioná un tipo válido/i)).toBeInTheDocument(),
)
})

View File

@@ -1,6 +1,5 @@
import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

View File

@@ -1,5 +1,5 @@
import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'
import { render, screen, waitFor, within } from '@testing-library/react'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'

View File

@@ -6,11 +6,11 @@ import { updateUserPermisosOverrides } from '../../../features/users/api/updateU
const API_URL = 'http://localhost:5000'
const mockResponse = {
usuarioId: 42,
rol: 'cajero',
rolPermisos: ['ventas:contado:crear'],
overrides: {
grant: ['textos:editar'],
deny: [],
},
effective: ['ventas:contado:crear', 'textos:editar'],
}
@@ -35,7 +35,7 @@ describe('updateUserPermisosOverrides api client', () => {
deny: [],
})
expect(result.grant).toEqual(['textos:editar'])
expect(result.overrides.grant).toEqual(['textos:editar'])
expect(result.effective).toContain('textos:editar')
expect(capturedBody).toMatchObject({ grant: ['textos:editar'], deny: [] })
})