mirror of
https://github.com/kardolus/chatgpt-cli.git
synced 2024-09-08 23:15:00 +03:00
Test http-error assembly
This commit is contained in:
@@ -13,6 +13,8 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
const expectedToken = "valid-api-key"
|
||||
|
||||
var (
|
||||
onceBuild sync.Once
|
||||
onceServe sync.Once
|
||||
@@ -81,6 +83,11 @@ func getModels(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkBearerToken(r, expectedToken); err != nil {
|
||||
http.Error(w, creatAuthError(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
const modelFile = "models.json"
|
||||
response, err := utils.FileToBytes(modelFile)
|
||||
if err != nil {
|
||||
@@ -96,6 +103,11 @@ func postCompletions(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkBearerToken(r, expectedToken); err != nil {
|
||||
http.Error(w, creatAuthError(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
const completionsFile = "completions.json"
|
||||
response, err := utils.FileToBytes(completionsFile)
|
||||
if err != nil {
|
||||
@@ -105,6 +117,37 @@ func postCompletions(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(response)
|
||||
}
|
||||
|
||||
func checkBearerToken(r *http.Request, expectedToken string) error {
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
return errors.New("missing Authorization header")
|
||||
}
|
||||
|
||||
splitToken := strings.Split(authHeader, "Bearer ")
|
||||
if len(splitToken) != 2 {
|
||||
return errors.New("malformed Authorization header")
|
||||
}
|
||||
|
||||
requestToken := splitToken[1]
|
||||
if requestToken != expectedToken {
|
||||
return errors.New("invalid token")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func creatAuthError() string {
|
||||
const errorFile = "error.json"
|
||||
|
||||
response, err := utils.FileToBytes(errorFile)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading %s: %s\n", errorFile, err.Error())
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(response)
|
||||
}
|
||||
|
||||
func validateRequest(w http.ResponseWriter, r *http.Request, allowedMethod string) error {
|
||||
if r.Method != allowedMethod {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
|
||||
@@ -156,7 +156,6 @@ func testIntegration(t *testing.T, when spec.G, it spec.S) {
|
||||
const (
|
||||
exitSuccess = 0
|
||||
exitFailure = 1
|
||||
apiKey = "some-key"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -181,7 +180,7 @@ func testIntegration(t *testing.T, when spec.G, it spec.S) {
|
||||
apiKeyEnvVar = configmanager.New(config.New()).WithEnvironment().APIKeyEnvVarName()
|
||||
|
||||
Expect(os.Setenv("HOME", homeDir)).To(Succeed())
|
||||
Expect(os.Setenv(apiKeyEnvVar, apiKey)).To(Succeed())
|
||||
Expect(os.Setenv(apiKeyEnvVar, expectedToken)).To(Succeed())
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
@@ -314,6 +313,21 @@ func testIntegration(t *testing.T, when spec.G, it spec.S) {
|
||||
Expect(output).To(ContainSubstring(`I don't have personal opinions about bars, but here are some popular bars in Red Hook, Brooklyn:`))
|
||||
})
|
||||
|
||||
it("should assemble http errors as expected", func() {
|
||||
Expect(os.Setenv(apiKeyEnvVar, "wrong-token")).To(Succeed())
|
||||
|
||||
command := exec.Command(binaryPath, "--query", "some-query")
|
||||
session, err := gexec.Start(command, io.Discard, io.Discard)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(session).Should(gexec.Exit(exitFailure))
|
||||
|
||||
output := string(session.Out.Contents())
|
||||
|
||||
// see error.json
|
||||
Expect(output).To(Equal("http status 401: Incorrect API key provided\n"))
|
||||
})
|
||||
|
||||
when("there is a hidden chatgpt-cli folder in the home dir", func() {
|
||||
var filePath string
|
||||
|
||||
@@ -487,7 +501,7 @@ func testIntegration(t *testing.T, when spec.G, it spec.S) {
|
||||
|
||||
// config.yaml should have the expected content
|
||||
content := string(contentBytes)
|
||||
Expect(content).NotTo(ContainSubstring(apiKey))
|
||||
Expect(content).NotTo(ContainSubstring(expectedToken))
|
||||
Expect(content).To(ContainSubstring(newModel))
|
||||
|
||||
// --list-models shows the new model as default
|
||||
@@ -565,7 +579,7 @@ func testIntegration(t *testing.T, when spec.G, it spec.S) {
|
||||
|
||||
// config.yaml should have the expected content
|
||||
content := string(contentBytes)
|
||||
Expect(content).NotTo(ContainSubstring(apiKey))
|
||||
Expect(content).NotTo(ContainSubstring(expectedToken))
|
||||
Expect(content).To(ContainSubstring(newMaxTokens))
|
||||
|
||||
// --config displays the new max-tokens as well
|
||||
|
||||
8
resources/testdata/error.json
vendored
Normal file
8
resources/testdata/error.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"error": {
|
||||
"message": "Incorrect API key provided",
|
||||
"type": "invalid_request_error",
|
||||
"param": null,
|
||||
"code": "invalid_api_key"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user