Spaces:
Running
Running
Yarin35
feat(quotations): add endpoint to update quotation line with fixed price and validation status
ed7ccec | """End-to-end tests for quotation line update endpoint.""" | |
| import pytest | |
| from httpx import AsyncClient | |
| from decimal import Decimal | |
| from app.schemas.quotation import CalculatePricesRequest | |
| async def test_update_quotation_line_success( | |
| client: AsyncClient, seeded_entities, prisma | |
| ) -> None: | |
| """Test updating a quotation line with fixed_price and validation.""" | |
| # 1. Create a quotation first by calculating prices | |
| ref = seeded_entities["primary_reference"] | |
| calc_request = CalculatePricesRequest(article_references=[ref], save_quotation=True) | |
| calc_response = await client.post( | |
| "/api/v1/quotations/calculate-prices", | |
| json=calc_request.model_dump(), | |
| ) | |
| assert calc_response.status_code == 200 | |
| calc_data = calc_response.json() | |
| quotation_id = calc_data.get("quotation_id") | |
| assert quotation_id is not None | |
| # We need to find the line_id. Since we don't have a GET quotation yet, | |
| # let's assume the response might contain it or we have to fetch it. | |
| # For now, let's check if 'calculations' has a line_id or similar. | |
| # If not, we might need a way to get the line_id. | |
| # Let's check the database directly or use a known line_id if available. | |
| # Looking at the current calculate_prices implementation in quotations.py: | |
| # it returns CalculatePricesResponse which contains calculations: list[PriceCalculation] | |
| # PriceCalculation schema (app/schemas/quotation.py) doesn't seem to have line_id. | |
| # Wait, I should check if I can get the line_id from the database. | |
| line = await prisma.cotation_lines.find_first( | |
| where={"cotation_id": quotation_id} | |
| ) | |
| assert line is not None | |
| line_id = line.id | |
| # 2. Update the line | |
| update_payload = { | |
| "fixed_price": 55.50, | |
| "validated": True | |
| } | |
| response = await client.patch( | |
| f"/api/v1/quotations/lines/{line_id}", | |
| json=update_payload, | |
| ) | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["id"] == line_id | |
| assert float(data["fixed_price"]) == 55.50 | |
| assert data["validated"] is True | |
| # 3. Verify in database | |
| db_line = await prisma.cotation_lines.find_unique(where={"id": line_id}) | |
| assert db_line.fixed_price == Decimal("55.50") | |
| assert db_line.validated is True | |
| async def test_update_quotation_line_partial_update( | |
| client: AsyncClient, seeded_entities, prisma | |
| ) -> None: | |
| """Test updating only one field of a quotation line.""" | |
| # Create a line | |
| calc_request = CalculatePricesRequest( | |
| article_references=[seeded_entities["primary_reference"]], | |
| save_quotation=True | |
| ) | |
| await client.post("/api/v1/quotations/calculate-prices", json=calc_request.model_dump()) | |
| line = await prisma.cotation_lines.find_first(order={"saved_at": "desc"}) | |
| line_id = line.id | |
| # Update only validated | |
| response = await client.patch( | |
| f"/api/v1/quotations/lines/{line_id}", | |
| json={"validated": True}, | |
| ) | |
| assert response.status_code == 200 | |
| assert response.json()["validated"] is True | |
| assert response.json()["fixed_price"] is None | |
| # Update only fixed_price | |
| response = await client.patch( | |
| f"/api/v1/quotations/lines/{line_id}", | |
| json={"fixed_price": 100.0}, | |
| ) | |
| assert response.status_code == 200 | |
| assert float(response.json()["fixed_price"]) == 100.0 | |
| assert response.json()["validated"] is True # Should remain True | |
| async def test_update_quotation_line_not_found( | |
| client: AsyncClient, seeded_entities | |
| ) -> None: | |
| """Test updating a non-existent quotation line.""" | |
| fake_id = "00000000-0000-0000-0000-000000000000" | |
| response = await client.patch( | |
| f"/api/v1/quotations/lines/{fake_id}", | |
| json={"validated": True}, | |
| ) | |
| # Now it should return 404 correctly | |
| assert response.status_code == 404 | |
| assert "not found" in response.json()["detail"].lower() | |
| async def test_update_quotation_line_clear_fixed_price( | |
| client: AsyncClient, seeded_entities, prisma | |
| ) -> None: | |
| """Test clearing fixed_price by setting it to null.""" | |
| # 1. Create a line with fixed_price | |
| calc_request = CalculatePricesRequest( | |
| article_references=[seeded_entities["primary_reference"]], | |
| save_quotation=True | |
| ) | |
| await client.post("/api/v1/quotations/calculate-prices", json=calc_request.model_dump()) | |
| line = await prisma.cotation_lines.find_first(order={"saved_at": "desc"}) | |
| line_id = line.id | |
| # Set fixed_price | |
| await client.patch(f"/api/v1/quotations/lines/{line_id}", json={"fixed_price": 50.0}) | |
| # 2. Try to clear it | |
| response = await client.patch( | |
| f"/api/v1/quotations/lines/{line_id}", | |
| json={"fixed_price": None}, | |
| ) | |
| assert response.status_code == 200 | |
| # THIS WILL CURRENTLY FAIL if the implementation doesn't support null | |
| assert response.json()["fixed_price"] is None | |