feat: Implement multi-tenancy support in middleware and security layers

- Enhanced TenantMiddleware to validate tenant information from JWT tokens.
- Added LicenseValidationMiddleware to check tenant licenses before processing requests.
- Updated security utilities to extract tenant information from tokens and validate company access.
- Introduced CompanyStore to manage active company state and handle company switching in the frontend.
- Modified API routes to include company_id in requests for better resource management.
- Improved logging and error handling throughout the middleware and API layers.
- Updated frontend components to reflect changes in company management and selection.
- Added new API route for fetching user's companies with proper authentication handling.
This commit is contained in:
2025-11-11 14:00:56 -06:00
parent e1eb6bbd01
commit 52b8fcd434
242 changed files with 7067 additions and 3274 deletions

View File

@@ -2,9 +2,9 @@ from pydantic import BaseModel, Field
from pydantic import ConfigDict
from typing import Optional
class PedimentoCodeDTO(BaseModel):
code: str = Field(..., min_length=1, max_length=3)
description: str
model_config = ConfigDict(from_attributes=True)

View File

@@ -5,25 +5,23 @@ from core.database import Base
if TYPE_CHECKING:
from ..code_pedimento_regimens.models import CodePedimentoRegimen
class PedimentoCode(Base):
__tablename__ = "pedimento_codes" # GClavePed
__table_args__ = (
PrimaryKeyConstraint("code", name="pedimento_codes_pkey"),
{"schema": "public"} # esquema del anexo 22
{"schema": "public"}, # esquema del anexo 22
)
code: Mapped[str] = mapped_column(String(3), nullable=False)
code: Mapped[str] = mapped_column(String(3), nullable=False)
description: Mapped[str] = mapped_column(String(250), nullable=False)
# Relación con los regímenes asociados
#GClavePedRegimen
regimens: Mapped[List['CodePedimentoRegimen']] = relationship(
"CodePedimentoRegimen",
uselist=True,
back_populates="pedimento"
# GClavePedRegimen
regimens: Mapped[List["CodePedimentoRegimen"]] = relationship(
"CodePedimentoRegimen", uselist=True, back_populates="pedimento"
)
def __repr__(self):
return f"<PedimentoCode(code={self.code}, description={self.description})>"
return f"<PedimentoCode(code={self.code}, description={self.description})>"

View File

@@ -1,4 +1,3 @@
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from core.database import get_core_db
@@ -16,7 +15,7 @@ def list_pedimento_codes(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user)
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(PedimentoCode)
@@ -26,21 +25,27 @@ def list_pedimento_codes(
"items": [PedimentoCodeDTO.model_validate(obj) for obj in items],
"total": total,
"page": page,
"page_size": page_size
"page_size": page_size,
}
@router.get("/{code}", response_model=PedimentoCodeDTO)
def get_pedimento_code(code: str, db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)):
def get_pedimento_code(
code: str,
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
obj = db.query(PedimentoCode).filter(PedimentoCode.code == code).first()
if not obj:
raise HTTPException(status_code=404, detail="Not found")
return obj
@router.post("/", response_model=PedimentoCodeDTO, status_code=201)
def create_pedimento_code(
data: PedimentoCodeDTO,
db: Session = Depends(get_core_db),
current_user: dict = Depends(has_role("admin"))
current_user: dict = Depends(has_role("admin")),
):
obj = PedimentoCode(**data.dict())
db.add(obj)
@@ -48,12 +53,13 @@ def create_pedimento_code(
db.refresh(obj)
return obj
@router.put("/{code}", response_model=PedimentoCodeDTO)
def update_pedimento_code(
code: str,
data: PedimentoCodeDTO,
db: Session = Depends(get_core_db),
current_user: dict = Depends(has_role("admin"))
current_user: dict = Depends(has_role("admin")),
):
obj = db.query(PedimentoCode).filter(PedimentoCode.code == code).first()
if not obj:
@@ -64,11 +70,12 @@ def update_pedimento_code(
db.refresh(obj)
return obj
@router.delete("/{code}", status_code=204)
def delete_pedimento_code(
code: str,
db: Session = Depends(get_core_db),
current_user: dict = Depends(has_role("admin"))
current_user: dict = Depends(has_role("admin")),
):
obj = db.query(PedimentoCode).filter(PedimentoCode.code == code).first()
if not obj:

View File

@@ -3,27 +3,69 @@ seed = [
("A3", "REGULARIZACION DE MERCANCIAS (IMPORTACION DEFINITIVA)."),
("A4", "INTRODUCCION PARA DEPOSITO FISCAL (AGD)."),
("A5", "INTRODUCCION A DEPOSITO FISCAL EN LOCAL AUTORIZADO."),
("A6", "IMPORTACIÓN TEMPORAL DE BIENES DE ACTIVO FIJO POR PARTE DE EMPRESAS CON PITEX."),
("AD", "IMPORTACIÓN TEMPORAL DE MERCANCIAS DESTINADAS A CONVENCIONES Y CONGRESOS INTERNACIONALES (ARTICULO 106, FRACCION III, INCISO A) DE LA LEY)."),
(
"A6",
"IMPORTACIÓN TEMPORAL DE BIENES DE ACTIVO FIJO POR PARTE DE EMPRESAS CON PITEX.",
),
(
"AD",
"IMPORTACIÓN TEMPORAL DE MERCANCIAS DESTINADAS A CONVENCIONES Y CONGRESOS INTERNACIONALES (ARTICULO 106, FRACCION III, INCISO A) DE LA LEY).",
),
("AF", "IMPORTACION TEMPORAL DE BIENES DE ACTIVO FIJO (IMMEX)."),
("AJ", "IMPORTACION Y EXPORTACION TEMPORAL DE ENVASES DE MERCANCIAS (ARTICULOS 106, FRACCION II, INCISO B) Y 116, FRACCION II, INCISO A) DE LA LEY)."),
("BA", "IMPORTACION Y EXPORTACION TEMPORAL DE BIENES PARA SER RETORNADOS EN SU MISMO ESTADO. (ARTICULO 106, FRACCIONES II, INCISOS A) Y C), Y IV, INCISO B) DE LA LEY)."),
(
"AJ",
"IMPORTACION Y EXPORTACION TEMPORAL DE ENVASES DE MERCANCIAS (ARTICULOS 106, FRACCION II, INCISO B) Y 116, FRACCION II, INCISO A) DE LA LEY).",
),
(
"BA",
"IMPORTACION Y EXPORTACION TEMPORAL DE BIENES PARA SER RETORNADOS EN SU MISMO ESTADO. (ARTICULO 106, FRACCIONES II, INCISOS A) Y C), Y IV, INCISO B) DE LA LEY).",
),
("BB", "EXPORTACION, IMPORTACION Y RETORNOS VIRTUALES."),
("BC", "IMPORTACION Y EXPORTACION TEMPORAL DE MERCANCIAS DESTINADAS A EVENTOS CULTURALES O DEPORTIVOS (ARTICULO 106, FRACCION III, INCISO B DE LA LEY)."),
("BD", "IMPORTACION Y EXPORTACION TEMPORAL DE EQUIPO PARA FILMACION (ARTICULOS 106, FRACCION III, INCISO C) Y 116, FRACCION II INCISO D) DE LA LEY)."),
("BE", "IMPORTACION Y EXPORTACION TEMPORAL DE VEHICULOS DE PRUEBA (ARTICULO 106, FRACCION III, INCISO D) DE LA LEY)."),
("BF", "EXPORTACION TEMPORAL DE MERCANCIAS DESTINADAS A EXPOSICIONES, CONVENCIONES O EVENTOS CULTURALES O DEPORTIVOS (ARTICULO 116, FRACCION III DE LA LEY)."),
("BH", "IMPORTACION TEMPORAL DE CONTENEDORES, AVIONES, HELICOPTEROS, EMBARCACIONES Y CARROS DE FERROCARRIL (ARTICULO 106, FRACCION V, INCISOS A), B) Y E) DE LA LEY)."),
(
"BC",
"IMPORTACION Y EXPORTACION TEMPORAL DE MERCANCIAS DESTINADAS A EVENTOS CULTURALES O DEPORTIVOS (ARTICULO 106, FRACCION III, INCISO B DE LA LEY).",
),
(
"BD",
"IMPORTACION Y EXPORTACION TEMPORAL DE EQUIPO PARA FILMACION (ARTICULOS 106, FRACCION III, INCISO C) Y 116, FRACCION II INCISO D) DE LA LEY).",
),
(
"BE",
"IMPORTACION Y EXPORTACION TEMPORAL DE VEHICULOS DE PRUEBA (ARTICULO 106, FRACCION III, INCISO D) DE LA LEY).",
),
(
"BF",
"EXPORTACION TEMPORAL DE MERCANCIAS DESTINADAS A EXPOSICIONES, CONVENCIONES O EVENTOS CULTURALES O DEPORTIVOS (ARTICULO 116, FRACCION III DE LA LEY).",
),
(
"BH",
"IMPORTACION TEMPORAL DE CONTENEDORES, AVIONES, HELICOPTEROS, EMBARCACIONES Y CARROS DE FERROCARRIL (ARTICULO 106, FRACCION V, INCISOS A), B) Y E) DE LA LEY).",
),
("BI", "IMPORTACION TEMPORAL (ARTICULO 106, FRACCION III, INCISO E) DE LA LEY)."),
("BM", "EXPORTACION TEMPORAL DE MERCANCIAS PARA SU TRANSFORMACION, ELABORACION O REPARACION (ARTICULO 117 DE LA LEY)."),
("BO", "EXPORTACION TEMPORAL PARA REPARACION O SUSTITUCION Y RETORNO AL PAIS (IMMEX, RFE U OPERADOR ECONOMICO AUTORIZADO."),
("BP", "IMPORTACION Y EXPORTACION TEMPORAL DE MUESTRAS O MUESTRARIOS (ARTICULOS 106, FRACCION II, INCISO D) Y 116, FRACCION II, INCISO C) DE LA LEY)."),
(
"BM",
"EXPORTACION TEMPORAL DE MERCANCIAS PARA SU TRANSFORMACION, ELABORACION O REPARACION (ARTICULO 117 DE LA LEY).",
),
(
"BO",
"EXPORTACION TEMPORAL PARA REPARACION O SUSTITUCION Y RETORNO AL PAIS (IMMEX, RFE U OPERADOR ECONOMICO AUTORIZADO.",
),
(
"BP",
"IMPORTACION Y EXPORTACION TEMPORAL DE MUESTRAS O MUESTRARIOS (ARTICULOS 106, FRACCION II, INCISO D) Y 116, FRACCION II, INCISO C) DE LA LEY).",
),
("BR", "EXPORTACION TEMPORAL Y RETORNO DE MERCANCIAS FUNGIBLES."),
("C1", "IMPORTACION DEFINITIVA A LA FRANJA FRONTERIZA NORTE Y REGION FRONTERIZA AL AMPARO DEL „DECRETO DE LA FRANJA O REGION FRONTERIZA“ (DOF 24/12/2008 Y SUS POSTERIORES MODIFICACIONES)."),
(
"C1",
"IMPORTACION DEFINITIVA A LA FRANJA FRONTERIZA NORTE Y REGION FRONTERIZA AL AMPARO DEL „DECRETO DE LA FRANJA O REGION FRONTERIZA“ (DOF 24/12/2008 Y SUS POSTERIORES MODIFICACIONES).",
),
("C3", "EXTRACCION DE DEPOSITO FISCAL DE FRANJA O REGION FRONTERIZA (AGD)."),
("CT", "PEDIMENTO COMPLEMENTARIO."),
("D1", "RETORNO POR SUSTITUCION."),
("E1", "EXTRACCION DE DEPOSITO FISCAL DE BIENES QUE SERAN SUJETOS A TRANSFORMACION, ELABORACION O REPARACION (AGD)."),
(
"E1",
"EXTRACCION DE DEPOSITO FISCAL DE BIENES QUE SERAN SUJETOS A TRANSFORMACION, ELABORACION O REPARACION (AGD).",
),
("E2", "EXTRACCION DE DEPOSITO FISCAL DE BIENES DE ACTIVO FIJO (AGD)."),
("E3", "EXTRACCION DE DEPOSITO FISCAL EN LOCAL AUTORIZADO (INSUMOS)."),
("E4", "EXTRACCION DE DEPOSITO FISCAL EN LOCAL AUTORIZADO (ACTIVO FIJO)."),
@@ -31,49 +73,112 @@ seed = [
("F3", "EXTRACCION DE DEPOSITO FISCAL (IA)."),
("F4", "CAMBIO DE REGIMEN DE INSUMOS O DE MERCANCIA EXPORTADA TEMPORALMENTE."),
("F5", "CAMBIO DE REGIMEN DE MERCANCÍAS DE IMPORTACIÓN TEMPORAL A DEFINITIVA."),
("F8", "INTRODUCCION Y EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS NACIONALES O NACIONALIZADAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE)."),
("F9", "INTRODUCCION Y EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS EXTRANJERAS PARA EXPOSICION Y VENTA DE MERCANCIAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE)."),
(
"F8",
"INTRODUCCION Y EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS NACIONALES O NACIONALIZADAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE).",
),
(
"F9",
"INTRODUCCION Y EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS EXTRANJERAS PARA EXPOSICION Y VENTA DE MERCANCIAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE).",
),
("G1", "EXTRACCION DE DEPOSITO FISCAL (AGD)."),
("G2", "EXTRACCION DE DEPOSITO FISCAL EN LOCAL AUTORIZADO PARA SU IMPORTACION DEFINITIVA."),
("G6", "INFORME DE EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS NACIONALES O NACIONALIZADAS VENDIDAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE)."),
("G7", "INFORME DE EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS EXTRANJERAS VENDIDAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE)."),
(
"G2",
"EXTRACCION DE DEPOSITO FISCAL EN LOCAL AUTORIZADO PARA SU IMPORTACION DEFINITIVA.",
),
(
"G6",
"INFORME DE EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS NACIONALES O NACIONALIZADAS VENDIDAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE).",
),
(
"G7",
"INFORME DE EXTRACCION DE DEPOSITO FISCAL DE MERCANCIAS EXTRANJERAS VENDIDAS EN TIENDAS LIBRES DE IMPUESTOS (DUTY FREE).",
),
("G8", "REINCORPORAR AL MERCADO NACIONAL (RFE)."),
("G9", "TRANSFERENCIA DE MERCANCÍAS DE RECINTO FISCALIZADO ESTRATEGICO NO COLINDANTE CON LA ADUANA (RETIRO VIRTUAL PARA IMPORTACIÓN DEFINTIVA POR RESIDENTES EN TERRITORIO NACIONAL)."),
(
"G9",
"TRANSFERENCIA DE MERCANCÍAS DE RECINTO FISCALIZADO ESTRATEGICO NO COLINDANTE CON LA ADUANA (RETIRO VIRTUAL PARA IMPORTACIÓN DEFINTIVA POR RESIDENTES EN TERRITORIO NACIONAL).",
),
("GC", "GLOBAL COMPLEMENTARIO."),
("H1", "RETORNO DE MERCANCIAS EN SU MISMO ESTADO."),
("H8", "RETORNO DE ENVASES."),
("I1", "IMPORTACION, EXPORTACION Y RETORNO DE MERCANCIAS ELABORADAS, TRANSFORMADAS O REPARADAS."),
("IN", "IMPORTACION TEMPORAL DE BIENES QUE SERAN SUJETOS A TRANSFORMACION, ELABORACION O REPARACION (IMMEX)."),
("J3", "RETORNO Y EXPORTACION DE INSUMOS ELABORADOS O TRANSFORMADOS EN RECINTO FISCALIZADO."),
(
"I1",
"IMPORTACION, EXPORTACION Y RETORNO DE MERCANCIAS ELABORADAS, TRANSFORMADAS O REPARADAS.",
),
(
"IN",
"IMPORTACION TEMPORAL DE BIENES QUE SERAN SUJETOS A TRANSFORMACION, ELABORACION O REPARACION (IMMEX).",
),
(
"J3",
"RETORNO Y EXPORTACION DE INSUMOS ELABORADOS O TRANSFORMADOS EN RECINTO FISCALIZADO.",
),
("J4", "RETORNO DE MERCANCIAS EXTRANJERAS (RFE)."),
("K1", "DESISTIMIENTO DE REGIMEN Y RETORNO DE MERCANCIAS POR DEVOLUCION."),
("K2", "EXTRACCION DE DEPOSITO FISCAL POR DESISTIMIENTO O TRANSFERENCIAS (AGD)."),
("K3", "EXTRACCION DE DEPOSITO FISCAL EN LOCAL AUTORIZADO PARA RETORNO O TRANSFERENCIA."),
(
"K3",
"EXTRACCION DE DEPOSITO FISCAL EN LOCAL AUTORIZADO PARA RETORNO O TRANSFERENCIA.",
),
("L1", "PEQUEÑA IMPORTACION DEFINITIVA."),
("M1", "INTRODUCCION Y EXPORTACION DE INSUMOS."),
("M2", "INTRODUCCION Y EXPORTACION DE MAQUINARIA Y EQUIPO."),
("M3", "INTRODUCCION DE MERCANCIAS (RFE)."),
("M4", "INTRODUCCION DE ACTIVO FIJO (RFE)."),
("M5", "INTRODUCCION DE MERCANCIA NACIONAL O NACIONALIZADA (RFE)."),
("P1", "REEXPEDICION DE MERCANCIAS DE FRANJA FRONTERIZA O REGION FRONTERIZA AL INTERIOR DEL PAIS."),
(
"P1",
"REEXPEDICION DE MERCANCIAS DE FRANJA FRONTERIZA O REGION FRONTERIZA AL INTERIOR DEL PAIS.",
),
("R1", "RECTIFICACION DE PEDIMENTOS."),
("RT", "RETORNO DE MERCANCIAS (IMMEX)."),
("S2", "IMPORTACION Y EXPORTACION DE MERCANCIAS PARA RETORNAR EN SU MISMO ESTADO (ARTICULO 86 DE LA LEY)."),
(
"S2",
"IMPORTACION Y EXPORTACION DE MERCANCIAS PARA RETORNAR EN SU MISMO ESTADO (ARTICULO 86 DE LA LEY).",
),
("T1", "IMPORTACION Y EXPORTACION POR EMPRESAS DE MENSAJERIA."),
("T3", "TRANSITO INTERNO."),
("T6", "TRANSITO INTERNACIONAL POR TERRITORIO EXTRANJERO."),
("T7", "TRANSITO INTERNACIONAL POR TERRITORIO NACIONAL."),
("T9", "TRANSITO INTERNACIONAL DE TRANSMIGRANTES."),
("V1", "TRANSFERENCIAS DE MERCANCIAS (IMPORTACION TEMPORAL VIRTUAL; INTRODUCCION VIRTUAL A DEPOSITO FISCAL O A RECINTO FISCALIZADO ESTRATEGICO; RETORNO VIRTUAL; EXPORTACION VIRTUAL DE PROVEEDORES NACIONALES)."),
("V2", "TRANSFERENCIAS DE MERCANCIAS IMPORTADAS CON CUENTA ADUANERA (EXPORTACION E IMPORTACION VIRTUAL)."),
("V3", "EXTRACCION DE DEPOSITO FISCAL DE BIENES PARA SU RETORNO O EXPORTACION VIRTUAL (IA)."),
("V4", "RETORNO VIRTUAL DERIVADO DE LA CONSTANCIA DE TRANSFERENCIA DE MERCANCIAS (IA)."),
("V5", "TRANSFERENCIAS DE MERCANCIAS DE EMPRESAS CERTIFICADAS (RETORNO VIRTUAL PARA IMPORTACION DEFINITIVA)."),
("V6", "TRANSFERENCIAS DE MERCANCIAS SUJETAS A CUPO (IMPORTACION DEFINITIVA Y RETORNO VIRTUAL)."),
("V7", "TRANSFERENCIAS DEL SECTOR AZUCARERO (EXPORTACION VIRTUAL E IMPORTACION TEMPORAL VIRTUAL)."),
("V8", "TRANSFERENCIA DE MERCANCIAS EN DEPOSITO FISCAL PARA LA EXPOSICION Y VENTA DE MERCANCIAS EXTRANJERAS, NACIONALES Y NACIONALIZADAS DE TIENDAS LIBRES DE IMPUESTOS (DUTY FREE)."),
(
"V1",
"TRANSFERENCIAS DE MERCANCIAS (IMPORTACION TEMPORAL VIRTUAL; INTRODUCCION VIRTUAL A DEPOSITO FISCAL O A RECINTO FISCALIZADO ESTRATEGICO; RETORNO VIRTUAL; EXPORTACION VIRTUAL DE PROVEEDORES NACIONALES).",
),
(
"V2",
"TRANSFERENCIAS DE MERCANCIAS IMPORTADAS CON CUENTA ADUANERA (EXPORTACION E IMPORTACION VIRTUAL).",
),
(
"V3",
"EXTRACCION DE DEPOSITO FISCAL DE BIENES PARA SU RETORNO O EXPORTACION VIRTUAL (IA).",
),
(
"V4",
"RETORNO VIRTUAL DERIVADO DE LA CONSTANCIA DE TRANSFERENCIA DE MERCANCIAS (IA).",
),
(
"V5",
"TRANSFERENCIAS DE MERCANCIAS DE EMPRESAS CERTIFICADAS (RETORNO VIRTUAL PARA IMPORTACION DEFINITIVA).",
),
(
"V6",
"TRANSFERENCIAS DE MERCANCIAS SUJETAS A CUPO (IMPORTACION DEFINITIVA Y RETORNO VIRTUAL).",
),
(
"V7",
"TRANSFERENCIAS DEL SECTOR AZUCARERO (EXPORTACION VIRTUAL E IMPORTACION TEMPORAL VIRTUAL).",
),
(
"V8",
"TRANSFERENCIA DE MERCANCIAS EN DEPOSITO FISCAL PARA LA EXPOSICION Y VENTA DE MERCANCIAS EXTRANJERAS, NACIONALES Y NACIONALIZADAS DE TIENDAS LIBRES DE IMPUESTOS (DUTY FREE).",
),
("V9", "TRANSFERENCIAS DE MERCANCIAS POR DONACION"),
("VD", "VIRTUALES DIVERSOS."),
("VF", "IMPORTACION DEFINITIVA DE VEHICULOS USADOS A LA FRANJA O REGION FRONTERIZA NORTE."),
("VU", "IMPORTACION DEFINITIVA DE VEHICULOS USADOS.")
]
(
"VF",
"IMPORTACION DEFINITIVA DE VEHICULOS USADOS A LA FRANJA O REGION FRONTERIZA NORTE.",
),
("VU", "IMPORTACION DEFINITIVA DE VEHICULOS USADOS."),
]

View File

@@ -7,6 +7,7 @@ app = FastAPI()
app.include_router(router)
client = TestClient(app)
@pytest.mark.usefixtures("client", "access_token")
def test_list_pedimento_codes(client, access_token):
headers = {"Authorization": f"Bearer {access_token}"}
@@ -16,20 +17,28 @@ def test_list_pedimento_codes(client, access_token):
assert "page" in response.json()
assert "page_size" in response.json()
@pytest.mark.usefixtures("client", "access_token")
def test_get_pedimento_code_not_found(client, access_token):
headers = {"Authorization": f"Bearer {access_token}"}
response = client.get("/pedimento-codes/invalid_code", headers=headers)
assert response.status_code == 404
def test_create_pedimento_code_forbidden():
response = client.post("/pedimento-codes/", json={"code": "TST", "description": "Test"})
response = client.post(
"/pedimento-codes/", json={"code": "TST", "description": "Test"}
)
assert response.status_code in (403, 405, 404)
def test_update_pedimento_code_forbidden():
response = client.put("/pedimento-codes/TST", json={"code": "TST", "description": "Test"})
response = client.put(
"/pedimento-codes/TST", json={"code": "TST", "description": "Test"}
)
assert response.status_code in (403, 405, 404)
def test_delete_pedimento_code_forbidden():
response = client.delete("/pedimento-codes/TST")
assert response.status_code in (403, 405, 404)