119 lines
3.9 KiB
Dart
119 lines
3.9 KiB
Dart
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
|
|
import 'package:flutter_test/flutter_test.dart';
|
||
|
|
import 'package:mocktail/mocktail.dart';
|
||
|
|
import 'package:todo_app/features/todo/domain/entities/todo.dart';
|
||
|
|
import 'package:todo_app/features/todo/domain/entities/create_todo_params.dart';
|
||
|
|
import 'package:todo_app/features/todo/domain/repositories/todo_repository.dart';
|
||
|
|
import 'package:todo_app/features/todo/presentation/providers/todo_providers.dart';
|
||
|
|
|
||
|
|
class MockTodoRepository extends Mock implements TodoRepository {}
|
||
|
|
|
||
|
|
class FakeCreateTodoParams extends Fake implements CreateTodoParams {}
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
late MockTodoRepository repository;
|
||
|
|
late ProviderContainer container;
|
||
|
|
|
||
|
|
final testTodo = Todo(
|
||
|
|
id: '1',
|
||
|
|
title: 'Test Todo',
|
||
|
|
priority: 'medium',
|
||
|
|
sortOrder: 0,
|
||
|
|
createdAt: DateTime(2026, 1, 1),
|
||
|
|
updatedAt: DateTime(2026, 1, 1),
|
||
|
|
);
|
||
|
|
|
||
|
|
setUpAll(() {
|
||
|
|
registerFallbackValue(FakeCreateTodoParams());
|
||
|
|
});
|
||
|
|
|
||
|
|
setUp(() {
|
||
|
|
repository = MockTodoRepository();
|
||
|
|
container = ProviderContainer(overrides: [
|
||
|
|
todoRepositoryProvider.overrideWithValue(repository),
|
||
|
|
]);
|
||
|
|
addTearDown(container.dispose);
|
||
|
|
});
|
||
|
|
|
||
|
|
group('todoListProvider', () {
|
||
|
|
test('builds with todo list from repository', () async {
|
||
|
|
when(() => repository.getTodos(
|
||
|
|
priorityFilter: any(named: 'priorityFilter'),
|
||
|
|
completedFilter: any(named: 'completedFilter'),
|
||
|
|
)).thenAnswer((_) async => [testTodo]);
|
||
|
|
|
||
|
|
await container.read(todoListProvider.future);
|
||
|
|
|
||
|
|
expect(container.read(todoListProvider).value, equals([testTodo]));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('handles error state', () async {
|
||
|
|
when(() => repository.getTodos(
|
||
|
|
priorityFilter: any(named: 'priorityFilter'),
|
||
|
|
completedFilter: any(named: 'completedFilter'),
|
||
|
|
)).thenThrow(Exception('Failed'));
|
||
|
|
|
||
|
|
try {
|
||
|
|
await container.read(todoListProvider.future);
|
||
|
|
fail('Should have thrown');
|
||
|
|
} catch (_) {
|
||
|
|
expect(container.read(todoListProvider).hasError, isTrue);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('todoDetailProvider', () {
|
||
|
|
test('returns todo by id', () async {
|
||
|
|
when(() => repository.getTodo('1')).thenAnswer((_) async => testTodo);
|
||
|
|
|
||
|
|
final result = await container.read(todoDetailProvider('1').future);
|
||
|
|
|
||
|
|
expect(result, equals(testTodo));
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('TodoListNotifier.createTodo', () {
|
||
|
|
test('creates todo and refreshes list', () async {
|
||
|
|
when(() => repository.getTodos(
|
||
|
|
priorityFilter: any(named: 'priorityFilter'),
|
||
|
|
completedFilter: any(named: 'completedFilter'),
|
||
|
|
)).thenAnswer((_) async => [testTodo]);
|
||
|
|
when(() => repository.createTodo(any())).thenAnswer((_) async => testTodo);
|
||
|
|
|
||
|
|
await container.read(todoListProvider.notifier).createTodo(
|
||
|
|
const CreateTodoParams(title: 'New'),
|
||
|
|
);
|
||
|
|
|
||
|
|
verify(() => repository.createTodo(any())).called(1);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('TodoListNotifier.toggleTodo', () {
|
||
|
|
test('toggles and refreshes', () async {
|
||
|
|
when(() => repository.getTodos(
|
||
|
|
priorityFilter: any(named: 'priorityFilter'),
|
||
|
|
completedFilter: any(named: 'completedFilter'),
|
||
|
|
)).thenAnswer((_) async => [testTodo]);
|
||
|
|
when(() => repository.toggleTodo('1')).thenAnswer((_) async => testTodo);
|
||
|
|
|
||
|
|
await container.read(todoListProvider.notifier).toggleTodo('1');
|
||
|
|
|
||
|
|
verify(() => repository.toggleTodo('1')).called(1);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
group('TodoListNotifier.deleteTodo', () {
|
||
|
|
test('deletes and refreshes', () async {
|
||
|
|
when(() => repository.getTodos(
|
||
|
|
priorityFilter: any(named: 'priorityFilter'),
|
||
|
|
completedFilter: any(named: 'completedFilter'),
|
||
|
|
)).thenAnswer((_) async => []);
|
||
|
|
when(() => repository.deleteTodo('1')).thenAnswer((_) async {});
|
||
|
|
|
||
|
|
await container.read(todoListProvider.notifier).deleteTodo('1');
|
||
|
|
|
||
|
|
verify(() => repository.deleteTodo('1')).called(1);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|