Files
Genarrative/src/routing/RouteImageReadyGate.test.ts
T
kdletters 542fb09365 接入微信 Native 充值与订单过期处理
调整网页端充值渠道,微信内浏览器在开放平台接入前走 Native 支付。

拆分 Native 支付二维码弹窗,展示金额和充值内容并取消无效 code_url 跳转。

修复微信 Native 下单 time_expire 秒级 RFC3339 格式,避免小数秒参数错误。

新增充值订单 5 分钟过期调度,过期前查询微信真实订单状态。

补充微信授权绑定、路由加载恢复和后台表时间显示等配套逻辑。

更新 SpacetimeDB schema、绑定和相关文档测试。
2026-07-08 21:35:02 +08:00

164 lines
4.7 KiB
TypeScript

// @vitest-environment jsdom
import { act, render, screen } from '@testing-library/react';
import { createElement } from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { RouteImageReadyGate } from './RouteImageReadyGate';
import {
collectRouteImageUrls,
extractCssImageUrls,
normalizePreloadImageUrl,
} from './routeImageReadyGateUtils';
import { RouteLoadingScreen } from './RouteLoadingScreen';
afterEach(() => {
vi.useRealTimers();
window.localStorage.clear();
window.sessionStorage.clear();
});
describe('RouteImageReadyGate image url helpers', () => {
it('extracts urls from layered CSS image values', () => {
expect(
extractCssImageUrls(
'linear-gradient(#000,#111), url("/hero.png"), url("icons/card.webp")',
),
).toEqual(['/hero.png', 'icons/card.webp']);
});
it('normalizes preloadable urls against the current document', () => {
expect(normalizePreloadImageUrl('/cover.png')).toBe(
new URL('/cover.png', document.baseURI).href,
);
expect(normalizePreloadImageUrl('data:image/png;base64,abc')).toBe(
'data:image/png;base64,abc',
);
expect(normalizePreloadImageUrl('')).toBeNull();
});
it('collects img and CSS background urls from a route root', () => {
const root = document.createElement('section');
root.innerHTML = `
<img src="/images/card.png" />
<div style='background-image: url("/images/bg.webp")'></div>
<div style='border-image-source: url("/ui/frame.png")'></div>
`;
expect(collectRouteImageUrls(root)).toEqual([
new URL('/images/card.png', document.baseURI).href,
new URL('/images/bg.webp', document.baseURI).href,
new URL('/ui/frame.png', document.baseURI).href,
]);
});
it('reveals route content after a short cap when images stay pending', () => {
vi.useFakeTimers();
render(
createElement(
RouteImageReadyGate,
{
eyebrow: '正在载入游戏',
text: '正在加载内容',
},
createElement(
'section',
{
'data-testid': 'route-content',
},
createElement('img', {
src: '/generated-characters/slow-cover.png',
alt: 'slow cover',
}),
),
),
);
const content = screen.getByTestId('route-content');
const visibilityGate = content.parentElement;
expect(visibilityGate?.getAttribute('aria-hidden')).toBe('true');
expect(visibilityGate?.style.visibility).toBe('hidden');
act(() => {
vi.advanceTimersByTime(1600);
});
expect(visibilityGate?.getAttribute('aria-hidden')).toBe('false');
expect(visibilityGate?.style.visibility).toBe('visible');
});
it('does not show the full screen route loader again after the same route was revealed', () => {
vi.useFakeTimers();
const firstRender = render(
createElement(
RouteImageReadyGate,
{
eyebrow: 'Loading',
text: 'Please wait',
},
createElement(
'section',
{
'data-testid': 'route-content',
},
createElement('img', {
src: '/generated-characters/slow-cover.png',
alt: 'slow cover',
}),
),
),
);
expect(screen.getByText('Please wait')).toBeTruthy();
act(() => {
vi.advanceTimersByTime(1600);
});
expect(screen.queryByText('Please wait')).toBeNull();
firstRender.unmount();
render(
createElement(
RouteImageReadyGate,
{
eyebrow: 'Loading',
text: 'Please wait',
},
createElement('section', { 'data-testid': 'route-content' }, 'Ready'),
),
);
const content = screen.getByTestId('route-content');
const visibilityGate = content.parentElement;
expect(visibilityGate?.getAttribute('aria-hidden')).toBe('false');
expect(visibilityGate?.style.visibility).toBe('visible');
expect(screen.queryByText('Please wait')).toBeNull();
});
it('uses the saved platform theme tokens for the route loading screen', () => {
window.localStorage.setItem(
'tavernrealms.settings.v1',
JSON.stringify({
version: 1,
musicVolume: 0.42,
platformTheme: 'dark',
}),
);
const { container } = render(
createElement(RouteLoadingScreen, {
eyebrow: '正在载入游戏',
text: '正在加载内容',
}),
);
const shell = container.firstElementChild;
expect(shell?.classList.contains('platform-theme')).toBe(true);
expect(shell?.classList.contains('platform-theme--dark')).toBe(true);
expect(shell?.className).toContain('bg-[image:var(--platform-body-fill)]');
});
});