import 'package:flutter_test/flutter_test.dart'; import 'package:todo_app/features/todo/data/repositories/in_memory_todo_repository.dart'; import 'package:todo_app/features/todo/domain/entities/create_todo_params.dart'; import 'package:todo_app/features/todo/domain/entities/update_todo_params.dart'; void main() { late InMemoryTodoRepository repository; setUp(() { repository = InMemoryTodoRepository(); }); group('createTodo', () { test('creates a todo with required fields', () async { final todo = await repository.createTodo( const CreateTodoParams(title: 'Test Todo'), ); expect(todo.title, equals('Test Todo')); expect(todo.isCompleted, isFalse); expect(todo.priority, equals('medium')); expect(todo.id, isNotEmpty); expect(todo.createdAt, isNotNull); }); test('creates a todo with all fields', () async { final dueDate = DateTime(2026, 12, 31); final todo = await repository.createTodo( CreateTodoParams( title: 'Full Todo', description: 'A description', priority: 'high', dueDate: dueDate, ), ); expect(todo.title, equals('Full Todo')); expect(todo.description, equals('A description')); expect(todo.priority, equals('high')); expect(todo.dueDate, equals(dueDate)); }); }); group('getTodos', () { test('returns empty list initially', () async { final todos = await repository.getTodos(); expect(todos, isEmpty); }); test('returns all todos sorted by sortOrder', () async { await repository.createTodo(const CreateTodoParams(title: 'B')); await repository.createTodo(const CreateTodoParams(title: 'A')); final todos = await repository.getTodos(); expect(todos.length, equals(2)); expect(todos[0].title, equals('B')); expect(todos[1].title, equals('A')); }); test('filters by priority', () async { await repository.createTodo( const CreateTodoParams(title: 'High', priority: 'high'), ); await repository.createTodo( const CreateTodoParams(title: 'Low', priority: 'low'), ); final highTodos = await repository.getTodos(priorityFilter: 'high'); expect(highTodos.length, equals(1)); expect(highTodos.first.title, equals('High')); }); test('filters by completion status', () async { final todo = await repository.createTodo( const CreateTodoParams(title: 'Done'), ); await repository.createTodo( const CreateTodoParams(title: 'Pending'), ); await repository.toggleTodo(todo.id); final completed = await repository.getTodos(completedFilter: true); expect(completed.length, equals(1)); expect(completed.first.title, equals('Done')); }); }); group('getTodo', () { test('returns todo by id', () async { final created = await repository.createTodo( const CreateTodoParams(title: 'Find Me'), ); final found = await repository.getTodo(created.id); expect(found.title, equals('Find Me')); }); test('throws when not found', () async { expect( () => repository.getTodo('nonexistent'), throwsA(isA()), ); }); }); group('updateTodo', () { test('updates todo fields', () async { final created = await repository.createTodo( const CreateTodoParams(title: 'Original'), ); final updated = await repository.updateTodo( created.id, const UpdateTodoParams(title: 'Updated', priority: 'high'), ); expect(updated.title, equals('Updated')); expect(updated.priority, equals('high')); expect(updated.updatedAt, isNotNull); }); test('partial update preserves other fields', () async { final created = await repository.createTodo( const CreateTodoParams(title: 'Original', priority: 'low'), ); final updated = await repository.updateTodo( created.id, const UpdateTodoParams(title: 'Renamed'), ); expect(updated.title, equals('Renamed')); expect(updated.priority, equals('low')); }); }); group('toggleTodo', () { test('toggles completion status', () async { final created = await repository.createTodo( const CreateTodoParams(title: 'Toggle'), ); expect(created.isCompleted, isFalse); final toggled = await repository.toggleTodo(created.id); expect(toggled.isCompleted, isTrue); final untoggled = await repository.toggleTodo(created.id); expect(untoggled.isCompleted, isFalse); }); }); group('deleteTodo', () { test('removes todo', () async { final created = await repository.createTodo( const CreateTodoParams(title: 'Delete Me'), ); await repository.deleteTodo(created.id); final todos = await repository.getTodos(); expect(todos, isEmpty); }); }); group('reorderTodos', () { test('reorders todos and updates sortOrder', () async { await repository.createTodo(const CreateTodoParams(title: 'A')); await repository.createTodo(const CreateTodoParams(title: 'B')); await repository.createTodo(const CreateTodoParams(title: 'C')); await repository.reorderTodos(0, 2); final todos = await repository.getTodos(); expect(todos[0].title, equals('B')); expect(todos[1].title, equals('C')); expect(todos[2].title, equals('A')); expect(todos[0].sortOrder, equals(0)); expect(todos[1].sortOrder, equals(1)); expect(todos[2].sortOrder, equals(2)); }); }); }