mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
chore(server): delete production-dead code; move test helpers to export_test
Applied from a deadcode (RTA from mains, all build tags) sweep with
per-symbol adversarial verification:
Deleted (nothing but their own self-tests used them):
- admin.Handler (deprecated since Phase 6; production mounts NewHandler)
plus its two self-tests
- ws.Hub.broadcastVoiceStateUpdate + wrapper + two self-tests (pre-V2
leftover; the live voice_state path is the hub voice routines)
- ws.VoiceLeaveEvent + methods ('retained as scaffolding', never
constructed in production; MsgTypeVoiceLeaveBC stays — live via the
leave routine)
- ws.parseIdentity (production calls parseParticipantIdentity directly;
ParseIdentityForTest now exercises the real parser)
- telemetry.Float64 (String/Int64 are used; the float case is covered by
the otel-tagged internal test, re-addable when a caller appears)
Moved into export_test.go so they leave the production binary (all
callers are same-package tests): the eight ws test-client constructors
and voice/E2EE setters from ws/client.go, admin.SetBackupBaseDir
(new admin/export_test.go), api.SecurityHeaders (test-only wrapper;
production uses SecurityHeadersWithTLS — docs/api.md updated to the
real name). Client.getVoiceJoinToken/setVoiceChID inlined into their
existing ForTest wrappers; TestSetVoiceChID_* self-tests deleted.
Kept after verification: updater.SetBaseURL (11 cross-package test call
sites) and telemetry.resetAppMetricsForInit (live under -tags otel —
untagged deadcode false positive).
Full gate green: gofmt/vet, 4 build-tag variants, full suite, deadlock,
race.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,11 +56,3 @@ func NewHandler(database *db.DB, version string, hub HubBroadcaster, u *updater.
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Handler returns the admin panel http.Handler using a nil database.
|
||||
//
|
||||
// Deprecated: use NewHandler instead. Kept for backwards-compat with any
|
||||
// caller that already imported this symbol before Phase 6.
|
||||
func Handler() http.Handler {
|
||||
return http.FileServer(http.FS(staticFiles))
|
||||
}
|
||||
|
||||
@@ -115,33 +115,6 @@ func TestNewHandler_WithUpdater(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Handler (deprecated) ────────────────────────────────────────────────────
|
||||
|
||||
// TestHandler_ReturnsNonNil verifies the deprecated Handler() function returns
|
||||
// a non-nil http.Handler (it serves the embedded static files).
|
||||
func TestHandler_ReturnsNonNil(t *testing.T) {
|
||||
h := admin.Handler()
|
||||
if h == nil {
|
||||
t.Fatal("Handler() returned nil")
|
||||
}
|
||||
}
|
||||
|
||||
// TestHandler_ServesEmbeddedFiles verifies that the deprecated Handler() serves
|
||||
// a response (the embedded static FS) without panicking.
|
||||
func TestHandler_ServesEmbeddedFiles(t *testing.T) {
|
||||
h := admin.Handler()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/index.html", nil)
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
|
||||
// http.FileServer returns 200 for a found file or 301/404 for others;
|
||||
// the important thing is it doesn't panic and returns a valid HTTP status.
|
||||
if w.Code == 0 {
|
||||
t.Error("Handler() response has zero status code")
|
||||
}
|
||||
}
|
||||
|
||||
// ─── ownerOnlyMiddleware (tested via API endpoints that use it) ───────────────
|
||||
|
||||
// TestOwnerOnlyMiddleware_OwnerAllowed verifies that a user with Owner role
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package admin
|
||||
|
||||
// SetBackupBaseDir overrides backupBaseDir so tests can point backup handlers
|
||||
// at a temp dir. Lives here so it stays out of the production binary.
|
||||
func SetBackupBaseDir(dir string) { backupBaseDir = dir }
|
||||
@@ -28,9 +28,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// SetBackupBaseDir overrides backupBaseDir. Intended for tests only.
|
||||
func SetBackupBaseDir(dir string) { backupBaseDir = dir }
|
||||
|
||||
// ─── Backup Handlers ─────────────────────────────────────────────────────────
|
||||
|
||||
func handleBackup(database *db.DB) http.Handler {
|
||||
|
||||
@@ -44,3 +44,9 @@ func SetGIFUpstreamForTest(baseURL string, client *http.Client) func() {
|
||||
gifAPIBase, gifClient = baseURL, client
|
||||
return func() { gifAPIBase, gifClient = prevBase, prevClient }
|
||||
}
|
||||
|
||||
// SecurityHeaders is SecurityHeadersWithTLS with TLS disabled (no HSTS).
|
||||
// Test-only convenience — production always goes through SecurityHeadersWithTLS.
|
||||
func SecurityHeaders(next http.Handler) http.Handler {
|
||||
return SecurityHeadersWithTLS("")(next)
|
||||
}
|
||||
|
||||
@@ -375,12 +375,6 @@ func SecurityHeadersWithTLS(tlsMode string) func(http.Handler) http.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// SecurityHeaders is a convenience wrapper for SecurityHeadersWithTLS with TLS
|
||||
// disabled (no HSTS header). Kept for backwards compatibility with tests.
|
||||
func SecurityHeaders(next http.Handler) http.Handler {
|
||||
return SecurityHeadersWithTLS("")(next)
|
||||
}
|
||||
|
||||
// MaxBodySize wraps r.Body with http.MaxBytesReader so that reads beyond
|
||||
// maxBytes return an error. This prevents clients from exhausting server memory
|
||||
// by sending arbitrarily large request bodies.
|
||||
|
||||
@@ -58,9 +58,6 @@ func String(k, v string) Attr { return Attr{Key: k, Value: v} }
|
||||
// Int64 constructs an int64 attribute.
|
||||
func Int64(k string, v int64) Attr { return Attr{Key: k, Value: v} }
|
||||
|
||||
// Float64 constructs a float64 attribute.
|
||||
func Float64(k string, v float64) Attr { return Attr{Key: k, Value: v} }
|
||||
|
||||
// Span is a single tracing span.
|
||||
type Span interface {
|
||||
End()
|
||||
|
||||
@@ -83,92 +83,6 @@ func (c *Client) GetTokenHash() string {
|
||||
return c.tokenHash
|
||||
}
|
||||
|
||||
// NewTestClient creates a client with a caller-supplied send channel.
|
||||
// Intended for unit tests only — conn is nil.
|
||||
func NewTestClient(hub *Hub, userID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: userID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestClientWithChannel creates a test client subscribed to a specific channel.
|
||||
func NewTestClientWithChannel(hub *Hub, userID, channelID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: userID,
|
||||
channelID: channelID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestClientWithUser creates a test client with an authenticated user record set.
|
||||
// Use this when tests need the client to pass permission checks.
|
||||
func NewTestClientWithUser(hub *Hub, user *db.User, channelID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: user.ID,
|
||||
user: user,
|
||||
channelID: channelID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// SetClientVoiceChID sets the voiceChID field on a client. For test use only.
|
||||
func SetClientVoiceChID(c *Client, channelID int64) {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
c.voiceChID = channelID
|
||||
if channelID == 0 {
|
||||
c.voiceJoinToken = ""
|
||||
}
|
||||
}
|
||||
|
||||
// SetClientVoiceStateForTest sets both the voice channel and join token.
|
||||
// For test use only.
|
||||
func SetClientVoiceStateForTest(c *Client, channelID int64, joinToken string) {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
c.voiceChID = channelID
|
||||
c.voiceJoinToken = joinToken
|
||||
}
|
||||
|
||||
// SetClientE2EEPubKeyForTest sets the E2EE public key on a client. For test use only.
|
||||
func SetClientE2EEPubKeyForTest(c *Client, key string) {
|
||||
c.setE2EEPubKey(key)
|
||||
}
|
||||
|
||||
// GetClientE2EEPubKeyForTest returns the E2EE public key from a client. For test use only.
|
||||
func GetClientE2EEPubKeyForTest(c *Client) string {
|
||||
return c.getE2EEPubKey()
|
||||
}
|
||||
|
||||
// NewTestClientWithTokenHash creates a test client that carries a session token
|
||||
// hash. Use this when tests need to exercise the periodic session-expiry check.
|
||||
func NewTestClientWithTokenHash(hub *Hub, user *db.User, tokenHash string, channelID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: user.ID,
|
||||
user: user,
|
||||
tokenHash: tokenHash,
|
||||
channelID: channelID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// touch updates the last activity timestamp and increments the received counter.
|
||||
func (c *Client) touch() {
|
||||
c.mu.Lock()
|
||||
@@ -198,28 +112,12 @@ func (c *Client) getVoiceChID() int64 {
|
||||
return c.voiceChID
|
||||
}
|
||||
|
||||
func (c *Client) getVoiceJoinToken() string {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
return c.voiceJoinToken
|
||||
}
|
||||
|
||||
func (c *Client) getVoiceState() (int64, string) {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
return c.voiceChID, c.voiceJoinToken
|
||||
}
|
||||
|
||||
// setVoiceChID sets the voice channel ID atomically.
|
||||
func (c *Client) setVoiceChID(chID int64) {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
c.voiceChID = chID
|
||||
if chID == 0 {
|
||||
c.voiceJoinToken = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) setVoiceState(chID int64, joinToken string) {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
|
||||
@@ -162,75 +162,6 @@ func TestBuildDMChannelOpen_NilAvatar(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ─── broadcastVoiceStateUpdate ──────────────────────────────────────────────
|
||||
|
||||
func TestBroadcastVoiceStateUpdate_NotInVoice(t *testing.T) {
|
||||
hub, database := newCoverageHub(t)
|
||||
user := seedCoverageOwner(t, database, "bvsu-noop")
|
||||
send := make(chan []byte, 16)
|
||||
c := ws.NewTestClientWithUser(hub, user, 0, send)
|
||||
hub.Register(c)
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
|
||||
// User not in voice — should be a no-op.
|
||||
hub.BroadcastVoiceStateUpdateForTest(c)
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
|
||||
// No voice_state message should have been sent since user is not in voice.
|
||||
for len(send) > 0 {
|
||||
msg := <-send
|
||||
var m struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
_ = json.Unmarshal(msg, &m)
|
||||
if m.Type == "voice_state" {
|
||||
t.Error("expected no voice_state broadcast when user is not in voice")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBroadcastVoiceStateUpdate_InVoice(t *testing.T) {
|
||||
hub, database := newCoverageHub(t)
|
||||
user := seedCoverageOwner(t, database, "bvsu-voice")
|
||||
|
||||
// Create a voice channel.
|
||||
chanID, err := database.CreateChannel("bvsu-ch", "voice", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateChannel: %v", err)
|
||||
}
|
||||
|
||||
// Join the voice channel in DB.
|
||||
if err := database.JoinVoiceChannel(user.ID, chanID); err != nil {
|
||||
t.Fatalf("JoinVoiceChannel: %v", err)
|
||||
}
|
||||
|
||||
send := make(chan []byte, 16)
|
||||
c := ws.NewTestClientWithUser(hub, user, 0, send)
|
||||
ws.SetClientVoiceChID(c, chanID)
|
||||
hub.Register(c)
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
|
||||
// Should broadcast a voice_state message.
|
||||
hub.BroadcastVoiceStateUpdateForTest(c)
|
||||
|
||||
// Drain the channel and check for voice_state message.
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
found := false
|
||||
for len(send) > 0 {
|
||||
msg := <-send
|
||||
var m struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
_ = json.Unmarshal(msg, &m)
|
||||
if m.Type == "voice_state" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Error("expected voice_state broadcast")
|
||||
}
|
||||
}
|
||||
|
||||
// ─── handleVoiceMute via HandleMessageForTest ───────────────────────────────
|
||||
|
||||
func TestHandleVoiceMute_NotInVoice2(t *testing.T) {
|
||||
|
||||
@@ -2300,43 +2300,6 @@ func TestGetLastActivity_MultipleTouch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ─── setVoiceChID (client.go:186) ───────────────────────────────────────────
|
||||
|
||||
func TestSetVoiceChID_SetsAndGetsValue(t *testing.T) {
|
||||
hub, _ := newCoverageHub(t)
|
||||
send := make(chan []byte, 4)
|
||||
c := ws.NewTestClient(hub, 1, send)
|
||||
|
||||
ws.SetVoiceChIDForTest(c, 77)
|
||||
if got := ws.GetClientVoiceChIDForTest(c); got != 77 {
|
||||
t.Fatalf("voiceChID = %d, want 77", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetVoiceChID_OverwritesPreviousValue(t *testing.T) {
|
||||
hub, _ := newCoverageHub(t)
|
||||
send := make(chan []byte, 4)
|
||||
c := ws.NewTestClient(hub, 1, send)
|
||||
|
||||
ws.SetVoiceChIDForTest(c, 10)
|
||||
ws.SetVoiceChIDForTest(c, 20)
|
||||
if got := ws.GetClientVoiceChIDForTest(c); got != 20 {
|
||||
t.Fatalf("voiceChID = %d, want 20", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetVoiceChID_ZeroMeansNotInVoice(t *testing.T) {
|
||||
hub, _ := newCoverageHub(t)
|
||||
send := make(chan []byte, 4)
|
||||
c := ws.NewTestClient(hub, 1, send)
|
||||
|
||||
ws.SetVoiceChIDForTest(c, 50)
|
||||
ws.SetVoiceChIDForTest(c, 0)
|
||||
if got := ws.GetClientVoiceChIDForTest(c); got != 0 {
|
||||
t.Fatalf("voiceChID = %d, want 0", got)
|
||||
}
|
||||
}
|
||||
|
||||
// ─── clearVoiceChID (client.go:203) ─────────────────────────────────────────
|
||||
|
||||
func TestClearVoiceChID_ReturnsOldValueAndClearsToZero(t *testing.T) {
|
||||
|
||||
@@ -259,17 +259,6 @@ type VoiceStateEvent struct {
|
||||
func (e VoiceStateEvent) EventType() string { return MsgTypeVoiceState }
|
||||
func (e VoiceStateEvent) Payload() []byte { return e.payload }
|
||||
|
||||
// VoiceLeaveEvent is a voice_leave broadcast to all connected clients.
|
||||
// NOTE: Currently unused — the voice_leave V2 handler triggers the hub's
|
||||
// handleVoiceLeave routine (via Result.LeaveVoice), which broadcasts the leave
|
||||
// directly. Retained as forward-compatible scaffolding.
|
||||
type VoiceLeaveEvent struct {
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func (e VoiceLeaveEvent) EventType() string { return MsgTypeVoiceLeaveBC }
|
||||
func (e VoiceLeaveEvent) Payload() []byte { return e.payload }
|
||||
|
||||
// PluginBroadcastEvent is a plugin slash-command result broadcast to a channel
|
||||
// (sequenced, replayable). Emitted by the chat_command handler after the
|
||||
// invoking user's post permission is verified.
|
||||
|
||||
@@ -83,7 +83,6 @@ func TestEventTypes(t *testing.T) {
|
||||
{"ReactionChannelEvent", ReactionChannelEvent{}, MsgTypeReactionUpdate},
|
||||
{"ReactionDMEvent", ReactionDMEvent{}, MsgTypeReactionUpdate},
|
||||
{"VoiceStateEvent", VoiceStateEvent{}, MsgTypeVoiceState},
|
||||
{"VoiceLeaveEvent", VoiceLeaveEvent{}, MsgTypeVoiceLeaveBC},
|
||||
{"VoiceE2EEAnnounceEvent", VoiceE2EEAnnounceEvent{}, MsgTypeVoiceE2EEAnnounceBC},
|
||||
{"VoiceE2EEOfferGuardedEvent", VoiceE2EEOfferGuardedEvent{}, MsgTypeVoiceE2EEOfferRelay},
|
||||
{"DMChannelOpenEvent", DMChannelOpenEvent{}, MsgTypeDMChannelOpen},
|
||||
@@ -207,7 +206,6 @@ func TestBroadcastAllEventInterface(t *testing.T) {
|
||||
}{
|
||||
{"PresenceEvent", PresenceEvent{payload: []byte("p")}},
|
||||
{"VoiceStateEvent", VoiceStateEvent{payload: []byte("vs")}},
|
||||
{"VoiceLeaveEvent", VoiceLeaveEvent{payload: []byte("vl")}},
|
||||
}
|
||||
for _, tt := range events {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
+96
-11
@@ -49,9 +49,95 @@ func ClearVoiceChIDForTest(c *Client) int64 {
|
||||
return c.clearVoiceChID()
|
||||
}
|
||||
|
||||
// SetVoiceChIDForTest exposes Client.setVoiceChID for external tests.
|
||||
// SetVoiceChIDForTest sets the voice channel ID atomically, clearing the join
|
||||
// token when leaving (chID 0) — the same contract production keeps via
|
||||
// setVoiceState. Test-only: production has no set-channel-without-token path.
|
||||
func SetVoiceChIDForTest(c *Client, chID int64) {
|
||||
c.setVoiceChID(chID)
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
c.voiceChID = chID
|
||||
if chID == 0 {
|
||||
c.voiceJoinToken = ""
|
||||
}
|
||||
}
|
||||
|
||||
// SetClientVoiceChID is an alias kept for existing tests.
|
||||
func SetClientVoiceChID(c *Client, channelID int64) {
|
||||
SetVoiceChIDForTest(c, channelID)
|
||||
}
|
||||
|
||||
// SetClientVoiceStateForTest sets both the voice channel and join token.
|
||||
func SetClientVoiceStateForTest(c *Client, channelID int64, joinToken string) {
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
c.voiceChID = channelID
|
||||
c.voiceJoinToken = joinToken
|
||||
}
|
||||
|
||||
// SetClientE2EEPubKeyForTest sets the E2EE public key on a client.
|
||||
func SetClientE2EEPubKeyForTest(c *Client, key string) {
|
||||
c.setE2EEPubKey(key)
|
||||
}
|
||||
|
||||
// GetClientE2EEPubKeyForTest returns the E2EE public key from a client.
|
||||
func GetClientE2EEPubKeyForTest(c *Client) string {
|
||||
return c.getE2EEPubKey()
|
||||
}
|
||||
|
||||
// NewTestClient creates a client with a caller-supplied send channel; conn is nil.
|
||||
func NewTestClient(hub *Hub, userID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: userID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestClientWithChannel creates a test client subscribed to a specific channel.
|
||||
func NewTestClientWithChannel(hub *Hub, userID, channelID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: userID,
|
||||
channelID: channelID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestClientWithUser creates a test client with an authenticated user record
|
||||
// set. Use this when tests need the client to pass permission checks.
|
||||
func NewTestClientWithUser(hub *Hub, user *db.User, channelID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: user.ID,
|
||||
user: user,
|
||||
channelID: channelID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTestClientWithTokenHash creates a test client that carries a session token
|
||||
// hash. Use this when tests need to exercise the periodic session-expiry check.
|
||||
func NewTestClientWithTokenHash(hub *Hub, user *db.User, tokenHash string, channelID int64, send chan []byte) *Client {
|
||||
return &Client{
|
||||
hub: hub,
|
||||
ctx: context.Background(),
|
||||
userID: user.ID,
|
||||
user: user,
|
||||
tokenHash: tokenHash,
|
||||
channelID: channelID,
|
||||
send: send,
|
||||
sendHigh: send, // unified for test observability
|
||||
sendLow: send,
|
||||
}
|
||||
}
|
||||
|
||||
// TouchForTest exposes Client.touch for external tests.
|
||||
@@ -138,9 +224,11 @@ func GetClientVoiceChIDForTest(c *Client) int64 {
|
||||
return c.getVoiceChID()
|
||||
}
|
||||
|
||||
// GetClientVoiceJoinTokenForTest exposes Client.getVoiceJoinToken.
|
||||
// GetClientVoiceJoinTokenForTest reads the join token under voiceMu.
|
||||
func GetClientVoiceJoinTokenForTest(c *Client) string {
|
||||
return c.getVoiceJoinToken()
|
||||
c.voiceMu.Lock()
|
||||
defer c.voiceMu.Unlock()
|
||||
return c.voiceJoinToken
|
||||
}
|
||||
|
||||
// ExpireSettingsCacheForTest forces the settings cache to appear stale so that
|
||||
@@ -161,9 +249,11 @@ func BuildJSONForTest(v any) []byte {
|
||||
return buildJSON(v)
|
||||
}
|
||||
|
||||
// ParseIdentityForTest exposes parseIdentity for external tests.
|
||||
// ParseIdentityForTest parses a LiveKit participant identity and discards the
|
||||
// join token, exercising the production parseParticipantIdentity.
|
||||
func ParseIdentityForTest(identity string) (int64, error) {
|
||||
return parseIdentity(identity)
|
||||
userID, _, err := parseParticipantIdentity(identity)
|
||||
return userID, err
|
||||
}
|
||||
|
||||
// ParseParticipantIdentityForTest exposes parseParticipantIdentity for tests.
|
||||
@@ -202,11 +292,6 @@ func BuildDMChannelOpenForTest(channelID int64, recipient *db.User) []byte {
|
||||
return buildDMChannelOpen(channelID, recipient)
|
||||
}
|
||||
|
||||
// BroadcastVoiceStateUpdateForTest exposes broadcastVoiceStateUpdate for external tests.
|
||||
func (h *Hub) BroadcastVoiceStateUpdateForTest(c *Client) {
|
||||
h.broadcastVoiceStateUpdate(c)
|
||||
}
|
||||
|
||||
// HandleWebhookParticipantLeftForTest exposes handleWebhookParticipantLeft for
|
||||
// external tests so they can simulate LiveKit webhook events without HTTP.
|
||||
func (h *Hub) HandleWebhookParticipantLeftForTest(userID int64, channelID int64, joinToken string) {
|
||||
|
||||
@@ -89,12 +89,6 @@ func parseParticipantIdentity(identity string) (int64, string, error) {
|
||||
return userID, joinToken, nil
|
||||
}
|
||||
|
||||
// parseIdentity extracts a user ID from a LiveKit participant identity.
|
||||
func parseIdentity(identity string) (int64, error) {
|
||||
userID, _, err := parseParticipantIdentity(identity)
|
||||
return userID, err
|
||||
}
|
||||
|
||||
// parseRoomChannelID extracts a channel ID from a LiveKit room name
|
||||
// formatted as "channel-{id}".
|
||||
func parseRoomChannelID(roomName string) (int64, error) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package ws
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -33,18 +32,3 @@ func qualityBitrate(quality string) int {
|
||||
}
|
||||
return voiceQualities["medium"]
|
||||
}
|
||||
|
||||
// broadcastVoiceStateUpdate fetches the current voice state for the client
|
||||
// and broadcasts it to all members of the voice channel they are in.
|
||||
func (h *Hub) broadcastVoiceStateUpdate(c *Client) {
|
||||
state, err := h.db.GetVoiceState(c.userID)
|
||||
if err != nil {
|
||||
slog.Error("ws broadcastVoiceStateUpdate GetVoiceState", "err", err, "user_id", c.userID)
|
||||
c.sendMsg(buildErrorMsg(ErrCodeInternal, "failed to broadcast voice state update"))
|
||||
return
|
||||
}
|
||||
if state == nil {
|
||||
return // user not in a voice channel — nothing to broadcast
|
||||
}
|
||||
h.BroadcastToAll(buildVoiceState(*state))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user