mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-05-04 21:20:51 +08:00
将 vansour/sub2api#1555 的 OpenAI compact 能力建模手工移植到当前 main:账号 级 compact 状态/auto-force_on-force_off 模式、compact-only 模型映射、调度器 tier 分层(已支持 > 未知 > 已知不支持)、管理后台 compact 主动探测,以及对应 i18n/状态徽章。普通 /responses 流量行为不变,无数据库迁移。
163 lines
4.2 KiB
TypeScript
163 lines
4.2 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { mount } from '@vue/test-utils'
|
|
import AccountStatusIndicator from '../AccountStatusIndicator.vue'
|
|
import type { Account } from '@/types'
|
|
|
|
vi.mock('vue-i18n', async () => {
|
|
const actual = await vi.importActual<typeof import('vue-i18n')>('vue-i18n')
|
|
return {
|
|
...actual,
|
|
useI18n: () => ({
|
|
t: (key: string) => key
|
|
})
|
|
}
|
|
})
|
|
|
|
function makeAccount(overrides: Partial<Account>): Account {
|
|
return {
|
|
id: 1,
|
|
name: 'account',
|
|
platform: 'antigravity',
|
|
type: 'oauth',
|
|
proxy_id: null,
|
|
concurrency: 1,
|
|
priority: 1,
|
|
status: 'active',
|
|
error_message: null,
|
|
last_used_at: null,
|
|
expires_at: null,
|
|
auto_pause_on_expired: true,
|
|
created_at: '2026-03-15T00:00:00Z',
|
|
updated_at: '2026-03-15T00:00:00Z',
|
|
schedulable: true,
|
|
rate_limited_at: null,
|
|
rate_limit_reset_at: null,
|
|
overload_until: null,
|
|
temp_unschedulable_until: null,
|
|
temp_unschedulable_reason: null,
|
|
session_window_start: null,
|
|
session_window_end: null,
|
|
session_window_status: null,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
describe('AccountStatusIndicator', () => {
|
|
it('模型限流 + overages 启用 + 无 AICredits key → 显示 ⚡ (credits_active)', () => {
|
|
const wrapper = mount(AccountStatusIndicator, {
|
|
props: {
|
|
account: makeAccount({
|
|
id: 1,
|
|
name: 'ag-1',
|
|
extra: {
|
|
allow_overages: true,
|
|
model_rate_limits: {
|
|
'claude-sonnet-4-5': {
|
|
rate_limited_at: '2026-03-15T00:00:00Z',
|
|
rate_limit_reset_at: '2099-03-15T00:00:00Z'
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
global: {
|
|
stubs: {
|
|
Icon: true
|
|
}
|
|
}
|
|
})
|
|
|
|
expect(wrapper.text()).toContain('⚡')
|
|
expect(wrapper.text()).toContain('CSon45')
|
|
})
|
|
|
|
it('模型限流 + overages 未启用 → 普通限流样式(无 ⚡)', () => {
|
|
const wrapper = mount(AccountStatusIndicator, {
|
|
props: {
|
|
account: makeAccount({
|
|
id: 2,
|
|
name: 'ag-2',
|
|
extra: {
|
|
model_rate_limits: {
|
|
'claude-sonnet-4-5': {
|
|
rate_limited_at: '2026-03-15T00:00:00Z',
|
|
rate_limit_reset_at: '2099-03-15T00:00:00Z'
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
global: {
|
|
stubs: {
|
|
Icon: true
|
|
}
|
|
}
|
|
})
|
|
|
|
expect(wrapper.text()).toContain('CSon45')
|
|
expect(wrapper.text()).not.toContain('⚡')
|
|
})
|
|
|
|
it('AICredits key 生效 → 显示积分已用尽 (credits_exhausted)', () => {
|
|
const wrapper = mount(AccountStatusIndicator, {
|
|
props: {
|
|
account: makeAccount({
|
|
id: 3,
|
|
name: 'ag-3',
|
|
extra: {
|
|
allow_overages: true,
|
|
model_rate_limits: {
|
|
'AICredits': {
|
|
rate_limited_at: '2026-03-15T00:00:00Z',
|
|
rate_limit_reset_at: '2099-03-15T00:00:00Z'
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
global: {
|
|
stubs: {
|
|
Icon: true
|
|
}
|
|
}
|
|
})
|
|
|
|
expect(wrapper.text()).toContain('admin.accounts.status.creditsExhausted')
|
|
})
|
|
|
|
it('模型限流 + overages 启用 + AICredits key 生效 → 普通限流样式(积分耗尽,无 ⚡)', () => {
|
|
const wrapper = mount(AccountStatusIndicator, {
|
|
props: {
|
|
account: makeAccount({
|
|
id: 4,
|
|
name: 'ag-4',
|
|
extra: {
|
|
allow_overages: true,
|
|
model_rate_limits: {
|
|
'claude-sonnet-4-5': {
|
|
rate_limited_at: '2026-03-15T00:00:00Z',
|
|
rate_limit_reset_at: '2099-03-15T00:00:00Z'
|
|
},
|
|
'AICredits': {
|
|
rate_limited_at: '2026-03-15T00:00:00Z',
|
|
rate_limit_reset_at: '2099-03-15T00:00:00Z'
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
global: {
|
|
stubs: {
|
|
Icon: true
|
|
}
|
|
}
|
|
})
|
|
|
|
// 模型限流 + 积分耗尽 → 不应显示 ⚡
|
|
expect(wrapper.text()).toContain('CSon45')
|
|
expect(wrapper.text()).not.toContain('⚡')
|
|
// AICredits 积分耗尽状态应显示
|
|
expect(wrapper.text()).toContain('admin.accounts.status.creditsExhausted')
|
|
})
|
|
})
|