diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..3bb5362 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,35 @@ +name: Run Python Tests + +on: + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Cache pip dependencies + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Run tests + run: | + python -m unittest discover diff --git a/main.py b/main.py index ccfd9c2..d0fccf3 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,11 @@ from decimal import Decimal, ROUND_UP from typing import Annotated -from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.openapi.docs import get_swagger_ui_html -from fastapi import FastAPI, Request, Response, Form, Query +from fastapi.responses import HTMLResponse, JSONResponse, Response +from fastapi import FastAPI, Request, Form, Query, APIRouter, Body, HTTPException from pint import UnitRegistry from pint.errors import DimensionalityError, UndefinedUnitError @@ -148,4 +148,26 @@ async def convert( ) +json = APIRouter(prefix="/json") + + +@json.post("/convert") +async def convert_json( + request: Request, + quantity: Annotated[float, Body()], + from_unit: Annotated[str, Body()], + to_unit: Annotated[str, Body()], +) -> JSONResponse: + try: + result = UnitRegistry().Quantity(quantity, from_unit).to(to_unit) + result = Decimal(str(result.magnitude)) + result = result.quantize(Decimal("0.0001"), rounding=ROUND_UP) + except Exception as e: + raise HTTPException( + status_code=422, detail=f"Error while converting: {str(e)}" + ) from e + return {"result": result} + + app.mount("/hx", hx) +app.include_router(json) diff --git a/test.py b/test.py index 7d45cc3..26130b4 100644 --- a/test.py +++ b/test.py @@ -1,4 +1,4 @@ -from main import hx +from main import hx, app from unittest import TestCase from fastapi.testclient import TestClient @@ -16,8 +16,7 @@ def test_documentation(self): self.assertEqual(response.status_code, 200) def test_suggest_units(self): - response = self.client.get( - "/suggestions", headers={"HX-Request": "true"}) + response = self.client.get("/suggestions", headers={"HX-Request": "true"}) self.assertEqual(response.status_code, 200) def test_undefined_units(self): @@ -35,3 +34,19 @@ def test_incompatible_conversions(self): data={"quantity": 1, "from_unit": "second", "to_unit": "meter"}, ) self.assertEqual(response.status_code, 422) + + +class JsonApplicationTest(TestCase): + client = TestClient(app) + endpoint = "/json/convert" + + def test_undefined_units(self): + from_unit = "foo" + to_unit = "bar" + json = { + "quantity": 1, + "from_unit": from_unit, + "to_unit": to_unit, + } + response = self.client.post(self.endpoint, json=json) + self.assertEqual(response.status_code, 422)