at main 5.9 kB view raw
1import 'package:coves_flutter/services/api_exceptions.dart'; 2import 'package:coves_flutter/services/vote_service.dart'; 3import 'package:dio/dio.dart'; 4import 'package:flutter_test/flutter_test.dart'; 5 6void main() { 7 group('VoteService', () { 8 group('VoteResponse', () { 9 test('should create response with uri, cid, and rkey', () { 10 const response = VoteResponse( 11 uri: 'at://did:plc:test/social.coves.feed.vote/123', 12 cid: 'bafy123', 13 rkey: '123', 14 deleted: false, 15 ); 16 17 expect(response.uri, 'at://did:plc:test/social.coves.feed.vote/123'); 18 expect(response.cid, 'bafy123'); 19 expect(response.rkey, '123'); 20 expect(response.deleted, false); 21 }); 22 23 test('should create deleted response', () { 24 const response = VoteResponse(deleted: true); 25 26 expect(response.deleted, true); 27 expect(response.uri, null); 28 expect(response.cid, null); 29 expect(response.rkey, null); 30 }); 31 }); 32 33 group('API Exception handling', () { 34 test('should throw ApiException on Dio network error', () { 35 final dioError = DioException( 36 requestOptions: RequestOptions(path: '/test'), 37 type: DioExceptionType.connectionError, 38 ); 39 40 final exception = ApiException.fromDioError(dioError); 41 42 expect(exception, isA<NetworkException>()); 43 expect(exception.message, contains('Connection failed')); 44 }); 45 46 test('should throw ApiException on Dio timeout', () { 47 final dioError = DioException( 48 requestOptions: RequestOptions(path: '/test'), 49 type: DioExceptionType.connectionTimeout, 50 ); 51 52 final exception = ApiException.fromDioError(dioError); 53 54 expect(exception, isA<NetworkException>()); 55 expect(exception.message, contains('timeout')); 56 }); 57 58 test('should throw AuthenticationException on 401 response', () { 59 final dioError = DioException( 60 requestOptions: RequestOptions(path: '/test'), 61 type: DioExceptionType.badResponse, 62 response: Response( 63 requestOptions: RequestOptions(path: '/test'), 64 statusCode: 401, 65 data: {'message': 'Unauthorized'}, 66 ), 67 ); 68 69 final exception = ApiException.fromDioError(dioError); 70 71 expect(exception, isA<AuthenticationException>()); 72 expect(exception.statusCode, 401); 73 expect(exception.message, 'Unauthorized'); 74 }); 75 76 test('should throw NotFoundException on 404 response', () { 77 final dioError = DioException( 78 requestOptions: RequestOptions(path: '/test'), 79 type: DioExceptionType.badResponse, 80 response: Response( 81 requestOptions: RequestOptions(path: '/test'), 82 statusCode: 404, 83 data: {'message': 'Post not found'}, 84 ), 85 ); 86 87 final exception = ApiException.fromDioError(dioError); 88 89 expect(exception, isA<NotFoundException>()); 90 expect(exception.statusCode, 404); 91 expect(exception.message, 'Post not found'); 92 }); 93 94 test('should throw ServerException on 500 response', () { 95 final dioError = DioException( 96 requestOptions: RequestOptions(path: '/test'), 97 type: DioExceptionType.badResponse, 98 response: Response( 99 requestOptions: RequestOptions(path: '/test'), 100 statusCode: 500, 101 data: {'error': 'Internal server error'}, 102 ), 103 ); 104 105 final exception = ApiException.fromDioError(dioError); 106 107 expect(exception, isA<ServerException>()); 108 expect(exception.statusCode, 500); 109 expect(exception.message, 'Internal server error'); 110 }); 111 112 test('should extract error message from response data', () { 113 final dioError = DioException( 114 requestOptions: RequestOptions(path: '/test'), 115 type: DioExceptionType.badResponse, 116 response: Response( 117 requestOptions: RequestOptions(path: '/test'), 118 statusCode: 400, 119 data: {'message': 'Invalid post URI'}, 120 ), 121 ); 122 123 final exception = ApiException.fromDioError(dioError); 124 125 expect(exception.message, 'Invalid post URI'); 126 expect(exception.statusCode, 400); 127 }); 128 129 test('should use default message if no error message in response', () { 130 final dioError = DioException( 131 requestOptions: RequestOptions(path: '/test'), 132 type: DioExceptionType.badResponse, 133 response: Response( 134 requestOptions: RequestOptions(path: '/test'), 135 statusCode: 400, 136 data: {}, 137 ), 138 ); 139 140 final exception = ApiException.fromDioError(dioError); 141 142 expect(exception.message, 'Server error'); 143 }); 144 145 test('should handle cancelled requests', () { 146 final dioError = DioException( 147 requestOptions: RequestOptions(path: '/test'), 148 type: DioExceptionType.cancel, 149 ); 150 151 final exception = ApiException.fromDioError(dioError); 152 153 expect(exception.message, contains('cancelled')); 154 }); 155 156 test('should handle bad certificate errors', () { 157 final dioError = DioException( 158 requestOptions: RequestOptions(path: '/test'), 159 type: DioExceptionType.badCertificate, 160 ); 161 162 final exception = ApiException.fromDioError(dioError); 163 164 expect(exception, isA<NetworkException>()); 165 expect(exception.message, contains('certificate')); 166 }); 167 168 test('should handle unknown errors', () { 169 final dioError = DioException( 170 requestOptions: RequestOptions(path: '/test'), 171 ); 172 173 final exception = ApiException.fromDioError(dioError); 174 175 expect(exception, isA<NetworkException>()); 176 expect(exception.message, contains('Network error')); 177 }); 178 }); 179 }); 180}