diff --git a/src/__tests__/lib/easy-pay/client.test.ts b/src/__tests__/lib/easy-pay/client.test.ts index 33f82ac..cdc0f1f 100644 --- a/src/__tests__/lib/easy-pay/client.test.ts +++ b/src/__tests__/lib/easy-pay/client.test.ts @@ -7,9 +7,9 @@ const { mockGetEnv } = vi.hoisted(() => ({ EASY_PAY_API_BASE: 'https://pay.example.com', EASY_PAY_NOTIFY_URL: 'https://pay.example.com/api/easy-pay/notify', EASY_PAY_RETURN_URL: 'https://pay.example.com/pay/result', - EASY_PAY_CID: undefined, - EASY_PAY_CID_ALIPAY: undefined, - EASY_PAY_CID_WXPAY: undefined, + EASY_PAY_CID: undefined as string | undefined, + EASY_PAY_CID_ALIPAY: undefined as string | undefined, + EASY_PAY_CID_WXPAY: undefined as string | undefined, })), })); vi.mock('@/lib/config', () => ({ @@ -108,10 +108,9 @@ describe('EasyPay client', () => { it('should throw when API returns code !== 1', async () => { global.fetch = vi.fn().mockResolvedValue( - new Response( - JSON.stringify({ code: -1, msg: 'Invalid parameter' }), - { headers: { 'content-type': 'application/json' } }, - ), + new Response(JSON.stringify({ code: -1, msg: 'Invalid parameter' }), { + headers: { 'content-type': 'application/json' }, + }), ) as typeof fetch; await expect( @@ -296,15 +295,12 @@ describe('EasyPay client', () => { it('should throw when API returns code !== 1', async () => { global.fetch = vi.fn().mockResolvedValue( - new Response( - JSON.stringify({ code: -1, msg: 'Order not found' }), - { headers: { 'content-type': 'application/json' } }, - ), + new Response(JSON.stringify({ code: -1, msg: 'Order not found' }), { + headers: { 'content-type': 'application/json' }, + }), ) as typeof fetch; - await expect(queryOrder('nonexistent-order')).rejects.toThrow( - 'EasyPay query order failed: Order not found', - ); + await expect(queryOrder('nonexistent-order')).rejects.toThrow('EasyPay query order failed: Order not found'); }); it('should throw with "unknown error" when msg is absent', async () => { @@ -314,9 +310,7 @@ describe('EasyPay client', () => { }), ) as typeof fetch; - await expect(queryOrder('order-err')).rejects.toThrow( - 'EasyPay query order failed: unknown error', - ); + await expect(queryOrder('order-err')).rejects.toThrow('EasyPay query order failed: unknown error'); }); it('should parse all response fields correctly', async () => { diff --git a/src/__tests__/lib/order/limits.test.ts b/src/__tests__/lib/order/limits.test.ts index 7bcea84..0ba1af1 100644 --- a/src/__tests__/lib/order/limits.test.ts +++ b/src/__tests__/lib/order/limits.test.ts @@ -1,4 +1,5 @@ import { vi, describe, it, expect, beforeEach } from 'vitest'; +import type { MethodDefaultLimits } from '@/lib/payment/types'; vi.mock('@/lib/db', () => ({ prisma: { @@ -28,7 +29,7 @@ beforeEach(() => { vi.clearAllMocks(); // 默认:getEnv 返回无渠道限额字段,provider 无默认值 mockedGetEnv.mockReturnValue({} as ReturnType); - mockedGetDefaultLimit.mockReturnValue(undefined as any); + mockedGetDefaultLimit.mockReturnValue(undefined); }); describe('getMethodDailyLimit', () => { @@ -39,35 +40,35 @@ describe('getMethodDailyLimit', () => { it('从 getEnv 读取渠道每日限额', () => { mockedGetEnv.mockReturnValue({ MAX_DAILY_AMOUNT_ALIPAY: 5000, - } as any); + } as unknown as ReturnType); expect(getMethodDailyLimit('alipay')).toBe(5000); }); it('环境变量 0 表示不限制', () => { mockedGetEnv.mockReturnValue({ MAX_DAILY_AMOUNT_WXPAY: 0, - } as any); + } as unknown as ReturnType); expect(getMethodDailyLimit('wxpay')).toBe(0); }); it('getEnv 未设置时回退到 provider 默认值', () => { - mockedGetEnv.mockReturnValue({} as any); - mockedGetDefaultLimit.mockReturnValue({ dailyMax: 3000 } as any); + mockedGetEnv.mockReturnValue({} as ReturnType); + mockedGetDefaultLimit.mockReturnValue({ dailyMax: 3000 } as MethodDefaultLimits); expect(getMethodDailyLimit('stripe')).toBe(3000); }); it('getEnv 设置时覆盖 provider 默认值', () => { mockedGetEnv.mockReturnValue({ MAX_DAILY_AMOUNT_STRIPE: 8000, - } as any); - mockedGetDefaultLimit.mockReturnValue({ dailyMax: 3000 } as any); + } as unknown as ReturnType); + mockedGetDefaultLimit.mockReturnValue({ dailyMax: 3000 } as MethodDefaultLimits); expect(getMethodDailyLimit('stripe')).toBe(8000); }); it('paymentType 大小写不敏感(key 构造用 toUpperCase)', () => { mockedGetEnv.mockReturnValue({ MAX_DAILY_AMOUNT_ALIPAY: 2000, - } as any); + } as unknown as ReturnType); expect(getMethodDailyLimit('alipay')).toBe(2000); }); @@ -76,8 +77,8 @@ describe('getMethodDailyLimit', () => { }); it('getEnv 无值且 provider 默认值也无 dailyMax 时回退 process.env', () => { - mockedGetEnv.mockReturnValue({} as any); - mockedGetDefaultLimit.mockReturnValue({} as any); // no dailyMax + mockedGetEnv.mockReturnValue({} as ReturnType); + mockedGetDefaultLimit.mockReturnValue({} as MethodDefaultLimits); // no dailyMax process.env['MAX_DAILY_AMOUNT_ALIPAY'] = '7777'; try { expect(getMethodDailyLimit('alipay')).toBe(7777); @@ -111,13 +112,13 @@ describe('getMethodSingleLimit', () => { }); it('process.env 未设置时回退到 provider 默认值', () => { - mockedGetDefaultLimit.mockReturnValue({ singleMax: 200 } as any); + mockedGetDefaultLimit.mockReturnValue({ singleMax: 200 } as MethodDefaultLimits); expect(getMethodSingleLimit('alipay')).toBe(200); }); it('process.env 设置时覆盖 provider 默认值', () => { process.env['MAX_SINGLE_AMOUNT_ALIPAY'] = '999'; - mockedGetDefaultLimit.mockReturnValue({ singleMax: 200 } as any); + mockedGetDefaultLimit.mockReturnValue({ singleMax: 200 } as MethodDefaultLimits); try { expect(getMethodSingleLimit('alipay')).toBe(999); } finally { @@ -127,7 +128,7 @@ describe('getMethodSingleLimit', () => { it('无效 process.env 值回退到 provider 默认值', () => { process.env['MAX_SINGLE_AMOUNT_ALIPAY'] = 'abc'; - mockedGetDefaultLimit.mockReturnValue({ singleMax: 150 } as any); + mockedGetDefaultLimit.mockReturnValue({ singleMax: 150 } as MethodDefaultLimits); try { expect(getMethodSingleLimit('alipay')).toBe(150); } finally { diff --git a/src/__tests__/lib/sub2api/client-listSubscriptions.test.ts b/src/__tests__/lib/sub2api/client-listSubscriptions.test.ts index f0dbfa6..970f44e 100644 --- a/src/__tests__/lib/sub2api/client-listSubscriptions.test.ts +++ b/src/__tests__/lib/sub2api/client-listSubscriptions.test.ts @@ -17,7 +17,7 @@ describe('listSubscriptions', () => { it('should call correct URL with no query params when no params provided', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, - json: () => Promise.resolve({ data: [], total: 0, page: 1, page_size: 50 }), + json: () => Promise.resolve({ data: { items: [], total: 0, page: 1, page_size: 50 } }), }) as typeof fetch; await listSubscriptions(); @@ -30,7 +30,7 @@ describe('listSubscriptions', () => { it('should build correct query params when all params provided', async () => { global.fetch = vi.fn().mockResolvedValue({ ok: true, - json: () => Promise.resolve({ data: [], total: 0, page: 2, page_size: 10 }), + json: () => Promise.resolve({ data: { items: [], total: 0, page: 2, page_size: 10 } }), }) as typeof fetch; await listSubscriptions({ @@ -51,13 +51,11 @@ describe('listSubscriptions', () => { }); it('should parse normal response correctly', async () => { - const mockSubs = [ - { id: 1, user_id: 42, group_id: 5, status: 'active', expires_at: '2026-12-31' }, - ]; + const mockSubs = [{ id: 1, user_id: 42, group_id: 5, status: 'active', expires_at: '2026-12-31' }]; global.fetch = vi.fn().mockResolvedValue({ ok: true, - json: () => Promise.resolve({ data: mockSubs, total: 1, page: 1, page_size: 50 }), + json: () => Promise.resolve({ data: { items: mockSubs, total: 1, page: 1, page_size: 50 } }), }) as typeof fetch; const result = await listSubscriptions({ user_id: 42 }); diff --git a/src/app/admin/dashboard/page.tsx b/src/app/admin/dashboard/page.tsx index aec54b2..ed68a35 100644 --- a/src/app/admin/dashboard/page.tsx +++ b/src/app/admin/dashboard/page.tsx @@ -7,7 +7,7 @@ import DashboardStats from '@/components/admin/DashboardStats'; import DailyChart from '@/components/admin/DailyChart'; import Leaderboard from '@/components/admin/Leaderboard'; import PaymentMethodChart from '@/components/admin/PaymentMethodChart'; -import { resolveLocale, type Locale } from '@/lib/locale'; +import { resolveLocale } from '@/lib/locale'; interface DashboardData { summary: { diff --git a/src/app/admin/orders/page.tsx b/src/app/admin/orders/page.tsx index b67c2b1..93a4c8d 100644 --- a/src/app/admin/orders/page.tsx +++ b/src/app/admin/orders/page.tsx @@ -6,7 +6,7 @@ import OrderTable from '@/components/admin/OrderTable'; import OrderDetail from '@/components/admin/OrderDetail'; import PaginationBar from '@/components/PaginationBar'; import PayPageLayout from '@/components/PayPageLayout'; -import { resolveLocale, type Locale } from '@/lib/locale'; +import { resolveLocale } from '@/lib/locale'; interface AdminOrder { id: string; diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index aec54b2..ed68a35 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -7,7 +7,7 @@ import DashboardStats from '@/components/admin/DashboardStats'; import DailyChart from '@/components/admin/DailyChart'; import Leaderboard from '@/components/admin/Leaderboard'; import PaymentMethodChart from '@/components/admin/PaymentMethodChart'; -import { resolveLocale, type Locale } from '@/lib/locale'; +import { resolveLocale } from '@/lib/locale'; interface DashboardData { summary: {