integration_test.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package dialog
  2. import (
  3. "os"
  4. "testing"
  5. "time"
  6. "github.com/silenceper/wechat/v2/aispeech/config"
  7. aispeechContext "github.com/silenceper/wechat/v2/aispeech/context"
  8. "github.com/silenceper/wechat/v2/cache"
  9. )
  10. func TestIntegrationAccessTokenAndQuery(t *testing.T) {
  11. if os.Getenv("AISPEECH_INTEGRATION") != "1" {
  12. t.Skip("set AISPEECH_INTEGRATION=1 to run real aispeech API test")
  13. }
  14. cfg := &config.Config{
  15. AppID: os.Getenv("AISPEECH_APPID"),
  16. Token: os.Getenv("AISPEECH_TOKEN"),
  17. AESKey: os.Getenv("AISPEECH_AES_KEY"),
  18. Cache: cache.NewMemory(),
  19. }
  20. if cfg.AppID == "" || cfg.Token == "" || cfg.AESKey == "" {
  21. t.Fatal("AISPEECH_APPID, AISPEECH_TOKEN and AISPEECH_AES_KEY are required")
  22. }
  23. d := NewDialog(&aispeechContext.Context{
  24. Config: cfg,
  25. AccessTokenContextHandle: NewAccessToken(cfg),
  26. })
  27. accessToken, err := d.GetAccessToken()
  28. if err != nil {
  29. t.Fatalf("GetAccessToken error: %v", err)
  30. }
  31. if accessToken == "" {
  32. t.Fatal("access token is empty")
  33. }
  34. res, err := d.Query(&QueryRequest{
  35. Query: "你好",
  36. Env: "online",
  37. UserID: "gowechat-integration-test",
  38. })
  39. if err != nil {
  40. t.Fatalf("Query error: %v", err)
  41. }
  42. if res.RequestID == "" {
  43. t.Fatal("query request_id is empty")
  44. }
  45. }
  46. func TestIntegrationFullDialogFlow(t *testing.T) {
  47. if os.Getenv("AISPEECH_INTEGRATION_MUTATION") != "1" {
  48. t.Skip("set AISPEECH_INTEGRATION_MUTATION=1 to run import/publish/query real aispeech API test")
  49. }
  50. d := newIntegrationDialog(t)
  51. now := time.Now().Unix()
  52. question := "codex-smoke-test-question-" + time.Unix(now, 0).Format("20060102150405")
  53. answer := "codex-smoke-test-answer-" + time.Unix(now, 0).Format("20060102150405")
  54. importRes, err := d.ImportJSON(&ImportJSONRequest{
  55. Mode: 0,
  56. Data: []BotIntent{{
  57. Skill: "CodexSmokeTest",
  58. Intent: question,
  59. Disable: false,
  60. Questions: []string{question},
  61. Answers: []string{answer},
  62. }},
  63. })
  64. if err != nil {
  65. t.Fatalf("ImportJSON error: %v", err)
  66. }
  67. if importRes.TaskID == "" {
  68. t.Fatal("ImportJSON task_id is empty")
  69. }
  70. t.Logf("ImportJSON request_id=%s task_id=%s", importRes.RequestID, importRes.TaskID)
  71. importTask := waitAsyncTask(t, d, importRes.TaskID, 2*time.Minute)
  72. if importTask.State != 2 {
  73. t.Fatalf("import task failed: state=%d msg=%s progress=%d", importTask.State, importTask.Msg, importTask.Progress)
  74. }
  75. t.Logf("FetchAsync import request_id=%s state=%d progress=%d", importTask.RequestID, importTask.State, importTask.Progress)
  76. publishRes, err := d.Publish()
  77. if err != nil {
  78. t.Fatalf("Publish error: %v", err)
  79. }
  80. if publishRes.TaskID == "" {
  81. t.Fatal("Publish task_id is empty")
  82. }
  83. t.Logf("Publish request_id=%s task_id=%s", publishRes.RequestID, publishRes.TaskID)
  84. progress := waitEffectiveProgress(t, d, "online", 3*time.Minute)
  85. if progress.Status != 1 {
  86. t.Fatalf("publish progress failed: status=%d progress=%d", progress.Status, progress.Progress)
  87. }
  88. t.Logf("GetEffectiveProgress request_id=%s status=%d progress=%d", progress.RequestID, progress.Status, progress.Progress)
  89. queryRes := waitQueryAnswer(t, d, question, answer, 2*time.Minute)
  90. t.Logf("Query request_id=%s status=%s answer_type=%s answer=%s", queryRes.RequestID, queryRes.Status, queryRes.AnswerType, queryRes.Answer)
  91. }
  92. func newIntegrationDialog(t *testing.T) *Dialog {
  93. t.Helper()
  94. cfg := &config.Config{
  95. AppID: os.Getenv("AISPEECH_APPID"),
  96. Token: os.Getenv("AISPEECH_TOKEN"),
  97. AESKey: os.Getenv("AISPEECH_AES_KEY"),
  98. Account: os.Getenv("AISPEECH_ACCOUNT"),
  99. Cache: cache.NewMemory(),
  100. }
  101. if cfg.AppID == "" || cfg.Token == "" || cfg.AESKey == "" {
  102. t.Fatal("AISPEECH_APPID, AISPEECH_TOKEN and AISPEECH_AES_KEY are required")
  103. }
  104. return NewDialog(&aispeechContext.Context{
  105. Config: cfg,
  106. AccessTokenContextHandle: NewAccessToken(cfg),
  107. })
  108. }
  109. func waitAsyncTask(t *testing.T, d *Dialog, taskID string, timeout time.Duration) *FetchAsyncResponse {
  110. t.Helper()
  111. deadline := time.Now().Add(timeout)
  112. for {
  113. res, err := d.FetchAsync(&FetchAsyncRequest{TaskID: taskID})
  114. if err != nil {
  115. t.Fatalf("FetchAsync error: %v", err)
  116. }
  117. if res.State == 2 || res.State == 3 {
  118. return res
  119. }
  120. if time.Now().After(deadline) {
  121. t.Fatalf("FetchAsync timeout: state=%d progress=%d msg=%s", res.State, res.Progress, res.Msg)
  122. }
  123. time.Sleep(3 * time.Second)
  124. }
  125. }
  126. func waitEffectiveProgress(t *testing.T, d *Dialog, env string, timeout time.Duration) *EffectiveProgressResponse {
  127. t.Helper()
  128. deadline := time.Now().Add(timeout)
  129. for {
  130. res, err := d.GetEffectiveProgress(&EffectiveProgressRequest{Env: env})
  131. if err != nil {
  132. t.Fatalf("GetEffectiveProgress error: %v", err)
  133. }
  134. if res.Status == 1 || res.Status == 2 {
  135. return res
  136. }
  137. if time.Now().After(deadline) {
  138. t.Fatalf("GetEffectiveProgress timeout: status=%d progress=%d", res.Status, res.Progress)
  139. }
  140. time.Sleep(5 * time.Second)
  141. }
  142. }
  143. func waitQueryAnswer(t *testing.T, d *Dialog, question, answer string, timeout time.Duration) *QueryResponse {
  144. t.Helper()
  145. deadline := time.Now().Add(timeout)
  146. for {
  147. res, err := d.Query(&QueryRequest{
  148. Query: question,
  149. Env: "online",
  150. UserID: "gowechat-full-integration-test",
  151. })
  152. if err != nil {
  153. t.Fatalf("Query error: %v", err)
  154. }
  155. if res.Answer == answer {
  156. return res
  157. }
  158. if time.Now().After(deadline) {
  159. t.Fatalf("Query timeout: status=%s answer=%s want=%s", res.Status, res.Answer, answer)
  160. }
  161. time.Sleep(5 * time.Second)
  162. }
  163. }