为什么:客户端此前完全没有账号概念(mine 页的"登录"只是本地 demo 开关), 而受限动作(收藏/评论)要对到具体账号。本批把账号链路接上,为后续互动、进度同步、下载打底。 - AuthApi + AuthController + AuthSessionStore:注册/登录/登出/刷新,令牌与设备号存 shared_preferences (用 SharedPreferencesAsync,与 engagement 仓库同一套 API) - ApiClient:统一带 Authorization 与 X-Device-Id;401 自动刷新一次并重试,刷新失败清登录态走 onUnauthorized - 登录/注册页(pages/auth,沿用 binding/logic/view 与现有视觉):邮箱格式、密码 8-64 位含字母数字本地先校验, 错误提示走 l10n;登录/注册一键切换 - 匿名/登录分叉:首页、发现、详情保持匿名可看;收藏/点赞等受限动作走 ensureSignedIn() 弹底部提示引导登录 - mine 页展示真实账号(昵称 + uid),拿不到才回落到演示文案 - 测试:新增 auth 控制器(注册落盘/401 刷新重试/刷新失败清会话/登出)与登录页(校验/切换)用例; widget_test 改为预置本地会话(账号不再是本地开关);修掉 playback 用例对 host 大小写的环境依赖断言 门禁:flutter analyze 0 问题;flutter test 148 全过。
38 lines
1.2 KiB
Dart
38 lines
1.2 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:nontonki/core/config/app_config.dart';
|
||
import 'package:nontonki/core/data/models/drama.dart';
|
||
import 'package:nontonki/core/data/services/video_player_port.dart';
|
||
|
||
Episode _episode(String videoUrl) => Episode(
|
||
id: '1',
|
||
number: 1,
|
||
title: '第 1 集',
|
||
isFree: true,
|
||
videoUrl: videoUrl,
|
||
);
|
||
|
||
void main() {
|
||
test('相对播放地址补上服务地址', () {
|
||
final uri = VideoPlayerPort.resolveUri(
|
||
_episode('/files/episode/202610/clip.mp4'),
|
||
);
|
||
|
||
expect(uri.isAbsolute, isTrue);
|
||
// Uri.parse().toString() 会把 host 规范成小写,而 devHostBaseUrl 里的
|
||
// Bonjour 名字带大写(jiangdeMacBook-Air.local)—— 比较时统一小写,
|
||
// 否则会依赖运行平台(flutter test 里 defaultTargetPlatform 默认是 android)
|
||
expect(
|
||
uri.toString().toLowerCase(),
|
||
'${AppConfig.apiBaseUrl}/files/episode/202610/clip.mp4'.toLowerCase(),
|
||
);
|
||
});
|
||
|
||
test('已经是绝对地址的不再拼接', () {
|
||
final uri = VideoPlayerPort.resolveUri(
|
||
_episode('https://cdn.example.test/clip.mp4'),
|
||
);
|
||
|
||
expect(uri.toString(), 'https://cdn.example.test/clip.mp4');
|
||
});
|
||
}
|