add test to checkout
This commit is contained in:
@@ -47,6 +47,7 @@ app.include_router(users.emails, prefix='/users')
|
||||
app.include_router(users.orgs, prefix='/users')
|
||||
app.include_router(users.password, prefix='/users')
|
||||
app.include_router(orders.router, prefix='/orders')
|
||||
app.include_router(orders.checkout, prefix='/orders')
|
||||
app.include_router(orgs.add, prefix='/orgs')
|
||||
app.include_router(orgs.admins, prefix='/orgs')
|
||||
app.include_router(orgs.billing, prefix='/orgs')
|
||||
@@ -64,7 +65,7 @@ def health():
|
||||
|
||||
@app.exception_handler(ServiceError)
|
||||
def exc_error(exc: ServiceError):
|
||||
# logger.exception(exc)
|
||||
logger.exception(exc)
|
||||
|
||||
return JSONResponse(
|
||||
body={
|
||||
|
||||
@@ -7,6 +7,10 @@ from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ORDER_TABLE
|
||||
|
||||
from .checkout import router as checkout
|
||||
|
||||
__all__ = ['checkout']
|
||||
|
||||
router = Router()
|
||||
dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
|
||||
|
||||
|
||||
89
api.saladeaula.digital/app/routes/orders/checkout.py
Normal file
89
api.saladeaula.digital/app/routes/orders/checkout.py
Normal file
@@ -0,0 +1,89 @@
|
||||
import re
|
||||
from decimal import Decimal
|
||||
from http import HTTPStatus
|
||||
from typing import Annotated, Literal
|
||||
|
||||
from aws_lambda_powertools.event_handler.api_gateway import Router
|
||||
from aws_lambda_powertools.event_handler.openapi.params import Body
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer
|
||||
from layercake.extra_types import CnpjStr, CpfStr, NameStr
|
||||
from pydantic import (
|
||||
UUID4,
|
||||
BaseModel,
|
||||
ConfigDict,
|
||||
EmailStr,
|
||||
field_validator,
|
||||
model_validator,
|
||||
)
|
||||
|
||||
from api_gateway import JSONResponse
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ORDER_TABLE
|
||||
|
||||
router = Router()
|
||||
dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: UUID4 | str
|
||||
name: NameStr
|
||||
|
||||
|
||||
class Address(BaseModel):
|
||||
model_config = ConfigDict(str_strip_whitespace=True)
|
||||
|
||||
postcode: str
|
||||
address1: str
|
||||
address2: str | None = None
|
||||
neighborhood: str
|
||||
city: str
|
||||
state: str
|
||||
|
||||
@field_validator('postcode')
|
||||
@classmethod
|
||||
def ensure_numbers(cls, v: str) -> str:
|
||||
return re.sub(r'\D', '', v)
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
id: UUID4
|
||||
name: str
|
||||
unit_price: Decimal
|
||||
quantity: int = 1
|
||||
|
||||
|
||||
class Checkout(BaseModel):
|
||||
model_config = ConfigDict(str_strip_whitespace=True)
|
||||
|
||||
name: str
|
||||
email: EmailStr
|
||||
address: Address
|
||||
payment_method: Literal['PIX', 'CREDIT_CARD', 'BANK_SLIP', 'MANUAL']
|
||||
items: tuple[Item, ...]
|
||||
user: User | None = None
|
||||
org_id: UUID4 | str | None = None
|
||||
user_id: UUID4 | str | None = None
|
||||
cnpj: CnpjStr | None = None
|
||||
cpf: CpfStr | None = None
|
||||
|
||||
@model_validator(mode='after')
|
||||
def verify_fields(self):
|
||||
if not any([self.cnpj, self.cpf]):
|
||||
raise ValueError('cnpj or cpf is required')
|
||||
|
||||
if self.cnpj is not None:
|
||||
if self.org_id is None:
|
||||
raise ValueError('org_id is missing')
|
||||
|
||||
if self.user is None:
|
||||
raise ValueError('user is missing')
|
||||
|
||||
if self.cpf is not None and self.user_id is None:
|
||||
raise ValueError('user_id is missing')
|
||||
|
||||
return self
|
||||
|
||||
|
||||
@router.post('/')
|
||||
def checkout(body: Annotated[Checkout, Body()]):
|
||||
return JSONResponse(status_code=HTTPStatus.CREATED)
|
||||
@@ -11,7 +11,6 @@ from pydantic import FutureDatetime
|
||||
from api_gateway import JSONResponse
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ENROLLMENT_TABLE
|
||||
from middlewares.authentication_middleware import User as Authenticated
|
||||
|
||||
from ...enrollments.enroll import Enrollment, Org, Subscription, enroll_now
|
||||
|
||||
|
||||
91
api.saladeaula.digital/tests/routes/orders/test_checkout.py
Normal file
91
api.saladeaula.digital/tests/routes/orders/test_checkout.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from http import HTTPMethod, HTTPStatus
|
||||
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer
|
||||
|
||||
from ...conftest import HttpApiProxy, LambdaContext
|
||||
|
||||
|
||||
def test_checkout(
|
||||
app,
|
||||
seeds,
|
||||
http_api_proxy: HttpApiProxy,
|
||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||
lambda_context: LambdaContext,
|
||||
):
|
||||
r = app.lambda_handler(
|
||||
http_api_proxy(
|
||||
raw_path='/orders',
|
||||
method=HTTPMethod.POST,
|
||||
body={
|
||||
'org_id': 'f6000f79-6e5c-49a0-952f-3bda330ef278',
|
||||
'cnpj': '00000000000191',
|
||||
'name': 'Branco do Brasil',
|
||||
'email': 'sergio@somosbeta.com.br',
|
||||
'payment_method': 'MANUAL',
|
||||
'user': {
|
||||
'id': '15bacf02-1535-4bee-9022-19d106fd7518',
|
||||
'name': 'Sérgio R Siqueira',
|
||||
},
|
||||
'address': {
|
||||
'city': 'Curitiba',
|
||||
'postcode': '81280350',
|
||||
'neighborhood': 'Cidade Industrial',
|
||||
'address1': 'Rua Monsenhor Ivo Zanlorenzi',
|
||||
'address2': 'nº 5190, ap 1802',
|
||||
'state': 'PR',
|
||||
},
|
||||
'items': [
|
||||
{
|
||||
'id': 'e1c44881-2fe3-484e-ada2-12b6bf5b9398',
|
||||
'name': 'NR-35 Segurança nos Trabalhos em Altura',
|
||||
'quantity': 2,
|
||||
'unit_price': 119,
|
||||
}
|
||||
],
|
||||
},
|
||||
),
|
||||
lambda_context,
|
||||
)
|
||||
print(r)
|
||||
assert r['statusCode'] == HTTPStatus.CREATED
|
||||
|
||||
|
||||
def test_checkout_from_user(
|
||||
app,
|
||||
seeds,
|
||||
http_api_proxy: HttpApiProxy,
|
||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||
lambda_context: LambdaContext,
|
||||
):
|
||||
r = app.lambda_handler(
|
||||
http_api_proxy(
|
||||
raw_path='/orders',
|
||||
method=HTTPMethod.POST,
|
||||
body={
|
||||
'user_id': '15bacf02-1535-4bee-9022-19d106fd7518',
|
||||
'cpf': '07879819908',
|
||||
'name': 'Sérgio R Siqueira',
|
||||
'email': 'sergio@somosbeta.com.br',
|
||||
'payment_method': 'MANUAL',
|
||||
'address': {
|
||||
'city': 'Curitiba',
|
||||
'postcode': '81280350',
|
||||
'neighborhood': 'Cidade Industrial',
|
||||
'address1': 'Rua Monsenhor Ivo Zanlorenzi',
|
||||
'address2': 'nº 5190, ap 1802',
|
||||
'state': 'PR',
|
||||
},
|
||||
'items': [
|
||||
{
|
||||
'id': 'e1c44881-2fe3-484e-ada2-12b6bf5b9398',
|
||||
'name': 'NR-35 Segurança nos Trabalhos em Altura',
|
||||
'quantity': 2,
|
||||
'unit_price': 119,
|
||||
}
|
||||
],
|
||||
},
|
||||
),
|
||||
lambda_context,
|
||||
)
|
||||
print(r)
|
||||
assert r['statusCode'] == HTTPStatus.CREATED
|
||||
Reference in New Issue
Block a user