Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
mjhea0 committed Jan 24, 2024
1 parent ce4a559 commit 49d02c4
Show file tree
Hide file tree
Showing 4 changed files with 299 additions and 7 deletions.
15 changes: 15 additions & 0 deletions project/app/api/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,18 @@ async def post(payload: SummaryPayloadSchema) -> int:
)
await summary.save()
return summary.id


async def put(id: int, payload: SummaryPayloadSchema) -> Union[dict, None]:
summary = await TextSummary.filter(id=id).update(
url=payload.url, summary=payload.summary
)
if summary:
updated_summary = await TextSummary.filter(id=id).first().values()
return updated_summary
return None


async def delete(id: int) -> int:
summary = await TextSummary.filter(id=id).first().delete()
return summary
33 changes: 30 additions & 3 deletions project/app/api/summaries.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
from typing import List

from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, HTTPException, Path

from app.api import crud
from app.models.pydantic import SummaryPayloadSchema, SummaryResponseSchema
from app.models.tortoise import SummarySchema

from app.models.pydantic import ( # isort:skip
SummaryPayloadSchema,
SummaryResponseSchema,
SummaryUpdatePayloadSchema,
)

router = APIRouter()


@router.get("/{id}/", response_model=SummarySchema)
async def read_summary(id: int) -> SummarySchema:
async def read_summary(id: int = Path(..., gt=0)) -> SummarySchema:
summary = await crud.get(id)
if not summary:
raise HTTPException(status_code=404, detail="Summary not found")
Expand All @@ -29,3 +34,25 @@ async def create_summary(payload: SummaryPayloadSchema) -> SummaryResponseSchema

response_object = {"id": summary_id, "url": payload.url}
return response_object


@router.put("/{id}/", response_model=SummarySchema)
async def update_summary(
payload: SummaryUpdatePayloadSchema, id: int = Path(..., gt=0)
) -> SummarySchema:
summary = await crud.put(id, payload)
if not summary:
raise HTTPException(status_code=404, detail="Summary not found")

return summary


@router.delete("/{id}/", response_model=SummaryResponseSchema)
async def delete_summary(id: int = Path(..., gt=0)) -> SummaryResponseSchema:
summary = await crud.get(id)
if not summary:
raise HTTPException(status_code=404, detail="Summary not found")

await crud.delete(id)

return summary
8 changes: 6 additions & 2 deletions project/app/models/pydantic.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from pydantic import BaseModel
from pydantic import AnyHttpUrl, BaseModel


class SummaryPayloadSchema(BaseModel):
url: str
url: AnyHttpUrl


class SummaryResponseSchema(SummaryPayloadSchema):
id: int


class SummaryUpdatePayloadSchema(SummaryPayloadSchema):
summary: str
250 changes: 248 additions & 2 deletions project/tests/test_summaries.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import json

import pytest


def test_create_summary(test_app_with_db):
response = test_app_with_db.post(
"/summaries/", data=json.dumps({"url": "https://foo.bar"})
)

assert response.status_code == 201
assert response.json()["url"] == "https://foo.bar"
assert response.json()["url"] == "https://foo.bar/"


def test_create_summaries_invalid_json(test_app):
Expand All @@ -25,6 +27,12 @@ def test_create_summaries_invalid_json(test_app):
]
}

response = test_app.post("/summaries/", data=json.dumps({"url": "invalid://url"}))
assert response.status_code == 422
assert (
response.json()["detail"][0]["msg"] == "URL scheme should be 'http' or 'https'"
)


