The editor never saved which API the Base URL was picked as; reopening showed the first API with a URL, chat first. A provider added as OpenAI compatible keeps its chat URL when Responses is picked (#105), so after Responses was picked, its URL typed and saved, it opened as OpenAI compatible again. Picked with no URL of its own, the Save sent nothing for it and the pick was gone without a word. Now the pick is saved with the provider (baseAPI), sent back to the editor and shown while it has a URL; a save that doesn't say keeps it, and one whose URL is cleared elsewhere drops it. A Save with the picked API's URL empty while another has one says so in the form. Requests are unchanged: they go by which URLs are set. Verified: reproduced on origin/main in a sandbox HOME with the built binary (magpie web, real GUI via Playwright, fake Responses-only upstream): a provider added as OpenAI compatible, then saved as Responses with and without its URL typed, reopened as OpenAI compatible. With the change it reopens as OpenAI Responses after a reload, a 65s wait and an app restart, and the empty Save shows the message. A provider added as Responses from the start was already kept and still is. TestProviderBaseAPIKept fails without the change ("added as OpenAI compatible, shown as \"\""); provider-base-api.test.cjs fails on the old app.js (actual 'OpenAI compatible', expected 'OpenAI Responses') and passes in Chromium and WebKit, en and zh. gui-ja, gui-de, i18n-keys and the provider*/system-one/azure/add-sheet/menu-scroll GUI tests pass in both engines. go vet, GOOS=linux/windows builds, go test -tags nogui ./... pass under a temp HOME.
85 lines
2.8 KiB
Go
85 lines
2.8 KiB
Go
package gui
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/yetone/magpie/internal/provider"
|
|
)
|
|
|
|
// The API a custom provider's Base URL was given as in its editor is kept
|
|
// (01huadalang on Discord: 我选 response 保存了然后再打开一会就变成 openai
|
|
// 兼容了). A provider saved as OpenAI compatible, then given its URL as
|
|
// OpenAI Responses, has both URLs: the editor showed the first, chat, and
|
|
// so OpenAI compatible. The pick is saved, sent back to the editor, kept by
|
|
// a save that doesn't say, and dropped once its URL is gone.
|
|
func TestProviderBaseAPIKept(t *testing.T) {
|
|
t.Setenv("HOME", t.TempDir())
|
|
t.Setenv("USERPROFILE", os.Getenv("HOME"))
|
|
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
|
|
t.Setenv("XDG_CACHE_HOME", t.TempDir())
|
|
mux := http.NewServeMux()
|
|
providerRoutes(mux, nil)
|
|
post := func(action, body string) {
|
|
t.Helper()
|
|
w := httptest.NewRecorder()
|
|
mux.ServeHTTP(w, httptest.NewRequest("POST", "/api/provider/"+action, strings.NewReader(body)))
|
|
if w.Code != 200 {
|
|
t.Fatalf("%s: %d %s", action, w.Code, w.Body)
|
|
}
|
|
}
|
|
shown := func() string {
|
|
t.Helper()
|
|
w := httptest.NewRecorder()
|
|
mux.ServeHTTP(w, httptest.NewRequest("GET", "/api/providers", nil))
|
|
var got struct{ Providers []map[string]any }
|
|
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, p := range got.Providers {
|
|
if p["id"] == "relay" {
|
|
s, _ := p["baseAPI"].(string)
|
|
return s
|
|
}
|
|
}
|
|
t.Fatalf("relay not listed: %s", w.Body)
|
|
return ""
|
|
}
|
|
const u = "http://127.0.0.1:1/v1"
|
|
// added as OpenAI compatible, as the editor sends it
|
|
post("save", `{"id":"relay","name":"Relay","key":"sk-a","chat":"`+u+`","icon":"generic","baseAPI":"chat","new":true}`)
|
|
if got := shown(); got != "chat" {
|
|
t.Fatalf("added as OpenAI compatible, shown as %q", got)
|
|
}
|
|
// reopened, OpenAI Responses picked and its URL typed: chat's stays (#105)
|
|
post("save", `{"id":"relay","from":"relay","name":"Relay","chat":"`+u+`","responses":"`+u+`","icon":"generic","baseAPI":"responses"}`)
|
|
if got := shown(); got != "responses" {
|
|
t.Fatalf("saved as OpenAI Responses, shown as %q", got)
|
|
}
|
|
p, err := provider.Find("relay")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if p.Chat != u || p.Responses != u {
|
|
t.Fatalf("stored %+v", p)
|
|
}
|
|
// a save that doesn't say which (an older window, another page) keeps it
|
|
post("save", `{"id":"relay","from":"relay","name":"Relay","chat":"`+u+`","responses":"`+u+`","icon":"generic"}`)
|
|
if got := shown(); got != "responses" {
|
|
t.Fatalf("a save without the pick lost it: %q", got)
|
|
}
|
|
// the Responses URL cleared elsewhere (the CLI): no pick is left to show
|
|
p, _ = provider.Find("relay")
|
|
p.Responses = ""
|
|
if err := provider.Save(*p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := shown(); got != "" {
|
|
t.Fatalf("a pick with no URL kept: %q", got)
|
|
}
|
|
}
|