repertory-api/tests/test_instruments.py

131 lines
6 KiB
Python
Raw Permalink Normal View History

2026-06-09 15:07:08 -04:00
"""Tests for tune_by_instrument endpoints."""
from tests.conftest import AUTH
def make_tune(client):
r = client.post("/tunes/", json={"name": "Test Tune", "key": "D"}, headers=AUTH)
assert r.status_code == 201
return r.get_json()
def make_musician(client, name="Earl Scruggs"):
r = client.post("/musicians/", json={"name": name}, headers=AUTH)
assert r.status_code == 201
return r.get_json()
def get_instrument_id(client, name):
return next(i["id"] for i in client.get("/instruments").get_json() if i["name"] == name)
def make_tuning(client, name="double C"):
r = client.post("/tunings/", json={"name": name}, headers=AUTH)
assert r.status_code == 201
return r.get_json()
class TestTuneByInstrument:
def test_create_entry(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
tuning = make_tuning(client, "double C")
r = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id, "tuning_id": tuning["id"], "callable": True},
headers=AUTH)
assert r.status_code == 201
body = r.get_json()
assert body["instrument_name"] == "banjo"
assert body["tuning"] == "double C"
assert body["callable"] is True
def test_create_with_musician(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
m = make_musician(client)
r = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id, "learned_from_id": m["id"]},
headers=AUTH)
assert r.status_code == 201
assert r.get_json()["learned_from"] == "Earl Scruggs"
def test_update_entry(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
tuning = make_tuning(client, "sawmill")
entry = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id, "callable": False},
headers=AUTH).get_json()
r = client.patch(f'/tunes/{tune["id"]}/instruments/{entry["id"]}',
json={"callable": True, "tuning_id": tuning["id"]}, headers=AUTH)
assert r.status_code == 200
assert r.get_json()["callable"] is True
assert r.get_json()["tuning"] == "sawmill"
def test_delete_entry(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
entry = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH).get_json()
r = client.delete(f'/tunes/{tune["id"]}/instruments/{entry["id"]}', headers=AUTH)
assert r.status_code == 200
remaining = client.get(f'/tunes/{tune["id"]}/instruments').get_json()
assert all(e["id"] != entry["id"] for e in remaining)
def test_unique_constraint(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH)
r = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH)
assert r.status_code == 409
class TestInstrumentNotes:
def test_add_and_list_notes(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
entry = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH).get_json()
client.post(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes',
json={"note": "tricky B part"}, headers=AUTH)
client.post(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes',
json={"note": "watch the timing"}, headers=AUTH)
notes = client.get(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes').get_json()
assert len(notes) == 2
def test_update_note(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
entry = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH).get_json()
note = client.post(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes',
json={"note": "old"}, headers=AUTH).get_json()
r = client.patch(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes/{note["id"]}',
json={"note": "new"}, headers=AUTH)
assert r.get_json()["note"] == "new"
def test_delete_note(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
entry = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH).get_json()
note = client.post(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes',
json={"note": "to delete"}, headers=AUTH).get_json()
r = client.delete(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes/{note["id"]}',
headers=AUTH)
assert r.status_code == 200
def test_notes_included_in_entry_to_dict(self, client):
tune = make_tune(client)
banjo_id = get_instrument_id(client, "banjo")
entry = client.post(f'/tunes/{tune["id"]}/instruments',
json={"instrument_id": banjo_id}, headers=AUTH).get_json()
client.post(f'/tunes/{tune["id"]}/instruments/{entry["id"]}/notes',
json={"note": "my note"}, headers=AUTH)
# Notes appear in the instrument entry and in the parent tune
tune_data = client.get(f'/tunes/{tune["id"]}').get_json()
inst_entry = tune_data["instruments"][0]
assert len(inst_entry["notes"]) == 1
assert inst_entry["notes"][0]["note"] == "my note"