def test_read_summary(test_app_with_db):
response = test_app_with_db.post(
Expand All @@ -37,7 +45,7 @@ def test_read_summary(test_app_with_db):

response_dict = response.json()
assert response_dict["id"] == summary_id
assert response_dict["url"] == "https://foo.bar"
assert response_dict["url"] == "https://foo.bar/"
assert response_dict["summary"]
assert response_dict["created_at"]

Expand All @@ -47,6 +55,21 @@ def test_read_summary_incorrect_id(test_app_with_db):
assert response.status_code == 404
assert response.json()["detail"] == "Summary not found"

response = test_app_with_db.get("/summaries/0/")
assert response.status_code == 422
assert response.json() == {
"detail": [
{
"ctx": {"gt": 0},
"input": "0",
"loc": ["path", "id"],
"msg": "Input should be greater than 0",
"type": "greater_than",
"url": "https://errors.pydantic.dev/2.5/v/greater_than",
}
]
}


def test_read_all_summaries(test_app_with_db):
response = test_app_with_db.post(
Expand All @@ -59,3 +82,226 @@ def test_read_all_summaries(test_app_with_db):

response_list = response.json()
assert len(list(filter(lambda d: d["id"] == summary_id, response_list))) == 1


def test_remove_summary(test_app_with_db):
response = test_app_with_db.post(
"/summaries/", data=json.dumps({"url": "https://foo.bar"})
)
summary_id = response.json()["id"]

response = test_app_with_db.delete(f"/summaries/{summary_id}/")
assert response.status_code == 200
assert response.json() == {"id": summary_id, "url": "https://foo.bar/"}


def test_remove_summary_incorrect_id(test_app_with_db):
response = test_app_with_db.delete("/summaries/999/")
assert response.status_code == 404
assert response.json()["detail"] == "Summary not found"

response = test_app_with_db.delete("/summaries/0/")
assert response.status_code == 422
assert response.json() == {
"detail": [
{
"ctx": {"gt": 0},
"input": "0",
"loc": ["path", "id"],
"msg": "Input should be greater than 0",
"type": "greater_than",
"url": "https://errors.pydantic.dev/2.5/v/greater_than",
}
]
}


def test_update_summary(test_app_with_db):
response = test_app_with_db.post(
"/summaries/", data=json.dumps({"url": "https://foo.bar"})
)
summary_id = response.json()["id"]

response = test_app_with_db.put(
f"/summaries/{summary_id}/",
data=json.dumps({"url": "https://foo.bar", "summary": "updated!"}),
)
assert response.status_code == 200

response_dict = response.json()
assert response_dict["id"] == summary_id
assert response_dict["url"] == "https://foo.bar/"
assert response_dict["summary"] == "updated!"
assert response_dict["created_at"]


# def test_update_summary_incorrect_id(test_app_with_db):
# response = test_app_with_db.put(
# "/summaries/999/",
# data=json.dumps({"url": "https://foo.bar", "summary": "updated!"})
# )
# assert response.status_code == 404
# assert response.json()["detail"] == "Summary not found"

# response = test_app_with_db.put(
# f"/summaries/0/",
# data=json.dumps({"url": "https://foo.bar", "summary": "updated!"})
# )
# assert response.status_code == 422
# assert response.json() == {
# "detail": [
# {
# "ctx": {"gt": 0},
# "input": "0",
# "loc": ["path", "id"],
# "msg": "Input should be greater than 0",
# "type": "greater_than",
# "url": "https://errors.pydantic.dev/2.5/v/greater_than",
# }
# ]
# }


# def test_update_summary_invalid_json(test_app_with_db):
# response = test_app_with_db.post(
# "/summaries/", data=json.dumps({"url": "https://foo.bar"})
# )
# summary_id = response.json()["id"]

# response = test_app_with_db.put(
# f"/summaries/{summary_id}/",
# data=json.dumps({})
# )
# assert response.status_code == 422
# assert response.json() == {
# "detail": [
# {
# "input": {},
# "loc": ["body", "url"],
# "msg": "Field required",
# "type": "missing",
# "url": "https://errors.pydantic.dev/2.5/v/missing",
# },
# {
# "input": {},
# "loc": ["body", "summary"],
# "msg": "Field required",
# "type": "missing",
# "url": "https://errors.pydantic.dev/2.5/v/missing",
# }
# ]
# }


# def test_update_summary_invalid_keys(test_app_with_db):
# response = test_app_with_db.post(
# "/summaries/", data=json.dumps({"url": "https://foo.bar"})
# )
# summary_id = response.json()["id"]

# response = test_app_with_db.put(
# f"/summaries/{summary_id}/",
# data=json.dumps({"url": "https://foo.bar"})
# )
# assert response.status_code == 422
# assert response.json() == {
# "detail": [
# {
# "input": {"url": "https://foo.bar"},
# "loc": ["body", "summary"],
# "msg": "Field required",
# "type": "missing",
# "url": "https://errors.pydantic.dev/2.5/v/missing",
# }
# ]
# }

# response = test_app_with_db.put(
# f"/summaries/{summary_id}/",
# data=json.dumps({"url": "invalid://url", "summary": "updated!"})
# )
# assert response.status_code == 422
# assert response.json()["detail"][0]["msg"] == "URL scheme should be 'http' or 'https'"


@pytest.mark.parametrize(
"summary_id, payload, status_code, detail",
[
[
999,
{"url": "https://foo.bar", "summary": "updated!"},
404,
"Summary not found",
],
[
0,
{"url": "https://foo.bar", "summary": "updated!"},
422,
[
{
"type": "greater_than",
"loc": ["path", "id"],
"msg": "Input should be greater than 0",
"input": "0",
"ctx": {"gt": 0},
"url": "https://errors.pydantic.dev/2.5/v/greater_than",
}
],
],
[
1,
{},
422,
[
{
"type": "missing",
"loc": ["body", "url"],
"msg": "Field required",
"input": {},
"url": "https://errors.pydantic.dev/2.5/v/missing",
},
{
"type": "missing",
"loc": ["body", "summary"],
"msg": "Field required",
"input": {},
"url": "https://errors.pydantic.dev/2.5/v/missing",
},
],
],
[
1,
{"url": "https://foo.bar"},
422,
[
{
"type": "missing",
"loc": ["body", "summary"],
"msg": "Field required",
"input": {"url": "https://foo.bar"},
"url": "https://errors.pydantic.dev/2.5/v/missing",
}
],
],
],
)
def test_update_summary_invalid(
test_app_with_db, summary_id, payload, status_code, detail
):
response = test_app_with_db.put(
f"/summaries/{summary_id}/", data=json.dumps(payload)
)
assert response.status_code == status_code
print(response.json()["detail"])
assert response.json()["detail"] == detail


def test_update_summary_invalid_url(test_app):
response = test_app.put(
"/summaries/1/",
data=json.dumps({"url": "invalid://url", "summary": "updated!"}),
)
assert response.status_code == 422
assert (
response.json()["detail"][0]["msg"] == "URL scheme should be 'http' or 'https'"
)

0 comments on commit 49d02c4

Please sign in to comment.