Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests and move formatting to api level #8

Merged
merged 4 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ jobs:
with:
python-version: "3.10"
- name: Install Python dependencies
working-directory: ./backend
working-directory: ./backend/src
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Format check
working-directory: ./backend
working-directory: ./backend/src
run: make fmt-check
- name: Isort check
working-directory: ./backend
working-directory: ./backend/src
run: make isort-check
- name: Pylint
working-directory: ./backend
working-directory: ./backend/src
run: make pylint
test:
runs-on: ubuntu-latest
Expand Down
8 changes: 8 additions & 0 deletions backend/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions backend/.idea/backend.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions backend/.idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions backend/.idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions backend/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions backend/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions backend/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 0 additions & 12 deletions backend/Makefile

This file was deleted.

2 changes: 1 addition & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
```
cd src
uvicorn api.index:app --reload
```
```
3 changes: 0 additions & 3 deletions backend/requirements-dev.txt

This file was deleted.

1 change: 1 addition & 0 deletions backend/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
venv
8 changes: 8 additions & 0 deletions backend/src/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions backend/src/.idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions backend/src/.idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions backend/src/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions backend/src/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions backend/src/.idea/src.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions backend/src/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions backend/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,18 @@ test-cov:
test-cov-ci:
python -m pytest --junitxml=pytest.xml --cov=./ --cov-report term-missing | tee pytest-coverage.txt

fmt-write:
black .
fmt-check:
black . --check
isort-write:
isort .
isort-check:
isort . --check
pylint:
pylint --recursive=y .
mypy:
mypy .

fmt: fmt-write isort-write
lint: fmt-check isort-check pylint
12 changes: 10 additions & 2 deletions backend/src/api/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ def list_products(next_token: str = None):

@app.post("/products", status_code=201, response_model=models.ProductResponse)
def post_product(payload: models.CreatePayload):
res = dynamo.create_product(stores=payload.stores, name=payload.name)
res = dynamo.create_product(
stores=payload.stores, name=payload.name, categories=payload.categories
)
return res


Expand All @@ -69,6 +71,7 @@ def update_product(product_id: str, payload: models.UpdatePayload):
product_id=product_id,
stores=payload.stores,
name=payload.name,
categories=payload.categories,
)
except dynamo.ProductNotFoundError as err:
raise HTTPException(status_code=404, detail="Product not found") from err
Expand Down Expand Up @@ -120,9 +123,14 @@ def bulk_upload(payload: models.ProductsBulkUploadRequest):
product_id=existing_products[0]["id"],
stores=product.stores,
name=product.name,
categories=product.categories,
)
except dynamo.ProductNotFoundError:
dynamo.create_product(stores=product.stores, name=product.name)
dynamo.create_product(
stores=product.stores,
name=product.name,
categories=product.categories,
)

except Exception as err:
print(err)
Expand Down
15 changes: 13 additions & 2 deletions backend/src/api/lib/dynamo.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ class ProductNotFoundError(Error):
pass


def create_product(name: str, stores: list[str]) -> dict:
def create_product(name: str, stores: list[str], categories: list[str]) -> dict:
print("Creating product")

item = {
"id": str(uuid4()),
"name": name,
"stores": stores,
"images": [],
"categories": categories,
"created_at": datetime.now().isoformat(),
"updated_at": datetime.now().isoformat(),
}
Expand Down Expand Up @@ -62,7 +63,12 @@ def get_products_by_name(name: str) -> dict:
return response["Items"]


def update_product(product_id: str, stores: list[str] = None, name: str = None) -> dict:
def update_product(
product_id: str,
stores: list[str] = None,
name: str = None,
categories: list[str] = None,
) -> dict:
expr = []
attr_values = {}
attr_names = {}
Expand All @@ -72,6 +78,11 @@ def update_product(product_id: str, stores: list[str] = None, name: str = None)
attr_values[":k"] = stores
attr_names["#K"] = "stores"

if categories is not None:
expr.append("#C=:c")
attr_values[":c"] = categories
attr_names["#C"] = "categories"

if name is not None:
expr.append("#N=:n")
attr_values[":n"] = name
Expand Down
3 changes: 3 additions & 0 deletions backend/src/api/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ class ProductResponse(BaseModel):
stores: list[str]
images: list[str]
image_urls: dict[str, str] = {}
categories: list[str]
header_image: str = None


class CreatePayload(BaseModel):
name: str
stores: list[str]
categories: list[str]


class UpdatePayload(BaseModel):
name: Optional[str]
stores: Optional[list[str]]
categories: Optional[list[str]]


class ProductsListResponse(BaseModel):
Expand Down
3 changes: 2 additions & 1 deletion backend/pyproject.toml → backend/src/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[tool.isort]
profile = "black"
src_paths = ["src", "serverless_backend", "app.py"]
src_paths = ["."]
[tool.pylint]
disable = ["C0114", "C0116", "C0115", "E0401", "W0511"]
ignore = ["venv"]
6 changes: 5 additions & 1 deletion backend/src/requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pytest==8.0.2
uvicorn[standard]
boto3
boto3~=1.34.61
httpx==0.27.0
pytest-env==1.1.3
pytest-cov==4.1.0
moto==5.0.3
black==24.2.0
isort==5.13.2
pylint==3.0.3
29 changes: 29 additions & 0 deletions backend/src/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import os

import boto3
import pytest
from moto import mock_aws


@pytest.fixture(scope="function", name="aws_credentials")
def fixture_aws_credentials():
"""Mocked AWS Credentials for moto."""
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
os.environ["AWS_SECURITY_TOKEN"] = "testing"
os.environ["AWS_SESSION_TOKEN"] = "testing"
os.environ["AWS_DEFAULT_REGION"] = "us-east-2"


@pytest.fixture(scope="function")
# pylint: disable-next=unused-argument
def dynamodb_client(aws_credentials):
with mock_aws():
yield boto3.client("dynamodb", region_name="us-east-2")


@pytest.fixture(scope="function")
# pylint: disable-next=unused-argument
def s3_client(aws_credentials):
with mock_aws():
yield boto3.client("s3")
Loading
Loading