Ctrl K
ComunidadGuías…

frontend/test/feedback.test.ts

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import {describe,expect,it} from 'vitest';
import {requestErrorMessage} from '../src/core';
import {noteHtml,projectBannerHtml,gaugeHtml,progressHtml,configurationSkeletonHtml} from '../src/ui-kit';

describe('中文错误反馈',()=>{
  it.each(['Failed to fetch','NetworkError when attempting to fetch resource.','Load failed'])('网络异常 %s 给出连接检查方法',message=>{
    expect(requestErrorMessage(new TypeError(message))).toBe('无法连接到 Peach 服务,请确认网络连接和托盘服务已启动。');
  });
  it.each([[401,'登录已失效'],[403,'没有执行此操作的权限'],[404,'已不存在'],[429,'过于频繁'],[503,'暂时不可用'],[504,'超时']])('HTTP %s 使用明确原因', (code,reason)=>{
    expect(requestErrorMessage('request failed',code)).toContain(reason);
  });
  it('正文里的 timeout 字样不把 500 读成超时',()=>{
    expect(requestErrorMessage('Traceback: httpx.ReadTimeout raised in handler (timeout=30)',500))
      .toBe('Peach 服务处理失败,请重试;持续失败时查看托盘日志。');
    expect(requestErrorMessage('read timed out')).toContain('超时');
  });
  it('本机接口的 502 说的是 Peach 服务,不提代理',()=>{
    const text=requestErrorMessage('Bad Gateway',502);
    expect(text).toContain('Peach 服务');
    expect(text).not.toContain('代理');
  });
  it('保留服务端明确的中文原因',()=>{
    expect(requestErrorMessage('媒体盘没有挂载,请先连接媒体盘。',409)).toBe('媒体盘没有挂载,请先连接媒体盘。');
  });
});
describe('持久提示控件',()=>{
  it('配置骨架标题和卡片共用真实页面网格与正文底栏',()=>{
    const host=document.createElement('div');host.innerHTML=configurationSkeletonHtml();
    const page=host.querySelector('.ui-configpage')!;
    expect(page.querySelectorAll(':scope > .ui-configgroup')).toHaveLength(5);
    expect(page.querySelectorAll(':scope > .configfieldset')).toHaveLength(12);
    for(const card of page.querySelectorAll('.configfieldset')){
      expect(card.querySelector(':scope > .geist-fieldset-content')).not.toBeNull();
      expect(card.querySelector(':scope > .geist-fieldset-footer')).not.toBeNull();
    }
    expect(host.children).toHaveLength(1);
  });
  it.each([[79,'normal'],[80,'warning'],[94,'warning'],[95,'error']])('容量 %s 使用一致阈值', (value,level)=>{
    const host=document.createElement('div');host.innerHTML=gaugeHtml('空间使用率',value,100,{usage:true});
    expect(host.querySelector('.ui-geist-gauge')?.getAttribute('data-level')).toBe(level);
    expect(gaugeHtml('完成率',value,100)).toContain('data-level="normal"');
  });
  it('失败提示包含一个次要样式的内部操作按钮',()=>{
    const host=document.createElement('div');host.innerHTML=noteHtml('来源离线',{variant:'error',filled:true,actionLabel:'立即重试'});
    const buttons=host.querySelectorAll('[role=alert] button');
    expect(buttons).toHaveLength(1);
    expect(buttons[0]!.classList.contains('primary')).toBe(false);
  });
  it('容量比例和任务计数使用真实上限,未知容量不显示零',()=>{
    const host=document.createElement('div');host.innerHTML=gaugeHtml('使用率',25,50);
    expect(host.querySelector('[role=progressbar]')?.getAttribute('aria-valuenow')).toBe('50');
    expect(gaugeHtml('使用率',0,0)).toContain('未取得');
    host.innerHTML=progressHtml('分析记录',3,10,{stops:[{value:5,label:'分析结束'}],variant:'warning'});
    expect(host.querySelector('[role=progressbar]')?.getAttribute('aria-valuemax')).toBe('10');
    expect(host.querySelector('[aria-label="分析结束"]')).not.toBeNull();
  });
  it('Note 错误不会直接输出英文网络异常',()=>{
    const host=document.createElement('div');host.innerHTML=noteHtml('Failed to fetch',{variant:'error',size:'small',filled:true});
    expect(host.querySelector('[role=alert]')?.textContent).toContain('无法连接到 Peach');
    expect(host.querySelector('.geist-note-small.geist-note-filled')).not.toBeNull();
    expect(host.querySelector('button')).toBeNull();
  });
  it('Project Banner 包含处理入口且没有关闭键',()=>{
    const host=document.createElement('div');host.innerHTML=projectBannerHtml('扫描未完成',{variant:'warning',href:'/data-cleanup',label:'查看并处理'});
    expect(host.querySelector('.ui-project-banner-warning')).not.toBeNull();
    expect(host.querySelector('a')?.getAttribute('href')).toBe('/data-cleanup');
    expect(host.querySelector('button')).toBeNull();
  });
});