Skip to content

Commit 1a47789

Browse files
authored
Merge pull request #46 from shadowfish07/test/add
fix: 增加一些单测,修复一些问题
2 parents 5979b73 + 1ce48cd commit 1a47789

File tree

8 files changed

+509
-71
lines changed

8 files changed

+509
-71
lines changed

codecov.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
coverage:
2+
status:
3+
project:
4+
default:
5+
informational: true
6+
patch:
7+
default:
8+
informational: true

lib/data/repository/bookmark/bookmark_repository.dart

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,122 +29,155 @@ class BookmarkRepository {
2929
/// 添加数据变化监听器
3030
void addListener(BookmarkChangeListener listener) {
3131
_listeners.add(listener);
32+
appLogger.d('添加书签数据变化监听器,当前监听器数量: ${_listeners.length}');
3233
}
3334

3435
/// 移除数据变化监听器
3536
void removeListener(BookmarkChangeListener listener) {
3637
_listeners.remove(listener);
38+
appLogger.d('移除书签数据变化监听器,当前监听器数量: ${_listeners.length}');
3739
}
3840

3941
/// 通知所有监听器数据已变化
4042
void _notifyListeners() {
43+
appLogger.d('通知 ${_listeners.length} 个监听器书签数据已变化');
4144
for (final listener in _listeners) {
4245
listener();
4346
}
4447
}
4548

4649
/// 插入或更新单个书签到缓存
47-
void insertOrUpdateBookmark(Bookmark bookmark) {
50+
void _insertOrUpdateBookmark(Bookmark bookmark, {bool batch = false}) {
4851
final index = _bookmarks.indexWhere((b) => b.id == bookmark.id);
4952
if (index != -1) {
5053
_bookmarks[index] = bookmark;
5154
} else {
5255
_bookmarks.add(bookmark);
5356
}
54-
_notifyListeners();
57+
if (!batch) {
58+
_notifyListeners();
59+
}
5560
}
5661

5762
/// 批量插入或更新书签到缓存
5863
void _insertOrUpdateCachedBookmarks(List<Bookmark> bookmarks) {
64+
appLogger.i('批量更新缓存书签,数量: ${bookmarks.length}');
5965
for (var bookmark in bookmarks) {
60-
insertOrUpdateBookmark(bookmark);
66+
_insertOrUpdateBookmark(bookmark, batch: true);
6167
}
68+
_notifyListeners();
6269
}
6370

6471
/// 从缓存获取单个书签
6572
Bookmark? getCachedBookmark(String id) {
66-
return _bookmarks.where((b) => b.id == id).firstOrNull;
73+
final bookmark = _bookmarks.where((b) => b.id == id).firstOrNull;
74+
return bookmark;
6775
}
6876

6977
/// 从缓存获取多个书签
7078
List<Bookmark?> getCachedBookmarks(List<String> ids) {
71-
return ids.map((id) => getCachedBookmark(id)).toList();
79+
appLogger.d('从缓存批量获取书签,请求数量: ${ids.length}');
80+
final result = ids.map((id) => getCachedBookmark(id)).toList();
81+
final foundCount = result.where((b) => b != null).length;
82+
appLogger.d('批量获取书签完成,找到: $foundCount/${ids.length}');
83+
return result;
7284
}
7385

7486
/// 从缓存删除书签
7587
void _deleteCachedBookmark(String id) {
88+
final removedCount = _bookmarks.length;
7689
_bookmarks.removeWhere((b) => b.id == id);
90+
final actualRemovedCount = removedCount - _bookmarks.length;
91+
appLogger.i('从缓存删除书签: $id, 删除数量: $actualRemovedCount');
7792
_notifyListeners();
7893
}
7994

8095
/// 释放资源,清空所有监听器
8196
void dispose() {
97+
appLogger.i('释放 BookmarkRepository 资源,清空 ${_listeners.length} 个监听器');
8298
_listeners.clear();
8399
}
84100

85101
AsyncResult<List<Bookmark>> loadBookmarksByIds(List<String> ids) async {
102+
appLogger.i('开始根据ID加载书签,数量: ${ids.length}');
86103
final result = await _readeckApiClient.getBookmarks(ids: ids);
87104
if (result.isSuccess()) {
88-
_insertOrUpdateCachedBookmarks(result.getOrThrow());
105+
final bookmarks = result.getOrThrow();
106+
appLogger.i('成功加载书签 ${bookmarks.length} 个');
107+
_insertOrUpdateCachedBookmarks(bookmarks);
89108
return result;
90109
}
91110

111+
appLogger.e('根据ID加载书签失败', error: result.exceptionOrNull());
92112
return result;
93113
}
94114

95115
AsyncResult<List<Bookmark>> loadUnarchivedBookmarks({
96116
int limit = 10,
97117
int page = 1,
98118
}) async {
119+
appLogger.i('开始加载未归档书签,页码: $page, 限制: $limit');
99120
final result = await _readeckApiClient.getBookmarks(
100121
isArchived: false,
101122
limit: limit,
102123
offset: (page - 1) * limit,
103124
);
104125
if (result.isSuccess()) {
105-
_insertOrUpdateCachedBookmarks(result.getOrThrow());
126+
final bookmarks = result.getOrThrow();
127+
appLogger.i('成功加载未归档书签 ${bookmarks.length} 个');
128+
_insertOrUpdateCachedBookmarks(bookmarks);
106129
return result;
107130
}
108131

132+
appLogger.e('加载未归档书签失败', error: result.exceptionOrNull());
109133
return result;
110134
}
111135

112136
AsyncResult<List<Bookmark>> loadArchivedBookmarks({
113137
int limit = 10,
114138
int page = 1,
115139
}) async {
140+
appLogger.i('开始加载已归档书签,页码: $page, 限制: $limit');
116141
final result = await _readeckApiClient.getBookmarks(
117142
isArchived: true,
118143
limit: limit,
119144
offset: (page - 1) * limit,
120145
);
121146
if (result.isSuccess()) {
122-
_insertOrUpdateCachedBookmarks(result.getOrThrow());
147+
final bookmarks = result.getOrThrow();
148+
appLogger.i('成功加载已归档书签 ${bookmarks.length} 个');
149+
_insertOrUpdateCachedBookmarks(bookmarks);
123150
return result;
124151
}
125152

153+
appLogger.e('加载已归档书签失败', error: result.exceptionOrNull());
126154
return result;
127155
}
128156

129157
AsyncResult<List<Bookmark>> loadMarkedBookmarks({
130158
int limit = 10,
131159
int page = 1,
132160
}) async {
161+
appLogger.i('开始加载已标记书签,页码: $page, 限制: $limit');
133162
final result = await _readeckApiClient.getBookmarks(
134163
isMarked: true,
135164
limit: limit,
136165
offset: (page - 1) * limit,
137166
);
138167
if (result.isSuccess()) {
139-
_insertOrUpdateCachedBookmarks(result.getOrThrow());
168+
final bookmarks = result.getOrThrow();
169+
appLogger.i('成功加载已标记书签 ${bookmarks.length} 个');
170+
_insertOrUpdateCachedBookmarks(bookmarks);
140171
return result;
141172
}
142173

174+
appLogger.e('加载已标记书签失败', error: result.exceptionOrNull());
143175
return result;
144176
}
145177

146178
AsyncResult<List<Bookmark>> loadRandomUnarchivedBookmarks(
147179
int randomCount) async {
180+
appLogger.i('开始加载随机未归档书签,请求数量: $randomCount');
148181
final allBookmarks = await loadUnarchivedBookmarks(limit: 100);
149182

150183
if (allBookmarks.isSuccess()) {
@@ -153,63 +186,85 @@ class BookmarkRepository {
153186
// 随机打乱并取前5个
154187
final shuffled = List<Bookmark>.from(allBookmarks.getOrDefault([]));
155188
shuffled.shuffle(Random());
189+
final randomBookmarks = shuffled.take(5).toList();
156190

157-
return Success(shuffled.take(5).toList());
191+
appLogger.i('成功获取随机未归档书签 ${randomBookmarks.length} 个');
192+
return Success(randomBookmarks);
158193
}
159194

160195
appLogger.w('获取所有未读书签失败: $allBookmarks');
161196
return allBookmarks;
162197
}
163198

164199
AsyncResult<void> toggleMarked(Bookmark bookmark) async {
200+
final newMarkedState = !bookmark.isMarked;
201+
appLogger
202+
.i('切换书签标记状态: ${bookmark.id}, ${bookmark.isMarked} -> $newMarkedState');
165203
final result = await _readeckApiClient.updateBookmark(
166204
bookmark.id,
167-
isMarked: !bookmark.isMarked,
205+
isMarked: newMarkedState,
168206
);
169207
if (result.isSuccess()) {
170-
insertOrUpdateBookmark(bookmark.copyWith(isMarked: !bookmark.isMarked));
208+
_insertOrUpdateBookmark(bookmark.copyWith(isMarked: newMarkedState));
209+
appLogger.i('书签标记状态切换成功: ${bookmark.id}');
210+
} else {
211+
appLogger.e('书签标记状态切换失败: ${bookmark.id}',
212+
error: result.exceptionOrNull());
171213
}
172214
return result;
173215
}
174216

175217
AsyncResult<void> toggleArchived(Bookmark bookmark) async {
218+
final newArchivedState = !bookmark.isArchived;
219+
appLogger.i(
220+
'切换书签归档状态: ${bookmark.id}, ${bookmark.isArchived} -> $newArchivedState');
176221
final result = await _readeckApiClient.updateBookmark(
177222
bookmark.id,
178-
isArchived: !bookmark.isArchived,
223+
isArchived: newArchivedState,
179224
);
180225
if (result.isSuccess()) {
181-
insertOrUpdateBookmark(
182-
bookmark.copyWith(isArchived: !bookmark.isArchived));
226+
_insertOrUpdateBookmark(bookmark.copyWith(isArchived: newArchivedState));
227+
appLogger.i('书签归档状态切换成功: ${bookmark.id}');
228+
} else {
229+
appLogger.e('书签归档状态切换失败: ${bookmark.id}',
230+
error: result.exceptionOrNull());
183231
}
184232
return result;
185233
}
186234

187235
AsyncResult<void> updateLabels(Bookmark bookmark, List<String> labels) async {
236+
appLogger.i('更新书签标签: ${bookmark.id}, 标签: ${labels.join(", ")}');
188237
final result = await _readeckApiClient.updateBookmark(
189238
bookmark.id,
190239
labels: labels,
191240
);
192241

193242
if (result.isSuccess()) {
194-
insertOrUpdateBookmark(bookmark.copyWith(labels: labels));
243+
_insertOrUpdateBookmark(bookmark.copyWith(labels: labels));
244+
appLogger.i('书签标签更新成功: ${bookmark.id}');
195245
return const Success(unit);
196246
}
197247

248+
appLogger.e('书签标签更新失败: ${bookmark.id}', error: result.exceptionOrNull());
198249
return Failure(result.exceptionOrNull()!);
199250
}
200251

201252
AsyncResult<void> updateReadProgress(
202253
Bookmark bookmark, int readProgress) async {
254+
appLogger.i(
255+
'更新书签阅读进度: ${bookmark.id}, 进度: ${bookmark.readProgress} -> $readProgress');
203256
final result = await _readeckApiClient.updateBookmark(
204257
bookmark.id,
205258
readProgress: readProgress,
206259
);
207260

208261
if (result.isSuccess()) {
209-
insertOrUpdateBookmark(bookmark.copyWith(readProgress: readProgress));
262+
_insertOrUpdateBookmark(bookmark.copyWith(readProgress: readProgress));
263+
appLogger.i('书签阅读进度更新成功: ${bookmark.id}');
210264
return const Success(unit);
211265
}
212266

267+
appLogger.e('书签阅读进度更新失败: ${bookmark.id}', error: result.exceptionOrNull());
213268
return Failure(result.exceptionOrNull()!);
214269
}
215270

@@ -262,10 +317,14 @@ class BookmarkRepository {
262317

263318
/// 删除书签
264319
AsyncResult<void> deleteBookmark(String bookmarkId) async {
320+
appLogger.i('开始删除书签: $bookmarkId');
265321
final result = await _readeckApiClient.deleteBookmark(bookmarkId);
266322
if (result.isSuccess()) {
267323
_deleteCachedBookmark(bookmarkId);
268324
await _databaseService.deleteBookmarkArticle(bookmarkId);
325+
appLogger.i('书签删除成功: $bookmarkId');
326+
} else {
327+
appLogger.e('书签删除失败: $bookmarkId', error: result.exceptionOrNull());
269328
}
270329
return result;
271330
}

lib/data/service/readeck_api_client.dart

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import 'package:readeck_app/utils/resource_not_found_exception.dart';
1111
import 'package:result_dart/result_dart.dart';
1212

1313
class ReadeckApiClient {
14-
ReadeckApiClient(this._host, this._token);
14+
ReadeckApiClient(this._host, this._token, {http.Client? httpClient})
15+
: _httpClient = httpClient ?? http.Client();
1516

17+
final http.Client _httpClient;
1618
String? _host;
1719
String? _token;
1820

@@ -22,8 +24,13 @@ class ReadeckApiClient {
2224
_token = token;
2325
}
2426

27+
/// 释放资源
28+
void dispose() {
29+
_httpClient.close();
30+
}
31+
2532
bool get _isConfigured =>
26-
(_host != null && _host != '') || (_token != null && _token != '');
33+
(_host != null && _host != '') && (_token != null && _token != '');
2734

2835
Map<String, String> get _headers => {
2936
'Authorization': 'Bearer $_token',
@@ -127,7 +134,7 @@ class ReadeckApiClient {
127134
final uri = Uri.parse('$_host/api/bookmarks$queryString');
128135

129136
try {
130-
final response = await http.get(uri, headers: _headers);
137+
final response = await _httpClient.get(uri, headers: _headers);
131138

132139
if (response.statusCode == 200) {
133140
// 检查响应体是否为空或无效
@@ -226,7 +233,7 @@ class ReadeckApiClient {
226233
Uri.parse('$_host/api/bookmarks/${Uri.encodeComponent(bookmarkId)}');
227234

228235
try {
229-
final response = await http.patch(
236+
final response = await _httpClient.patch(
230237
uri,
231238
headers: _headers,
232239
body: json.encode(requestBody),
@@ -277,7 +284,7 @@ class ReadeckApiClient {
277284
final uri = Uri.parse('$_host/api/bookmarks/labels');
278285

279286
try {
280-
final response = await http.get(uri, headers: _headers);
287+
final response = await _httpClient.get(uri, headers: _headers);
281288

282289
if (response.statusCode == 200) {
283290
// 检查响应体是否为空或无效
@@ -334,7 +341,7 @@ class ReadeckApiClient {
334341
'$_host/api/bookmarks/${Uri.encodeComponent(bookmarkId)}/article');
335342

336343
try {
337-
final response = await http.get(uri, headers: {
344+
final response = await _httpClient.get(uri, headers: {
338345
'Authorization': 'Bearer $_token',
339346
'Accept': 'text/html',
340347
});
@@ -381,7 +388,7 @@ class ReadeckApiClient {
381388
Uri.parse('$_host/api/bookmarks/${Uri.encodeComponent(bookmarkId)}');
382389

383390
try {
384-
final response = await http.delete(uri, headers: _headers);
391+
final response = await _httpClient.delete(uri, headers: _headers);
385392

386393
if (response.statusCode == 204) {
387394
appLogger.i('deleteBookmark success for bookmark: $bookmarkId');

lib/domain/use_cases/bookmark_operation_use_cases.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class BookmarkOperationUseCases {
8686
await _sharedPreferencesService.getReadingStats(bookmark.id);
8787
if (cachedStatsResult.isSuccess() &&
8888
cachedStatsResult.getOrNull() != null) {
89-
appLogger.i('从缓存加载书签 ${bookmark.id} 的阅读统计数据');
89+
appLogger.d('从缓存加载书签 ${bookmark.id} 的阅读统计数据');
9090
return cachedStatsResult.getOrNull()!;
9191
}
9292

0 commit comments

Comments
 (0)