/** * T16: 名片社媒快捷字段 telegram / twitter / wechat */ import { getMetadataArgsStorage } from 'typeorm'; import { CardInfoEntity } from '../../../src/modules/card/entity/info'; import { CardPortalService } from '../../../src/modules/card/service/portal'; import { CardProfile, CardPortalDetail } from '../../../src/comm/types/omni'; describe('T16 社媒快捷字段 telegram / twitter / wechat', () => { describe('1. 实体元数据列名下划线', () => { it('telegram / twitter / wechat 应为可空 varchar(255),数据库列名下划线', () => { const columns = getMetadataArgsStorage().columns.filter( c => c.target === CardInfoEntity ); const expected: Record = { telegram: 'telegram', twitter: 'twitter', wechat: 'wechat', }; for (const [prop, dbCol] of Object.entries(expected)) { const col = columns.find(c => c.propertyName === prop); expect(col).toBeDefined(); expect(col?.options.name || col?.propertyName).toBe(dbCol); expect(col?.options.length).toBe(255); expect(col?.options.nullable).toBe(true); } }); it('CardProfile 与 CardPortalDetail 契约应包含三字段', () => { const profile: CardProfile = { id: 1, tenantId: 1, userId: 1, name: 'Alex', title: 'BD', company: 'Omni', status: 'published', telegram: '@omni_ai', twitter: 'https://x.com/omni', wechat: 'omni_wx', }; const detail: CardPortalDetail = { id: 1, name: 'Alex', title: 'BD', company: 'Omni', status: 'published', bentoBlocks: [], telegram: '@omni_ai', twitter: 'https://x.com/omni', wechat: 'omni_wx', }; expect(profile.telegram).toBe('@omni_ai'); expect(profile.twitter).toBe('https://x.com/omni'); expect(profile.wechat).toBe('omni_wx'); expect(detail.telegram).toBe('@omni_ai'); expect(detail.twitter).toBe('https://x.com/omni'); expect(detail.wechat).toBe('omni_wx'); }); }); describe('2. 门户公开详情映射', () => { let service: CardPortalService; beforeEach(() => { CardPortalService.clearAllCache(); service = new CardPortalService(); service.cardInfoEntity = { findOne: async () => ({ id: 201, tenantId: 1, slug: 'social-card', name: 'Social User', title: 'BD', company: 'Omni', status: 'published', telegram: '@omni_ai', twitter: 'https://x.com/omni', wechat: 'omni_wx', }), } as unknown as CardPortalService['cardInfoEntity']; service.cardBentoEntity = { find: async () => [], } as unknown as CardPortalService['cardBentoEntity']; }); it('getPortalDetail 应带出 telegram / twitter / wechat', async () => { const detail = await service.getPortalDetail(201); expect(detail.telegram).toBe('@omni_ai'); expect(detail.twitter).toBe('https://x.com/omni'); expect(detail.wechat).toBe('omni_wx'); }); }); describe('3. usePortal 快捷动作新 type', () => { let toastCalls: Array<{ title: string; icon?: string }>; let clipboardText: string; beforeEach(() => { toastCalls = []; clipboardText = ''; (global as { uni?: unknown }).uni = { getStorageSync: () => '', setStorageSync: () => undefined, showToast: (options: { title: string; icon?: string }) => { toastCalls.push(options); }, makePhoneCall: () => undefined, setClipboardData: (options: { data: string; success?: () => void }) => { clipboardText = options.data; options.success?.(); }, getLocale: () => 'zh-CN', getSystemInfoSync: () => ({ language: 'zh-CN' }), }; jest.resetModules(); }); afterEach(() => { delete (global as { uni?: unknown }).uni; }); it('telegram / twitter / wechat 新 type 不报错', () => { const { triggerQuickAction } = require('../../../../mpuniapp/pages/portal/usePortal.uts') as { triggerQuickAction: (type: string, value?: string) => boolean; }; expect(() => triggerQuickAction('telegram', '@omni_ai')).not.toThrow(); expect(() => triggerQuickAction('twitter', 'https://x.com/omni')).not.toThrow(); expect(() => triggerQuickAction('wechat', 'omni_wx')).not.toThrow(); expect(triggerQuickAction('telegram', '@omni_ai')).toBe(true); expect(triggerQuickAction('twitter', 'https://x.com/omni')).toBe(true); expect(triggerQuickAction('wechat', 'omni_wx')).toBe(true); }); it('telegram 不含 http 时补 https://t.me/ 前缀并复制', () => { const { triggerQuickAction } = require('../../../../mpuniapp/pages/portal/usePortal.uts') as { triggerQuickAction: (type: string, value?: string) => boolean; }; const ok = triggerQuickAction('telegram', '@omni_ai'); expect(ok).toBe(true); expect(clipboardText).toBe('https://t.me/omni_ai'); expect(toastCalls[0].title.length).toBeGreaterThan(0); }); it('telegram 已含 http 时原样复制', () => { const { triggerQuickAction } = require('../../../../mpuniapp/pages/portal/usePortal.uts') as { triggerQuickAction: (type: string, value?: string) => boolean; }; triggerQuickAction('telegram', 'https://t.me/omni_ai'); expect(clipboardText).toBe('https://t.me/omni_ai'); }); it('twitter 复制对应链接,wechat 只复制微信号', () => { const { triggerQuickAction } = require('../../../../mpuniapp/pages/portal/usePortal.uts') as { triggerQuickAction: (type: string, value?: string) => boolean; }; triggerQuickAction('twitter', 'https://x.com/omni'); expect(clipboardText).toBe('https://x.com/omni'); triggerQuickAction('wechat', 'omni_wx'); expect(clipboardText).toBe('omni_wx'); }); it('无值时 toast 走 i18n 且不抛错', () => { const { triggerQuickAction } = require('../../../../mpuniapp/pages/portal/usePortal.uts') as { triggerQuickAction: (type: string, value?: string) => boolean; }; expect(triggerQuickAction('telegram', '')).toBe(false); expect(triggerQuickAction('twitter')).toBe(false); expect(triggerQuickAction('wechat', ' ')).toBe(false); expect(toastCalls.length).toBe(3); expect(toastCalls[0].title).toContain('未设置'); }); }); });