Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions dtos/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,36 @@ type Token struct {
PushEnabled bool `json:"pushEnabled"`
}

// UnmarshalJSON parses the legacy `pushEnabled` boolean when present, and otherwise falls back to
// `config.streaming.enabled` - some auth backends (e.g. the Configs auth service) have moved
// streaming capability there instead of the top-level field. When neither is present, PushEnabled
// defaults to false, matching the pre-existing zero-value behavior.
func (t *Token) UnmarshalJSON(raw []byte) error {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing the connDelay and config.streaming.delay fields (analog to pushEnabled and config.streaming.enabled)

var shadow struct {
Token string `json:"token"`
PushEnabled *bool `json:"pushEnabled"`
Config *struct {
Streaming *struct {
Enabled *bool `json:"enabled"`
} `json:"streaming"`
} `json:"config"`
}
if err := json.Unmarshal(raw, &shadow); err != nil {
return err
}

t.Token = shadow.Token
switch {
case shadow.PushEnabled != nil:
t.PushEnabled = *shadow.PushEnabled
case shadow.Config != nil && shadow.Config.Streaming != nil && shadow.Config.Streaming.Enabled != nil:
t.PushEnabled = *shadow.Config.Streaming.Enabled
default:
t.PushEnabled = false
}
return nil
}

// TokenPayload payload dto
type TokenPayload struct {
Capabilitites string `json:"x-ably-capability"`
Expand Down
41 changes: 41 additions & 0 deletions dtos/token_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,53 @@
package dtos

import (
"encoding/json"
"testing"
"time"

"github.com/splitio/go-toolkit/v5/datastructures/set"
)

func TestTokenUnmarshalJSON(t *testing.T) {
// Legacy shape: top-level pushEnabled wins, config.streaming.enabled is ignored if present.
var legacy Token
if err := json.Unmarshal([]byte(`{"token":"abc","pushEnabled":true,"config":{"streaming":{"enabled":false}}}`), &legacy); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !legacy.PushEnabled {
t.Error("expected top-level pushEnabled to take precedence")
}

var legacyFalse Token
if err := json.Unmarshal([]byte(`{"token":"abc","pushEnabled":false}`), &legacyFalse); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if legacyFalse.PushEnabled {
t.Error("expected pushEnabled=false to be honored")
}

// New shape: no top-level pushEnabled, fall back to config.streaming.enabled.
var viaConfig Token
if err := json.Unmarshal([]byte(`{"token":"abc","config":{"streaming":{"enabled":true}}}`), &viaConfig); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !viaConfig.PushEnabled {
t.Error("expected config.streaming.enabled fallback to enable push")
}
if viaConfig.Token != "abc" {
t.Error("expected token field to still be parsed")
}

// Neither field present: defaults to false, same as the zero value.
var neither Token
if err := json.Unmarshal([]byte(`{"token":"abc"}`), &neither); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if neither.PushEnabled {
t.Error("expected PushEnabled to default to false")
}
}

func TestTokenChannels(t *testing.T) {
token := Token{
PushEnabled: false,
Expand Down