import 'package:dio/dio.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:http_mock_adapter/http_mock_adapter.dart'; import 'package:jmap_dart_client/http/http_client.dart'; import 'package:jmap_dart_client/jmap/core/error/set_error.dart'; import 'package:jmap_dart_client/jmap/core/filter/filter.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/method/response/set_response.dart'; import 'package:jmap_dart_client/jmap/core/state.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart'; import 'package:model/error_type_handler/set_method_error_handler_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/mail_api_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/session_mixin.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'; import '../../../fixtures/account_fixtures.dart'; import '../../../fixtures/session_fixtures.dart'; class TestMailApiMixin with HandleSetErrorMixin, SessionMixin, MailAPIMixin { @override void handleSetErrors({ SetMethodErrors? notDestroyedError, SetMethodErrors? notUpdatedError, SetMethodErrors? notCreatedError, Set? notDestroyedHandlers, Set? notUpdatedHandlers, Set? notCreatedHandlers, SetMethodErrorHandler? unCatchErrorHandler, }) {} @override Map handleSetResponse(List listSetResponse) { throw UnimplementedError(); } @override parseErrorForSetResponse(SetResponse? response, Id requestId) { throw UnimplementedError(); } } void main() { final baseOption = BaseOptions(method: 'POST'); final dio = Dio(baseOption)..options.baseUrl = 'http://domain.com/jmap'; late DioAdapter dioAdapter; late HttpClient httpClient; late TestMailApiMixin testMailApiMixin; final sessionState = State('some-session-state'); final state = State('some-state'); final filter = EmailFilterCondition(text: 'some-text'); final queryState = State('some-query-state'); setUp(() { dioAdapter = DioAdapter(dio: dio); httpClient = HttpClient(dio); testMailApiMixin = TestMailApiMixin(); }); group('mail api mixin test:', () { group('fetchAllEmail:', () { Map generateRequest({ required Filter filter, int? position, }) => { "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:apache:james:params:jmap:mail:shares", ], "methodCalls": [ [ "Email/query", { "accountId": AccountFixtures.aliceAccountId.id.value, if (position != null) "position": position, "filter": filter.toJson(), }, "c0" ], [ "Email/get", { "accountId": AccountFixtures.aliceAccountId.id.value, "#ids": { "resultOf": "c0", "name": "Email/query", "path": "/ids/*" }, }, "c1" ] ] }; Map generateResponse({ required List foundEmails, required List notFoundEmailIds, }) => { "sessionState": sessionState.value, "methodResponses": [ [ "Email/query", { "accountId": AccountFixtures.aliceAccountId.id.value, "ids": foundEmails.map((email) => email.id?.id.value).toList() ..addAll( notFoundEmailIds.map((emailId) => emailId.id.value)), "queryState": queryState.value, "canCalculateChanges": true, "position": 0, }, "c0" ], [ "Email/get", { "accountId": AccountFixtures.aliceAccountId.id.value, "state": state.value, "list": foundEmails.map((email) => email.toJson()).toList(), "notFound": notFoundEmailIds .map((emailId) => emailId.id.value) .toList(), }, "c1" ] ] }; test( 'should not add position to request ' 'when position is null', () async { // arrange final email = Email( id: EmailId(Id('someEmailId')), ); dioAdapter.onPost( '', (server) => server.reply( 200, generateResponse( foundEmails: [email], notFoundEmailIds: [], ), ), data: generateRequest(filter: filter), ); // act final result = await testMailApiMixin.fetchAllEmail( session: SessionFixtures.aliceSession, accountId: AccountFixtures.aliceAccountId, httpClient: httpClient, filter: filter, ); // assert expect( result, equals( EmailsResponse( emailList: [email], state: state, notFoundEmailIds: [], ), ), ); }, ); test( 'should not add position to request ' 'when position is 0', () async { // arrange final email = Email( id: EmailId(Id('someEmailId')), ); dioAdapter.onPost( '', (server) => server.reply( 403, generateResponse( foundEmails: [email], notFoundEmailIds: [], ), ), data: generateRequest(filter: filter, position: 0), ); // act & assert expect( () => testMailApiMixin.fetchAllEmail( session: SessionFixtures.aliceSession, accountId: AccountFixtures.aliceAccountId, httpClient: httpClient, filter: filter, position: 0, ), throwsA(isA()), ); }, ); test( 'should add position to request ' 'when position > 0', () async { // arrange final email = Email( id: EmailId(Id('someEmailId')), ); dioAdapter.onPost( '', (server) => server.reply( 200, generateResponse( foundEmails: [email], notFoundEmailIds: [], ), ), data: generateRequest(filter: filter, position: 1), ); // act final result = await testMailApiMixin.fetchAllEmail( session: SessionFixtures.aliceSession, accountId: AccountFixtures.aliceAccountId, httpClient: httpClient, filter: filter, position: 1, ); // assert expect( result, equals( EmailsResponse( emailList: [email], state: state, notFoundEmailIds: [], ), ), ); }, ); }); }); }