diff --git a/.pubnub.yml b/.pubnub.yml index 0f87d06c..95efd8aa 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,5 +1,12 @@ --- changelog: + - + changes: + - + text: "UUID param in Set and Get State" + type: improvement + date: Aug 1, 19 + version: v4.2.5 - changes: - @@ -363,4 +370,4 @@ supported-platforms: - "Mac OS X 10.8 or later, amd64" - "Windows 7 or later, amd64, 386" version: "PubNub Go SDK" -version: v4.2.4 +version: v4.2.5 diff --git a/README.md b/README.md index d18adb37..4223a279 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# PubNub 4.2.4 client for Go +# PubNub 4.2.5 client for Go * Go (1.9+) # Please direct all Support Questions and Concerns to Support@PubNub.com diff --git a/VERSION b/VERSION index cf78d5b6..df0228df 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.2.4 +4.2.5 diff --git a/examples/cli/cli_demo.go b/examples/cli/cli_demo.go index c1af6871..9336e13d 100644 --- a/examples/cli/cli_demo.go +++ b/examples/cli/cli_demo.go @@ -615,7 +615,7 @@ func setStateRequest(args []string) { } } - res, status, err := pn.SetState().Channels([]string{channel}).State(state).Execute() + res, status, err := pn.SetState().Channels([]string{channel}).State(state).UUID("nuuid").Execute() fmt.Println("status===>", status) if err != nil { @@ -638,7 +638,7 @@ func getStateRequest(args []string) { channel = args[0] } - res, status, err := pn.GetState().Channels([]string{channel}).Execute() + res, status, err := pn.GetState().Channels([]string{channel}).UUID("").Execute() fmt.Println("status===>", status) if err != nil { diff --git a/get_state_request.go b/get_state_request.go index 415e1f3b..373a3a19 100644 --- a/get_state_request.go +++ b/get_state_request.go @@ -135,10 +135,15 @@ func (o *getStateOpts) buildPath() (string, error) { channels = append(channels, utils.PamEncode(channel)) } + uuid := o.UUID + if uuid == "" { + uuid = o.pubnub.Config.UUID + } + return fmt.Sprintf(getStatePath, o.pubnub.Config.SubscribeKey, strings.Join(channels, ","), - utils.URLEncode(o.pubnub.Config.UUID)), nil + utils.URLEncode(uuid)), nil } func (o *getStateOpts) buildQuery() (*url.Values, error) { @@ -191,6 +196,7 @@ func (o *getStateOpts) telemetryManager() *TelemetryManager { // GetStateResponse is the struct returned when the Execute function of GetState is called. type GetStateResponse struct { State map[string]interface{} + UUID string } func newGetStateResponse(jsonBytes []byte, status StatusResponse) ( @@ -222,6 +228,9 @@ func newGetStateResponse(jsonBytes []byte, status StatusResponse) ( return emptyGetStateResp, status, errors.New(message) } + if v["uuid"] != nil { + resp.UUID = v["uuid"].(string) + } m := make(map[string]interface{}) if v["channel"] != nil { if channel, ok2 := v["channel"].(string); ok2 { diff --git a/get_state_request_test.go b/get_state_request_test.go index 837181fc..f3123d43 100644 --- a/get_state_request_test.go +++ b/get_state_request_test.go @@ -1,6 +1,7 @@ package pubnub import ( + "fmt" "net/url" "testing" @@ -97,6 +98,39 @@ func TestGetStateBasicRequest(t *testing.T) { assert.Equal([]byte{}, body) } +func TestGetStateBasicRequestWithUUID(t *testing.T) { + assert := assert.New(t) + + uuid := "customuuid" + + opts := &getStateOpts{ + Channels: []string{"ch"}, + ChannelGroups: []string{"cg"}, + UUID: uuid, + pubnub: pubnub, + } + + path, err := opts.buildPath() + assert.Nil(err) + u := &url.URL{ + Path: path, + } + h.AssertPathsEqual(t, + fmt.Sprintf("/v2/presence/sub-key/sub_key/channel/ch/uuid/%s", uuid), + u.EscapedPath(), []int{}) + + query, err := opts.buildQuery() + assert.Nil(err) + + expected := &url.Values{} + expected.Set("channel-group", "cg") + h.AssertQueriesEqual(t, expected, query, []string{"pnsdk", "uuid"}, []string{}) + + body, err := opts.buildBody() + assert.Nil(err) + assert.Equal([]byte{}, body) +} + func TestNewGetStateBuilder(t *testing.T) { assert := assert.New(t) diff --git a/pubnub.go b/pubnub.go index 3c72fa81..fa722978 100644 --- a/pubnub.go +++ b/pubnub.go @@ -12,7 +12,7 @@ import ( // Default constants const ( // Version :the version of the SDK - Version = "4.2.4" + Version = "4.2.5" // MaxSequence for publish messages MaxSequence = 65535 ) diff --git a/set_state_request.go b/set_state_request.go index 1b577a8a..10bbfd70 100644 --- a/set_state_request.go +++ b/set_state_request.go @@ -66,6 +66,13 @@ func (b *setStateBuilder) QueryParam(queryParam map[string]string) *setStateBuil return b } +// UUID sets the UUID for the Set State request. +func (b *setStateBuilder) UUID(uuid string) *setStateBuilder { + b.opts.UUID = uuid + + return b +} + // Execute runs the the Set State request and returns the SetStateResponse func (b *setStateBuilder) Execute() (*SetStateResponse, StatusResponse, error) { stateOperation := StateOperation{} @@ -87,6 +94,7 @@ type setStateOpts struct { State map[string]interface{} Channels []string ChannelGroups []string + UUID string QueryParam map[string]string pubnub *PubNub stringState string @@ -129,11 +137,15 @@ func (o *setStateOpts) validate() error { func (o *setStateOpts) buildPath() (string, error) { channels := string(utils.JoinChannels(o.Channels)) + uuid := o.UUID + if uuid == "" { + uuid = o.pubnub.Config.UUID + } return fmt.Sprintf(setStatePath, o.pubnub.Config.SubscribeKey, channels, - utils.URLEncode(o.pubnub.Config.UUID), + utils.URLEncode(uuid), ), nil } diff --git a/set_state_request_test.go b/set_state_request_test.go index 0acf00ec..05e54881 100644 --- a/set_state_request_test.go +++ b/set_state_request_test.go @@ -29,6 +29,27 @@ func TestNewSetStateBuilder(t *testing.T) { u.EscapedPath(), []int{}) } +func TestNewSetStateBuilderWithUUID(t *testing.T) { + assert := assert.New(t) + + o := newSetStateBuilder(pubnub) + o.Channels([]string{"ch1", "ch2", "ch3"}) + uuid := "customuuid" + o.UUID(uuid) + + path, err := o.opts.buildPath() + assert.Nil(err) + + u := &url.URL{ + Path: path, + } + + h.AssertPathsEqual(t, + fmt.Sprintf("/v2/presence/sub-key/sub_key/channel/ch1,ch2,ch3/uuid/%s/data", + uuid), + u.EscapedPath(), []int{}) +} + func TestNewSetStateBuilderContext(t *testing.T) { assert := assert.New(t) diff --git a/tests/e2e/set_state_test.go b/tests/e2e/set_state_test.go index 47a8dc71..ed276b4e 100644 --- a/tests/e2e/set_state_test.go +++ b/tests/e2e/set_state_test.go @@ -42,6 +42,42 @@ func TestSetStateSucessNotStubbed(t *testing.T) { } } +func TestSetStateSucessNotStubbedWithUUID(t *testing.T) { + assert := assert.New(t) + + pn := pubnub.NewPubNub(configCopy()) + uuid := "nuuid" + + state := make(map[string]interface{}) + state["age"] = "20" + + setStateRes, _, err := pn.SetState().State(state).UUID(uuid).Channels([]string{"ch"}). + ChannelGroups([]string{"cg"}).Execute() + + assert.Nil(err) + if s, ok := setStateRes.State.(map[string]interface{}); ok { + assert.Equal("20", s["age"]) + } else { + assert.Fail(fmt.Sprintf("!map[string]interface{} %v %v", reflect.TypeOf(setStateRes.State).Kind(), reflect.TypeOf(setStateRes.State))) + } + + assert.Equal("OK", setStateRes.Message) + + getStateRes, _, err := pn.GetState(). + Channels([]string{"ch"}). + ChannelGroups([]string{"cg"}). + UUID(uuid). + Execute() + + assert.Nil(err) + if s, ok := getStateRes.State["ch"].(map[string]interface{}); ok { + assert.Equal("20", s["age"]) + } else { + assert.Fail(fmt.Sprintf("!map[string]interface{} %v %v", reflect.TypeOf(getStateRes.State["ch"]).Kind(), reflect.TypeOf(setStateRes.State))) + } + assert.Equal(uuid, getStateRes.UUID) +} + func TestSetStateSucessNotStubbedContext(t *testing.T) { assert := assert.New(t)