151 lines
5.0 KiB
TypeScript
151 lines
5.0 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
BANNER_HOTSPOT_DEFAULT_HOVER_SCALE,
|
|
createBannerHotspot,
|
|
hasBannerImage,
|
|
mergeHomeConfig,
|
|
normalizeHomeBanner,
|
|
} from './homeConfig'
|
|
|
|
describe('normalizeHomeBanner', () => {
|
|
it('把旧的扁平 image_url 结构升级为 PC / 移动两端共用同一张图', () => {
|
|
const banner = normalizeHomeBanner({
|
|
title: '旧结构',
|
|
eyebrow: '首页',
|
|
tone: 'green',
|
|
image_url: ' https://cdn.example/legacy.png ',
|
|
})
|
|
|
|
expect(banner.pc.image_url).toBe('https://cdn.example/legacy.png')
|
|
expect(banner.mobile.image_url).toBe('https://cdn.example/legacy.png')
|
|
expect(banner.tone).toBe('green')
|
|
expect(banner.enabled).toBe(true)
|
|
expect(banner.pc.hotspots).toEqual([])
|
|
})
|
|
|
|
it('两端分别配图时互不覆盖', () => {
|
|
const banner = normalizeHomeBanner({
|
|
title: '两端分图',
|
|
pc: { image_url: 'https://cdn.example/pc.png' },
|
|
mobile: { image_url: 'https://cdn.example/mobile.png' },
|
|
})
|
|
|
|
expect(banner.pc.image_url).toBe('https://cdn.example/pc.png')
|
|
expect(banner.mobile.image_url).toBe('https://cdn.example/mobile.png')
|
|
})
|
|
|
|
it('只配移动图时 PC 端不会误用移动图', () => {
|
|
const banner = normalizeHomeBanner({
|
|
title: '仅移动图',
|
|
mobile: { image_url: 'https://cdn.example/mobile.png' },
|
|
})
|
|
|
|
expect(banner.pc.image_url).toBe('')
|
|
expect(banner.mobile.image_url).toBe('https://cdn.example/mobile.png')
|
|
expect(hasBannerImage(banner.pc)).toBe(false)
|
|
})
|
|
|
|
it('收敛热区坐标并丢弃无效热区', () => {
|
|
const banner = normalizeHomeBanner({
|
|
title: '热区',
|
|
pc: {
|
|
image_url: '/pc.png',
|
|
hotspots: [
|
|
{
|
|
id: ' h1 ',
|
|
x: 90,
|
|
y: 95,
|
|
width: 20,
|
|
height: 20,
|
|
action: { type: 'route', target: '/x' },
|
|
},
|
|
{ id: 'zero', y: 10, width: 0, height: 10, action: { type: 'route', target: '/x' } },
|
|
],
|
|
},
|
|
})
|
|
|
|
expect(banner.pc.hotspots).toHaveLength(1)
|
|
expect(banner.pc.hotspots[0]).toMatchObject({ id: 'h1', x: 80, y: 80 })
|
|
})
|
|
|
|
it('缺失目标的跳转退化为不跳转,避免死热区', () => {
|
|
const banner = normalizeHomeBanner({
|
|
title: '死区',
|
|
pc: { image_url: '/pc.png', action: { type: 'route', target: ' ' } },
|
|
mobile: { image_url: '/m.png', action: { type: 'link', target: 'https://a.example' } },
|
|
})
|
|
|
|
expect(banner.pc.action).toEqual({ type: 'none', target: '', open_new_tab: false })
|
|
expect(banner.mobile.action).toEqual({
|
|
type: 'link',
|
|
target: 'https://a.example',
|
|
open_new_tab: false,
|
|
})
|
|
})
|
|
|
|
it('热区按钮图去空格,悬浮倍数默认与收敛', () => {
|
|
const banner = normalizeHomeBanner({
|
|
title: '按钮图',
|
|
pc: {
|
|
image_url: '/pc.png',
|
|
hotspots: [
|
|
{ id: 'a', width: 20, height: 20, image_url: ' https://cdn.example/btn.png ' },
|
|
{ id: 'b', width: 20, height: 20, hover_scale: 9 },
|
|
{ id: 'c', width: 20, height: 20, hover_scale: 0.5 },
|
|
],
|
|
},
|
|
})
|
|
|
|
expect(banner.pc.hotspots[0]?.image_url).toBe('https://cdn.example/btn.png')
|
|
expect(banner.pc.hotspots[0]?.hover_scale).toBe(BANNER_HOTSPOT_DEFAULT_HOVER_SCALE)
|
|
expect(banner.pc.hotspots[1]?.hover_scale).toBe(1.5)
|
|
expect(banner.pc.hotspots[2]?.hover_scale).toBe(1)
|
|
})
|
|
|
|
it('保留停用标记', () => {
|
|
expect(normalizeHomeBanner({ title: '停用', enabled: false }).enabled).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('mergeHomeConfig', () => {
|
|
it('过滤掉既无文案也无图片的空轮播', () => {
|
|
const config = mergeHomeConfig({
|
|
banners: [
|
|
{ title: '有效' },
|
|
{ title: ' ', pc: { image_url: 'https://cdn.example/pc.png' } },
|
|
{ title: '' },
|
|
],
|
|
})
|
|
|
|
// 只有图片没有文案的轮播要保留,全空的条目被丢弃
|
|
expect(config.banners.map(item => item.pc.image_url)).toEqual([
|
|
'',
|
|
'https://cdn.example/pc.png',
|
|
])
|
|
})
|
|
|
|
it('全部无效时回落到默认轮播', () => {
|
|
const config = mergeHomeConfig({ banners: [{ title: '' }] })
|
|
expect(config.banners.length).toBeGreaterThan(0)
|
|
expect(config.banners[0]?.pc.image_url).toBe('')
|
|
})
|
|
|
|
it('首页业务入口总开关缺省关闭,显式开启时透传', () => {
|
|
expect(mergeHomeConfig({}).home_entries_enabled).toBe(false)
|
|
expect(mergeHomeConfig({ home_entries_enabled: true }).home_entries_enabled).toBe(true)
|
|
expect(mergeHomeConfig({ home_entries_enabled: false }).home_entries_enabled).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('createBannerHotspot', () => {
|
|
it('生成带默认行为的热区,便于后台直接框选', () => {
|
|
const hotspot = createBannerHotspot({ x: 10, y: 12 })
|
|
|
|
expect(hotspot.id).toBeTruthy()
|
|
expect(hotspot.action).toEqual({ type: 'none', target: '', open_new_tab: false })
|
|
expect(hotspot.image_url).toBe('')
|
|
expect(hotspot.hover_scale).toBe(BANNER_HOTSPOT_DEFAULT_HOVER_SCALE)
|
|
expect(hotspot).toMatchObject({ x: 10, y: 12, width: 24, height: 24 })
|
|
})
|
|
})
|