Tests and vite config change to support

This commit is contained in:
Peter Clement 2025-05-02 13:22:09 +01:00
parent 1e7456a31c
commit 4821ce1e8c
2 changed files with 117 additions and 16 deletions

View File

@ -1,11 +1,23 @@
import { it, expect, describe, vi } from "vitest" import { it, expect, describe, vi } from "vitest"
import AISettings from "./index.svelte" import AISettings from "./index.svelte"
import { render, fireEvent } from "@testing-library/svelte" import { render, waitFor } from "@testing-library/svelte"
import { admin, licensing, featureFlags } from "@/stores/portal" import { admin, licensing, featureFlags } from "@/stores/portal"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
import { API } from "@/api"
vi.spyOn(notifications, "error").mockImplementation(vi.fn) vi.spyOn(notifications, "error").mockImplementation(vi.fn)
vi.spyOn(notifications, "success").mockImplementation(vi.fn) vi.spyOn(notifications, "success").mockImplementation(vi.fn)
vi.mock("@/api", () => ({
API: {
getConfig: vi.fn().mockResolvedValue({
config: {},
}),
getLicenseKey: vi.fn().mockResolvedValue({
licenseKey: "abc-123",
}),
saveConfig: vi.fn(),
},
}))
const Hosting = { const Hosting = {
Cloud: "cloud", Cloud: "cloud",
@ -15,7 +27,6 @@ const Hosting = {
function setupEnv(hosting, features = {}, flags = {}) { function setupEnv(hosting, features = {}, flags = {}) {
const defaultFeatures = { const defaultFeatures = {
budibaseAIEnabled: false, budibaseAIEnabled: false,
customAIConfigsEnabled: false,
...features, ...features,
} }
const defaultFlags = { const defaultFlags = {
@ -41,33 +52,122 @@ describe("AISettings", () => {
let instance = null let instance = null
const setupDOM = () => { const setupDOM = () => {
instance = render(AISettings, {}) instance = render(AISettings)
const modalContainer = document.createElement("div") const modalContainer = document.createElement("div")
modalContainer.classList.add("modal-container") modalContainer.classList.add("modal-container")
instance.baseElement.appendChild(modalContainer) instance.baseElement.appendChild(modalContainer)
} }
beforeEach(() => {
setupEnv(Hosting.Self)
})
afterEach(() => { afterEach(() => {
vi.restoreAllMocks() vi.restoreAllMocks()
}) })
it("that the AISettings is rendered", () => { describe("Basic rendering", () => {
setupDOM() it("should render the AI header", async () => {
expect(instance).toBeDefined() setupDOM()
await waitFor(() => {
const header = instance.getByText("AI")
expect(header).toBeInTheDocument()
})
})
it("should show 'No LLMs are enabled' when no providers are active", async () => {
API.getConfig.mockResolvedValueOnce({ config: {} })
setupDOM()
await waitFor(() => {
const noEnabledText = instance.getByText("No LLMs are enabled")
expect(noEnabledText).toBeInTheDocument()
})
})
it("should display the 'Enable BB AI' button", async () => {
setupDOM()
await waitFor(() => {
const enableButton = instance.getByText("Enable BB AI")
expect(enableButton).toBeInTheDocument()
})
})
}) })
describe("DOM Render tests", () => { describe("Provider rendering", () => {
it("the enable bb ai button should not do anything if the user doesn't have the correct license on self host", async () => { it("should display active provider with active status tag", async () => {
let addAiButton API.getConfig.mockResolvedValueOnce({
let configModal config: {
BudibaseAI: {
provider: "BudibaseAI",
active: true,
isDefault: true,
name: "Budibase AI",
},
},
})
setupEnv(Hosting.Self, { customAIConfigsEnabled: false })
setupDOM() setupDOM()
addAiButton = instance.queryByText("Enable BB AI")
expect(addAiButton).toBeInTheDocument() await waitFor(() => {
await fireEvent.click(addAiButton) const providerName = instance.getByText("Budibase AI")
configModal = instance.queryByText("Custom AI Configuration") expect(providerName).toBeInTheDocument()
expect(configModal).not.toBeInTheDocument()
const statusTags = instance.baseElement.querySelectorAll(".tag.active")
expect(statusTags.length).toBeGreaterThan(0)
let foundEnabledTag = false
statusTags.forEach(tag => {
if (tag.textContent === "Enabled") {
foundEnabledTag = true
}
})
expect(foundEnabledTag).toBe(true)
})
})
it("should display disabled provider with disabled status tag", async () => {
API.getConfig.mockResolvedValueOnce({
config: {
BudibaseAI: {
provider: "BudibaseAI",
active: true,
isDefault: true,
name: "Budibase AI",
},
OpenAI: {
provider: "OpenAI",
active: false,
isDefault: false,
name: "OpenAI",
},
},
})
setupDOM()
await waitFor(async () => {
const disabledProvider = instance.getByText("OpenAI")
expect(disabledProvider).toBeInTheDocument()
const disabledTags =
instance.baseElement.querySelectorAll(".tag.disabled")
expect(disabledTags.length).toBeGreaterThan(0)
let foundDisabledTag = false
disabledTags.forEach(tag => {
if (tag.textContent === "Disabled") {
foundDisabledTag = true
}
})
expect(foundDisabledTag).toBe(true)
const openAIOption = disabledProvider.closest(".option")
expect(openAIOption).not.toBeNull()
const disabledTagNearOpenAI =
openAIOption.querySelector(".tag.disabled")
expect(disabledTagNearOpenAI).not.toBeNull()
expect(disabledTagNearOpenAI.textContent).toBe("Disabled")
})
}) })
}) })
}) })

View File

@ -87,6 +87,7 @@ export default defineConfig(({ mode }) => {
exclude: ["@roxi/routify", "fsevents"], exclude: ["@roxi/routify", "fsevents"],
}, },
resolve: { resolve: {
conditions: mode === "test" ? ["browser"] : [],
dedupe: ["@roxi/routify"], dedupe: ["@roxi/routify"],
alias: { alias: {
"@budibase/types": path.resolve(__dirname, "../types/src"), "@budibase/types": path.resolve(__dirname, "../types/src"),