package tickets import ( "testing" "github.com/leolionad58/ticketbot/internal/config" "github.com/leolionad58/ticketbot/internal/db" ) func makeProvider() *config.Provider { cfg := &config.Config{ Bot: config.Bot{AdminRole: "admin-role"}, Panels: map[string]config.Panel{ "support_panel": { Types: map[string]config.TicketType{ "support": {StaffRole: "staff-role"}, "mod": {StaffRole: "mod-role"}, }, }, }, } return config.NewProvider(cfg) } func supportTicket() *db.Ticket { return &db.Ticket{Panel: "support_panel", Type: "support"} } func TestCanAdmin(t *testing.T) { auth := NewAuthService(makeProvider()) if !auth.Can([]string{"admin-role"}, ActionAdmin, nil) { t.Error("admin should pass ActionAdmin") } if auth.Can([]string{"random"}, ActionAdmin, nil) { t.Error("non-admin should fail ActionAdmin") } } func TestCanClaim(t *testing.T) { auth := NewAuthService(makeProvider()) ticket := supportTicket() if !auth.Can([]string{"staff-role"}, ActionClaim, ticket) { t.Error("staff should claim") } if !auth.Can([]string{"admin-role"}, ActionClaim, ticket) { t.Error("admin should claim") } if auth.Can([]string{"mod-role"}, ActionClaim, ticket) { t.Error("wrong-staff should not claim support ticket") } if auth.Can([]string{"random"}, ActionClaim, ticket) { t.Error("non-staff should not claim") } } func TestCanTicketActions(t *testing.T) { auth := NewAuthService(makeProvider()) ticket := supportTicket() for _, action := range []Action{ActionClose, ActionAdd, ActionRemove, ActionRename, ActionTranscript} { if !auth.Can([]string{"staff-role"}, action, ticket) { t.Errorf("staff should be able to action %d", action) } if !auth.Can([]string{"admin-role"}, action, ticket) { t.Errorf("admin should be able to action %d", action) } if auth.Can([]string{"random"}, action, ticket) { t.Errorf("random should not be able to action %d", action) } } } func TestCanConvocation(t *testing.T) { auth := NewAuthService(makeProvider()) // any staff role across all panels if !auth.Can([]string{"staff-role"}, ActionConvocation, nil) { t.Error("support staff should convocation") } if !auth.Can([]string{"mod-role"}, ActionConvocation, nil) { t.Error("mod staff should convocation") } if !auth.Can([]string{"admin-role"}, ActionConvocation, nil) { t.Error("admin should convocation") } if auth.Can([]string{"random"}, ActionConvocation, nil) { t.Error("non-staff should not convocation") } } func TestCanNilTicket(t *testing.T) { auth := NewAuthService(makeProvider()) if auth.Can([]string{"staff-role"}, ActionClaim, nil) { t.Error("should not claim nil ticket") } } func TestCanCloseOwner(t *testing.T) { auth := NewAuthService(makeProvider()) ticket := &db.Ticket{Panel: "support_panel", Type: "support", UserID: "owner-123", Status: "open"} // Owner can close if open if !auth.CanClose([]string{}, "owner-123", ticket) { t.Error("owner should close open ticket") } // Owner cannot close once claimed ticket.Status = "claimed" if auth.CanClose([]string{}, "owner-123", ticket) { t.Error("owner should not close claimed ticket") } // Non-owner without staff role cannot close ticket.Status = "open" if auth.CanClose([]string{}, "other-user", ticket) { t.Error("non-owner without staff should not close") } // Staff can still close claimed tickets ticket.Status = "claimed" if !auth.CanClose([]string{"staff-role"}, "other-user", ticket) { t.Error("staff should close claimed ticket") } // Admin can always close if !auth.CanClose([]string{"admin-role"}, "other-user", ticket) { t.Error("admin should always close") } }