mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-11 03:59:58 +08:00
155 lines
5.2 KiB
TypeScript
155 lines
5.2 KiB
TypeScript
import { describe, expect, it } from "vitest"
|
|||
|
|
import enDict from "@/lib/i18n/dictionaries/en.json"
|
||
|
|
import jaDict from "@/lib/i18n/dictionaries/ja.json"
|
||
|
|
import zhDict from "@/lib/i18n/dictionaries/zh.json"
|
||
|
|
import zhHantDict from "@/lib/i18n/dictionaries/zh-Hant.json"
|
||
|
|
import {
|
||
|
|
filterProviderGroups,
|
||
|
|
hasCredentials,
|
||
|
|
POPULAR_PROVIDERS,
|
||
|
|
PROVIDER_GROUPS,
|
||
|
|
PROVIDER_NOTE_KEYS,
|
||
|
|
providerStatus,
|
||
|
|
} from "@/lib/provider-setup"
|
||
|
|
import { PROVIDER_INFO, type ProviderConfig } from "@/lib/types/model-config"
|
||
|
|
import { useUiStore } from "@/stores/ui-store"
|
||
|
|
|
||
|
|
const provider = (p: Partial<ProviderConfig>): ProviderConfig => ({
|
||
|
|
id: "p",
|
||
|
|
provider: "openai",
|
||
|
|
apiKey: "",
|
||
|
|
models: [],
|
||
|
|
...p,
|
||
|
|
})
|
||
|
|
|
||
|
|
describe("provider groups", () => {
|
||
|
|
it("hold every provider exactly once", () => {
|
||
|
|
const grouped = PROVIDER_GROUPS.flatMap((g) => g.providers)
|
||
|
|
expect([...grouped].sort()).toEqual(Object.keys(PROVIDER_INFO).sort())
|
||
|
|
expect(new Set(grouped).size).toBe(grouped.length)
|
||
|
|
})
|
||
|
|
|
||
|
|
it("offer known providers as popular ones", () => {
|
||
|
|
for (const p of POPULAR_PROVIDERS) expect(PROVIDER_INFO[p]).toBeTruthy()
|
||
|
|
})
|
||
|
|
|
||
|
|
it("have their notes in every language", () => {
|
||
|
|
for (const dict of [enDict, zhDict, jaDict, zhHantDict]) {
|
||
|
|
const t = dict.modelConfig as Record<string, string>
|
||
|
|
for (const key of Object.values(PROVIDER_NOTE_KEYS)) {
|
||
|
|
expect(t[key as string]).toBeTruthy()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it("are searched by label or name, ignoring case and spaces", () => {
|
||
|
|
expect(filterProviderGroups(" ")).toBe(PROVIDER_GROUPS)
|
||
|
|
const kimi = filterProviderGroups("MOONSHOT")
|
||
|
|
expect(kimi.map((g) => g.providers)).toEqual([["kimi"]])
|
||
|
|
// By the provider's own name too
|
||
|
|
expect(
|
||
|
|
filterProviderGroups("vertexai").flatMap((g) => g.providers),
|
||
|
|
).toEqual(["vertexai"])
|
||
|
|
expect(filterProviderGroups("no such provider")).toEqual([])
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe("hasCredentials", () => {
|
||
|
|
it("asks each provider for what it signs in with", () => {
|
||
|
|
const cases: [Partial<ProviderConfig>, boolean][] = [
|
||
|
|
[{ provider: "openai" }, false],
|
||
|
|
[{ provider: "openai", apiKey: "k" }, true],
|
||
|
|
[{ provider: "ollama" }, true],
|
||
|
|
[{ provider: "edgeone" }, true],
|
||
|
|
[{ provider: "vertexai", apiKey: "k" }, false],
|
||
|
|
[{ provider: "vertexai", vertexApiKey: "k" }, true],
|
||
|
|
[{ provider: "bedrock", apiKey: "k" }, false],
|
||
|
|
[
|
||
|
|
{ provider: "bedrock", apiKey: "k", awsRegion: "us-east-1" },
|
||
|
|
true,
|
||
|
|
],
|
||
|
|
[
|
||
|
|
{
|
||
|
|
provider: "bedrock",
|
||
|
|
awsAccessKeyId: "a",
|
||
|
|
awsRegion: "us-east-1",
|
||
|
|
},
|
||
|
|
false,
|
||
|
|
],
|
||
|
|
[
|
||
|
|
{
|
||
|
|
provider: "bedrock",
|
||
|
|
awsAccessKeyId: "a",
|
||
|
|
awsSecretAccessKey: "s",
|
||
|
|
awsRegion: "us-east-1",
|
||
|
|
},
|
||
|
|
true,
|
||
|
|
],
|
||
|
|
]
|
||
|
|
for (const [p, expected] of cases) {
|
||
|
|
expect([p, hasCredentials(provider(p))]).toEqual([p, expected])
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe("providerStatus", () => {
|
||
|
|
const models = (...validated: (boolean | undefined)[]) =>
|
||
|
|
validated.map((v, i) => ({
|
||
|
|
id: `m${i}`,
|
||
|
|
modelId: `m${i}`,
|
||
|
|
validated: v,
|
||
|
|
}))
|
||
|
|
|
||
|
|
it("puts a failed model first", () => {
|
||
|
|
expect(
|
||
|
|
providerStatus(provider({ models: models(false, false, true) })),
|
||
|
|
).toEqual({ kind: "error", count: 2 })
|
||
|
|
// Even without credentials
|
||
|
|
expect(providerStatus(provider({ models: models(false) }))).toEqual({
|
||
|
|
kind: "error",
|
||
|
|
count: 1,
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
it("then a missing key or no model", () => {
|
||
|
|
expect(providerStatus(provider({ models: models(true) }))).toEqual({
|
||
|
|
kind: "incomplete",
|
||
|
|
})
|
||
|
|
expect(providerStatus(provider({ apiKey: "k" }))).toEqual({
|
||
|
|
kind: "incomplete",
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
it("then untested models, else all working", () => {
|
||
|
|
expect(
|
||
|
|
providerStatus(
|
||
|
|
provider({ apiKey: "k", models: models(true, undefined) }),
|
||
|
|
),
|
||
|
|
).toEqual({ kind: "untested", count: 1 })
|
||
|
|
expect(
|
||
|
|
providerStatus(
|
||
|
|
provider({ apiKey: "k", models: models(true, true) }),
|
||
|
|
),
|
||
|
|
).toEqual({ kind: "ok", count: 2 })
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe("openSettings", () => {
|
||
|
|
it("opens the models tab's list unless a page is given", () => {
|
||
|
|
const store = useUiStore.getState()
|
||
|
|
store.openSettings("models", { providerId: "p1" })
|
||
|
|
expect(useUiStore.getState().modelsPage).toEqual({ providerId: "p1" })
|
||
|
|
store.setSettingsOpen(false)
|
||
|
|
// Opened again some other way: back on the list, on the last tab
|
||
|
|
store.setSettingsTab("drawing")
|
||
|
|
store.openSettings()
|
||
|
|
expect(useUiStore.getState()).toMatchObject({
|
||
|
|
settingsOpen: true,
|
||
|
|
settingsTab: "drawing",
|
||
|
|
modelsPage: "list",
|
||
|
|
})
|
||
|
|
store.openSettings("models", "picker")
|
||
|
|
expect(useUiStore.getState().modelsPage).toBe("picker")
|
||
|
|
})
|
||
|
|
})
|