
All checks were successful
Publish / build-and-push (push) Successful in 6m14s
Reasonably hacky, in that I introduce a facade to reuse the data format previously provided by the `csv` module, rather than using the `list[list[str]]` directly. Next I want to introduce something like Celery to continually refresh. Note that this will require changes to the deployment repo in order to provide the required secrets.
164 lines
6.7 KiB
Python
164 lines
6.7 KiB
Python
import pytest
|
|
from typing import Mapping
|
|
|
|
import httpx
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app import app
|
|
|
|
client = TestClient(app)
|
|
|
|
# These tests run in a clean database.
|
|
# Note, however, that they do not _each_ run in a clean database - it persists between executions.
|
|
# Note the use of `cleanups` (defined in `conftest.py`) to allow for cleanup operations that should leave the database
|
|
# in a clean state after each test - but also, note the comment above the commented-out
|
|
# `test_adding_games_with_ties`
|
|
|
|
|
|
def test_add_and_retrieve_player(test_client: TestClient, cleanups):
|
|
response = _json_get(test_client, "/player/1")
|
|
assert response.status_code == 404
|
|
|
|
create_player_response = _json_post(client, "/player", {"name": "jason"})
|
|
assert create_player_response.status_code == 201
|
|
|
|
response_1 = _json_get(client, "/player/1")
|
|
assert response_1.json()["name"] == "jason"
|
|
|
|
def cleanup():
|
|
delete_response = _json_delete(client, "/player/1")
|
|
assert delete_response.status_code == 204
|
|
|
|
cleanups.add_success(cleanup)
|
|
|
|
|
|
def test_add_and_retrieve_deck(test_client: TestClient, cleanups):
|
|
not_found_response = _json_get(test_client, "/deck/1")
|
|
assert not_found_response.status_code == 404
|
|
|
|
# Try (and fail) to create a deck owned by a non-existent player
|
|
invalid_owner_response = _json_post(
|
|
test_client, "/deck", {"name": "Baby's First Deck", "owner_id": 1}
|
|
)
|
|
assert invalid_owner_response.status_code == 400
|
|
assert invalid_owner_response.json()["detail"] == "Owner id 1 not found"
|
|
|
|
create_jim_response = _json_post(test_client, "/player", {"name": "jim"})
|
|
assert create_jim_response.status_code == 201
|
|
jim_id = create_jim_response.json()["id"]
|
|
|
|
create_deck_response = _json_post(
|
|
test_client, "/deck", {"name": "Baby's First Deck", "owner_id": str(jim_id)}
|
|
)
|
|
assert create_deck_response.status_code == 201
|
|
# _Should_ always be 1, since we expect to start with an empty database, but why risk it?
|
|
deck_id = create_deck_response.json()["id"]
|
|
|
|
get_deck_response = _json_get(test_client, f"/deck/{deck_id}")
|
|
assert get_deck_response.status_code == 200
|
|
assert get_deck_response.json()["name"] == "Baby's First Deck"
|
|
|
|
# Very basic HTML testing
|
|
html_response = test_client.get(f"/deck/{deck_id}")
|
|
assert """owned by <a href="/player/1">jim</a>""" in html_response.text
|
|
|
|
def success_cleanup():
|
|
delete_response = _json_delete(test_client, f"/deck/{deck_id}")
|
|
assert delete_response.status_code == 204
|
|
|
|
cleanups.add_success(success_cleanup)
|
|
|
|
|
|
# Keeping this around because it would be useful to reintroduce it if I factor out data-sourcing
|
|
# (I did briefly try doing so, but because the logic of full-seeding involves recreating the iterable,
|
|
# and the two different data sources have different object-types, it wasn't obvious how to reinitialize.
|
|
# Probably would be possible, but given that I'm likely gonna deprecate the csv-upload model anyway, probably not worth it.)
|
|
@pytest.mark.skip(
|
|
reason="Moved from an injected-data model, to reading from Google Sheets"
|
|
)
|
|
def test_incremental_add_of_games(test_client: TestClient, cleanups):
|
|
latest_game_response = _json_get(test_client, "/game/latest_game")
|
|
assert latest_game_response.status_code == 404
|
|
|
|
# https://github.com/tiangolo/fastapi/issues/1536#issuecomment-640781718
|
|
with open("seed-data/all-in-one.csv", "rb") as f:
|
|
test_client.post(
|
|
"/api/seed/all_in_one",
|
|
files={"file": ("fake_all_in_one_filename.csv", f, "text/csv")},
|
|
)
|
|
|
|
latest_game_response = _json_get(test_client, "/game/latest_game")
|
|
assert latest_game_response.status_code == 200
|
|
print(latest_game_response.json())
|
|
assert latest_game_response.json()["date"] == "2024-07-05T00:00:00"
|
|
|
|
# then seed again, and check that it successfully gets the expected latest
|
|
with open(
|
|
"seed-data/all-in-one-updated-for-incremental-add-testing.csv", "rb"
|
|
) as f:
|
|
test_client.post(
|
|
"/api/seed/all_in_one",
|
|
files={"file": ("fake_all_in_one_filename.csv", f, "text/csv")},
|
|
)
|
|
|
|
latest_deck_response = _json_get(test_client, "/game/latest_game")
|
|
assert latest_deck_response.status_code == 200
|
|
assert latest_deck_response.json()["date"] == "2024-07-25T00:00:00"
|
|
|
|
def success_cleanup():
|
|
games = _json_get(test_client, "/game/list")
|
|
for game in games.json():
|
|
_json_delete(test_client, f"/game/{game['id']}")
|
|
|
|
decks = _json_get(test_client, "/deck/list")
|
|
for deck in decks.json():
|
|
_json_delete(test_client, f"/deck/{deck['id']}")
|
|
|
|
players = _json_get(test_client, "/player/list")
|
|
for player in players.json():
|
|
_json_delete(test_client, f"/player/{player['id']}")
|
|
|
|
cleanups.add_success(success_cleanup)
|
|
|
|
|
|
# TODO - this test is valid and correct, but I can't find a way to run it.
|
|
# The "cleanups" can only interact with the database via APIs (not directly), and the preceding test adds content to the
|
|
# database that cannot (currently) be nuked (specifically - sequence numbers).
|
|
# Either:
|
|
# * Add a full "nuke the database" API (probably not a good thing to expose!)
|
|
# * Find a way to initialize a full fresh database for each _test_ (see `isolated_database` in `tests/sql/test_crud.py`
|
|
# and `tests/routers/test_stats.py` for inspiration )
|
|
#
|
|
# def test_adding_games_with_ties(test_client: TestClient, cleanups):
|
|
# latest_game_response = _json_get(test_client, "/game/latest_game")
|
|
# assert latest_game_response.status_code == 404
|
|
|
|
# with open("seed-data/all-in-one-with-tied-games.csv", "rb") as f:
|
|
# test_client.post(
|
|
# "/api/seed/all_in_one",
|
|
# files={"file": ("fake_all_in_one_filename.csv", f, "text/csv")},
|
|
# )
|
|
|
|
# tied_game_response = _json_get(test_client, "/game/141")
|
|
# assert tied_game_response.status_code == 200
|
|
|
|
# winning_deck_id = tied_game_response.json()["winning_deck_id"]
|
|
# other_winning_deck_ids = tied_game_response.json()["other_winning_deck_ids"].split(',')
|
|
# assert _json_get(test_client, f"/deck/{winning_deck_id}").json()['name'] == "Narset, Enlightened Exile"
|
|
# assert len(other_winning_deck_ids) == 1
|
|
# assert _json_get(test_client, f"/deck/{other_winning_deck_ids[0]}").json()['name'] == "Aminatou, Veil Piercer"
|
|
|
|
|
|
def _json_get(c: TestClient, path: str) -> httpx.Response:
|
|
return c.get(f"/api{path}", headers={"Content-Type": "application/json"})
|
|
|
|
|
|
def _json_post(c: TestClient, path: str, body: Mapping) -> httpx.Response:
|
|
return c.post(
|
|
f"/api{path}", headers={"Content-Type": "application/json"}, json=body
|
|
)
|
|
|
|
|
|
def _json_delete(c: TestClient, path: str) -> httpx.Response:
|
|
return c.delete(f"/api{path}", headers={"Content-Type": "application/json"})
|