Skip to content

Commit 7c21455

Browse files
committed
added session state implementation
1 parent e95de36 commit 7c21455

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

request.go

+23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package alice
22

33
import (
4+
"encoding/json"
45
"errors"
56
"strings"
67
)
@@ -49,6 +50,10 @@ type Request struct {
4950
UserID string `json:"user_id"`
5051
} `json:"session"`
5152

53+
State struct {
54+
Session interface{} `json:"session,omitempty"`
55+
} `json:"state,omitempty"`
56+
5257
Version string `json:"version"`
5358
Bearer string
5459
}
@@ -190,6 +195,24 @@ func (req *Request) Ver() string {
190195
return req.Version
191196
}
192197

198+
// State.Session Состояние сессии.
199+
func (req *Request) StateSession(key string) interface{} {
200+
if req.State.Session == nil {
201+
return nil
202+
}
203+
session := req.State.Session.(map[string]interface{})
204+
205+
return session[key]
206+
}
207+
208+
// State.Session Состояние сессии json строкой
209+
func (req *Request) StateSessionAsJson() (string, error) {
210+
data, err := json.Marshal(req.State.Session)
211+
212+
return string(data), err
213+
}
214+
215+
193216
// AuthToken токен, полученный при связке аккаунтов.
194217
func (req *Request) AuthToken() string {
195218
if req.Bearer != "" {

request_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -487,12 +487,58 @@ func TestRequest_Ver(t *testing.T) {
487487
}
488488
}
489489

490+
func TestRequest_StateSession(t *testing.T) {
491+
tests := map[string]struct {
492+
request *alice.Request
493+
want interface{}
494+
}{
495+
"when state is empty 0": {
496+
request: getReq(0),
497+
want: nil,
498+
},
499+
"when state is empty 1":{
500+
request: getReq(1),
501+
want: nil,
502+
},
503+
"when state is empty 2":{
504+
request: getReq(2),
505+
want: nil,
506+
},
507+
}
508+
for name, tt := range tests {
509+
t.Run(name, func(t *testing.T) {
510+
req := tt.request
511+
got := req.StateSession("");
512+
if !assert.Equal(t, tt.want, got) {
513+
t.Errorf("Request.StateSession() = %v, want %v", got, tt.want)
514+
}
515+
516+
})
517+
}
518+
t.Run("when state is struct", func(t *testing.T) {
519+
req := getReq(3)
520+
want := make(map[string]interface{})
521+
want["int_value"] = 42
522+
523+
assert.Equal(t, 42.0, req.StateSession("int_value"))
524+
assert.Equal(t, "exampleString", req.StateSession("string_value"))
525+
assert.Equal(t, []interface{}{1.0,2.0,3.0,4.0}, req.StateSession("array_value"))
526+
assert.Equal(t, map[string]interface{}{"one":"one"}, req.StateSession("struct_value"))
527+
stateJson, err := req.StateSessionAsJson()
528+
if assert.NoError(t, err) {
529+
assert.Equal(t, `{"array_value":[1,2,3,4],"int_value":42,"string_value":"exampleString","struct_value":{"one":"one"}}`, stateJson)
530+
}
531+
})
532+
}
533+
490534
func getReq(n int) *alice.Request {
491535
source := []string{`{"meta":{"client_id":"ru.yandex.searchplugin/7.16 (none none; android 4.4.2)","interfaces":{"account_linking":{},"payments":{},"screen":{}},"locale":"ru-RU","timezone":"UTC"},"request":{"command":"съешь еще этих мягких французских булок","nlu":{"entities":[],"tokens":["съешь","еще","этих","мягких","французских","булок"]},"original_utterance":"съешь еще этих мягких французских булок","type":"SimpleUtterance"},"session":{"message_id":0,"new":true,"session_id":"e19e8eee-ae065e8-36e3f907-567a814b","skill_id":"e03f8d5b-35ef-4d57-9450-b721ca17a6c3","user_id":"03B1D487CAA1C7EBF80A195491B78ACA0AC9934CDFB12A29D063A8329BC42BF0"},"version":"1.0"}`,
492536

493537
`{"meta":{"client_id":"ru.yandex.searchplugin/7.16 (none none; android 4.4.2)","interfaces":{"account_linking":{},"payments":{}},"locale":"ru-RU","timezone":"UTC"},"request":{"nlu":{"entities":[],"tokens":[]},"payload":{"msg":"ok"},"type":"ButtonPressed"},"session":{"message_id":1,"new":false,"session_id":"eeb9fa7f-940e2502-1fbf9dfb-9448a1a9","skill_id":"e03f8d5b-35ef-4d57-9450-b721ca17a6c3","user_id":"03B1D487CAA1C7EBF80A195491B78ACA0AC9934CDFB12A29D063A8329BC42BF0"},"version":"1.0"}`,
494538

495539
`{"meta":{"client_id":"ru.yandex.searchplugin/7.16 (none none; android 4.4.2)","interfaces":{"account_linking":{},"payments":{}},"locale":"ru-RU","timezone":"UTC"},"request":{"nlu":{"entities":[],"tokens":[]},"payload":"msg","type":"ButtonPressed"},"session":{"message_id":1,"new":false,"session_id":"eeb9fa7f-940e2502-1fbf9dfb-9448a1a9","skill_id":"e03f8d5b-35ef-4d57-9450-b721ca17a6c3","user_id":"03B1D487CAA1C7EBF80A195491B78ACA0AC9934CDFB12A29D063A8329BC42BF0"},"version":"1.0"}`,
540+
541+
`{"meta":{"client_id":"ru.yandex.searchplugin/7.16 (none none; android 4.4.2)","interfaces":{"account_linking":{},"payments":{}},"locale":"ru-RU","timezone":"UTC"},"request":{"nlu":{"entities":[],"tokens":[]},"payload":"msg","type":"ButtonPressed"},"session":{"message_id":1,"new":false,"session_id":"eeb9fa7f-940e2502-1fbf9dfb-9448a1a9","skill_id":"e03f8d5b-35ef-4d57-9450-b721ca17a6c3","user_id":"03B1D487CAA1C7EBF80A195491B78ACA0AC9934CDFB12A29D063A8329BC42BF0"},"state":{"session":{"array_value":[1,2,3,4],"int_value":42,"string_value":"exampleString","struct_value":{"one":"one"}}},"version":"1.0"}`,
496542
}
497543

498544
var req = new(alice.Request)

response.go

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package alice
22

33
import (
4+
"errors"
45
"fmt"
56
"math/rand"
67
"strings"
@@ -26,6 +27,8 @@ type Response struct {
2627
UserID string `json:"user_id"`
2728
} `json:"session"`
2829

30+
SessionState interface{} `json:"session_state,omitempty"`
31+
2932
Version string `json:"version"`
3033
}
3134

@@ -38,6 +41,7 @@ func (resp *Response) clean() *Response {
3841
EndSession bool `json:"end_session"`
3942
}{}
4043
resp.StartAccountLinking = nil
44+
resp.SessionState = nil
4145
return resp
4246
}
4347

@@ -218,3 +222,19 @@ func (resp *Response) RandomPhrase(p ...Phrase) *Response {
218222
resp.Response.TTS += p[ix].TTS
219223
return resp
220224
}
225+
226+
// AddSessionState добавляет па
227+
func (resp *Response) AddSessionState(key string, data interface{}) error {
228+
if resp.SessionState == nil {
229+
resp.SessionState = make(map[string]interface{})
230+
}
231+
232+
if stateBag, ok := resp.SessionState.(map[string]interface{}); ok {
233+
stateBag[key] = data
234+
resp.SessionState = stateBag
235+
} else {
236+
return errors.New(fmt.Sprintf("session_state: can't set data because session_state have type %T",
237+
resp.SessionState))
238+
}
239+
return nil
240+
}

response_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,22 @@ func TestResponse_RandomPhrase(t *testing.T) {
703703
}
704704
}
705705

706+
func TestResponse_AddSessionState(t *testing.T) {
707+
wantResp := getResp(0)
708+
state := make(map[string]interface{})
709+
state["one"] = struct{}{}
710+
state["two"] = "twotwo"
711+
wantResp.SessionState = state
712+
713+
resp := getResp(0)
714+
err := resp.AddSessionState("one", struct{}{})
715+
assert.NoError(t, err)
716+
err = resp.AddSessionState("two", "twotwo")
717+
if assert.NoError(t, err) {
718+
assert.Equal(t, wantResp, resp)
719+
}
720+
}
721+
706722
func getResp(n int) *alice.Response {
707723
source := []string{`{"response":{"text":"","end_session":true},"session":{"message_id":0,"session_id":"","user_id":""},"version":"1.0"}`,
708724

0 commit comments

Comments
 (0)