mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-07 04:53:24 -05:00
No release ever shipped add-ons, so there is no installed base on api 1.
The manifest must now declare api {"min": 2, "max": 2}; a manifest with
api 1, no api or a wider range is refused with a message that names the
range.
Every field that was gated on api 2 is now part of the contract, so the
Min*API constants and their gates are gone, and so are HostAPIMin and
the apiMin host field. Three older-manifest shims go with them: the
resource listing the host implied for one add-on, the legacyArgs hint
for arguments an older version of a tool took, and the tests that
checked the gates. All shipped manifests and the test fixtures declare
api 2.
Assisted-by: Claude:claude-sonnet-5-5 go test
89 lines
3.3 KiB
Go
89 lines
3.3 KiB
Go
// SPDX-License-Identifier: MIT
|
|
package contract
|
|
|
|
import (
|
|
"os"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("the roles and permissions of a connector kind", func() {
|
|
var m Manifest
|
|
BeforeEach(func() {
|
|
b, err := os.ReadFile("../../../tests/addons/fixtures/contracts/page.json")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
m, err = ParseManifest(b)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
m.API = VersionRange{Min: 2, Max: 2}
|
|
m.Capabilities.UI = nil
|
|
m.Capabilities.Connector = &ConnectorCapability{Kinds: []ConnectorKind{{ID: "chat", Title: "Chat", Delivery: DeliveryPull}}}
|
|
})
|
|
host := func() HostCompatibility {
|
|
h := compatible()
|
|
h.SDK = HostSDKVersion
|
|
return h
|
|
}
|
|
kind := func() *ConnectorKind { return &m.Capabilities.Connector.Kinds[0] }
|
|
|
|
It("accepts roles and known permissions", func() {
|
|
kind().Roles = []ConnectorRole{{ID: "admin", Title: "Admin", Description: "Workspace admin"}}
|
|
kind().Permissions = []string{CapProposalsConfirm, CapMemoryWrite, CapProfileWrite}
|
|
Expect(ValidateManifest(m, host())).To(Succeed())
|
|
})
|
|
|
|
It("refuses an unknown or repeated permission", func() {
|
|
kind().Permissions = []string{"root.everything"}
|
|
Expect(ValidateManifest(m, host())).NotTo(Succeed())
|
|
kind().Permissions = []string{CapMemoryWrite, CapMemoryWrite}
|
|
Expect(ValidateManifest(m, host())).NotTo(Succeed())
|
|
})
|
|
|
|
It("refuses too many roles or permissions, a bad role ID and a repeated role", func() {
|
|
kind().Roles = nil
|
|
for i := 0; i <= MaxConnectorRoles; i++ {
|
|
kind().Roles = append(kind().Roles, ConnectorRole{ID: "r" + string(rune('a'+i)), Title: "R"})
|
|
}
|
|
Expect(ValidateManifest(m, host())).NotTo(Succeed())
|
|
kind().Roles = []ConnectorRole{{ID: "Bad Id", Title: "R"}}
|
|
Expect(ValidateManifest(m, host())).NotTo(Succeed())
|
|
kind().Roles = []ConnectorRole{{ID: "a", Title: "A"}, {ID: "a", Title: "B"}}
|
|
Expect(ValidateManifest(m, host())).NotTo(Succeed())
|
|
kind().Roles = nil
|
|
kind().Permissions = ConnectorCapabilityNames()
|
|
Expect(ValidateManifest(m, host())).To(Succeed()) // the whole list fits
|
|
kind().Permissions = append(kind().Permissions, "x.1", "x.2")
|
|
Expect(ValidateManifest(m, host())).NotTo(Succeed())
|
|
})
|
|
|
|
It("describes every capability, and never makes a sensitive one usual", func() {
|
|
list := ConnectorCapabilities()
|
|
Expect(list).To(HaveLen(len(ConnectorCapabilityNames())))
|
|
usual := 0
|
|
for _, c := range list {
|
|
Expect(c.Title).NotTo(BeEmpty(), c.Name)
|
|
Expect(c.Description).NotTo(BeEmpty(), c.Name)
|
|
Expect(c.Sensitive).To(Equal(SensitiveCapability(c.Name)))
|
|
if c.Usual {
|
|
usual++
|
|
Expect(c.Sensitive).To(BeFalse(), c.Name)
|
|
}
|
|
}
|
|
Expect(usual).To(BeNumerically(">", 0))
|
|
Expect(capabilityText).To(HaveLen(len(capabilities)))
|
|
})
|
|
|
|
It("never grants a sensitive capability to a role", func() {
|
|
kind().Permissions = []string{CapProfileWrite, CapMemoryWrite}
|
|
Expect(kind().Grantable(CapProfileWrite)).To(BeFalse())
|
|
Expect(kind().Grantable(CapMemoryWrite)).To(BeTrue())
|
|
Expect(kind().Grantable(CapFilesUpload)).To(BeFalse(), "not listed by the kind")
|
|
})
|
|
|
|
It("keeps only declared, distinct roles of a message", func() {
|
|
kind().Roles = []ConnectorRole{{ID: "admin", Title: "Admin"}}
|
|
Expect(kind().FilterRoles([]string{"admin", "root", "admin"})).To(Equal([]string{"admin"}))
|
|
Expect((ConnectorKind{}).FilterRoles([]string{"admin"})).To(BeEmpty())
|
|
})
|
|
})
|