177 lines
5.2 KiB
Dart
177 lines
5.2 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:mocktail/mocktail.dart';
|
|
import 'package:social_app/features/todo/data/todo_api.dart';
|
|
import 'package:social_app/core/api/i_api_client.dart';
|
|
|
|
class MockApiClient extends Mock implements IApiClient {}
|
|
|
|
class FakeRequestOptions extends Fake implements RequestOptions {}
|
|
|
|
void main() {
|
|
late TodoApi todoApi;
|
|
late MockApiClient mockClient;
|
|
|
|
setUpAll(() {
|
|
registerFallbackValue(FakeRequestOptions());
|
|
});
|
|
|
|
setUp(() {
|
|
mockClient = MockApiClient();
|
|
todoApi = TodoApi(mockClient);
|
|
});
|
|
|
|
group('TodoApi.updateTodo - cross-quadrant drag', () {
|
|
test(
|
|
'calls PATCH with priority when moving to different quadrant',
|
|
() async {
|
|
const todoId = 'todo-123';
|
|
const targetPriority = 2;
|
|
const targetOrder = 0;
|
|
|
|
when(
|
|
() => mockClient.patch(any(), data: any(named: 'data')),
|
|
).thenAnswer(
|
|
(_) async => Response(
|
|
requestOptions: RequestOptions(path: '/api/v1/todos/$todoId'),
|
|
data: {
|
|
'id': todoId,
|
|
'owner_id': 'user-1',
|
|
'title': 'Test Todo',
|
|
'priority': targetPriority,
|
|
'order': targetOrder,
|
|
'status': 'pending',
|
|
'created_at': '2024-01-01T00:00:00Z',
|
|
'updated_at': '2024-01-01T00:00:00Z',
|
|
},
|
|
),
|
|
);
|
|
|
|
final result = await todoApi.updateTodo(
|
|
todoId,
|
|
priority: targetPriority,
|
|
order: targetOrder,
|
|
);
|
|
|
|
expect(result.priority, targetPriority);
|
|
expect(result.order, targetOrder);
|
|
verify(
|
|
() => mockClient.patch(
|
|
'/api/v1/todos/$todoId',
|
|
data: {'priority': targetPriority, 'order': targetOrder},
|
|
),
|
|
).called(1);
|
|
},
|
|
);
|
|
|
|
test('throws when API fails - triggers rollback', () async {
|
|
const todoId = 'todo-123';
|
|
|
|
when(
|
|
() => mockClient.patch(any(), data: any(named: 'data')),
|
|
).thenThrow(Exception('Network error'));
|
|
|
|
expect(
|
|
() => todoApi.updateTodo(todoId, priority: 2, order: 0),
|
|
throwsException,
|
|
);
|
|
});
|
|
});
|
|
|
|
group('Quadrant priority mapping', () {
|
|
test('priority 1 = important urgent (Q1)', () async {
|
|
when(() => mockClient.patch(any(), data: any(named: 'data'))).thenAnswer(
|
|
(_) async => Response(
|
|
requestOptions: RequestOptions(path: '/api/v1/todos/todo-1'),
|
|
data: {
|
|
'id': 'todo-1',
|
|
'owner_id': 'user-1',
|
|
'title': 'Q1 Todo',
|
|
'priority': 1,
|
|
'order': 1,
|
|
'status': 'pending',
|
|
'created_at': '2024-01-01T00:00:00Z',
|
|
'updated_at': '2024-01-01T00:00:00Z',
|
|
},
|
|
),
|
|
);
|
|
|
|
final result = await todoApi.updateTodo('todo-1', priority: 1, order: 1);
|
|
expect(result.priority, 1);
|
|
expect(result.order, 1);
|
|
});
|
|
|
|
test('priority 2 = important not urgent (Q3)', () async {
|
|
when(() => mockClient.patch(any(), data: any(named: 'data'))).thenAnswer(
|
|
(_) async => Response(
|
|
requestOptions: RequestOptions(path: '/api/v1/todos/todo-2'),
|
|
data: {
|
|
'id': 'todo-2',
|
|
'owner_id': 'user-1',
|
|
'title': 'Q3 Todo',
|
|
'priority': 2,
|
|
'order': 2,
|
|
'status': 'pending',
|
|
'created_at': '2024-01-01T00:00:00Z',
|
|
'updated_at': '2024-01-01T00:00:00Z',
|
|
},
|
|
),
|
|
);
|
|
|
|
final result = await todoApi.updateTodo('todo-2', priority: 2, order: 2);
|
|
expect(result.priority, 2);
|
|
expect(result.order, 2);
|
|
});
|
|
|
|
test('priority 3 = urgent not important (Q2)', () async {
|
|
when(() => mockClient.patch(any(), data: any(named: 'data'))).thenAnswer(
|
|
(_) async => Response(
|
|
requestOptions: RequestOptions(path: '/api/v1/todos/todo-3'),
|
|
data: {
|
|
'id': 'todo-3',
|
|
'owner_id': 'user-1',
|
|
'title': 'Q2 Todo',
|
|
'priority': 3,
|
|
'order': 0,
|
|
'status': 'pending',
|
|
'created_at': '2024-01-01T00:00:00Z',
|
|
'updated_at': '2024-01-01T00:00:00Z',
|
|
},
|
|
),
|
|
);
|
|
|
|
final result = await todoApi.updateTodo('todo-3', priority: 3, order: 0);
|
|
expect(result.priority, 3);
|
|
expect(result.order, 0);
|
|
});
|
|
});
|
|
|
|
group('TodoApi.reorderTodos', () {
|
|
test('calls batch reorder endpoint once', () async {
|
|
when(() => mockClient.patch(any(), data: any(named: 'data'))).thenAnswer(
|
|
(_) async => Response(
|
|
requestOptions: RequestOptions(path: '/api/v1/todos/reorder'),
|
|
data: {},
|
|
),
|
|
);
|
|
|
|
await todoApi.reorderTodos(const [
|
|
TodoReorderItemPayload(id: 'todo-1', priority: 1, order: 0),
|
|
TodoReorderItemPayload(id: 'todo-2', priority: 1, order: 1),
|
|
]);
|
|
|
|
verify(
|
|
() => mockClient.patch(
|
|
'/api/v1/todos/reorder',
|
|
data: {
|
|
'items': [
|
|
{'id': 'todo-1', 'priority': 1, 'order': 0},
|
|
{'id': 'todo-2', 'priority': 1, 'order': 1},
|
|
],
|
|
},
|
|
),
|
|
).called(1);
|
|
});
|
|
});
|
|
}
|