feat: 添加自动化任务(automation_jobs)功能模块
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:social_app/features/settings/data/models/automation_job_model.dart';
|
||||
|
||||
void main() {
|
||||
group('MessageContextConfigModel', () {
|
||||
test('fromJson parses all fields correctly', () {
|
||||
final json = {
|
||||
'source': 'messages',
|
||||
'window_mode': 'week',
|
||||
'window_count': 5,
|
||||
};
|
||||
|
||||
final model = MessageContextConfigModel.fromJson(json);
|
||||
|
||||
expect(model.source, 'messages');
|
||||
expect(model.windowMode, 'week');
|
||||
expect(model.windowCount, 5);
|
||||
});
|
||||
|
||||
test('fromJson uses defaults for missing fields', () {
|
||||
final model = MessageContextConfigModel.fromJson(null);
|
||||
|
||||
expect(model.source, 'latest_chat');
|
||||
expect(model.windowMode, 'day');
|
||||
expect(model.windowCount, 2);
|
||||
});
|
||||
|
||||
test('toJson serializes correctly', () {
|
||||
final model = MessageContextConfigModel(
|
||||
source: 'messages',
|
||||
windowMode: 'week',
|
||||
windowCount: 5,
|
||||
);
|
||||
|
||||
final json = model.toJson();
|
||||
|
||||
expect(json['source'], 'messages');
|
||||
expect(json['window_mode'], 'week');
|
||||
expect(json['window_count'], 5);
|
||||
});
|
||||
});
|
||||
|
||||
group('AutomationJobConfigModel', () {
|
||||
test('fromJson parses all fields correctly', () {
|
||||
final json = {
|
||||
'input_template': 'Hello {{name}}',
|
||||
'enabled_tools': ['tool1', 'tool2'],
|
||||
'context': {
|
||||
'source': 'messages',
|
||||
'window_mode': 'week',
|
||||
'window_count': 5,
|
||||
},
|
||||
};
|
||||
|
||||
final model = AutomationJobConfigModel.fromJson(json);
|
||||
|
||||
expect(model.inputTemplate, 'Hello {{name}}');
|
||||
expect(model.enabledTools, ['tool1', 'tool2']);
|
||||
expect(model.context.source, 'messages');
|
||||
expect(model.context.windowMode, 'week');
|
||||
expect(model.context.windowCount, 5);
|
||||
});
|
||||
|
||||
test('fromJson uses defaults for null input', () {
|
||||
final model = AutomationJobConfigModel.fromJson(null);
|
||||
|
||||
expect(model.inputTemplate, '');
|
||||
expect(model.enabledTools, []);
|
||||
expect(model.context.source, 'latest_chat');
|
||||
expect(model.context.windowMode, 'day');
|
||||
expect(model.context.windowCount, 2);
|
||||
});
|
||||
});
|
||||
|
||||
group('AutomationJobModel', () {
|
||||
test('fromJson parses all fields correctly', () {
|
||||
final json = {
|
||||
'id': 'job-123',
|
||||
'owner_id': 'user-456',
|
||||
'bootstrap_key': 'key-789',
|
||||
'title': 'Daily Report',
|
||||
'schedule_type': 'DAILY',
|
||||
'run_at': '09:00:00',
|
||||
'timezone': 'America/New_York',
|
||||
'status': 'ACTIVE',
|
||||
'is_system': false,
|
||||
'config': {
|
||||
'input_template': 'Hello',
|
||||
'enabled_tools': ['tool1'],
|
||||
'context': {
|
||||
'source': 'latest_chat',
|
||||
'window_mode': 'day',
|
||||
'window_count': 2,
|
||||
},
|
||||
},
|
||||
'next_run_at': '2024-01-15T09:00:00Z',
|
||||
'last_run_at': '2024-01-14T09:00:00Z',
|
||||
'created_at': '2024-01-01T00:00:00Z',
|
||||
'updated_at': '2024-01-14T12:00:00Z',
|
||||
};
|
||||
|
||||
final model = AutomationJobModel.fromJson(json);
|
||||
|
||||
expect(model.id, 'job-123');
|
||||
expect(model.ownerId, 'user-456');
|
||||
expect(model.bootstrapKey, 'key-789');
|
||||
expect(model.title, 'Daily Report');
|
||||
expect(model.scheduleType, 'DAILY');
|
||||
expect(model.runAt, '09:00:00');
|
||||
expect(model.timezone, 'America/New_York');
|
||||
expect(model.status, 'ACTIVE');
|
||||
expect(model.isSystem, false);
|
||||
expect(model.config.inputTemplate, 'Hello');
|
||||
expect(model.config.enabledTools, ['tool1']);
|
||||
expect(model.config.context.windowCount, 2);
|
||||
expect(model.nextRunAt, DateTime.parse('2024-01-15T09:00:00Z'));
|
||||
expect(model.lastRunAt, DateTime.parse('2024-01-14T09:00:00Z'));
|
||||
expect(model.createdAt, DateTime.parse('2024-01-01T00:00:00Z'));
|
||||
expect(model.updatedAt, DateTime.parse('2024-01-14T12:00:00Z'));
|
||||
});
|
||||
|
||||
test('fromJson throws for missing required date fields', () {
|
||||
final json = <String, dynamic>{
|
||||
'id': 'job-123',
|
||||
'owner_id': 'user-456',
|
||||
'title': 'Test',
|
||||
'schedule_type': 'DAILY',
|
||||
'run_at': '09:00:00',
|
||||
'timezone': 'UTC',
|
||||
'status': 'ACTIVE',
|
||||
'is_system': false,
|
||||
'config': null,
|
||||
};
|
||||
|
||||
expect(
|
||||
() => AutomationJobModel.fromJson(json),
|
||||
throwsA(isA<FormatException>()),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('AutomationJobConfigPatchModel', () {
|
||||
test('toJson only includes non-null fields', () {
|
||||
final model = AutomationJobConfigPatchModel(
|
||||
inputTemplate: 'Updated template',
|
||||
);
|
||||
|
||||
final json = model.toJson();
|
||||
|
||||
expect(json.containsKey('input_template'), true);
|
||||
expect(json.containsKey('enabled_tools'), false);
|
||||
expect(json.containsKey('context'), false);
|
||||
expect(json['input_template'], 'Updated template');
|
||||
});
|
||||
|
||||
test('toJson includes all fields when set', () {
|
||||
final model = AutomationJobConfigPatchModel(
|
||||
inputTemplate: 'Template',
|
||||
enabledTools: ['tool1', 'tool2'],
|
||||
context: MessageContextConfigModel(
|
||||
source: 'messages',
|
||||
windowMode: 'week',
|
||||
windowCount: 3,
|
||||
),
|
||||
);
|
||||
|
||||
final json = model.toJson();
|
||||
|
||||
expect(json['input_template'], 'Template');
|
||||
expect(json['enabled_tools'], ['tool1', 'tool2']);
|
||||
expect(json['context'], {
|
||||
'source': 'messages',
|
||||
'window_mode': 'week',
|
||||
'window_count': 3,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('AutomationJobUpdateRequest', () {
|
||||
test('toJson only includes non-null fields', () {
|
||||
final request = AutomationJobUpdateRequest(
|
||||
title: 'Updated Title',
|
||||
status: 'INACTIVE',
|
||||
);
|
||||
|
||||
final json = request.toJson();
|
||||
|
||||
expect(json.containsKey('title'), true);
|
||||
expect(json.containsKey('status'), true);
|
||||
expect(json.containsKey('schedule_type'), false);
|
||||
expect(json.containsKey('run_at'), false);
|
||||
expect(json['title'], 'Updated Title');
|
||||
expect(json['status'], 'INACTIVE');
|
||||
});
|
||||
|
||||
test('toJson includes patch config with only non-null fields', () {
|
||||
final request = AutomationJobUpdateRequest(
|
||||
config: AutomationJobConfigPatchModel(inputTemplate: 'New template'),
|
||||
);
|
||||
|
||||
final json = request.toJson();
|
||||
|
||||
expect(json.containsKey('config'), true);
|
||||
final configJson = json['config'] as Map<String, dynamic>;
|
||||
expect(configJson.containsKey('input_template'), true);
|
||||
expect(configJson.containsKey('enabled_tools'), false);
|
||||
expect(configJson.containsKey('context'), false);
|
||||
});
|
||||
});
|
||||
|
||||
group('AutomationJobCreateRequest', () {
|
||||
test('toJson serializes correctly', () {
|
||||
final request = AutomationJobCreateRequest(
|
||||
title: 'New Job',
|
||||
scheduleType: 'DAILY',
|
||||
runAt: '10:00:00',
|
||||
timezone: 'UTC',
|
||||
status: 'ACTIVE',
|
||||
config: AutomationJobConfigModel(
|
||||
inputTemplate: 'Hello',
|
||||
enabledTools: ['tool1'],
|
||||
context: MessageContextConfigModel(
|
||||
source: 'latest_chat',
|
||||
windowMode: 'day',
|
||||
windowCount: 2,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final json = request.toJson();
|
||||
|
||||
expect(json['title'], 'New Job');
|
||||
expect(json['schedule_type'], 'DAILY');
|
||||
expect(json['run_at'], '10:00:00');
|
||||
expect(json['timezone'], 'UTC');
|
||||
expect(json['status'], 'ACTIVE');
|
||||
expect(json['config'], {
|
||||
'input_template': 'Hello',
|
||||
'enabled_tools': ['tool1'],
|
||||
'context': {
|
||||
'source': 'latest_chat',
|
||||
'window_mode': 'day',
|
||||
'window_count': 2,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('AutomationJobListResponse', () {
|
||||
test('fromJson parses items correctly', () {
|
||||
final json = {
|
||||
'items': [
|
||||
{
|
||||
'id': 'job-1',
|
||||
'owner_id': 'user-1',
|
||||
'title': 'Job 1',
|
||||
'schedule_type': 'DAILY',
|
||||
'run_at': '09:00:00',
|
||||
'timezone': 'UTC',
|
||||
'status': 'ACTIVE',
|
||||
'is_system': false,
|
||||
'config': null,
|
||||
'next_run_at': '2024-01-15T09:00:00Z',
|
||||
'created_at': '2024-01-01T00:00:00Z',
|
||||
'updated_at': '2024-01-14T12:00:00Z',
|
||||
},
|
||||
{
|
||||
'id': 'job-2',
|
||||
'owner_id': 'user-1',
|
||||
'title': 'Job 2',
|
||||
'schedule_type': 'HOURLY',
|
||||
'run_at': '00:00:00',
|
||||
'timezone': 'UTC',
|
||||
'status': 'INACTIVE',
|
||||
'is_system': false,
|
||||
'config': null,
|
||||
'next_run_at': '2024-01-15T10:00:00Z',
|
||||
'created_at': '2024-01-02T00:00:00Z',
|
||||
'updated_at': '2024-01-14T12:00:00Z',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
final response = AutomationJobListResponse.fromJson(json);
|
||||
|
||||
expect(response.items.length, 2);
|
||||
expect(response.items[0].id, 'job-1');
|
||||
expect(response.items[1].id, 'job-2');
|
||||
});
|
||||
|
||||
test('fromJson returns empty list for null items', () {
|
||||
final response = AutomationJobListResponse.fromJson(null);
|
||||
|
||||
expect(response.items, isEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user