Compare commits
2 commits
68a11bb50e
...
e97b9b2134
| Author | SHA1 | Date | |
|---|---|---|---|
| e97b9b2134 | |||
| adfd4529f5 |
3 changed files with 67 additions and 8 deletions
|
|
@ -46,7 +46,7 @@ def build_nip52_event(event: Event, pubkey: str) -> NostrEvent:
|
||||||
start - unix timestamp (31923) or YYYY-MM-DD (31922)
|
start - unix timestamp (31923) or YYYY-MM-DD (31922)
|
||||||
end - same encoding (optional)
|
end - same encoding (optional)
|
||||||
image, location, t (categories) - optional
|
image, location, t (categories) - optional
|
||||||
tickets_available - current remaining capacity (omitted when unlimited)
|
tickets_available - current remaining capacity (always emitted; 0 = sold out)
|
||||||
tickets_sold - running paid-count (always emitted; clients can
|
tickets_sold - running paid-count (always emitted; clients can
|
||||||
derive original_capacity = available + sold)
|
derive original_capacity = available + sold)
|
||||||
tickets_price - price_per_ticket (always emitted; 0 means free)
|
tickets_price - price_per_ticket (always emitted; 0 means free)
|
||||||
|
|
@ -96,10 +96,13 @@ def build_nip52_event(event: Event, pubkey: str) -> NostrEvent:
|
||||||
for cat in event.categories or []:
|
for cat in event.categories or []:
|
||||||
tags.append(["t", cat])
|
tags.append(["t", cat])
|
||||||
|
|
||||||
# `amount_tickets == 0` means unlimited capacity in this extension's
|
# Always emitted, including zero. Omitting it used to mean "unlimited",
|
||||||
# schema. Omitting the tag is how clients distinguish unlimited from
|
# which contradicted every other reader: `api_get_event` and
|
||||||
# "0 left" (sold out).
|
# `api_ticket_create` both treat `amount_tickets < 1` as sold out, so a
|
||||||
if event.amount_tickets > 0:
|
# zero-capacity event advertised "Unlimited tickets" on the card while
|
||||||
|
# the detail page and the purchase both returned 410 (aiolabs/events#34).
|
||||||
|
# Clients that must still handle an absent tag — a NIP-52 event from
|
||||||
|
# some other publisher — are unaffected; we simply never omit it.
|
||||||
tags.append(["tickets_available", str(event.amount_tickets)])
|
tags.append(["tickets_available", str(event.amount_tickets)])
|
||||||
tags.append(["tickets_sold", str(event.sold)])
|
tags.append(["tickets_sold", str(event.sold)])
|
||||||
tags.append(["tickets_price", str(event.price_per_ticket)])
|
tags.append(["tickets_price", str(event.price_per_ticket)])
|
||||||
|
|
|
||||||
|
|
@ -614,9 +614,9 @@
|
||||||
dense
|
dense
|
||||||
v-model.number="formDialog.data.amount_tickets"
|
v-model.number="formDialog.data.amount_tickets"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="1"
|
||||||
label="Amount of tickets"
|
label="Amount of tickets"
|
||||||
hint="0 = unlimited"
|
hint="Total tickets on sale"
|
||||||
></q-input>
|
></q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|
|
||||||
56
tests/test_publish_availability.py
Normal file
56
tests/test_publish_availability.py
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
"""`tickets_available` is always published, including zero (#34).
|
||||||
|
|
||||||
|
Omitting the tag used to mean "unlimited", which contradicted every other
|
||||||
|
reader: `api_get_event` and `api_ticket_create` both treat
|
||||||
|
`amount_tickets < 1` as sold out. On aio-demo three zero-capacity events
|
||||||
|
advertised "Unlimited tickets" on the card while the detail endpoint and
|
||||||
|
the purchase both returned 410.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from ..models import Event
|
||||||
|
from ..nostr_publisher import build_nip52_event
|
||||||
|
|
||||||
|
PUBKEY = "a" * 64
|
||||||
|
|
||||||
|
|
||||||
|
def _event(amount_tickets: int, sold: int = 0) -> Event:
|
||||||
|
return Event(
|
||||||
|
id="evt",
|
||||||
|
wallet="w",
|
||||||
|
name="Availability",
|
||||||
|
info="",
|
||||||
|
closing_date="2030-01-01",
|
||||||
|
event_start_date="2030-01-01T18:00",
|
||||||
|
event_end_date="2030-01-01T22:00",
|
||||||
|
currency="sat",
|
||||||
|
price_per_ticket=0,
|
||||||
|
amount_tickets=amount_tickets,
|
||||||
|
sold=sold,
|
||||||
|
time=datetime.now(timezone.utc),
|
||||||
|
status="approved",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _tags(event: Event) -> dict[str, str]:
|
||||||
|
return {t[0]: t[1] for t in build_nip52_event(event, PUBKEY).tags if len(t) > 1}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("amount", [0, 1, 50])
|
||||||
|
def test_tickets_available_is_always_present(amount):
|
||||||
|
assert _tags(_event(amount))["tickets_available"] == str(amount)
|
||||||
|
|
||||||
|
|
||||||
|
def test_zero_capacity_reads_as_sold_out_not_unlimited():
|
||||||
|
"""The regression: an absent tag is what clients render as unlimited."""
|
||||||
|
tags = _tags(_event(0, sold=0))
|
||||||
|
assert "tickets_available" in tags
|
||||||
|
assert tags["tickets_available"] == "0"
|
||||||
|
|
||||||
|
|
||||||
|
def test_sold_out_after_selling_through_still_publishes_zero():
|
||||||
|
assert _tags(_event(0, sold=25))["tickets_available"] == "0"
|
||||||
|
assert _tags(_event(0, sold=25))["tickets_sold"] == "25"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue