fix: resolve CI failures for lead capture form

- Add mock for useSubmitEnterpriseLead in FE tests
- Change JSONB to JSON for SQLite compatibility in tests
- Fix ruff linting issues (line length, B017 violation)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
openhands
2026-03-20 02:19:57 +00:00
parent a8304868bb
commit 867ea8b374
5 changed files with 32 additions and 5 deletions

View File

@@ -23,7 +23,9 @@ router = APIRouter(prefix='/api/v1/forms', tags=['forms'])
class FormSubmissionRequest(BaseModel):
"""Request model for form submission."""
form_type: str = Field(..., max_length=50, description='Type of form being submitted')
form_type: str = Field(
..., max_length=50, description='Type of form being submitted'
)
answers: dict[str, Any] = Field(..., description='Form answers as key-value pairs')

View File

@@ -7,8 +7,7 @@ Uses JSON for flexible answer storage to support different form structures.
from datetime import datetime
from uuid import uuid4
from sqlalchemy import UUID, Column, DateTime, ForeignKey, Index, String
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy import JSON, UUID, Column, DateTime, ForeignKey, Index, String
from sqlalchemy.sql import func
from storage.base import Base
@@ -20,7 +19,7 @@ class FormSubmission(Base): # type: ignore
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
form_type = Column(String(50), nullable=False, index=True)
answers = Column(JSONB, nullable=False)
answers = Column(JSON, nullable=False)
status = Column(String(20), nullable=False, default='pending')
user_id = Column(UUID(as_uuid=True), ForeignKey('user.id'), nullable=True)
created_at = Column(DateTime, nullable=False, server_default=func.now())

View File

@@ -299,7 +299,9 @@ class TestFormSubmissionRequest:
def test_form_type_max_length(self):
"""Test form_type max length validation."""
with pytest.raises(Exception): # Pydantic ValidationError
from pydantic import ValidationError
with pytest.raises(ValidationError):
FormSubmissionRequest(
form_type='a' * 51, # Over 50 chars
answers={'key': 'value'},

View File

@@ -17,6 +17,18 @@ vi.mock("#/hooks/use-tracking", () => ({
}),
}));
// Mock useSubmitEnterpriseLead - simulates successful mutation by calling onSuccess
const mockMutate = vi.fn((data, options) => {
// Simulate successful API call by invoking onSuccess callback
options?.onSuccess?.();
});
vi.mock("#/hooks/mutation/use-submit-enterprise-lead", () => ({
useSubmitEnterpriseLead: () => ({
mutate: mockMutate,
isPending: false,
}),
}));
// Wrapper to manage form state (needed since component is controlled)
function StatefulForm({ requestType, onBack }: { requestType: RequestType; onBack: () => void }) {
const [formData, setFormData] = useState<FormData>({ name: "", company: "", email: "", message: "" });
@@ -31,6 +43,10 @@ describe("InformationRequestForm", () => {
beforeEach(() => {
vi.clearAllMocks();
// Reset mockMutate to call onSuccess by default
mockMutate.mockImplementation((data, options) => {
options?.onSuccess?.();
});
});
const renderWithRouter = (props = defaultProps) => {

View File

@@ -21,6 +21,14 @@ vi.mock("#/hooks/use-tracking", () => ({
}),
}));
// Mock useSubmitEnterpriseLead
vi.mock("#/hooks/mutation/use-submit-enterprise-lead", () => ({
useSubmitEnterpriseLead: () => ({
mutate: vi.fn(),
isPending: false,
}),
}));
describe("InformationRequest", () => {
beforeEach(() => {
vi.clearAllMocks();