Skip to content

Ring Syntactic sugar + other updates #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
9 changes: 9 additions & 0 deletions call.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions channel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 37 additions & 11 deletions chat.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 18 additions & 4 deletions chat_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,8 @@ func TestEnableCallRecordingAndBackstageMode(t *testing.T) {
response, err := call.Update(ctx, &UpdateCallRequest{
SettingsOverride: &CallSettingsRequest{
Recording: &RecordSettingsRequest{
Mode: "available",
Mode: "available",
Quality: PtrTo("720p"),
},
},
})
Expand Down
73 changes: 73 additions & 0 deletions examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,76 @@ func TestCall_AutoFrameRecording(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "auto-on", resp.Data.Settings.FrameRecording.Mode)
}

func TestRingIndividualMembers(t *testing.T) {
client := initClient(t)

// Create a new call with a random ID
callID := uuid.NewString()
call := client.Video().Call("default", callID)

// Create users for testing
myself := uuid.NewString()
myFriend := uuid.NewString()
myOtherFriend := uuid.NewString()

// Pre-create users
response, err := client.UpdateUsers(ctx, &getstream.UpdateUsersRequest{
Users: map[string]getstream.UserRequest{
myself: {
ID: myself,
Name: getstream.PtrTo("myself"),
},
myFriend: {
ID: myFriend,
Name: getstream.PtrTo("my-friend"),
},
myOtherFriend: {
ID: myOtherFriend,
Name: getstream.PtrTo("my-other-friend"),
},
},
})
require.NoError(t, err)
require.NotNil(t, response)
users := response.Data.Users
myselfID := users[myself].ID
myFriendID := users[myFriend].ID
myOtherFriendID := users[myOtherFriend].ID

// Create call with only two members to match the Python test flow
members := []getstream.MemberRequest{
{UserID: myselfID},
{UserID: myFriendID},
}

callRequest := getstream.GetOrCreateCallRequest{
Data: &getstream.CallRequest{
CreatedByID: getstream.PtrTo(myselfID),
Members: members,
},
}

callResponse, err := call.GetOrCreate(ctx, &callRequest)
require.NoError(t, err)
require.NotNil(t, callResponse)

// Ring existing member (myFriend)
ringResponse, err := call.Ring(ctx, []string{myFriendID})
require.NoError(t, err)
require.NotNil(t, ringResponse)

// Add new member (myOtherFriend) to the call, matching the Python flow
updateResponse, err := call.UpdateCallMembers(ctx, &getstream.UpdateCallMembersRequest{
UpdateMembers: []getstream.MemberRequest{
{UserID: myOtherFriendID},
},
})
require.NoError(t, err)
require.NotNil(t, updateResponse)

// Ring the newly added member
ringResponse, err = call.Ring(ctx, []string{myOtherFriendID})
require.NoError(t, err)
require.NotNil(t, ringResponse)
}
28 changes: 27 additions & 1 deletion http.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,33 @@
return strconv.FormatFloat(val.Float(), 'f', -1, 64)
case reflect.Bool:
return strconv.FormatBool(val.Bool())
case reflect.Map, reflect.Struct, reflect.Slice:
case reflect.Slice:
// Special handling for slices of primitive types - use comma-separated format
if val.Len() == 0 {
return "[]"
}

// Check if it's a slice of simple types (string, numbers, bool)
firstElem := val.Index(0)
switch firstElem.Kind() {
case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64, reflect.Bool:
// For simple types, create a comma-separated list
var values []string
for i := 0; i < val.Len(); i++ {
values = append(values, EncodeValueToQueryParam(val.Index(i).Interface()))
}
return strings.Join(values, ",")
default:
// For complex types, use JSON
b, err := json.Marshal(value)
if err != nil {
panic(err)

Check warning on line 274 in http.go

View check run for this annotation

Codecov / codecov/patch

http.go#L274

Added line #L274 was not covered by tests
}
return string(b)
}
case reflect.Map, reflect.Struct:
b, err := json.Marshal(value)
if err != nil {
panic(err)
Expand Down
97 changes: 97 additions & 0 deletions http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,103 @@ func TestExtractQueryParams(t *testing.T) {
})
}

func TestEncodeValueToQueryParam(t *testing.T) {
type testStruct struct {
Field1 string
Field2 int
}

tests := []struct {
name string
value interface{}
want string
}{
{
name: "String slice",
value: []string{"a", "b", "c"},
want: "a,b,c",
},
{
name: "Integer slice",
value: []int{1, 2, 3},
want: "1,2,3",
},
{
name: "Empty slice",
value: []string{},
want: "[]",
},
{
name: "Mixed type slice",
value: []interface{}{"a", 1, true},
want: `["a",1,true]`,
},
{
name: "Struct slice",
value: []testStruct{
{Field1: "value1", Field2: 1},
{Field1: "value2", Field2: 2},
},
want: `[{"Field1":"value1","Field2":1},{"Field1":"value2","Field2":2}]`,
},
{
name: "Slice with special characters",
value: []string{"a&b", "c/d", "e=f"},
want: "a&b,c/d,e=f",
},
{
name: "Single string",
value: "test",
want: "test",
},
{
name: "Single integer",
value: 123,
want: "123",
},
{
name: "Boolean",
value: true,
want: "true",
},
{
name: "Float",
value: 123.45,
want: "123.45",
},
{
name: "Map",
value: map[string]interface{}{
"key1": "value1",
"key2": 2,
},
want: `{"key1":"value1","key2":2}`,
},
{
name: "Struct",
value: testStruct{
Field1: "value",
Field2: 123,
},
want: `{"Field1":"value","Field2":123}`,
},
{
name: "Pointer to string",
value: PtrTo("test"),
want: "test",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := EncodeValueToQueryParam(tt.value)
if got != tt.want {
t.Errorf("EncodeValueToQueryParam() = %v, want %v", got, tt.want)
}
})
}
}

func TestRequestURL(t *testing.T) {
originalBaseURL := "https://api.example.com"

Expand Down
Loading