diff --git a/lib/config/oauth_config.dart b/lib/config/oauth_config.dart index 58e8695..8bb2b5a 100644 --- a/lib/config/oauth_config.dart +++ b/lib/config/oauth_config.dart @@ -30,8 +30,7 @@ class OAuthConfig { // not double! // Correct: dev.workers.example:/oauth/callback // Incorrect: dev.workers.example://oauth/callback - static const String customSchemeCallback = - '$customScheme:/oauth/callback'; + static const String customSchemeCallback = '$customScheme:/oauth/callback'; // HTTPS callback (fallback for PDS that don't support custom // URI schemes) diff --git a/lib/models/post.dart b/lib/models/post.dart index 3a69a6d..8f242a8 100644 --- a/lib/models/post.dart +++ b/lib/models/post.dart @@ -5,7 +5,6 @@ // /xrpc/social.coves.feed.getDiscover class TimelineResponse { - TimelineResponse({required this.feed, this.cursor}); factory TimelineResponse.fromJson(Map json) { @@ -33,7 +32,6 @@ class TimelineResponse { } class FeedViewPost { - FeedViewPost({required this.post, this.reason}); factory FeedViewPost.fromJson(Map json) { @@ -50,7 +48,6 @@ class FeedViewPost { } class PostView { - PostView({ required this.uri, required this.cid, @@ -107,7 +104,6 @@ class PostView { } class AuthorView { - AuthorView({ required this.did, required this.handle, @@ -130,7 +126,6 @@ class AuthorView { } class CommunityRef { - CommunityRef({required this.did, required this.name, this.avatar}); factory CommunityRef.fromJson(Map json) { @@ -146,7 +141,6 @@ class CommunityRef { } class PostStats { - PostStats({ required this.upvotes, required this.downvotes, @@ -169,7 +163,6 @@ class PostStats { } class PostEmbed { - PostEmbed({required this.type, this.external, required this.data}); factory PostEmbed.fromJson(Map json) { @@ -191,7 +184,6 @@ class PostEmbed { } class ExternalEmbed { - ExternalEmbed({ required this.uri, this.title, @@ -217,7 +209,6 @@ class ExternalEmbed { } class PostFacet { - PostFacet({required this.data}); factory PostFacet.fromJson(Map json) { @@ -227,7 +218,6 @@ class PostFacet { } class FeedReason { - FeedReason({required this.type, required this.data}); factory FeedReason.fromJson(Map json) { diff --git a/lib/providers/auth_provider.dart b/lib/providers/auth_provider.dart index 02c5f6d..4891544 100644 --- a/lib/providers/auth_provider.dart +++ b/lib/providers/auth_provider.dart @@ -15,10 +15,9 @@ import '../services/oauth_service.dart'; /// ✅ Tokens are stored securely by the package (iOS Keychain / Android EncryptedSharedPreferences) /// ✅ Automatic token refresh handled by the package class AuthProvider with ChangeNotifier { - /// Constructor with optional OAuthService for dependency injection (testing) AuthProvider({OAuthService? oauthService}) - : _oauthService = oauthService ?? OAuthService(); + : _oauthService = oauthService ?? OAuthService(); final OAuthService _oauthService; // SharedPreferences keys for storing session info diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index cc8540d..458a340 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -181,7 +181,8 @@ class _LoginScreenState extends State { onPressed: () { showDialog( context: context, - builder: (context) => AlertDialog( + builder: + (context) => AlertDialog( backgroundColor: const Color(0xFF1A2028), title: const Text( 'What is a handle?', diff --git a/lib/services/api_exceptions.dart b/lib/services/api_exceptions.dart index ff9fcfe..d05e87f 100644 --- a/lib/services/api_exceptions.dart +++ b/lib/services/api_exceptions.dart @@ -6,7 +6,6 @@ library; /// Base class for all API exceptions class ApiException implements Exception { - ApiException(this.message, {this.statusCode, this.originalError}); final String message; final int? statusCode; @@ -20,14 +19,14 @@ class ApiException implements Exception { /// Token expired, invalid, or missing class AuthenticationException extends ApiException { AuthenticationException(super.message, {super.originalError}) - : super(statusCode: 401); + : super(statusCode: 401); } /// Resource not found (404) /// PDS, community, post, or user not found class NotFoundException extends ApiException { NotFoundException(super.message, {super.originalError}) - : super(statusCode: 404); + : super(statusCode: 404); } /// Server error (500+) @@ -40,12 +39,12 @@ class ServerException extends ApiException { /// No internet, connection refused, timeout class NetworkException extends ApiException { NetworkException(super.message, {super.originalError}) - : super(statusCode: null); + : super(statusCode: null); } /// Federation error /// atProto PDS unreachable or DID resolution failure class FederationException extends ApiException { FederationException(super.message, {super.originalError}) - : super(statusCode: null); + : super(statusCode: null); } diff --git a/lib/services/coves_api_service.dart b/lib/services/coves_api_service.dart index 9c8a0b8..bcd74ce 100644 --- a/lib/services/coves_api_service.dart +++ b/lib/services/coves_api_service.dart @@ -15,7 +15,6 @@ import 'api_exceptions.dart'; /// rotates tokens automatically (~1 hour expiry), and caching tokens would /// cause 401 errors after the first token expires. class CovesApiService { - CovesApiService({Future Function()? tokenGetter}) : _tokenGetter = tokenGetter { _dio = Dio( @@ -264,10 +263,7 @@ class CovesApiService { case DioExceptionType.cancel: throw ApiException('Request cancelled', originalError: e); default: - throw ApiException( - 'Unknown error: ${e.message}', - originalError: e, - ); + throw ApiException('Unknown error: ${e.message}', originalError: e); } } diff --git a/lib/services/pds_discovery_service.dart b/lib/services/pds_discovery_service.dart index cd2ed99..ca47409 100644 --- a/lib/services/pds_discovery_service.dart +++ b/lib/services/pds_discovery_service.dart @@ -68,8 +68,7 @@ class PDSDiscoveryService { /// Fetch a DID document from the PLC directory Future> _fetchDIDDocument(String did) async { try { - final response = - await _dio.get('https://plc.directory/$did'); + final response = await _dio.get('https://plc.directory/$did'); if (response.statusCode != 200) { throw Exception('Failed to fetch DID document: ${response.statusCode}'); diff --git a/lib/widgets/logo.dart b/lib/widgets/logo.dart index a91dafd..5e8d646 100644 --- a/lib/widgets/logo.dart +++ b/lib/widgets/logo.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class CovesLogo extends StatelessWidget { - const CovesLogo({super.key, this.size = 150, this.useColorVersion = false}); final double size; final bool useColorVersion; diff --git a/lib/widgets/primary_button.dart b/lib/widgets/primary_button.dart index 9e66d4b..28abdaf 100644 --- a/lib/widgets/primary_button.dart +++ b/lib/widgets/primary_button.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; enum ButtonVariant { solid, outline, tertiary } class PrimaryButton extends StatelessWidget { - const PrimaryButton({ super.key, required this.title, diff --git a/test/providers/auth_provider_test.dart b/test/providers/auth_provider_test.dart index 0606758..3fde196 100644 --- a/test/providers/auth_provider_test.dart +++ b/test/providers/auth_provider_test.dart @@ -10,7 +10,6 @@ import 'auth_provider_test.mocks.dart'; // Generate mocks for OAuthService and OAuthSession only @GenerateMocks([OAuthService, OAuthSession]) - void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -206,22 +205,18 @@ void main() { // that are not exported from atproto_oauth_flutter package. // These tests would need integration testing or a different approach. - test( - 'should return null when not authenticated ' - '(skipped - needs integration test)', - () async { + test('should return null when not authenticated ' + '(skipped - needs integration test)', () async { // This test is skipped as it requires mocking internal OAuth classes // that cannot be mocked with mockito - }, skip: true,); + }, skip: true); - test( - 'should sign out user if token refresh fails ' - '(skipped - needs integration test)', - () async { + test('should sign out user if token refresh fails ' + '(skipped - needs integration test)', () async { // This test demonstrates the critical fix for issue #7 // Token refresh failure should trigger sign out // Skipped as it requires mocking internal OAuth classes - }, skip: true,); + }, skip: true); }); group('State Management', () {