diff --git a/lib/viewmodels/chat_viewmodel.dart b/lib/viewmodels/chat_viewmodel.dart index e69de29b..a2b32103 100644 --- a/lib/viewmodels/chat_viewmodel.dart +++ b/lib/viewmodels/chat_viewmodel.dart @@ -0,0 +1,46 @@ +import 'package:auto_gpt_flutter_client/models/chat.dart'; +import 'package:auto_gpt_flutter_client/models/message_type.dart'; +import 'package:flutter/foundation.dart'; +import 'mock_data.dart'; // Import the mock data + +// TODO: Update whole class once we have created TaskService +class ChatViewModel with ChangeNotifier { + List _chats = []; + + /// Returns the current list of chats. + List get chats => _chats; + + /// Fetches chats from the mock data source for a specific task. + void fetchChatsForTask(int taskId) { + try { + _chats = mockChats.where((chat) => chat.taskId == taskId).toList(); + notifyListeners(); // Notify listeners to rebuild UI + print("Chats fetched successfully for task ID: $taskId"); + } catch (error) { + print("Error fetching chats: $error"); + // TODO: Handle additional error scenarios or log them as required + } + } + + /// Simulates sending a chat message for a specific task. + void sendChatMessage(int taskId, String message) { + final userChat = Chat( + id: _chats.length + 1, + taskId: taskId, + message: message, + timestamp: DateTime.now(), + messageType: MessageType.user); + + // For now, we'll simulate an agent's reply after the user's message + final agentChat = Chat( + id: _chats.length + 2, + taskId: taskId, + message: 'Automated reply to: $message', + timestamp: DateTime.now().add(const Duration(seconds: 2)), + messageType: MessageType.agent); + + _chats.addAll([userChat, agentChat]); + notifyListeners(); // Notify UI of the new chats + print("User chat and automated agent reply added for task ID: $taskId"); + } +} diff --git a/lib/viewmodels/mock_data.dart b/lib/viewmodels/mock_data.dart index 7f553d78..dab7a7cc 100644 --- a/lib/viewmodels/mock_data.dart +++ b/lib/viewmodels/mock_data.dart @@ -1,3 +1,5 @@ +import 'package:auto_gpt_flutter_client/models/chat.dart'; +import 'package:auto_gpt_flutter_client/models/message_type.dart'; import 'package:auto_gpt_flutter_client/models/task.dart'; /// A list of mock tasks for the application. @@ -18,3 +20,22 @@ void addTask(Task task) { void removeTask(int id) { mockTasks.removeWhere((task) => task.id == id); } + +// mock_data.dart (extend the existing mock_data.dart file) + +// Sample chats for mock data +List mockChats = [ + Chat( + id: 1, + taskId: 1, + message: 'Hello Agent', + timestamp: DateTime.now(), + messageType: MessageType.user), + Chat( + id: 2, + taskId: 1, + message: 'Hello! How can I assist you today?', + timestamp: DateTime.now().add(Duration(minutes: 1)), + messageType: MessageType.agent), + // ... add more mock chat data as required +]; diff --git a/test/chat_viewmodel_test.dart b/test/chat_viewmodel_test.dart new file mode 100644 index 00000000..4fa8f5c6 --- /dev/null +++ b/test/chat_viewmodel_test.dart @@ -0,0 +1,48 @@ +import 'package:auto_gpt_flutter_client/models/chat.dart'; +import 'package:auto_gpt_flutter_client/models/message_type.dart'; +import 'package:auto_gpt_flutter_client/viewmodels/chat_viewmodel.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + // Initialize the ChatViewModel + // TODO: Dependency injection in view models for testing purposes when we implement services + final viewModel = ChatViewModel(); + + group('ChatViewModel', () { + test('fetch chats for a specific task', () { + viewModel + .fetchChatsForTask(1); // Assuming task with ID 1 exists in mock data + expect(viewModel.chats.isNotEmpty, true); + expect(viewModel.chats.every((chat) => chat.taskId == 1), true); + }); + + test('send chat message for a specific task', () { + final initialChatsLength = viewModel.chats.length; + viewModel.sendChatMessage(1, 'Test message'); + expect(viewModel.chats.length, + initialChatsLength + 2); // One user message and one agent reply + expect(viewModel.chats.last.messageType, + MessageType.agent); // Last message should be agent's reply + }); + + // TODO: Refactor to return errors when we implement service + test('fetch chats for invalid task id', () { + viewModel.fetchChatsForTask( + 9999); // Assuming task with ID 9999 does not exist in mock data + expect( + viewModel.chats.where((chat) => chat.taskId == 9999).isEmpty, true); + }); + + // TODO: Refactor to return errors when we implement service + test('send chat message for invalid task id', () { + final initialChatsLength = viewModel.chats.length; + viewModel.sendChatMessage(9999, 'Invalid test message'); + expect( + viewModel.chats.length, + initialChatsLength + + 2); // Even for invalid tasks, we're currently adding mock replies + expect(viewModel.chats.last.messageType, + MessageType.agent); // Last message should be agent's reply + }); + }); +} diff --git a/test/task_viewmodel_test.dart b/test/task_viewmodel_test.dart index 13828574..a89e368d 100644 --- a/test/task_viewmodel_test.dart +++ b/test/task_viewmodel_test.dart @@ -1,6 +1,6 @@ -import 'package:flutter_test/flutter_test.dart'; import 'package:auto_gpt_flutter_client/viewmodels/task_viewmodel.dart'; import 'package:auto_gpt_flutter_client/viewmodels/mock_data.dart'; +import 'package:flutter_test/flutter_test.dart'; void main() { group('TaskViewModel', () { @@ -37,10 +37,6 @@ void main() { expect(hasNotified, true); }); - test('Simulate error happening while fetching a task', () { - // TODO: Implement once you have error handling in place in fetchTasks. - }); - test('No tasks are fetched', () { // Clear mock data for this test mockTasks.clear(); @@ -67,6 +63,7 @@ void main() { }); test('Deletes a task with invalid id', () { + // TODO: Update this test to expect an error once we have TaskService implemented final initialCount = viewModel.tasks.length; viewModel.deleteTask(9999); // Assuming no task with this id exists expect(viewModel.tasks.length, initialCount); // Count remains same