Files
ReelShort/test/core/response_decoders_test.dart
Zhou Weidong 1be8ebf1f9 refactor(api): 统一响应解析并修复下载错误文案空白
各 *Api 类此前各自实现 data 结构判断,download_api 在结构异常时抛出空
message,界面会显示空白提示。抽出 ResponseDecoders 提供对象、可空对象、
对象数组三种语义,七个文件改为复用;下载侧异常文案与其他接口对齐。
2026-10-29 10:44:32 +08:00

88 lines
2.5 KiB
Dart

// Author: fruit.com.cn
import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/core/data/remote/api_client.dart';
import 'package:fruitshorts/core/data/remote/download_api.dart';
import 'package:fruitshorts/core/data/remote/response_decoders.dart';
import '../support/fake_http_adapter.dart';
void main() {
group('ResponseDecoders', () {
test('should_return_same_map_when_data_is_object', () {
const source = {'id': '1'};
expect(ResponseDecoders.asMap(source), same(source));
});
test('should_throw_with_readable_message_when_data_is_not_object', () {
expect(
() => ResponseDecoders.asMap(const []),
throwsA(
isA<ApiException>()
.having((e) => e.code, 'code', ResponseDecoders.malformedCode)
.having(
(e) => e.message,
'message',
ResponseDecoders.malformedMessage,
),
),
);
expect(ResponseDecoders.malformedMessage, isNotEmpty);
});
test('should_return_null_when_try_map_receives_non_object', () {
expect(ResponseDecoders.tryMap(null), isNull);
expect(ResponseDecoders.tryMap('text'), isNull);
expect(ResponseDecoders.tryMap({'a': 1})?['a'], 1);
});
test('should_skip_non_object_items_when_decoding_object_list', () {
final decoded = ResponseDecoders.asMapList([
{'id': '1'},
'bad',
{'id': '2'},
]);
expect(decoded.map((item) => item['id']), ['1', '2']);
});
test('should_return_empty_list_when_data_is_not_list', () {
expect(ResponseDecoders.asMapList(const {}), isEmpty);
expect(ResponseDecoders.asMapList(null), isEmpty);
});
test('should_throw_when_required_list_receives_non_list', () {
expect(
() => ResponseDecoders.requiredMapList(const {}),
throwsA(isA<ApiException>()),
);
});
});
test(
'should_raise_readable_error_when_download_policy_data_is_malformed',
() async {
final adapter = FakeHttpAdapter(
(options) async => FakeHttpResponse(
jsonEncode({'code': 0, 'message': 'ok', 'data': null}),
),
);
final client = ApiClient(adapter: adapter);
final api = DownloadApi(client);
await expectLater(
api.policy(),
throwsA(
isA<ApiException>().having(
(error) => error.message,
'message',
ResponseDecoders.malformedMessage,
),
),
);
client.close();
},
);
}