diff --git a/.gitignore b/.gitignore index 3ec0f35..f6602fc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ debug.test *.kate-swp *.swp sample-curl-call.txt +sessions +procedure diff --git a/chagSession_test.go b/chagSession_test.go deleted file mode 100644 index d203968..0000000 --- a/chagSession_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "log" - "testing" - "time" -) - -func TestSession(t *testing.T) { - id := "testopenid" - state := "testsate" - - //delete any existing - deleteSession(id) - path := getSessionPath(id) - AssertEqual(t, isFileExist(path), false, "Session file should not exist") - - //create new - setSessionState(id, state, 100) - - //wait 1 sec - log.Print("wait for 1 sec for testing timestamp ......") - time.Sleep(1 * time.Second) - log.Print("......waiting done") - - //read back , check state - s, _ := getCurrentSesssion(id) - AssertEqual(t, s.State, state, "") - now := int32(time.Now().Unix()) - - //check timing - AssertEqual(t, s.Expire > now, true, "Expire should be in future") - AssertEqual(t, s.UpdateAt < now, true, "Update should be in pass") - AssertEqual(t, s.CreateAt == s.UpdateAt, true, "Update should be equal to create") - AssertEqual(t, isExpired(now), false, "current time should not be expired") - - //update existing session - s, _ = setSessionState(id, state, 100) - //timeing should be exactly 1s diff - AssertEqual(t, s.CreateAt+1 == s.UpdateAt, true, "second Update should be bigger create") - n, _ := getCurrentSesssion(id) - AssertEqual(t, s, n, "session should be equal") - - //delete session, for clean up - deleteSession(id) - path = getSessionPath(id) - AssertEqual(t, isFileExist(path), false, "Session file should not exist") -} diff --git a/chatState.go b/chatState.go new file mode 100644 index 0000000..e8cf904 --- /dev/null +++ b/chatState.go @@ -0,0 +1,67 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + "log" + "os" +) + +//chat state that we might be use for collecting infomation from user +type chatState struct { + Name string `json:"Name"` //state name + Expire int32 `json:"Expire"` //unix timestamp when this state expire + Send struct { //anything we need to send? + Type string `json:"Type"` //what type of message + Message map[string]string `json:"Message"` //the message to be sent,key value pair to describe the message + } `json:"Send"` + + Receive struct { //anything we expect to receive + Validator string `json:"Validator"` + Hint string `json:"Hint"` + Message map[string]string `json:"Message"` //the description for receiving message + } `json:"Receive"` +} + +//for individual state +func getCurrentState(openID string, procedure string) (result chatState, err error) { + path := getProcedurePath(openID, procedure) + log.Printf("read state from %s\r\n", path) + body, err := ioutil.ReadFile(path) + if err != nil { //read file error + if isFileExist(path) { + log.Println("Error session reading " + path) + } + return //empty and expired session + } + err = json.Unmarshal(body, &result) + if err != nil { + log.Printf("Session Content [path=%s] not correct: ", path) + log.Println(err) + } + //we don't check Expire, we give the caller full control on + //how to deal wiht expired session + return +} + +func setCurrentState(openID, procedure string, state chatState) (newState chatState, err error) { + j, err := json.Marshal(state) + if err != nil { + return + } + path := getProcedurePath(openID, procedure) + err = ioutil.WriteFile(path, j, 0600) + if err != nil { + log.Println("write state error" + path) + log.Println(err) + return + } + newState = state + return +} + +func deleteChatState(openID, procedure string) (err error) { + path := getProcedurePath(openID, procedure) + err = os.Remove(path) + return +} diff --git a/chatState_test.go b/chatState_test.go new file mode 100644 index 0000000..b8a4cf9 --- /dev/null +++ b/chatState_test.go @@ -0,0 +1,42 @@ +package main + +import ( + "testing" + "time" +) + +func TestChatState(t *testing.T) { + procedure := "getUserBasicProfile" + s := chatState{} + s.Name = "waiting for username" + s.Expire = int32(time.Now().Unix() + 200) + s.Send.Message = map[string]string{ + "txt": "What is your date of birth?", + "icon": "/mnt/data/abc.jpg"} + s.Send.Type = "text" + s.Receive.Hint = "hint" + s.Receive.Validator = "validator email" + s.Receive.Message = map[string]string{ + "rtxt": "should be 3 chars at least", + "ricon": "icon path should be available"} + + //save + n, err := setCurrentState("id", procedure, s) + AssertEqual(t, err, nil, "save state should be successful") + + //read out + m, _ := getCurrentState("id", procedure) + + //compare + AssertEqual(t, m.Name, n.Name, "Name should be equal") + AssertEqual(t, m.Expire, n.Expire, "Expire should be equal") + AssertEqual(t, m.Send.Type, n.Send.Type, "Send.Type should be equal") + AssertEqual(t, m.Send.Message["txt"], n.Send.Message["txt"], "Message[txt] should be equal") + AssertEqual(t, m.Send.Message["icon"], n.Send.Message["icon"], "Message[icon] should be equal") + AssertEqual(t, m.Receive.Message["rtxt"], n.Receive.Message["rtxt"], "Message[rtxt] should be equal") + AssertEqual(t, m.Receive.Message["ricon"], n.Receive.Message["ricon"], "Message[ricon] should be equal") + + err = deleteChatState("id", procedure) + AssertEqual(t, err, nil, "delete chatState should be good") + +}