import 'package:flutter_test/flutter_test.dart'; import 'package:social_app/features/chat/data/models/ag_ui_event.dart'; void main() { group('agUiEventTypeFromWire', () { test('maps RUN_STARTED correctly', () { expect(agUiEventTypeFromWire('RUN_STARTED'), AgUiEventType.runStarted); }); test('maps RUN_FINISHED correctly', () { expect(agUiEventTypeFromWire('RUN_FINISHED'), AgUiEventType.runFinished); }); test('maps RUN_ERROR correctly', () { expect(agUiEventTypeFromWire('RUN_ERROR'), AgUiEventType.runError); }); test('maps TEXT_MESSAGE_START correctly', () { expect( agUiEventTypeFromWire('TEXT_MESSAGE_START'), AgUiEventType.textMessageStart, ); }); test('maps TEXT_MESSAGE_CONTENT correctly', () { expect( agUiEventTypeFromWire('TEXT_MESSAGE_CONTENT'), AgUiEventType.textMessageContent, ); }); test('maps TEXT_MESSAGE_END correctly', () { expect( agUiEventTypeFromWire('TEXT_MESSAGE_END'), AgUiEventType.textMessageEnd, ); }); test('maps TOOL_CALL_START correctly', () { expect( agUiEventTypeFromWire('TOOL_CALL_START'), AgUiEventType.toolCallStart, ); }); test('maps TOOL_CALL_ARGS correctly', () { expect( agUiEventTypeFromWire('TOOL_CALL_ARGS'), AgUiEventType.toolCallArgs, ); }); test('maps TOOL_CALL_END correctly', () { expect(agUiEventTypeFromWire('TOOL_CALL_END'), AgUiEventType.toolCallEnd); }); test('maps TOOL_CALL_RESULT correctly', () { expect( agUiEventTypeFromWire('TOOL_CALL_RESULT'), AgUiEventType.toolCallResult, ); }); test('maps TOOL_CALL_ERROR correctly', () { expect( agUiEventTypeFromWire('TOOL_CALL_ERROR'), AgUiEventType.toolCallError, ); }); test('maps STATE_SNAPSHOT correctly', () { expect( agUiEventTypeFromWire('STATE_SNAPSHOT'), AgUiEventType.stateSnapshot, ); }); test('returns unknown for unknown type', () { expect(agUiEventTypeFromWire('UNKNOWN_TYPE'), AgUiEventType.unknown); }); test('returns unknown for empty string', () { expect(agUiEventTypeFromWire(''), AgUiEventType.unknown); }); }); group('agUiEventTypeToWire', () { test('maps runStarted to RUN_STARTED', () { expect(agUiEventTypeToWire(AgUiEventType.runStarted), 'RUN_STARTED'); }); test('maps runFinished to RUN_FINISHED', () { expect(agUiEventTypeToWire(AgUiEventType.runFinished), 'RUN_FINISHED'); }); test('maps textMessageStart to TEXT_MESSAGE_START', () { expect( agUiEventTypeToWire(AgUiEventType.textMessageStart), 'TEXT_MESSAGE_START', ); }); test('maps unknown to empty string', () { expect(agUiEventTypeToWire(AgUiEventType.unknown), ''); }); }); group('AgUiEvent.fromJson', () { test('parses RunStartedEvent', () { final json = { 'type': 'RUN_STARTED', 'threadId': 'thread_123', 'runId': 'run_456', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final runStarted = event as RunStartedEvent; expect(runStarted.threadId, 'thread_123'); expect(runStarted.runId, 'run_456'); }); test('parses RunFinishedEvent', () { final json = { 'type': 'RUN_FINISHED', 'threadId': 'thread_123', 'runId': 'run_456', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final runFinished = event as RunFinishedEvent; expect(runFinished.threadId, 'thread_123'); }); test('parses RunErrorEvent', () { final json = { 'type': 'RUN_ERROR', 'message': 'Something went wrong', 'code': 'ERR_001', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final runError = event as RunErrorEvent; expect(runError.message, 'Something went wrong'); expect(runError.code, 'ERR_001'); }); test('parses TextMessageStartEvent', () { final json = { 'type': 'TEXT_MESSAGE_START', 'messageId': 'msg_123', 'role': 'assistant', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final textStart = event as TextMessageStartEvent; expect(textStart.messageId, 'msg_123'); expect(textStart.role, 'assistant'); }); test('parses TextMessageContentEvent', () { final json = { 'type': 'TEXT_MESSAGE_CONTENT', 'messageId': 'msg_123', 'delta': 'Hello', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final textContent = event as TextMessageContentEvent; expect(textContent.messageId, 'msg_123'); expect(textContent.delta, 'Hello'); }); test('parses TextMessageEndEvent', () { final json = {'type': 'TEXT_MESSAGE_END', 'messageId': 'msg_123'}; final event = AgUiEvent.fromJson(json); expect(event, isA()); final textEnd = event as TextMessageEndEvent; expect(textEnd.messageId, 'msg_123'); }); test('parses ToolCallStartEvent', () { final json = { 'type': 'TOOL_CALL_START', 'toolCallId': 'tc_123', 'toolCallName': 'back.mutate_calendar_event', 'parentMessageId': 'msg_001', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final toolStart = event as ToolCallStartEvent; expect(toolStart.toolCallId, 'tc_123'); expect(toolStart.toolCallName, 'back.mutate_calendar_event'); expect(toolStart.parentMessageId, 'msg_001'); }); test('parses ToolCallArgsEvent', () { final json = { 'type': 'TOOL_CALL_ARGS', 'toolCallId': 'tc_123', 'delta': '{"title": "test"}', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final toolArgs = event as ToolCallArgsEvent; expect(toolArgs.toolCallId, 'tc_123'); expect(toolArgs.delta, '{"title": "test"}'); }); test('parses ToolCallEndEvent', () { final json = {'type': 'TOOL_CALL_END', 'toolCallId': 'tc_123'}; final event = AgUiEvent.fromJson(json); expect(event, isA()); }); test('parses ToolCallResultEvent', () { final json = { 'type': 'TOOL_CALL_RESULT', 'messageId': 'msg_123', 'toolCallId': 'tc_123', 'content': '{"result":{"ok":true,"eventId":"evt_001"}}', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final toolResult = event as ToolCallResultEvent; expect(toolResult.messageId, 'msg_123'); expect(toolResult.toolCallId, 'tc_123'); expect(toolResult.result['ok'], true); }); test('parses ToolCallResultEvent content payload', () { final json = { 'type': 'TOOL_CALL_RESULT', 'messageId': 'msg_123', 'toolCallId': 'tc_123', 'content': '{"result":{"ok":true,"eventId":"evt_001"}}', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final toolResult = event as ToolCallResultEvent; expect(toolResult.messageId, 'msg_123'); expect(toolResult.toolCallId, 'tc_123'); expect(toolResult.result['ok'], true); expect(toolResult.result['eventId'], 'evt_001'); }); test('ToolCallResultEvent.ui parses from payload.ui', () { final json = { 'type': 'TOOL_CALL_RESULT', 'messageId': 'msg_123', 'toolCallId': 'tc_123', 'content': '{"ui":{"type":"calendar_card.v1","version":"v1","data":{"id":"evt_1","title":"会议","startAt":"2026-03-01T10:00:00Z"},"actions":[]}}', }; final event = AgUiEvent.fromJson(json) as ToolCallResultEvent; expect(event.ui, isNotNull); expect(event.ui!.cardType, 'calendar_card.v1'); }); test( 'ToolCallResultEvent.ui parses from payload.result when result is UiCard', () { final json = { 'type': 'TOOL_CALL_RESULT', 'messageId': 'msg_123', 'toolCallId': 'tc_123', 'content': '{"result":{"type":"calendar_operation.v1","version":"v1","data":{"operation":"delete","ok":true},"actions":[]}}', }; final event = AgUiEvent.fromJson(json) as ToolCallResultEvent; expect(event.ui, isNotNull); expect(event.ui!.cardType, 'calendar_operation.v1'); }, ); test('parses ToolCallErrorEvent', () { final json = { 'type': 'TOOL_CALL_ERROR', 'toolCallId': 'tc_123', 'error': 'Execution failed', 'code': 'EXEC_ERROR', }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final toolError = event as ToolCallErrorEvent; expect(toolError.toolCallId, 'tc_123'); expect(toolError.error, 'Execution failed'); expect(toolError.code, 'EXEC_ERROR'); }); test('parses StateSnapshotEvent', () { final json = { 'type': 'STATE_SNAPSHOT', 'snapshot': {'scope': 'history_day', 'hasMore': false, 'messages': []}, }; final event = AgUiEvent.fromJson(json); expect(event, isA()); final stateSnapshot = event as StateSnapshotEvent; expect(stateSnapshot.snapshot['scope'], 'history_day'); }); test('returns UnknownAgUiEvent for unknown type', () { final json = {'type': 'UNKNOWN_TYPE', 'someField': 'someValue'}; final event = AgUiEvent.fromJson(json); expect(event, isA()); final unknown = event as UnknownAgUiEvent; expect(unknown.rawJson['someField'], 'someValue'); }); test('returns UnknownAgUiEvent for missing type', () { final json = {'someField': 'someValue'}; final event = AgUiEvent.fromJson(json); expect(event, isA()); }); }); group('toJson', () { test('RunStartedEvent serializes with correct fields', () { final event = RunStartedEvent(threadId: 't1', runId: 'r1'); final json = event.toJson(); expect(json['threadId'], 't1'); expect(json['runId'], 'r1'); }); test('TextMessageContentEvent serializes with correct fields', () { final event = TextMessageContentEvent(messageId: 'm1', delta: 'hello'); final json = event.toJson(); expect(json['messageId'], 'm1'); expect(json['delta'], 'hello'); }); test('ToolCallStartEvent serializes with correct fields', () { final event = ToolCallStartEvent( toolCallId: 'tc1', toolCallName: 'test_tool', ); final json = event.toJson(); expect(json['toolCallId'], 'tc1'); expect(json['toolCallName'], 'test_tool'); }); }); }