Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts). Signed-off-by: lions dev Team
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
/// Tests unitaires pour ApproveTransaction use case
|
||||
library approve_transaction_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/approve_transaction.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'approve_transaction_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late ApproveTransaction useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = ApproveTransaction(mockRepository);
|
||||
});
|
||||
|
||||
group('ApproveTransaction Use Case', () {
|
||||
const tApprovalId = 'approval-123';
|
||||
const tComment = 'Approuvé - Montant conforme au budget';
|
||||
final tApprovedTransaction = TransactionApproval(
|
||||
id: tApprovalId,
|
||||
transactionId: 'tx-123',
|
||||
transactionType: TransactionType.withdrawal,
|
||||
amount: 500000.0,
|
||||
currency: 'XOF',
|
||||
requesterId: 'user-1',
|
||||
requesterName: 'Amadou Diallo',
|
||||
requiredLevel: ApprovalLevel.level1,
|
||||
status: ApprovalStatus.approved,
|
||||
approvers: [],
|
||||
createdAt: DateTime(2024, 12, 15),
|
||||
);
|
||||
|
||||
test('should approve transaction successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.approveTransaction(
|
||||
approvalId: tApprovalId,
|
||||
comment: tComment,
|
||||
)).thenAnswer((_) async => Right(tApprovedTransaction));
|
||||
|
||||
// Act
|
||||
final result = await useCase(approvalId: tApprovalId, comment: tComment);
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tApprovedTransaction));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approval) {
|
||||
expect(approval.id, equals(tApprovalId));
|
||||
expect(approval.status, equals(ApprovalStatus.approved));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.approveTransaction(
|
||||
approvalId: tApprovalId,
|
||||
comment: tComment,
|
||||
));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should approve transaction without comment', () async {
|
||||
// Arrange
|
||||
when(mockRepository.approveTransaction(
|
||||
approvalId: tApprovalId,
|
||||
comment: null,
|
||||
)).thenAnswer((_) async => Right(tApprovedTransaction));
|
||||
|
||||
// Act
|
||||
final result = await useCase(approvalId: tApprovalId);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approval) => expect(approval.status, equals(ApprovalStatus.approved)),
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when approvalId is empty', () async {
|
||||
// Act
|
||||
final result = await useCase(approvalId: '');
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
expect((failure as ValidationFailure).message, contains('ID approbation requis'));
|
||||
},
|
||||
(approval) => fail('Should not return approval'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when repository fails', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Transaction déjà approuvée');
|
||||
when(mockRepository.approveTransaction(
|
||||
approvalId: anyNamed('approvalId'),
|
||||
comment: anyNamed('comment'),
|
||||
)).thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase(approvalId: tApprovalId);
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(approval) => fail('Should not return approval'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/approve_transaction_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/// Tests unitaires pour CreateBudget use case
|
||||
library create_budget_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/create_budget.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'create_budget_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late CreateBudget useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = CreateBudget(mockRepository);
|
||||
});
|
||||
|
||||
group('CreateBudget Use Case', () {
|
||||
const tName = 'Budget 2025';
|
||||
const tOrgId = 'org-123';
|
||||
final tBudgetLines = [
|
||||
BudgetLine(
|
||||
id: 'line-1',
|
||||
category: BudgetCategory.contributions,
|
||||
name: 'Cotisations mensuelles',
|
||||
description: 'Revenus des cotisations',
|
||||
amountPlanned: 3000000.0,
|
||||
),
|
||||
BudgetLine(
|
||||
id: 'line-2',
|
||||
category: BudgetCategory.savings,
|
||||
name: 'Dépôts épargne',
|
||||
description: 'Collecte épargne',
|
||||
amountPlanned: 2000000.0,
|
||||
),
|
||||
BudgetLine(
|
||||
id: 'line-3',
|
||||
category: BudgetCategory.solidarity,
|
||||
name: 'Aide mutuelle',
|
||||
description: 'Soutien membres',
|
||||
amountPlanned: 1000000.0,
|
||||
),
|
||||
];
|
||||
final tCreatedBudget = Budget(
|
||||
id: 'budget-new',
|
||||
name: tName,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2025,
|
||||
status: BudgetStatus.draft,
|
||||
lines: tBudgetLines,
|
||||
totalPlanned: 6000000.0,
|
||||
totalRealized: 0.0,
|
||||
currency: 'XOF',
|
||||
createdBy: 'user-1',
|
||||
createdAt: DateTime.now(),
|
||||
startDate: DateTime(2025, 1, 1),
|
||||
endDate: DateTime(2025, 12, 31),
|
||||
);
|
||||
|
||||
test('should create budget successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.createBudget(
|
||||
name: tName,
|
||||
description: anyNamed('description'),
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2025,
|
||||
month: anyNamed('month'),
|
||||
lines: tBudgetLines,
|
||||
)).thenAnswer((_) async => Right(tCreatedBudget));
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
name: tName,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2025,
|
||||
lines: tBudgetLines,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tCreatedBudget));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budget) {
|
||||
expect(budget.id, equals('budget-new'));
|
||||
expect(budget.name, equals(tName));
|
||||
expect(budget.status, equals(BudgetStatus.draft));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.createBudget(
|
||||
name: tName,
|
||||
description: null,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2025,
|
||||
month: null,
|
||||
lines: tBudgetLines,
|
||||
));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should create monthly budget with description', () async {
|
||||
// Arrange
|
||||
const description = 'Budget opérationnel janvier 2025';
|
||||
final monthlyLines = [
|
||||
BudgetLine(
|
||||
id: 'line-monthly',
|
||||
category: BudgetCategory.contributions,
|
||||
name: 'Cotisations janvier',
|
||||
amountPlanned: 500000.0,
|
||||
),
|
||||
];
|
||||
final monthlyBudget = Budget(
|
||||
id: 'budget-monthly',
|
||||
name: 'Budget Janvier 2025',
|
||||
description: description,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.monthly,
|
||||
year: 2025,
|
||||
month: 1,
|
||||
status: BudgetStatus.draft,
|
||||
lines: monthlyLines,
|
||||
totalPlanned: 500000.0,
|
||||
totalRealized: 0.0,
|
||||
currency: 'XOF',
|
||||
createdBy: 'user-1',
|
||||
createdAt: DateTime.now(),
|
||||
startDate: DateTime(2025, 1, 1),
|
||||
endDate: DateTime(2025, 1, 31),
|
||||
);
|
||||
when(mockRepository.createBudget(
|
||||
name: 'Budget Janvier 2025',
|
||||
description: description,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.monthly,
|
||||
year: 2025,
|
||||
month: 1,
|
||||
lines: monthlyLines,
|
||||
)).thenAnswer((_) async => Right(monthlyBudget));
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
name: 'Budget Janvier 2025',
|
||||
description: description,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.monthly,
|
||||
year: 2025,
|
||||
month: 1,
|
||||
lines: monthlyLines,
|
||||
);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budget) {
|
||||
expect(budget.period, equals(BudgetPeriod.monthly));
|
||||
expect(budget.month, equals(1));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when name is empty', () async {
|
||||
// Act
|
||||
final result = await useCase(
|
||||
name: '',
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2025,
|
||||
lines: [BudgetLine(id: 'test-1', category: BudgetCategory.operational, name: 'Test line', amountPlanned: 100.0)],
|
||||
);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
},
|
||||
(budget) => fail('Should not return budget'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when repository fails', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Erreur création budget');
|
||||
when(mockRepository.createBudget(
|
||||
name: anyNamed('name'),
|
||||
description: anyNamed('description'),
|
||||
organizationId: anyNamed('organizationId'),
|
||||
period: anyNamed('period'),
|
||||
year: anyNamed('year'),
|
||||
month: anyNamed('month'),
|
||||
lines: anyNamed('lines'),
|
||||
)).thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
name: tName,
|
||||
organizationId: tOrgId,
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2025,
|
||||
lines: [BudgetLine(id: 'test-1', category: BudgetCategory.operational, name: 'Test line', amountPlanned: 100.0)],
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(budget) => fail('Should not return budget'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/create_budget_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/// Tests unitaires pour GetApprovalById use case
|
||||
library get_approval_by_id_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/get_approval_by_id.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'get_approval_by_id_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetApprovalById useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = GetApprovalById(mockRepository);
|
||||
});
|
||||
|
||||
group('GetApprovalById Use Case', () {
|
||||
const tApprovalId = 'approval-123';
|
||||
final tApproval = TransactionApproval(
|
||||
id: tApprovalId,
|
||||
transactionId: 'tx-456',
|
||||
transactionType: TransactionType.solidarity,
|
||||
amount: 350000.0,
|
||||
currency: 'XOF',
|
||||
requesterId: 'user-1',
|
||||
requesterName: 'Amadou Diallo',
|
||||
organizationId: 'org-123',
|
||||
requiredLevel: ApprovalLevel.level2,
|
||||
status: ApprovalStatus.pending,
|
||||
approvers: [],
|
||||
createdAt: DateTime(2024, 12, 15),
|
||||
);
|
||||
|
||||
test('should return approval details by ID', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getApprovalById(tApprovalId))
|
||||
.thenAnswer((_) async => Right(tApproval));
|
||||
|
||||
// Act
|
||||
final result = await useCase(tApprovalId);
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tApproval));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approval) {
|
||||
expect(approval.id, equals(tApprovalId));
|
||||
expect(approval.amount, equals(350000.0));
|
||||
expect(approval.transactionType, equals(TransactionType.solidarity));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.getApprovalById(tApprovalId));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return approval with level 2 requirement', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getApprovalById(tApprovalId))
|
||||
.thenAnswer((_) async => Right(tApproval));
|
||||
|
||||
// Act
|
||||
final result = await useCase(tApprovalId);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approval) {
|
||||
expect(approval.requiredLevel, equals(ApprovalLevel.level2));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when approvalId is empty', () async {
|
||||
// Act
|
||||
final result = await useCase('');
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
},
|
||||
(approval) => fail('Should not return approval'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when approval not found', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Approbation non trouvée');
|
||||
when(mockRepository.getApprovalById(any))
|
||||
.thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase('nonexistent');
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(approval) => fail('Should not return approval'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/get_approval_by_id_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/// Tests unitaires pour GetBudgetById use case
|
||||
library get_budget_by_id_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/get_budget_by_id.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'get_budget_by_id_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetBudgetById useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = GetBudgetById(mockRepository);
|
||||
});
|
||||
|
||||
group('GetBudgetById Use Case', () {
|
||||
const tBudgetId = 'budget-123';
|
||||
final tBudget = Budget(
|
||||
id: tBudgetId,
|
||||
name: 'Budget Annuel 2024',
|
||||
description: 'Budget prévisionnel pour l\'année 2024',
|
||||
organizationId: 'org-123',
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2024,
|
||||
status: BudgetStatus.active,
|
||||
lines: [],
|
||||
totalPlanned: 5000000.0,
|
||||
totalRealized: 3250000.0,
|
||||
currency: 'XOF',
|
||||
createdBy: 'user-1',
|
||||
createdAt: DateTime(2024, 1, 1),
|
||||
startDate: DateTime(2024, 1, 1),
|
||||
endDate: DateTime(2024, 12, 31),
|
||||
);
|
||||
|
||||
test('should return budget details by ID', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getBudgetById(tBudgetId))
|
||||
.thenAnswer((_) async => Right(tBudget));
|
||||
|
||||
// Act
|
||||
final result = await useCase(tBudgetId);
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tBudget));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budget) {
|
||||
expect(budget.id, equals(tBudgetId));
|
||||
expect(budget.name, equals('Budget Annuel 2024'));
|
||||
expect(budget.totalPlanned, equals(5000000.0));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.getBudgetById(tBudgetId));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return budget with realized amount', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getBudgetById(tBudgetId))
|
||||
.thenAnswer((_) async => Right(tBudget));
|
||||
|
||||
// Act
|
||||
final result = await useCase(tBudgetId);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budget) {
|
||||
expect(budget.totalRealized, equals(3250000.0));
|
||||
expect(budget.totalRealized, lessThan(budget.totalPlanned));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when budgetId is empty', () async {
|
||||
// Act
|
||||
final result = await useCase('');
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
},
|
||||
(budget) => fail('Should not return budget'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when budget not found', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Budget non trouvé');
|
||||
when(mockRepository.getBudgetById(any))
|
||||
.thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase('nonexistent');
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(budget) => fail('Should not return budget'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/get_budget_by_id_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/// Tests unitaires pour GetBudgetTracking use case
|
||||
library get_budget_tracking_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/get_budget_tracking.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'get_budget_tracking_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetBudgetTracking useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = GetBudgetTracking(mockRepository);
|
||||
});
|
||||
|
||||
group('GetBudgetTracking Use Case', () {
|
||||
const tBudgetId = 'budget-123';
|
||||
final tTrackingData = {
|
||||
'budgetId': tBudgetId,
|
||||
'totalPlanned': 5000000.0,
|
||||
'totalRealized': 3250000.0,
|
||||
'remainingAmount': 1750000.0,
|
||||
'realizationRate': 0.65,
|
||||
'categories': {
|
||||
'contributions': {'planned': 2000000.0, 'realized': 1800000.0, 'rate': 0.9},
|
||||
'savings': {'planned': 1500000.0, 'realized': 950000.0, 'rate': 0.63},
|
||||
'solidarity': {'planned': 1000000.0, 'realized': 350000.0, 'rate': 0.35},
|
||||
'events': {'planned': 500000.0, 'realized': 150000.0, 'rate': 0.3},
|
||||
},
|
||||
};
|
||||
|
||||
test('should return budget tracking data successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getBudgetTracking(budgetId: tBudgetId))
|
||||
.thenAnswer((_) async => Right(tTrackingData));
|
||||
|
||||
// Act
|
||||
final result = await useCase(budgetId: tBudgetId);
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tTrackingData));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(tracking) {
|
||||
expect(tracking['budgetId'], equals(tBudgetId));
|
||||
expect(tracking['totalPlanned'], equals(5000000.0));
|
||||
expect(tracking['realizationRate'], equals(0.65));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.getBudgetTracking(budgetId: tBudgetId));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return tracking with category breakdown', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getBudgetTracking(budgetId: tBudgetId))
|
||||
.thenAnswer((_) async => Right(tTrackingData));
|
||||
|
||||
// Act
|
||||
final result = await useCase(budgetId: tBudgetId);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(tracking) {
|
||||
final categories = tracking['categories'] as Map<String, dynamic>;
|
||||
expect(categories.keys, contains('contributions'));
|
||||
expect(categories.keys, contains('solidarity'));
|
||||
final contribs = categories['contributions'] as Map<String, dynamic>;
|
||||
expect(contribs['rate'], equals(0.9));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when budgetId is empty', () async {
|
||||
// Act
|
||||
final result = await useCase(budgetId: '');
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
},
|
||||
(tracking) => fail('Should not return tracking'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when repository fails', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Erreur suivi budget');
|
||||
when(mockRepository.getBudgetTracking(budgetId: anyNamed('budgetId')))
|
||||
.thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase(budgetId: tBudgetId);
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(tracking) => fail('Should not return tracking'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/get_budget_tracking_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/// Tests unitaires pour GetBudgets use case
|
||||
library get_budgets_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/get_budgets.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'get_budgets_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetBudgets useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = GetBudgets(mockRepository);
|
||||
});
|
||||
|
||||
group('GetBudgets Use Case', () {
|
||||
final tBudgets = [
|
||||
Budget(
|
||||
id: 'budget-1',
|
||||
name: 'Budget Annuel 2024',
|
||||
organizationId: 'org-123',
|
||||
period: BudgetPeriod.annual,
|
||||
year: 2024,
|
||||
status: BudgetStatus.active,
|
||||
lines: [],
|
||||
totalPlanned: 5000000.0,
|
||||
totalRealized: 3250000.0,
|
||||
currency: 'XOF',
|
||||
createdBy: 'user-1',
|
||||
createdAt: DateTime(2024, 1, 1),
|
||||
startDate: DateTime(2024, 1, 1),
|
||||
endDate: DateTime(2024, 12, 31),
|
||||
),
|
||||
Budget(
|
||||
id: 'budget-2',
|
||||
name: 'Budget Q4 2024',
|
||||
organizationId: 'org-123',
|
||||
period: BudgetPeriod.quarterly,
|
||||
year: 2024,
|
||||
month: 10,
|
||||
status: BudgetStatus.active,
|
||||
lines: [],
|
||||
totalPlanned: 1250000.0,
|
||||
totalRealized: 850000.0,
|
||||
currency: 'XOF',
|
||||
createdBy: 'user-1',
|
||||
createdAt: DateTime(2024, 10, 1),
|
||||
startDate: DateTime(2024, 10, 1),
|
||||
endDate: DateTime(2024, 12, 31),
|
||||
),
|
||||
];
|
||||
|
||||
test('should return list of budgets successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getBudgets(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
status: anyNamed('status'),
|
||||
year: anyNamed('year'),
|
||||
)).thenAnswer((_) async => Right(tBudgets));
|
||||
|
||||
// Act
|
||||
final result = await useCase(organizationId: 'org-123');
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tBudgets));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budgets) {
|
||||
expect(budgets.length, equals(2));
|
||||
expect(budgets[0].name, equals('Budget Annuel 2024'));
|
||||
expect(budgets[0].totalPlanned, equals(5000000.0));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.getBudgets(
|
||||
organizationId: 'org-123',
|
||||
status: null,
|
||||
year: null,
|
||||
));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should filter budgets by status and year', () async {
|
||||
// Arrange
|
||||
final activeBudgets = [tBudgets[0], tBudgets[1]];
|
||||
when(mockRepository.getBudgets(
|
||||
organizationId: 'org-123',
|
||||
status: BudgetStatus.active,
|
||||
year: 2024,
|
||||
)).thenAnswer((_) async => Right(activeBudgets));
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
organizationId: 'org-123',
|
||||
status: BudgetStatus.active,
|
||||
year: 2024,
|
||||
);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budgets) {
|
||||
expect(budgets.every((b) => b.status == BudgetStatus.active), isTrue);
|
||||
expect(budgets.every((b) => b.year == 2024), isTrue);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('should return empty list when no budgets exist', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getBudgets(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
status: anyNamed('status'),
|
||||
year: anyNamed('year'),
|
||||
)).thenAnswer((_) async => Right([]));
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(budgets) => expect(budgets, isEmpty),
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when repository fails', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Erreur serveur');
|
||||
when(mockRepository.getBudgets(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
status: anyNamed('status'),
|
||||
year: anyNamed('year'),
|
||||
)).thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(budgets) => fail('Should not return budgets'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/get_budgets_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/// Tests unitaires pour GetPendingApprovals use case
|
||||
library get_pending_approvals_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/get_pending_approvals.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'get_pending_approvals_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetPendingApprovals useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = GetPendingApprovals(mockRepository);
|
||||
});
|
||||
|
||||
group('GetPendingApprovals Use Case', () {
|
||||
final tApprovals = [
|
||||
TransactionApproval(
|
||||
id: 'approval-1',
|
||||
transactionId: 'tx-123',
|
||||
transactionType: TransactionType.withdrawal,
|
||||
amount: 500000.0,
|
||||
currency: 'XOF',
|
||||
requesterId: 'user-1',
|
||||
requesterName: 'Amadou Diallo',
|
||||
organizationId: 'org-123',
|
||||
requiredLevel: ApprovalLevel.level2,
|
||||
status: ApprovalStatus.pending,
|
||||
approvers: [],
|
||||
createdAt: DateTime(2024, 12, 15),
|
||||
),
|
||||
TransactionApproval(
|
||||
id: 'approval-2',
|
||||
transactionId: 'tx-456',
|
||||
transactionType: TransactionType.solidarity,
|
||||
amount: 200000.0,
|
||||
currency: 'XOF',
|
||||
requesterId: 'user-2',
|
||||
requesterName: 'Fatou Ndiaye',
|
||||
requiredLevel: ApprovalLevel.level1,
|
||||
status: ApprovalStatus.pending,
|
||||
approvers: [],
|
||||
createdAt: DateTime(2024, 12, 14),
|
||||
),
|
||||
];
|
||||
|
||||
test('should return list of pending approvals successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getPendingApprovals(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
)).thenAnswer((_) async => Right(tApprovals));
|
||||
|
||||
// Act
|
||||
final result = await useCase(organizationId: 'org-123');
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tApprovals));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approvals) {
|
||||
expect(approvals.length, equals(2));
|
||||
expect(approvals[0].status, equals(ApprovalStatus.pending));
|
||||
expect(approvals[0].amount, equals(500000.0));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.getPendingApprovals(organizationId: 'org-123'));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return approvals with different levels', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getPendingApprovals(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
)).thenAnswer((_) async => Right(tApprovals));
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approvals) {
|
||||
expect(approvals.any((a) => a.requiredLevel == ApprovalLevel.level2), isTrue);
|
||||
expect(approvals.any((a) => a.requiredLevel == ApprovalLevel.level1), isTrue);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('should return empty list when no pending approvals', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getPendingApprovals(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
)).thenAnswer((_) async => Right([]));
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approvals) => expect(approvals, isEmpty),
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ServerFailure when repository fails', () async {
|
||||
// Arrange
|
||||
final tFailure = ServerFailure('Erreur serveur');
|
||||
when(mockRepository.getPendingApprovals(
|
||||
organizationId: anyNamed('organizationId'),
|
||||
)).thenAnswer((_) async => Left(tFailure));
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result, Left(tFailure));
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ServerFailure>()),
|
||||
(approvals) => fail('Should not return approvals'),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/get_pending_approvals_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/// Tests unitaires pour RejectTransaction use case
|
||||
library reject_transaction_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/usecases/reject_transaction.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart';
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart';
|
||||
|
||||
@GenerateMocks([FinanceWorkflowRepository])
|
||||
import 'reject_transaction_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late RejectTransaction useCase;
|
||||
late MockFinanceWorkflowRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockFinanceWorkflowRepository();
|
||||
useCase = RejectTransaction(mockRepository);
|
||||
});
|
||||
|
||||
group('RejectTransaction Use Case', () {
|
||||
const tApprovalId = 'approval-123';
|
||||
const tReason = 'Montant trop élevé - Budget insuffisant';
|
||||
final tRejectedTransaction = TransactionApproval(
|
||||
id: tApprovalId,
|
||||
transactionId: 'tx-123',
|
||||
transactionType: TransactionType.withdrawal,
|
||||
amount: 500000.0,
|
||||
currency: 'XOF',
|
||||
requesterId: 'user-1',
|
||||
requesterName: 'Amadou Diallo',
|
||||
requiredLevel: ApprovalLevel.level2,
|
||||
status: ApprovalStatus.rejected,
|
||||
approvers: [],
|
||||
createdAt: DateTime(2024, 12, 15),
|
||||
);
|
||||
|
||||
test('should reject transaction successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.rejectTransaction(
|
||||
approvalId: tApprovalId,
|
||||
reason: tReason,
|
||||
)).thenAnswer((_) async => Right(tRejectedTransaction));
|
||||
|
||||
// Act
|
||||
final result = await useCase(approvalId: tApprovalId, reason: tReason);
|
||||
|
||||
// Assert
|
||||
expect(result, Right(tRejectedTransaction));
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approval) {
|
||||
expect(approval.id, equals(tApprovalId));
|
||||
expect(approval.status, equals(ApprovalStatus.rejected));
|
||||
},
|
||||
);
|
||||
verify(mockRepository.rejectTransaction(
|
||||
approvalId: tApprovalId,
|
||||
reason: tReason,
|
||||
));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should reject transaction with detailed reason', () async {
|
||||
// Arrange
|
||||
const detailedReason = 'Refus: Documentation incomplète + montant non justifié';
|
||||
when(mockRepository.rejectTransaction(
|
||||
approvalId: tApprovalId,
|
||||
reason: detailedReason,
|
||||
)).thenAnswer((_) async => Right(tRejectedTransaction));
|
||||
|
||||
// Act
|
||||
final result = await useCase(approvalId: tApprovalId, reason: detailedReason);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) => fail('Should not return failure'),
|
||||
(approval) => expect(approval.status, equals(ApprovalStatus.rejected)),
|
||||
);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when approvalId is empty', () async {
|
||||
// Act
|
||||
final result = await useCase(approvalId: '', reason: tReason);
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
expect((failure as ValidationFailure).message, contains('ID approbation requis'));
|
||||
},
|
||||
(approval) => fail('Should not return approval'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return ValidationFailure when reason is empty', () async {
|
||||
// Act
|
||||
final result = await useCase(approvalId: tApprovalId, reason: ' ');
|
||||
|
||||
// Assert
|
||||
result.fold(
|
||||
(failure) {
|
||||
expect(failure, isA<ValidationFailure>());
|
||||
expect((failure as ValidationFailure).message, contains('Raison du rejet requise'));
|
||||
},
|
||||
(approval) => fail('Should not return approval'),
|
||||
);
|
||||
verifyZeroInteractions(mockRepository);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/finance_workflow/domain/usecases/reject_transaction_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i4;
|
||||
|
||||
import 'package:dartz/dartz.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:unionflow_mobile_apps/core/error/failures.dart' as _i5;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/budget.dart'
|
||||
as _i7;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/financial_audit_log.dart'
|
||||
as _i8;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/entities/transaction_approval.dart'
|
||||
as _i6;
|
||||
import 'package:unionflow_mobile_apps/features/finance_workflow/domain/repositories/finance_workflow_repository.dart'
|
||||
as _i3;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
|
||||
_FakeEither_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [FinanceWorkflowRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockFinanceWorkflowRepository extends _i1.Mock
|
||||
implements _i3.FinanceWorkflowRepository {
|
||||
MockFinanceWorkflowRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getPendingApprovals({String? organizationId}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getPendingApprovals,
|
||||
[],
|
||||
{#organizationId: organizationId},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> getApprovalById(
|
||||
String? approvalId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalById,
|
||||
[approvalId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> approveTransaction({
|
||||
required String? approvalId,
|
||||
String? comment,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#approveTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#comment: comment,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, _i6.TransactionApproval>> rejectTransaction({
|
||||
required String? approvalId,
|
||||
required String? reason,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#rejectTransaction,
|
||||
[],
|
||||
{
|
||||
#approvalId: approvalId,
|
||||
#reason: reason,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>> requestApproval({
|
||||
required String? transactionId,
|
||||
required _i6.TransactionType? transactionType,
|
||||
required double? amount,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i6.TransactionApproval>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#requestApproval,
|
||||
[],
|
||||
{
|
||||
#transactionId: transactionId,
|
||||
#transactionType: transactionType,
|
||||
#amount: amount,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i6.TransactionApproval>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>
|
||||
getApprovalsHistory({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i6.ApprovalStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<
|
||||
_i2
|
||||
.Either<_i5.Failure, List<_i6.TransactionApproval>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i6.TransactionApproval>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getApprovalsHistory,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i6.TransactionApproval>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>> getBudgets({
|
||||
String? organizationId,
|
||||
_i7.BudgetStatus? status,
|
||||
int? year,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i7.Budget>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgets,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#status: status,
|
||||
#year: year,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i7.Budget>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> getBudgetById(
|
||||
String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetById,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> createBudget({
|
||||
required String? name,
|
||||
String? description,
|
||||
required String? organizationId,
|
||||
required _i7.BudgetPeriod? period,
|
||||
required int? year,
|
||||
int? month,
|
||||
required List<_i7.BudgetLine>? lines,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createBudget,
|
||||
[],
|
||||
{
|
||||
#name: name,
|
||||
#description: description,
|
||||
#organizationId: organizationId,
|
||||
#period: period,
|
||||
#year: year,
|
||||
#month: month,
|
||||
#lines: lines,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, _i7.Budget>> updateBudget({
|
||||
required String? budgetId,
|
||||
String? name,
|
||||
String? description,
|
||||
List<_i7.BudgetLine>? lines,
|
||||
_i7.BudgetStatus? status,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>.value(
|
||||
_FakeEither_0<_i5.Failure, _i7.Budget>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateBudget,
|
||||
[],
|
||||
{
|
||||
#budgetId: budgetId,
|
||||
#name: name,
|
||||
#description: description,
|
||||
#lines: lines,
|
||||
#status: status,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, _i7.Budget>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, void>> deleteBudget(String? budgetId) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, void>>.value(
|
||||
_FakeEither_0<_i5.Failure, void>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#deleteBudget,
|
||||
[budgetId],
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, void>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getBudgetTracking(
|
||||
{required String? budgetId}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getBudgetTracking,
|
||||
[],
|
||||
{#budgetId: budgetId},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAuditLogs({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
_i8.AuditOperation? operation,
|
||||
_i8.AuditEntityType? entityType,
|
||||
_i8.AuditSeverity? severity,
|
||||
int? limit,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#operation: operation,
|
||||
#entityType: entityType,
|
||||
#severity: severity,
|
||||
#limit: limit,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<
|
||||
_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>> getAnomalies({
|
||||
String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue: _i4
|
||||
.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>.value(
|
||||
_FakeEither_0<_i5.Failure, List<_i8.FinancialAuditLog>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getAnomalies,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, List<_i8.FinancialAuditLog>>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, String>> exportAuditLogs({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
String? format = r'csv',
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
returnValue: _i4.Future<_i2.Either<_i5.Failure, String>>.value(
|
||||
_FakeEither_0<_i5.Failure, String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#exportAuditLogs,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
#format: format,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, String>>);
|
||||
|
||||
@override
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>> getWorkflowStats({
|
||||
required String? organizationId,
|
||||
DateTime? startDate,
|
||||
DateTime? endDate,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>.value(
|
||||
_FakeEither_0<_i5.Failure, Map<String, dynamic>>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getWorkflowStats,
|
||||
[],
|
||||
{
|
||||
#organizationId: organizationId,
|
||||
#startDate: startDate,
|
||||
#endDate: endDate,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i4.Future<_i2.Either<_i5.Failure, Map<String, dynamic>>>);
|
||||
}
|
||||
Reference in New Issue
Block a user