refactor: 拆分主页与公共组件,扫码登录改走 WinHTTP
- 抽出 lib/core 的日期/JSON 工具,收敛各页重复解析 - 主页与音乐风险页拆成组件,风险功能共用一套运行框架 - 修复设置页作为主页页签保存时弹掉根路由导致的黑屏 - 登录对齐 Astral aimedb 协议:84 位二维码校验、签名与请求头修正, 补 GlobalSign 中间证书;Windows 改用 WinHTTP 绕过服务端对 BoringSSL 的 TLS 指纹拦截(证书校验保持开启) - 补开发预览数据与测试
This commit is contained in:
1 parent
0cb5320290
commit
e9357f5969
55 files changed
+4387
-3392
No files matched your search
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/testing.dart';
|
||||
import 'package:ichino/config/title_server_config.dart';
|
||||
import 'package:ichino/services/title_api_service.dart';
|
||||
|
||||
const _config = TitleServerConfig(
|
||||
titleServerUrl: 'http://127.0.0.1:9',
|
||||
aesKey: '0123456789abcdef',
|
||||
aesIv: 'fedcba9876543210',
|
||||
clientId: 'A63E01C2805',
|
||||
);
|
||||
|
||||
void main() {
|
||||
test('describeApiError 只取协议层异常的 message', () {
|
||||
expect(
|
||||
describeApiError(const TitleApiException('GetUserDataApi returned 500')),
|
||||
'GetUserDataApi returned 500',
|
||||
);
|
||||
expect(describeApiError(const FormatException('bad qr')), 'FormatException: bad qr');
|
||||
expect(describeApiError('oops'), 'oops');
|
||||
});
|
||||
|
||||
test('响应头里的 JSESSIONID 会写回实例并通知调用方', () async {
|
||||
final captured = <String>[];
|
||||
final sentCookies = <String?>[];
|
||||
final service = TitleApiService(
|
||||
_config,
|
||||
cookies: 'JSESSIONID=OLD',
|
||||
onCookiesChanged: captured.add,
|
||||
);
|
||||
|
||||
var requests = 0;
|
||||
final client = MockClient((request) async {
|
||||
sentCookies.add(request.headers['Cookie']);
|
||||
requests++;
|
||||
if (requests == 1) {
|
||||
return http.Response(
|
||||
'',
|
||||
500,
|
||||
headers: {'Set-Cookie': 'JSESSIONID=NEW; Path=/; HttpOnly'},
|
||||
);
|
||||
}
|
||||
return http.Response('', 500);
|
||||
});
|
||||
|
||||
await http.runWithClient(() async {
|
||||
// Cookie 捕获发生在状态码检查之前:即使这次请求失败,
|
||||
// 服务器轮换的 Cookie 也不能丢。
|
||||
await expectLater(
|
||||
service.getUserData(1),
|
||||
throwsA(isA<TitleApiException>()),
|
||||
);
|
||||
await expectLater(
|
||||
service.getUserData(1),
|
||||
throwsA(isA<TitleApiException>()),
|
||||
);
|
||||
}, () => client);
|
||||
|
||||
expect(captured, ['JSESSIONID=NEW']);
|
||||
expect(service.cookies, 'JSESSIONID=NEW');
|
||||
expect(sentCookies, ['JSESSIONID=OLD', 'JSESSIONID=NEW']);
|
||||
});
|
||||
|
||||
test('响应没有 JSESSIONID 时不回写', () async {
|
||||
final captured = <String>[];
|
||||
final service = TitleApiService(
|
||||
_config,
|
||||
cookies: 'JSESSIONID=OLD',
|
||||
onCookiesChanged: captured.add,
|
||||
);
|
||||
|
||||
await http.runWithClient(() async {
|
||||
await expectLater(
|
||||
service.getUserData(1),
|
||||
throwsA(isA<TitleApiException>()),
|
||||
);
|
||||
}, () => MockClient((_) async => http.Response('', 500)));
|
||||
|
||||
expect(captured, isEmpty);
|
||||
expect(service.cookies, 'JSESSIONID=OLD');
|
||||
});
|
||||
|
||||
test('lastRawResponse 是实例状态,不会跨实例串数据', () {
|
||||
final first = TitleApiService(_config);
|
||||
final second = TitleApiService(_config);
|
||||
|
||||
first.lastRawResponse = '{"userData":{}}';
|
||||
|
||||
expect(first.lastRawResponse, '{"userData":{}}');
|
||||
expect(second.lastRawResponse, isNull);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user