You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

105 lines
3.4 KiB

  1. package openai
  2. import (
  3. "io"
  4. "net/http"
  5. "net/http/httptest"
  6. "strings"
  7. "testing"
  8. "github.com/QuantumNous/new-api/common"
  9. "github.com/QuantumNous/new-api/dto"
  10. relaycommon "github.com/QuantumNous/new-api/relay/common"
  11. "github.com/gin-gonic/gin"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. )
  15. func TestResponsesStreamEventErrorParsing(t *testing.T) {
  16. t.Run("standalone error event", func(t *testing.T) {
  17. data := `{"type":"error","error":{"type":"too_many_requests","code":"too_many_requests","message":"Too Many Requests","param":null}}`
  18. var streamResp dto.ResponsesStreamResponse
  19. err := common.UnmarshalJsonStr(data, &streamResp)
  20. require.NoError(t, err)
  21. assert.Equal(t, "error", streamResp.Type)
  22. assert.NotNil(t, streamResp.Error)
  23. oaiErr := dto.GetOpenAIError(streamResp.Error)
  24. require.NotNil(t, oaiErr)
  25. assert.Equal(t, "too_many_requests", oaiErr.Type)
  26. assert.Equal(t, "Too Many Requests", oaiErr.Message)
  27. })
  28. t.Run("response.failed event", func(t *testing.T) {
  29. data := `{"type":"response.failed","response":{"id":"test-id","status":"failed","error":{"type":"server_error","message":"Internal server error"}}}`
  30. var streamResp dto.ResponsesStreamResponse
  31. err := common.UnmarshalJsonStr(data, &streamResp)
  32. require.NoError(t, err)
  33. assert.Equal(t, "response.failed", streamResp.Type)
  34. require.NotNil(t, streamResp.Response)
  35. oaiErr := streamResp.Response.GetOpenAIError()
  36. require.NotNil(t, oaiErr)
  37. assert.Equal(t, "server_error", oaiErr.Type)
  38. })
  39. t.Run("response.error event with error in response object", func(t *testing.T) {
  40. data := `{"type":"response.error","response":{"id":"test-id","status":"failed","error":{"type":"invalid_request_error","message":"Invalid model"}}}`
  41. var streamResp dto.ResponsesStreamResponse
  42. err := common.UnmarshalJsonStr(data, &streamResp)
  43. require.NoError(t, err)
  44. assert.Equal(t, "response.error", streamResp.Type)
  45. oaiErr := streamResp.Response.GetOpenAIError()
  46. require.NotNil(t, oaiErr)
  47. assert.Equal(t, "invalid_request_error", oaiErr.Type)
  48. })
  49. t.Run("normal event has no error", func(t *testing.T) {
  50. data := `{"type":"response.output_text.delta","delta":"hello"}`
  51. var streamResp dto.ResponsesStreamResponse
  52. err := common.UnmarshalJsonStr(data, &streamResp)
  53. require.NoError(t, err)
  54. assert.Equal(t, "response.output_text.delta", streamResp.Type)
  55. assert.Nil(t, streamResp.Error)
  56. })
  57. }
  58. func TestOaiResponsesHandlerAttachesUpstreamBodyOnInvalidJSON(t *testing.T) {
  59. gin.SetMode(gin.TestMode)
  60. w := httptest.NewRecorder()
  61. c, _ := gin.CreateTestContext(w)
  62. resp := &http.Response{
  63. StatusCode: http.StatusOK,
  64. Body: io.NopCloser(strings.NewReader(`{"incomplete":`)),
  65. }
  66. usage, err := OaiResponsesHandler(c, &relaycommon.RelayInfo{}, resp)
  67. require.Nil(t, usage)
  68. require.Error(t, err)
  69. assert.NotEmpty(t, err.UpstreamBody)
  70. assert.Contains(t, err.UpstreamBody, `{"incomplete":`)
  71. }
  72. func TestOaiResponsesToChatHandlerAttachesUpstreamBodyOnInvalidJSON(t *testing.T) {
  73. gin.SetMode(gin.TestMode)
  74. w := httptest.NewRecorder()
  75. c, _ := gin.CreateTestContext(w)
  76. resp := &http.Response{
  77. StatusCode: http.StatusOK,
  78. Body: io.NopCloser(strings.NewReader(`{"incomplete":`)),
  79. }
  80. usage, err := OaiResponsesToChatHandler(c, &relaycommon.RelayInfo{}, resp)
  81. require.Nil(t, usage)
  82. require.Error(t, err)
  83. assert.NotEmpty(t, err.UpstreamBody)
  84. assert.Contains(t, err.UpstreamBody, `{"incomplete":`)
  85. }