Main coves client
1import 'package:coves_flutter/models/coves_session.dart';
2import 'package:coves_flutter/providers/vote_provider.dart';
3import 'package:flutter/foundation.dart';
4
5/// Mock AuthProvider for testing
6class MockAuthProvider extends ChangeNotifier {
7 bool _isAuthenticated = false;
8 bool _isLoading = false;
9 String? _error;
10 String? _did;
11 String? _handle;
12 CovesSession? _session;
13
14 bool get isAuthenticated => _isAuthenticated;
15 bool get isLoading => _isLoading;
16 String? get error => _error;
17 String? get did => _did;
18 String? get handle => _handle;
19 CovesSession? get session => _session;
20
21 void setAuthenticated({required bool value, String? did}) {
22 _isAuthenticated = value;
23 _did = did ?? 'did:plc:testuser';
24 notifyListeners();
25 }
26
27 Future<void> signIn(String handle) async {
28 _isAuthenticated = true;
29 _handle = handle;
30 _did = 'did:plc:testuser';
31 notifyListeners();
32 }
33
34 Future<void> signOut() async {
35 _isAuthenticated = false;
36 _did = null;
37 _handle = null;
38 _session = null;
39 notifyListeners();
40 }
41
42 Future<void> initialize() async {
43 _isLoading = false;
44 }
45
46 Future<String?> getAccessToken() async {
47 return _isAuthenticated ? 'mock_access_token' : null;
48 }
49
50 void clearError() {
51 _error = null;
52 notifyListeners();
53 }
54}
55
56/// Mock VoteProvider for testing
57class MockVoteProvider extends ChangeNotifier {
58 final Map<String, VoteState> _votes = {};
59 final Map<String, int> _scoreAdjustments = {};
60 final Map<String, bool> _pendingRequests = {};
61
62 bool isLiked(String postUri) {
63 return _votes[postUri]?.direction == 'up' &&
64 !(_votes[postUri]?.deleted ?? false);
65 }
66
67 int getAdjustedScore(String postUri, int originalScore) {
68 final adjustment = _scoreAdjustments[postUri] ?? 0;
69 return originalScore + adjustment;
70 }
71
72 VoteState? getVoteState(String postUri) => _votes[postUri];
73
74 bool isPending(String postUri) => _pendingRequests[postUri] ?? false;
75
76 Future<bool> toggleVote({
77 required String postUri,
78 required String postCid,
79 String direction = 'up',
80 }) async {
81 final currentlyLiked = isLiked(postUri);
82
83 if (currentlyLiked) {
84 // Removing vote
85 _votes[postUri] = VoteState(direction: direction, deleted: true);
86 _scoreAdjustments[postUri] = (_scoreAdjustments[postUri] ?? 0) - 1;
87 } else {
88 // Adding vote
89 _votes[postUri] = VoteState(direction: direction, deleted: false);
90 _scoreAdjustments[postUri] = (_scoreAdjustments[postUri] ?? 0) + 1;
91 }
92
93 notifyListeners();
94 return !currentlyLiked;
95 }
96
97 void setVoteState({required String postUri, required bool liked}) {
98 if (liked) {
99 _votes[postUri] = const VoteState(direction: 'up', deleted: false);
100 } else {
101 _votes.remove(postUri);
102 }
103 notifyListeners();
104 }
105
106 void setInitialVoteState({
107 required String postUri,
108 String? voteDirection,
109 String? voteUri,
110 }) {
111 if (voteDirection != null) {
112 String? rkey;
113 if (voteUri != null) {
114 final parts = voteUri.split('/');
115 if (parts.isNotEmpty) {
116 rkey = parts.last;
117 }
118 }
119
120 _votes[postUri] = VoteState(
121 direction: voteDirection,
122 uri: voteUri,
123 rkey: rkey,
124 deleted: false,
125 );
126
127 _scoreAdjustments.remove(postUri);
128 } else {
129 _votes.remove(postUri);
130 }
131 }
132
133 void clear() {
134 _votes.clear();
135 _pendingRequests.clear();
136 _scoreAdjustments.clear();
137 notifyListeners();
138 }
139}