Files
fitguide/tests/test_augmented_part_on_website_preferred.py

227 lines
7.2 KiB
Python

"""`on_website` and `preferred_part` booleans on AugmentedPart: default to
False, settable via create/update (API + admin web UI), and `on_website`
is filterable in the admin listing."""
import pytest
from app.models.augmented_part import AugmentedPart
from app.models.manufacturer import Manufacturer
from app.models.part_colour import PartColour
from app.models.part_type import PartType
async def _seed_reference_data(db):
manufacturer = Manufacturer(name="Acme", url="https://acme.test")
colour = PartColour(name="Black")
part_type = PartType(name="Scope")
db.add_all([manufacturer, colour, part_type])
await db.flush()
return manufacturer, colour, part_type
async def _token(client, email, password="secret123"):
resp = await client.post(
"/api/auth/login", data={"username": email, "password": password}
)
assert resp.status_code == 200, resp.text
return resp.json()["access_token"]
async def _superuser_headers(client, make_user, email):
await make_user(email, is_superuser=True)
return {"Authorization": f"Bearer {await _token(client, email)}"}
async def _web_login(client, email, password="secret123"):
resp = await client.post("/login", data={"email": email, "password": password})
assert resp.status_code == 303
@pytest.mark.asyncio
async def test_api_create_defaults_both_fields_to_false(
client, seeded, make_user, db_sessionmaker
):
async with db_sessionmaker() as db:
manufacturer, colour, part_type = await _seed_reference_data(db)
manufacturer_id, colour_id, part_type_id = (
manufacturer.id,
colour.id,
part_type.id,
)
await db.commit()
headers = await _superuser_headers(client, make_user, "owp-api1@example.com")
resp = await client.post(
"/api/augmented-parts",
json={
"description": "Widget",
"colour_id": colour_id,
"manufacturer_id": manufacturer_id,
"part_type_id": part_type_id,
},
headers=headers,
)
assert resp.status_code == 201, resp.text
body = resp.json()
assert body["on_website"] is False
assert body["preferred_part"] is False
@pytest.mark.asyncio
async def test_api_create_and_update_can_set_both_fields(
client, seeded, make_user, db_sessionmaker
):
async with db_sessionmaker() as db:
manufacturer, colour, part_type = await _seed_reference_data(db)
manufacturer_id, colour_id, part_type_id = (
manufacturer.id,
colour.id,
part_type.id,
)
await db.commit()
headers = await _superuser_headers(client, make_user, "owp-api2@example.com")
resp = await client.post(
"/api/augmented-parts",
json={
"description": "Widget",
"colour_id": colour_id,
"manufacturer_id": manufacturer_id,
"part_type_id": part_type_id,
"on_website": True,
"preferred_part": True,
},
headers=headers,
)
assert resp.status_code == 201, resp.text
body = resp.json()
assert body["on_website"] is True
assert body["preferred_part"] is True
ap_id = body["id"]
resp = await client.patch(
f"/api/augmented-parts/{ap_id}",
json={"on_website": False},
headers=headers,
)
assert resp.status_code == 200
body = resp.json()
assert body["on_website"] is False
assert body["preferred_part"] is True # untouched by the partial update
@pytest.mark.asyncio
async def test_web_admin_create_form_sets_both_checkboxes(
client, seeded, make_user, db_sessionmaker
):
async with db_sessionmaker() as db:
manufacturer, colour, part_type = await _seed_reference_data(db)
manufacturer_id, colour_id, part_type_id = (
manufacturer.id,
colour.id,
part_type.id,
)
await db.commit()
await make_user("owp-web1@example.com", role_ids=[seeded["roles"]["admin"].id])
await _web_login(client, "owp-web1@example.com")
resp = await client.post(
"/admin/augmented-parts",
data={
"description": "Web widget",
"colour_id": colour_id,
"manufacturer_id": manufacturer_id,
"part_type_id": part_type_id,
"on_website": "true",
"preferred_part": "true",
},
)
assert resp.status_code == 200
assert "Web widget" in resp.text
@pytest.mark.asyncio
async def test_web_admin_update_form_toggles_both_fields(
client, seeded, make_user, db_sessionmaker
):
async with db_sessionmaker() as db:
manufacturer, colour, part_type = await _seed_reference_data(db)
ap = AugmentedPart(
description="Togglable widget",
colour_id=colour.id,
manufacturer_id=manufacturer.id,
part_type_id=part_type.id,
on_website=False,
preferred_part=False,
)
db.add(ap)
await db.commit()
ap_id, manufacturer_id, colour_id, part_type_id = (
ap.id,
manufacturer.id,
colour.id,
part_type.id,
)
await make_user("owp-web2@example.com", role_ids=[seeded["roles"]["admin"].id])
await _web_login(client, "owp-web2@example.com")
resp = await client.post(
f"/admin/augmented-parts/{ap_id}",
data={
"description": "Togglable widget",
"colour_id": colour_id,
"manufacturer_id": manufacturer_id,
"part_type_id": part_type_id,
"on_website": "true",
# preferred_part omitted, as an unchecked checkbox would be
},
)
assert resp.status_code == 200
async with db_sessionmaker() as db:
refreshed = await db.get(AugmentedPart, ap_id)
assert refreshed.on_website is True
assert refreshed.preferred_part is False
@pytest.mark.asyncio
async def test_web_admin_filter_by_on_website(
client, seeded, make_user, db_sessionmaker
):
async with db_sessionmaker() as db:
manufacturer, colour, part_type = await _seed_reference_data(db)
on_site = AugmentedPart(
description="On-site widget",
colour_id=colour.id,
manufacturer_id=manufacturer.id,
part_type_id=part_type.id,
on_website=True,
)
off_site = AugmentedPart(
description="Off-site widget",
colour_id=colour.id,
manufacturer_id=manufacturer.id,
part_type_id=part_type.id,
on_website=False,
)
db.add_all([on_site, off_site])
await db.commit()
await make_user("owp-web3@example.com", role_ids=[seeded["roles"]["admin"].id])
await _web_login(client, "owp-web3@example.com")
resp = await client.get("/admin/augmented-parts")
assert "On-site widget" in resp.text
assert "Off-site widget" in resp.text
resp = await client.get("/admin/augmented-parts/filter?on_website=true")
assert resp.status_code == 200
assert "On-site widget" in resp.text
assert "Off-site widget" not in resp.text
resp = await client.get("/admin/augmented-parts/filter")
assert "On-site widget" in resp.text
assert "Off-site widget" in resp.text