Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
d765359f
Commit
d765359f
authored
Apr 09, 2026
by
IanShaw027
Browse files
test(admin): 增加messages调度表单状态转换测试
parent
4de4823a
Changes
3
Hide whitespace changes
Inline
Side-by-side
frontend/src/types/index.ts
View file @
d765359f
...
...
@@ -366,6 +366,13 @@ export type GroupPlatform = 'anthropic' | 'openai' | 'gemini' | 'antigravity'
export
type
SubscriptionType
=
'
standard
'
|
'
subscription
'
export
interface
OpenAIMessagesDispatchModelConfig
{
opus_mapped_model
?:
string
sonnet_mapped_model
?:
string
haiku_mapped_model
?:
string
exact_model_mappings
?:
Record
<
string
,
string
>
}
export
interface
Group
{
id
:
number
name
:
string
...
...
@@ -388,6 +395,8 @@ export interface Group {
fallback_group_id_on_invalid_request
:
number
|
null
// OpenAI Messages 调度开关(用户侧需要此字段判断是否展示 Claude Code 教程)
allow_messages_dispatch
?:
boolean
default_mapped_model
?:
string
messages_dispatch_model_config
?:
OpenAIMessagesDispatchModelConfig
require_oauth_only
:
boolean
require_privacy_set
:
boolean
created_at
:
string
...
...
@@ -414,6 +423,7 @@ export interface AdminGroup extends Group {
// OpenAI Messages 调度配置(仅 openai 平台使用)
default_mapped_model
?:
string
messages_dispatch_model_config
?:
OpenAIMessagesDispatchModelConfig
// 分组排序
sort_order
:
number
...
...
frontend/src/views/admin/__tests__/groupsMessagesDispatch.spec.ts
0 → 100644
View file @
d765359f
import
{
describe
,
expect
,
it
}
from
"
vitest
"
;
import
{
createDefaultMessagesDispatchFormState
,
messagesDispatchConfigToFormState
,
messagesDispatchFormStateToConfig
,
resetMessagesDispatchFormState
,
}
from
"
../groupsMessagesDispatch
"
;
describe
(
"
groupsMessagesDispatch
"
,
()
=>
{
it
(
"
returns the expected default form state
"
,
()
=>
{
expect
(
createDefaultMessagesDispatchFormState
()).
toEqual
({
allow_messages_dispatch
:
false
,
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.3-codex
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
[],
});
});
it
(
"
sanitizes exact model mapping rows when converting to config
"
,
()
=>
{
const
config
=
messagesDispatchFormStateToConfig
({
allow_messages_dispatch
:
true
,
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.3-codex
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
[
{
claude_model
:
"
claude-sonnet-4-5-20250929
"
,
target_model
:
"
gpt-5.2
"
,
},
{
claude_model
:
""
,
target_model
:
"
gpt-5.4
"
},
{
claude_model
:
"
claude-opus-4-6
"
,
target_model
:
"
"
},
],
});
expect
(
config
).
toEqual
({
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.3-codex
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
{
"
claude-sonnet-4-5-20250929
"
:
"
gpt-5.2
"
,
},
});
});
it
(
"
hydrates form state from api config
"
,
()
=>
{
expect
(
messagesDispatchConfigToFormState
({
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.2
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
{
"
claude-opus-4-6
"
:
"
gpt-5.4
"
,
"
claude-haiku-4-5-20251001
"
:
"
gpt-5.4-mini
"
,
},
}),
).
toEqual
({
allow_messages_dispatch
:
false
,
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.2
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
[
{
claude_model
:
"
claude-haiku-4-5-20251001
"
,
target_model
:
"
gpt-5.4-mini
"
,
},
{
claude_model
:
"
claude-opus-4-6
"
,
target_model
:
"
gpt-5.4
"
},
],
});
});
it
(
"
resets mutable form state when platform switches away from openai
"
,
()
=>
{
const
state
=
{
allow_messages_dispatch
:
true
,
opus_mapped_model
:
"
gpt-5.2
"
,
sonnet_mapped_model
:
"
gpt-5.4
"
,
haiku_mapped_model
:
"
gpt-5.1
"
,
exact_model_mappings
:
[
{
claude_model
:
"
claude-opus-4-6
"
,
target_model
:
"
gpt-5.4
"
},
],
};
resetMessagesDispatchFormState
(
state
);
expect
(
state
).
toEqual
({
allow_messages_dispatch
:
false
,
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.3-codex
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
[],
});
});
});
frontend/src/views/admin/groupsMessagesDispatch.ts
0 → 100644
View file @
d765359f
import
type
{
OpenAIMessagesDispatchModelConfig
}
from
"
@/types
"
;
export
interface
MessagesDispatchMappingRow
{
claude_model
:
string
;
target_model
:
string
;
}
export
interface
MessagesDispatchFormState
{
allow_messages_dispatch
:
boolean
;
opus_mapped_model
:
string
;
sonnet_mapped_model
:
string
;
haiku_mapped_model
:
string
;
exact_model_mappings
:
MessagesDispatchMappingRow
[];
}
export
function
createDefaultMessagesDispatchFormState
():
MessagesDispatchFormState
{
return
{
allow_messages_dispatch
:
false
,
opus_mapped_model
:
"
gpt-5.4
"
,
sonnet_mapped_model
:
"
gpt-5.3-codex
"
,
haiku_mapped_model
:
"
gpt-5.4-mini
"
,
exact_model_mappings
:
[],
};
}
export
function
messagesDispatchConfigToFormState
(
config
?:
OpenAIMessagesDispatchModelConfig
|
null
,
):
MessagesDispatchFormState
{
const
defaults
=
createDefaultMessagesDispatchFormState
();
const
exactMappings
=
Object
.
entries
(
config
?.
exact_model_mappings
||
{})
.
sort
(([
left
],
[
right
])
=>
left
.
localeCompare
(
right
))
.
map
(([
claude_model
,
target_model
])
=>
({
claude_model
,
target_model
}));
return
{
allow_messages_dispatch
:
false
,
opus_mapped_model
:
config
?.
opus_mapped_model
?.
trim
()
||
defaults
.
opus_mapped_model
,
sonnet_mapped_model
:
config
?.
sonnet_mapped_model
?.
trim
()
||
defaults
.
sonnet_mapped_model
,
haiku_mapped_model
:
config
?.
haiku_mapped_model
?.
trim
()
||
defaults
.
haiku_mapped_model
,
exact_model_mappings
:
exactMappings
,
};
}
export
function
messagesDispatchFormStateToConfig
(
state
:
MessagesDispatchFormState
,
):
OpenAIMessagesDispatchModelConfig
{
const
exactModelMappings
=
Object
.
fromEntries
(
state
.
exact_model_mappings
.
map
((
row
)
=>
[
row
.
claude_model
.
trim
(),
row
.
target_model
.
trim
()]
as
const
)
.
filter
(([
claudeModel
,
targetModel
])
=>
claudeModel
&&
targetModel
),
);
return
{
opus_mapped_model
:
state
.
opus_mapped_model
.
trim
(),
sonnet_mapped_model
:
state
.
sonnet_mapped_model
.
trim
(),
haiku_mapped_model
:
state
.
haiku_mapped_model
.
trim
(),
exact_model_mappings
:
exactModelMappings
,
};
}
export
function
resetMessagesDispatchFormState
(
target
:
MessagesDispatchFormState
,
):
void
{
const
defaults
=
createDefaultMessagesDispatchFormState
();
target
.
allow_messages_dispatch
=
defaults
.
allow_messages_dispatch
;
target
.
opus_mapped_model
=
defaults
.
opus_mapped_model
;
target
.
sonnet_mapped_model
=
defaults
.
sonnet_mapped_model
;
target
.
haiku_mapped_model
=
defaults
.
haiku_mapped_model
;
target
.
exact_model_mappings
=
[];
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment