mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
feat(waitlist): queue position on the customer manage page
A waitlisted customer saw only a bare status — worse, the badge fell back to "Pending" for both waitlisted and cancelled states. The view now carries a 1-based waitlistPosition (earlier-created waitlisted bookings on the session + 1) and the page renders a warning-tone notice with the queue spot and auto-promotion explanation, in CS/EN. Also fixed the badge's nonexistent --danger-soft/--warning-soft tokens. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
7509e82261
commit
3892e9ce8c
7 files changed
+155
-14
No files matched your search
@@ -703,3 +703,66 @@ func TestCreateArmsSmsReminderWhenEnabled(t *testing.T) {
|
||||
t.Fatalf("expected email+sms channels, got %v", channels)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitlistPositionReflectsQueueOrder(t *testing.T) {
|
||||
repo := db.NewMemoryRepository()
|
||||
service := NewService(repo, nil, "http://localhost:3000")
|
||||
customerService := NewCustomerService(repo, nil, "http://localhost:3000")
|
||||
ctx := context.Background()
|
||||
|
||||
session, err := repo.GetClassSessionByID(ctx, "4bf74c12-44dd-45ca-86bb-b104f16f2435")
|
||||
if err != nil {
|
||||
t.Fatalf("get session: %v", err)
|
||||
}
|
||||
sessionID := session.ID
|
||||
book := func(email string) domain.CreateBookingResponse {
|
||||
resp, err := service.Create(ctx, domain.CreateBookingRequest{
|
||||
TenantSlug: "studio-atelier",
|
||||
BookingMode: "class",
|
||||
ClassSessionID: &sessionID,
|
||||
CustomerName: "Queue Test",
|
||||
CustomerEmail: email,
|
||||
StartsAt: session.StartsAt.UTC().Format(time.RFC3339),
|
||||
EndsAt: session.EndsAt.UTC().Format(time.RFC3339),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("book %s: %v", email, err)
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
var seats []domain.CreateBookingResponse
|
||||
for i := 0; i < 4; i++ {
|
||||
seats = append(seats, book(fmt.Sprintf("qseat%[email protected]", i)))
|
||||
}
|
||||
first := book("[email protected]")
|
||||
second := book("[email protected]")
|
||||
|
||||
positionOf := func(resp domain.CreateBookingResponse) int {
|
||||
manageURL, _ := url.Parse(resp.ManageURL)
|
||||
view, err := customerService.GetBookingByReference(ctx, resp.Reference, manageURL.Query().Get("token"))
|
||||
if err != nil {
|
||||
t.Fatalf("get booking view: %v", err)
|
||||
}
|
||||
return view.WaitlistPosition
|
||||
}
|
||||
|
||||
if got := positionOf(first); got != 1 {
|
||||
t.Fatalf("expected first waiter at position 1, got %d", got)
|
||||
}
|
||||
if got := positionOf(second); got != 2 {
|
||||
t.Fatalf("expected second waiter at position 2, got %d", got)
|
||||
}
|
||||
|
||||
// Free a seat: first waiter is promoted, second moves to the front.
|
||||
manageURL, _ := url.Parse(seats[0].ManageURL)
|
||||
if err := customerService.CancelBooking(ctx, seats[0].Reference, manageURL.Query().Get("token")); err != nil {
|
||||
t.Fatalf("cancel: %v", err)
|
||||
}
|
||||
if got := positionOf(second); got != 1 {
|
||||
t.Fatalf("expected second waiter at position 1 after promotion, got %d", got)
|
||||
}
|
||||
if got := positionOf(first); got != 0 {
|
||||
t.Fatalf("expected promoted booking to report no position, got %d", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user