diff --git a/lib/src/network_response.dart b/lib/src/network_response.dart index 0479c2a..48e6967 100644 --- a/lib/src/network_response.dart +++ b/lib/src/network_response.dart @@ -20,12 +20,18 @@ sealed class NetworkResponseSuccess extends NetworkResponse { final class OkNoContent extends NetworkResponseSuccess { const OkNoContent(); + + @override + String toString() => 'OkNoContent()'; } final class OkResponse extends NetworkResponseSuccess { final T response; const OkResponse(this.response); + + @override + String toString() => 'OkResponse(response: $response)'; } sealed class NetworkResponseFailure extends NetworkResponse { @@ -37,6 +43,9 @@ final class Unauthorized extends NetworkResponseFailure { final DioException error; const Unauthorized({required this.error}); + + @override + String toString() => 'Unauthorized(error: $error)'; } /// 403 - for responses when the request was authenticated but the @@ -45,6 +54,9 @@ final class Forbidden extends NetworkResponseFailure { final DioException error; const Forbidden({required this.error}); + + @override + String toString() => 'Forbidden(error: $error)'; } /// 404 - for responses when we could not locate a resource, or when @@ -53,6 +65,9 @@ final class NotFound extends NetworkResponseFailure { final DioException error; const NotFound({required this.error}); + + @override + String toString() => 'NotFound(error: $error)'; } /// 422 - for responses when the request inputs failed our validations. @@ -61,6 +76,10 @@ final class UnprocessableEntity extends NetworkResponseFailure { final R response; const UnprocessableEntity({required this.error, required this.response}); + + @override + String toString() => + 'UnprocessableEntity(error: $error, response: $response)'; } /// 426 - for responses when a client version upgrade is required @@ -68,6 +87,9 @@ final class UpgradeRequired extends NetworkResponseFailure { final DioException error; const UpgradeRequired({required this.error}); + + @override + String toString() => 'UpgradeRequired(error: $error)'; } /// 500 - for responses where the service had an error while processing @@ -76,6 +98,9 @@ final class ServerError extends NetworkResponseFailure { final DioException error; const ServerError({required this.error}); + + @override + String toString() => 'ServerError(error: $error)'; } /// 503 - for responses when an underlying service issue prevents us from @@ -84,6 +109,9 @@ final class ServiceUnavailable extends NetworkResponseFailure { final DioException error; const ServiceUnavailable({required this.error}); + + @override + String toString() => 'ServiceUnavailable(error: $error)'; } /// Any "other" error not covered by the above cases. If a [DioException] is present, @@ -99,6 +127,10 @@ final class GenericError extends NetworkResponseFailure { final DioException? error; final String message; final bool isConnectionIssue; + + @override + String toString() => + 'GenericError(error: $error, message: $message, isConnectionIssue: $isConnectionIssue)'; } /// Extensions on the [NetworkResponse] type diff --git a/test/src/network_response_test.dart b/test/src/network_response_test.dart new file mode 100644 index 0000000..4cad818 --- /dev/null +++ b/test/src/network_response_test.dart @@ -0,0 +1,125 @@ +import 'package:dio/dio.dart'; +import 'package:sturdy_http/sturdy_http.dart'; +import 'package:test/test.dart'; + +void main() { + group('NetworkResponse toString', () { + group('success types', () { + test('OkNoContent', () { + const response = OkNoContent(); + + expect(response.toString(), 'OkNoContent()'); + }); + + test('OkResponse', () { + const response = OkResponse('success data'); + + expect(response.toString(), 'OkResponse(response: success data)'); + }); + }); + + group('failure types', () { + late DioException dioException; + + setUp(() { + dioException = DioException( + requestOptions: RequestOptions(path: '/test'), + message: 'Test error message', + type: DioExceptionType.badResponse, + ); + }); + + test('Unauthorized', () { + final response = Unauthorized(error: dioException); + + expect( + response.toString(), + 'Unauthorized(error: DioException [bad response]: Test error message)', + ); + }); + + test('Forbidden', () { + final response = Forbidden(error: dioException); + + expect( + response.toString(), + 'Forbidden(error: DioException [bad response]: Test error message)', + ); + }); + + test('NotFound', () { + final response = NotFound(error: dioException); + + expect( + response.toString(), + 'NotFound(error: DioException [bad response]: Test error message)', + ); + }); + + test('UnprocessableEntity', () { + final response = UnprocessableEntity>( + error: dioException, + response: {'field': 'email', 'message': 'is invalid'}, + ); + + expect( + response.toString(), + 'UnprocessableEntity(error: DioException [bad response]: Test error message, response: {field: email, message: is invalid})', + ); + }); + + test('UpgradeRequired', () { + final response = UpgradeRequired(error: dioException); + + expect( + response.toString(), + 'UpgradeRequired(error: DioException [bad response]: Test error message)', + ); + }); + + test('ServerError', () { + final response = ServerError(error: dioException); + + expect( + response.toString(), + 'ServerError(error: DioException [bad response]: Test error message)', + ); + }); + + test('ServiceUnavailable', () { + final response = ServiceUnavailable(error: dioException); + + expect( + response.toString(), + 'ServiceUnavailable(error: DioException [bad response]: Test error message)', + ); + }); + + test('GenericError', () { + final response = GenericError( + error: dioException, + message: 'Something went wrong', + isConnectionIssue: false, + ); + + expect( + response.toString(), + 'GenericError(error: DioException [bad response]: Test error message, message: Something went wrong, isConnectionIssue: false)', + ); + }); + + test('GenericError with null error', () { + const response = GenericError( + error: null, + message: 'Connection timeout', + isConnectionIssue: true, + ); + + expect( + response.toString(), + 'GenericError(error: null, message: Connection timeout, isConnectionIssue: true)', + ); + }); + }); + }); +}