todo_app/test/unit/todo_repository_test.dart

184 lines
5.5 KiB
Dart
Raw Normal View History

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<Exception>()),
);
});
});
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));
});
});
}