feat(web): refuse an unusable API key on the field that holds it
This commit is contained in:
@@ -11,6 +11,7 @@ import { pathOps } from '../src/client/ProviderEditor.tsx'
|
||||
import {
|
||||
DeepSeekModelsEditor, formatCapacity, modelDrafts, parseCapacity, validateDeepSeekModels,
|
||||
} from '../src/client/DeepSeekModelsEditor.tsx'
|
||||
import { apiKeyFailure } from '../src/client/apiKey.ts'
|
||||
import { deriveKeyRef, ModelsSettingsStore } from '../src/client/store.ts'
|
||||
import type { ProviderRow } from '../src/client/store.ts'
|
||||
import { en } from '../src/client/locales.ts'
|
||||
@@ -1080,3 +1081,52 @@ describe('ModelsSection', () => {
|
||||
expect(failure).toBe('connection lost')
|
||||
})
|
||||
})
|
||||
|
||||
describe('apiKeyFailure', () => {
|
||||
it('treats a blank field as no failure — it means keep the stored key', () => {
|
||||
expect(apiKeyFailure('')).toBeUndefined()
|
||||
})
|
||||
|
||||
it.each([
|
||||
['a printable-ASCII key', 'sk-0123456789'],
|
||||
['a padded key, which the caller trims', ' sk-abc '],
|
||||
['the printable-ASCII boundary characters', '!~'],
|
||||
['a hyphenated key carrying an equals sign', 'sk-ABC=xyz'],
|
||||
])('accepts %s', (_label, draft) => {
|
||||
expect(apiKeyFailure(draft)).toBeUndefined()
|
||||
})
|
||||
|
||||
it.each([
|
||||
['spaces', ' '],
|
||||
['a tab', '\t'],
|
||||
])('fails a field holding only %s instead of silently dropping it', (_label, draft) => {
|
||||
expect(apiKeyFailure(draft)).toBe('keyBlank')
|
||||
})
|
||||
|
||||
it.each([
|
||||
['an emoji', 'sk-\u{1F600}'],
|
||||
['CJK text', 'sk-你好'],
|
||||
['full-width punctuation', 'sk-abc,'],
|
||||
['an interior space', 'sk-abc def'],
|
||||
['a C0 control character', 'sk-abc\x01'],
|
||||
['a latin-1 character', 'sk-café'],
|
||||
])('fails %s as illegal characters', (_label, draft) => {
|
||||
expect(apiKeyFailure(draft)).toBe('keyIllegalCharacters')
|
||||
})
|
||||
|
||||
it.each([
|
||||
['a pasted environment line', 'DEEPSEEK_API_KEY=sk-abc'],
|
||||
['double quotes', '"sk-abc"'],
|
||||
['single quotes', '\'sk-abc\''],
|
||||
['backticks', '`sk-abc`'],
|
||||
])('fails %s as wrapped', (_label, draft) => {
|
||||
expect(apiKeyFailure(draft)).toBe('keyLooksWrapped')
|
||||
})
|
||||
|
||||
it('needs a matching closing quote before it calls a value wrapped', () => {
|
||||
// A lone quote and an unbalanced one are legal printable ASCII, so the
|
||||
// heuristic leaves them alone rather than guessing at a paste error.
|
||||
expect(apiKeyFailure('"')).toBeUndefined()
|
||||
expect(apiKeyFailure('"a')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user