feat: 增强日历功能并集成 AgentScope 代理服务
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:social_app/core/api/mock_api_client.dart';
|
||||
import 'package:social_app/features/calendar/data/calendar_api.dart';
|
||||
import 'package:social_app/features/calendar/data/models/schedule_item_model.dart';
|
||||
|
||||
void main() {
|
||||
group('CalendarApi', () {
|
||||
test('listByRange parses metadata and attachments', () async {
|
||||
final client = MockApiClient();
|
||||
client.registerPatternHandler(
|
||||
RegExp(r'^/api/v1/schedule-items\?.*$'),
|
||||
'GET',
|
||||
(_) => [
|
||||
{
|
||||
'id': 'evt_1',
|
||||
'title': '晨会',
|
||||
'description': '同步',
|
||||
'start_at': '2026-03-11T01:00:00Z',
|
||||
'end_at': '2026-03-11T02:00:00Z',
|
||||
'timezone': 'Asia/Shanghai',
|
||||
'metadata': {
|
||||
'color': '#4F46E5',
|
||||
'location': '会议室A',
|
||||
'notes': '带电脑',
|
||||
'attachments': [
|
||||
{
|
||||
'name': '议程文档',
|
||||
'visible_to': ['u1'],
|
||||
'url': 'https://example.com/a',
|
||||
'note': '会前阅读',
|
||||
'content': null,
|
||||
'type': 'document',
|
||||
},
|
||||
],
|
||||
'version': 1,
|
||||
'new_field': 'future',
|
||||
},
|
||||
'status': 'active',
|
||||
'source_type': 'manual',
|
||||
'created_at': '2026-03-10T01:00:00Z',
|
||||
'updated_at': '2026-03-10T01:30:00Z',
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
final api = CalendarApi(client);
|
||||
final result = await api.listByRange(
|
||||
startAt: DateTime.utc(2026, 3, 1),
|
||||
endAt: DateTime.utc(2026, 3, 31, 23, 59, 59),
|
||||
);
|
||||
|
||||
expect(result, hasLength(1));
|
||||
expect(result.first.metadata?.attachments, hasLength(1));
|
||||
expect(result.first.metadata?.raw['new_field'], 'future');
|
||||
expect(result.first.startAt.isUtc, isFalse);
|
||||
});
|
||||
|
||||
test('create serializes full metadata', () async {
|
||||
final client = MockApiClient();
|
||||
client.registerHandler('/api/v1/schedule-items', 'POST', (request) {
|
||||
final body = request.data as Map<String, dynamic>;
|
||||
expect(body['metadata']['version'], 1);
|
||||
expect(body['metadata']['attachments'], isA<List<dynamic>>());
|
||||
return {
|
||||
'id': 'evt_2',
|
||||
...body,
|
||||
'status': 'active',
|
||||
'source_type': 'manual',
|
||||
'created_at': '2026-03-10T01:00:00Z',
|
||||
'updated_at': '2026-03-10T01:00:00Z',
|
||||
};
|
||||
});
|
||||
|
||||
final api = CalendarApi(client);
|
||||
final created = await api.create(
|
||||
ScheduleItemModel(
|
||||
id: 'evt_local',
|
||||
title: '评审',
|
||||
startAt: DateTime.utc(2026, 3, 11, 3),
|
||||
endAt: DateTime.utc(2026, 3, 11, 4),
|
||||
metadata: ScheduleMetadata(
|
||||
color: '#F59E0B',
|
||||
location: '线上',
|
||||
notes: '准备 demo',
|
||||
attachments: [Attachment(name: 'PRD', type: 'document')],
|
||||
version: 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(created.id, 'evt_2');
|
||||
expect(created.metadata?.location, '线上');
|
||||
});
|
||||
|
||||
test('update does not send unknown metadata fields', () async {
|
||||
final client = MockApiClient();
|
||||
client.registerHandler('/api/v1/schedule-items/evt_3', 'PATCH', (
|
||||
request,
|
||||
) {
|
||||
final body = request.data as Map<String, dynamic>;
|
||||
final metadata = body['metadata'] as Map<String, dynamic>;
|
||||
expect(metadata.containsKey('new_field'), isFalse);
|
||||
return {
|
||||
'id': 'evt_3',
|
||||
...body,
|
||||
'status': 'active',
|
||||
'source_type': 'manual',
|
||||
'created_at': '2026-03-10T01:00:00Z',
|
||||
'updated_at': '2026-03-11T01:00:00Z',
|
||||
};
|
||||
});
|
||||
|
||||
final api = CalendarApi(client);
|
||||
final event = ScheduleItemModel(
|
||||
id: 'evt_3',
|
||||
title: '同步会',
|
||||
startAt: DateTime.utc(2026, 3, 11, 1),
|
||||
metadata: ScheduleMetadata.fromJson({
|
||||
'color': '#3B82F6',
|
||||
'location': '会议室B',
|
||||
'notes': '更新周报',
|
||||
'attachments': const [],
|
||||
'version': 1,
|
||||
'new_field': 'future',
|
||||
}),
|
||||
);
|
||||
|
||||
final updated = await api.update(event);
|
||||
expect(updated.id, 'evt_3');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('时间自动对齐逻辑', () {
|
||||
test('开始时间改变后,结束时间早于开始时间应自动对齐', () {
|
||||
DateTime startTime = DateTime(2026, 3, 11, 10, 0);
|
||||
DateTime endTime = DateTime(2026, 3, 11, 9, 0);
|
||||
|
||||
final newStartTime = DateTime(2026, 3, 11, 14, 30);
|
||||
|
||||
if (endTime.isBefore(newStartTime)) {
|
||||
endTime = newStartTime;
|
||||
}
|
||||
|
||||
expect(endTime.hour, 14);
|
||||
expect(endTime.minute, 30);
|
||||
});
|
||||
|
||||
test('结束时间晚于开始时间则不需要对齐', () {
|
||||
DateTime startTime = DateTime(2026, 3, 11, 10, 0);
|
||||
DateTime endTime = DateTime(2026, 3, 11, 12, 0);
|
||||
|
||||
final newStartTime = DateTime(2026, 3, 11, 14, 30);
|
||||
|
||||
if (endTime.isBefore(newStartTime)) {
|
||||
endTime = newStartTime;
|
||||
}
|
||||
|
||||
expect(endTime.hour, 14);
|
||||
expect(endTime.minute, 30);
|
||||
});
|
||||
|
||||
test('结束时间等于开始时间也需要对齐', () {
|
||||
DateTime startTime = DateTime(2026, 3, 11, 10, 0);
|
||||
DateTime endTime = DateTime(2026, 3, 11, 10, 0);
|
||||
|
||||
final newStartTime = DateTime(2026, 3, 11, 14, 30);
|
||||
|
||||
if (endTime.isBefore(newStartTime)) {
|
||||
endTime = newStartTime;
|
||||
}
|
||||
|
||||
expect(endTime.hour, 14);
|
||||
expect(endTime.minute, 30);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user