Files
Genarrative/scripts/miniprogram-web-view-auth.test.ts
2026-05-26 19:59:14 +08:00

150 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import vm from 'node:vm';
import { beforeEach, describe, expect, test, vi } from 'vitest';
const repoRoot = process.cwd();
const pageScriptPath = join(
repoRoot,
'miniprogram',
'pages',
'web-view',
'index.js',
);
type MiniProgramPage = {
data: Record<string, unknown>;
setData: (patch: Record<string, unknown>) => void;
onLoad: (query?: Record<string, string>) => Promise<void>;
};
function createWxMock() {
return {
getStorageSync: vi.fn(() => ''),
getSystemInfoSync: vi.fn(() => ({ platform: 'ios' })),
login: vi.fn(),
navigateBack: vi.fn(),
removeStorageSync: vi.fn(),
request: vi.fn(),
setStorageSync: vi.fn(),
};
}
function loadWebViewPage(
wxMock: ReturnType<typeof createWxMock>,
configOverrides: Record<string, unknown> = {},
) {
let pageConfig: Record<string, unknown> | null = null;
const source = readFileSync(pageScriptPath, 'utf8');
const sandbox = {
console,
getCurrentPages: () => [],
module: { exports: {} },
Page(config: Record<string, unknown>) {
pageConfig = config;
},
require(requestPath: string) {
if (requestPath === '../../config') {
return {
API_BASE_URL: 'https://www.genarrative.world/',
MINI_PROGRAM_APP_ID: 'wx-test-app',
MINI_PROGRAM_ENV: 'release',
WEB_VIEW_ENTRY_URL: 'https://www.genarrative.world/',
WEB_VIEW_SOURCE_QUERY: {
clientType: 'mini_program',
clientRuntime: 'wechat_mini_program',
},
...configOverrides,
};
}
throw new Error(`Unexpected require: ${requestPath}`);
},
wx: wxMock,
};
vm.runInNewContext(source, sandbox, { filename: pageScriptPath });
if (!pageConfig) {
throw new Error('web-view page did not call Page()');
}
const page = {
...pageConfig,
data: { ...(pageConfig.data as Record<string, unknown>) },
setData(patch: Record<string, unknown>) {
Object.assign(this.data, patch);
},
} as MiniProgramPage;
return page;
}
describe('mini-program web-view auth page', () => {
beforeEach(() => {
vi.clearAllMocks();
});
test('默认进入时直接打开 web-view不触发微信登录请求', async () => {
const wxMock = createWxMock();
const page = loadWebViewPage(wxMock);
await page.onLoad({});
expect(wxMock.login).not.toHaveBeenCalled();
expect(wxMock.request).not.toHaveBeenCalled();
expect(page.data.loading).toBe(false);
expect(page.data.phoneBindingRequired).toBe(false);
expect(page.data.webViewUrl).toBe(
'https://www.genarrative.world/?clientType=mini_program&clientRuntime=wechat_mini_program',
);
});
test('默认匿名进入 web-view 不依赖 API_BASE_URL 配置', async () => {
const wxMock = createWxMock();
const page = loadWebViewPage(wxMock, {
API_BASE_URL: '',
});
await page.onLoad({});
expect(wxMock.login).not.toHaveBeenCalled();
expect(wxMock.request).not.toHaveBeenCalled();
expect(page.data.errorMessage).toBe('');
expect(page.data.webViewUrl).toBe(
'https://www.genarrative.world/?clientType=mini_program&clientRuntime=wechat_mini_program',
);
});
test('H5 请求登录时才启动微信小程序登录并进入手机号授权态', async () => {
const wxMock = createWxMock();
wxMock.login.mockImplementation(({ success }) => {
success({ code: 'wx-login-code' });
});
wxMock.request.mockImplementation(({ success }) => {
success({
statusCode: 200,
data: {
token: 'jwt-pending-wechat',
bindingStatus: 'pending_bind_phone',
},
});
});
const page = loadWebViewPage(wxMock);
await page.onLoad({ authAction: 'login', returnTo: 'previous' });
expect(wxMock.login).toHaveBeenCalledTimes(1);
expect(wxMock.request).toHaveBeenCalledWith(
expect.objectContaining({
url: 'https://www.genarrative.world/api/auth/wechat/miniprogram-login',
method: 'POST',
data: { code: 'wx-login-code' },
}),
);
expect(page.data.webViewUrl).toBe('');
expect(page.data.loading).toBe(false);
expect(page.data.phoneBindingRequired).toBe(true);
});
});