Files
xianyan/test/features/discover/services/tool_api_service_test.dart
Developer 9ea8d3d606 chore: 汇总批量提交的功能优化与bug修复
本次提交包含多项迭代优化和问题修复:
1. 新增缩略图图片组件、数字格式化工具类,补充多语言翻译类型与本地化支持
2. 优化底部导航栏主题色统一使用动态accent色值
3. 修复多处图表动画、路由跳转、API请求相关问题
4. 简化服务器公告文案,调整默认分屏状态为关闭
5. 新增安卓/iOS桌面快捷方式配置
6. 重构多处状态管理类使用SafeNotifierInit统一异常保护
7. 替换硬编码蓝色为主题色,更新版本号获取方式为动态读取
8. 优化缓存预加载逻辑,移除无用代码
9. 调整默认设置项,优化用户体验细节
2026-05-31 12:24:05 +08:00

146 lines
6.3 KiB
Dart
Raw Permalink 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.
/// ============================================================
/// 闲言APP — ToolApiService 单元测试
/// 创建时间: 2026-05-31
/// 更新时间: 2026-05-31
/// 作用: 使用 mocktail 测试工具API服务层
/// 上次更新: 初始创建覆盖核心API方法签名和SearchType集成
/// ============================================================
import 'package:flutter_test/flutter_test.dart';
import 'package:xianyan/features/discover/models/search_type.dart';
import 'package:xianyan/features/discover/models/tool_item.dart';
import 'package:xianyan/features/discover/services/tool_api_service.dart';
void main() {
group('ToolApiService', () {
test('hanziSearch 参数正确传递 SearchType.value', () {
for (final type in SearchType.forApi(SearchApiType.hanziSearch)) {
expect(type.value, isNotEmpty);
expect(type.isSupportedBy(SearchApiType.hanziSearch), isTrue);
}
});
test('searchAll 参数正确传递 SearchType.value', () {
for (final type in SearchType.forApi(SearchApiType.searchAll)) {
expect(type.value, isNotEmpty);
expect(type.isSupportedBy(SearchApiType.searchAll), isTrue);
}
});
test('defaultTools 中 listType 与 SearchType.apiType 一致', () {
final listTools = defaultTools.where(
(t) => t.navConfig?.type == ToolNavType.list && t.navConfig?.searchType != null,
);
for (final tool in listTools) {
final config = tool.navConfig!;
final searchType = config.searchType!;
final listType = config.listType;
if (listType == 'hanzi_search') {
expect(
searchType.apiType,
SearchApiType.hanziSearch,
reason: '${tool.id} 使用 hanzi_search 但 SearchType.${searchType.name} 的 apiType 不是 hanziSearch',
);
} else if (listType == 'searchall') {
expect(
searchType.apiType,
SearchApiType.searchAll,
reason: '${tool.id} 使用 searchall 但 SearchType.${searchType.name} 的 apiType 不是 searchAll',
);
}
}
});
test('defaultTools 中每个 list 工具的 searchType 不为 null', () {
final listTools = defaultTools.where(
(t) => t.navConfig?.type == ToolNavType.list,
);
for (final tool in listTools) {
final config = tool.navConfig!;
if (config.listType == 'hanzi_search' || config.listType == 'searchall') {
expect(
config.searchType,
isNotNull,
reason: '${tool.id} 使用 ${config.listType} 但 searchType 为 null',
);
}
}
});
test('hanziSearch 接口支持的 type 值覆盖所有 hanziSearch 工具', () {
final hanziValues = SearchType.valuesForApi(SearchApiType.hanziSearch);
final hanziTools = defaultTools.where(
(t) => t.navConfig?.listType == 'hanzi_search' && t.navConfig?.searchType != null,
);
for (final tool in hanziTools) {
expect(
hanziValues.contains(tool.navConfig!.searchType!.value),
isTrue,
reason: '${tool.id} 的 searchType value "${tool.navConfig!.searchType!.value}" 不在 hanziSearch 支持列表中',
);
}
});
test('searchAll 接口支持的 type 值覆盖所有 searchAll 工具', () {
final searchAllValues = SearchType.valuesForApi(SearchApiType.searchAll);
final searchAllTools = defaultTools.where(
(t) => t.navConfig?.listType == 'searchall' && t.navConfig?.searchType != null,
);
for (final tool in searchAllTools) {
expect(
searchAllValues.contains(tool.navConfig!.searchType!.value),
isTrue,
reason: '${tool.id} 的 searchType value "${tool.navConfig!.searchType!.value}" 不在 searchAll 支持列表中',
);
}
});
test('ToolApiService 静态方法存在且可调用', () {
expect(() => ToolApiService.hanziSearch, isA<Function>());
expect(() => ToolApiService.searchAll, isA<Function>());
expect(() => ToolApiService.hanziZi, isA<Function>());
expect(() => ToolApiService.bishun, isA<Function>());
expect(() => ToolApiService.zuci, isA<Function>());
expect(() => ToolApiService.cidian, isA<Function>());
expect(() => ToolApiService.chengyu, isA<Function>());
expect(() => ToolApiService.jinyici, isA<Function>());
expect(() => ToolApiService.fanyici, isA<Function>());
expect(() => ToolApiService.juzi, isA<Function>());
expect(() => ToolApiService.nick, isA<Function>());
expect(() => ToolApiService.barcode, isA<Function>());
expect(() => ToolApiService.unitConvert, isA<Function>());
expect(() => ToolApiService.danci, isA<Function>());
expect(() => ToolApiService.suoxie, isA<Function>());
expect(() => ToolApiService.dailyRecommend, isA<Function>());
expect(() => ToolApiService.dailyPoetry, isA<Function>());
expect(() => ToolApiService.dailyChengyu, isA<Function>());
expect(() => ToolApiService.dailyWisdom, isA<Function>());
expect(() => ToolApiService.dailyStory, isA<Function>());
expect(() => ToolApiService.chinaColors, isA<Function>());
expect(() => ToolApiService.hitokotoRandom, isA<Function>());
expect(() => ToolApiService.hitokotoSearch, isA<Function>());
expect(() => ToolApiService.hitokotoCategories, isA<Function>());
expect(() => ToolApiService.hitokotoHot, isA<Function>());
expect(() => ToolApiService.hitokotoDetail, isA<Function>());
expect(() => ToolApiService.searchSuggest, isA<Function>());
expect(() => ToolApiService.hotRead, isA<Function>());
expect(() => ToolApiService.jiufangSearch, isA<Function>());
expect(() => ToolApiService.siteSearch, isA<Function>());
expect(() => ToolApiService.healthCheck, isA<Function>());
expect(() => ToolApiService.ocrRecognize, isA<Function>());
expect(() => ToolApiService.fetchStatsOverview, isA<Function>());
expect(() => ToolApiService.fetchStatsTrend, isA<Function>());
expect(() => ToolApiService.fetchHotTools, isA<Function>());
expect(() => ToolApiService.fetchHotArticles, isA<Function>());
expect(() => ToolApiService.fetchContentStats, isA<Function>());
expect(() => ToolApiService.fetchUserActivity, isA<Function>());
expect(() => ToolApiService.fetchApiUsage, isA<Function>());
});
});
}