mirror of
https://github.com/Smile-QWQ/SubTracker.git
synced 2026-06-04 08:32:36 +08:00
## 中文 - 为 web 单测补上统一的测试语言初始化,避免每个用例重复手动设置 locale。 - 修复 lite Worker 中匿名读取 /api/v1/app/locale 会被鉴权拦截的问题,使新会话也能读取已持久化的语言设置。 - 同步补齐相关 API / Web 测试断言,并将换汇缺失汇率时的错误提示接入 i18n。 ## English - Add shared locale initialization for web tests so each case no longer has to set the locale manually. - Fix the lite Worker auth guard so anonymous GET /api/v1/app/locale can read the persisted locale in fresh sessions. - Update the related API and web assertions and localize the missing-rate currency conversion error.
104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
calculateNextRenewalDateTs,
|
|
canRecalculateNextRenewal,
|
|
validateSubscriptionForm
|
|
} from '../../../src/utils/subscription-form'
|
|
|
|
describe('subscription form helpers', () => {
|
|
it('normalizes websiteUrl without protocol before submit', () => {
|
|
const result = validateSubscriptionForm({
|
|
name: 'GitHub Pro',
|
|
description: '',
|
|
amount: 99,
|
|
currency: 'USD',
|
|
billingIntervalCount: 1,
|
|
billingIntervalUnit: 'year',
|
|
startDateTs: Date.parse('2024-01-01T00:00:00.000Z'),
|
|
nextRenewalDateTs: Date.parse('2027-01-01T00:00:00.000Z'),
|
|
websiteUrl: 'example.com',
|
|
notes: ''
|
|
})
|
|
|
|
expect(result.errors.websiteUrl).toBeUndefined()
|
|
expect(result.normalizedWebsiteUrl).toBe('https://example.com')
|
|
})
|
|
|
|
it('blocks invalid websiteUrl with field error', () => {
|
|
const result = validateSubscriptionForm({
|
|
name: 'GitHub Pro',
|
|
description: '',
|
|
amount: 99,
|
|
currency: 'USD',
|
|
billingIntervalCount: 1,
|
|
billingIntervalUnit: 'year',
|
|
startDateTs: Date.parse('2024-01-01T00:00:00.000Z'),
|
|
nextRenewalDateTs: Date.parse('2027-01-01T00:00:00.000Z'),
|
|
websiteUrl: 'not a url',
|
|
notes: ''
|
|
})
|
|
|
|
expect(result.errors.websiteUrl).toBe('请输入合法网址,例如 https://example.com')
|
|
expect(result.normalizedWebsiteUrl).toBeNull()
|
|
})
|
|
|
|
it('recalculates next renewal date only when explicitly requested', () => {
|
|
const nextRenewalTs = calculateNextRenewalDateTs(Date.parse('2024-01-01T00:00:00.000Z'), 1, 'year')
|
|
|
|
expect(new Date(nextRenewalTs).toISOString()).toBe('2025-01-01T00:00:00.000Z')
|
|
})
|
|
|
|
it('disables manual recalculate button when required fields are missing', () => {
|
|
expect(
|
|
canRecalculateNextRenewal({
|
|
startDateTs: null,
|
|
billingIntervalCount: 1,
|
|
billingIntervalUnit: 'year'
|
|
})
|
|
).toBe(false)
|
|
|
|
expect(
|
|
canRecalculateNextRenewal({
|
|
startDateTs: Date.parse('2024-01-01T00:00:00.000Z'),
|
|
billingIntervalCount: 0,
|
|
billingIntervalUnit: 'year'
|
|
})
|
|
).toBe(false)
|
|
})
|
|
|
|
it('requires next renewal date to be after or equal to start date', () => {
|
|
const result = validateSubscriptionForm({
|
|
name: 'GitHub Pro',
|
|
description: '',
|
|
amount: 99,
|
|
currency: 'USD',
|
|
billingIntervalCount: 1,
|
|
billingIntervalUnit: 'year',
|
|
startDateTs: Date.parse('2027-01-01T00:00:00.000Z'),
|
|
nextRenewalDateTs: Date.parse('2024-01-01T00:00:00.000Z'),
|
|
websiteUrl: '',
|
|
notes: ''
|
|
})
|
|
|
|
expect(result.errors.nextRenewalDateTs).toBe('下次续订日期不能早于开始日期')
|
|
})
|
|
|
|
it('validates description and notes length locally', () => {
|
|
const result = validateSubscriptionForm({
|
|
name: 'GitHub Pro',
|
|
description: 'a'.repeat(501),
|
|
amount: 99,
|
|
currency: 'USD',
|
|
billingIntervalCount: 1,
|
|
billingIntervalUnit: 'year',
|
|
startDateTs: Date.parse('2024-01-01T00:00:00.000Z'),
|
|
nextRenewalDateTs: Date.parse('2027-01-01T00:00:00.000Z'),
|
|
websiteUrl: '',
|
|
notes: 'b'.repeat(1001)
|
|
})
|
|
|
|
expect(result.errors.description).toBe('描述不能超过 500 个字符')
|
|
expect(result.errors.notes).toBe('备注不能超过 1000 个字符')
|
|
})
|
|
})
|