mirror of
https://github.com/fusion44/blitz_api.git
synced 2026-08-13 11:52:45 +02:00
refactor(lightning): migrate SendCoinsInput validator to Pydantic v2
Replace the deprecated Pydantic v1 @validator('amount', pre=True,
always=True) with a v2 @model_validator(mode='after'). The model
validator always runs and can see both amount and send_all, preserving
the cross-field rule (and the always=True semantics that reject the
empty/default case). Removes the last Pydantic v1 deprecation warning.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
cf423f52c1
commit
df62098cd1
2 changed files with 46 additions and 17 deletions
|
|
@ -6,7 +6,7 @@ from typing import List, Optional, Union
|
|||
from deepdiff import DeepDiff
|
||||
from fastapi.param_functions import Query
|
||||
from loguru import logger
|
||||
from pydantic import BaseModel, validator
|
||||
from pydantic import BaseModel, model_validator
|
||||
from pydantic.types import conint
|
||||
|
||||
import app.lightning.docs as docs
|
||||
|
|
@ -1320,12 +1320,10 @@ class SendCoinsInput(BaseModel):
|
|||
),
|
||||
)
|
||||
|
||||
@validator("amount", pre=True, always=True)
|
||||
def check_amount_or_send_all(cls, amount, values):
|
||||
if amount is None:
|
||||
amount = 0
|
||||
|
||||
send_all = values.get("send_all") if "send_all" in values else False
|
||||
@model_validator(mode="after")
|
||||
def check_amount_or_send_all(self):
|
||||
amount = self.amount if self.amount is not None else 0
|
||||
send_all = self.send_all
|
||||
|
||||
if amount < 0:
|
||||
raise ValueError("Amount must not be negative")
|
||||
|
|
@ -1339,10 +1337,6 @@ class SendCoinsInput(BaseModel):
|
|||
)
|
||||
)
|
||||
|
||||
if amount > 0 and not send_all:
|
||||
# amount is set and send_all is false
|
||||
return amount
|
||||
|
||||
if amount > 0 and send_all:
|
||||
# amount is set and send_all is true
|
||||
raise ValueError(
|
||||
|
|
@ -1352,12 +1346,8 @@ class SendCoinsInput(BaseModel):
|
|||
)
|
||||
)
|
||||
|
||||
if amount == 0 and send_all:
|
||||
# amount is not set and send_all is true
|
||||
return amount
|
||||
|
||||
# normally this should never be reached
|
||||
raise ValueError("Unknown input.")
|
||||
# valid: (amount > 0 and not send_all) or (amount == 0 and send_all)
|
||||
return self
|
||||
|
||||
|
||||
class SendCoinsResponse(BaseModel):
|
||||
|
|
|
|||
39
tests/test_send_coins_input.py
Normal file
39
tests/test_send_coins_input.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
"""
|
||||
Characterization tests for SendCoinsInput.amount / send_all validation.
|
||||
|
||||
These lock the behaviour of the amount/send_all cross-field rule while the
|
||||
Pydantic v1 `@validator` is migrated to v2. They must pass before and after
|
||||
the migration.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from app.lightning.models import SendCoinsInput
|
||||
|
||||
|
||||
def test_neither_amount_nor_send_all_is_rejected():
|
||||
with pytest.raises(ValidationError):
|
||||
SendCoinsInput(address="bc1qexample")
|
||||
|
||||
|
||||
def test_zero_amount_without_send_all_is_rejected():
|
||||
with pytest.raises(ValidationError):
|
||||
SendCoinsInput(address="bc1qexample", amount=0)
|
||||
|
||||
|
||||
def test_amount_and_send_all_together_is_rejected():
|
||||
with pytest.raises(ValidationError):
|
||||
SendCoinsInput(address="bc1qexample", amount=1000, send_all=True)
|
||||
|
||||
|
||||
def test_positive_amount_is_accepted():
|
||||
m = SendCoinsInput(address="bc1qexample", amount=1000)
|
||||
assert m.amount == 1000
|
||||
assert m.send_all is False
|
||||
|
||||
|
||||
def test_send_all_without_amount_is_accepted():
|
||||
m = SendCoinsInput(address="bc1qexample", send_all=True)
|
||||
assert m.send_all is True
|
||||
assert m.amount == 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue