Files
pangolin/client/test/unit/notices_api_test.dart
T

75 lines
2.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:pangolin_vpn/l10n/app_text.dart';
import 'package:pangolin_vpn/services/api_client.dart';
import 'package:pangolin_vpn/services/notices_api.dart';
ApiClient _c(MockClient m) => ApiClient(baseUrl: 'http://x', getToken: () => 't', refresh: () async => false, client: m);
const _utf8Json = {'content-type': 'application/json; charset=utf-8'};
void main() {
test('fetch 解析公告列表 + unread_count(双语字段)', () async {
final api = NoticesApi(_c(MockClient((req) async {
expect(req.url.path, '/v1/notices');
return http.Response(
'{"notices":['
'{"id":1,"type":"maintenance","title_zh":"维护通知","title_en":"Maintenance",'
'"body_zh":"今晚维护","body_en":"Tonight maintenance","link":"https://x/1",'
'"published_at":"2026-07-10T08:00:00Z","unread":true},'
'{"id":2,"type":"promo","title_zh":"活动","title_en":"Promo",'
'"published_at":"2026-07-09T08:00:00Z","unread":false}'
'],"unread_count":1}',
200,
headers: _utf8Json);
})));
final data = await api.fetch();
expect(data.items.length, 2);
expect(data.unreadCount, 1);
final first = data.items[0];
expect(first.id, 1);
expect(first.type, 'maintenance');
expect(first.titleZh, '维护通知');
expect(first.titleEn, 'Maintenance');
expect(first.bodyZh, '今晚维护');
expect(first.bodyEn, 'Tonight maintenance');
expect(first.link, 'https://x/1');
expect(first.publishedAt, DateTime.parse('2026-07-10T08:00:00Z'));
expect(first.unread, true);
expect(first.title(AppLang.zh), '维护通知');
expect(first.title(AppLang.en), 'Maintenance');
final second = data.items[1];
expect(second.id, 2);
expect(second.bodyZh, '');
expect(second.bodyEn, '');
expect(second.link, '');
expect(second.unread, false);
// 非 zh 语言取 en 兜底
expect(second.title(AppLang.ja), second.titleEn);
});
test('fetch 缺字段安全默认(不 crash)', () async {
final api = NoticesApi(_c(MockClient((req) async {
return http.Response('{}', 200);
})));
final data = await api.fetch();
expect(data.items, isEmpty);
expect(data.unreadCount, 0);
});
test('markRead 打 POST /v1/notices/read', () async {
var called = false;
final api = NoticesApi(_c(MockClient((req) async {
called = true;
expect(req.method, 'POST');
expect(req.url.path, '/v1/notices/read');
return http.Response('{"ok":true}', 200);
})));
await api.markRead();
expect(called, true);
});
}