feat: implement cross-platform features and UI integration

- iOS: Add BackgroundSyncService, SyncScheduler, SyncWorker, BookmarkViewModel, FeedViewModel
- iOS: Add BackgroundSyncService, SyncScheduler, SyncWorker services
- Linux: Add settings-store.vala, State.vala signals, view widgets (FeedList, FeedDetail, AddFeed, Search, Settings, Bookmark)
- Linux: Add bookmark-store.vala, bookmark vala model, search-service.vala
- Android: Add NotificationService, NotificationManager, NotificationPreferencesStore
- Android: Add BookmarkDao, BookmarkRepository, SettingsStore
- Add unit tests for iOS, Android, Linux
- Add integration tests
- Add performance benchmarks
- Update tasks and documentation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-03-30 23:06:12 -04:00
parent 6191458730
commit 14efe072fa
98 changed files with 11262 additions and 109 deletions

View File

@@ -0,0 +1,247 @@
/*
* RepositoryTests.vala
*
* Unit tests for repository layer.
*/
public class RSSuper.RepositoryTests {
public static int main(string[] args) {
var tests = new RepositoryTests();
tests.test_bookmark_repository_create();
tests.test_bookmark_repository_read();
tests.test_bookmark_repository_update();
tests.test_bookmark_repository_delete();
tests.test_bookmark_repository_tags();
tests.test_bookmark_repository_by_feed_item();
print("All repository tests passed!\n");
return 0;
}
public void test_bookmark_repository_create() {
// Create a test database
var db = new Database(":memory:");
// Create bookmark repository
var repo = new BookmarkRepositoryImpl(db);
// Create a test bookmark
var bookmark = Bookmark.new_internal(
id: "test-bookmark-1",
feed_item_id: "test-item-1",
created_at: Time.now()
);
// Test creation
var result = repo.add(bookmark);
if (result.is_error()) {
printerr("FAIL: Bookmark creation failed: %s\n", result.error.message);
return;
}
print("PASS: test_bookmark_repository_create\n");
}
public void test_bookmark_repository_read() {
// Create a test database
var db = new Database(":memory:");
// Create bookmark repository
var repo = new BookmarkRepositoryImpl(db);
// Create a test bookmark
var bookmark = Bookmark.new_internal(
id: "test-bookmark-2",
feed_item_id: "test-item-2",
created_at: Time.now()
);
var create_result = repo.add(bookmark);
if (create_result.is_error()) {
printerr("FAIL: Could not create bookmark: %s\n", create_result.error.message);
return;
}
// Test reading
var read_result = repo.get_by_id("test-bookmark-2");
if (read_result.is_error()) {
printerr("FAIL: Bookmark read failed: %s\n", read_result.error.message);
return;
}
var saved = read_result.value;
if (saved.id != "test-bookmark-2") {
printerr("FAIL: Expected id 'test-bookmark-2', got '%s'\n", saved.id);
return;
}
print("PASS: test_bookmark_repository_read\n");
}
public void test_bookmark_repository_update() {
// Create a test database
var db = new Database(":memory:");
// Create bookmark repository
var repo = new BookmarkRepositoryImpl(db);
// Create a test bookmark
var bookmark = Bookmark.new_internal(
id: "test-bookmark-3",
feed_item_id: "test-item-3",
created_at: Time.now()
);
var create_result = repo.add(bookmark);
if (create_result.is_error()) {
printerr("FAIL: Could not create bookmark: %s\n", create_result.error.message);
return;
}
// Update the bookmark
bookmark.tags = ["important", "read-later"];
var update_result = repo.update(bookmark);
if (update_result.is_error()) {
printerr("FAIL: Bookmark update failed: %s\n", update_result.error.message);
return;
}
// Verify update
var read_result = repo.get_by_id("test-bookmark-3");
if (read_result.is_error()) {
printerr("FAIL: Could not read bookmark: %s\n", read_result.error.message);
return;
}
var saved = read_result.value;
if (saved.tags.length != 2) {
printerr("FAIL: Expected 2 tags, got %d\n", saved.tags.length);
return;
}
print("PASS: test_bookmark_repository_update\n");
}
public void test_bookmark_repository_delete() {
// Create a test database
var db = new Database(":memory:");
// Create bookmark repository
var repo = new BookmarkRepositoryImpl(db);
// Create a test bookmark
var bookmark = Bookmark.new_internal(
id: "test-bookmark-4",
feed_item_id: "test-item-4",
created_at: Time.now()
);
var create_result = repo.add(bookmark);
if (create_result.is_error()) {
printerr("FAIL: Could not create bookmark: %s\n", create_result.error.message);
return;
}
// Delete the bookmark
var delete_result = repo.remove("test-bookmark-4");
if (delete_result.is_error()) {
printerr("FAIL: Bookmark deletion failed: %s\n", delete_result.error.message);
return;
}
// Verify deletion
var read_result = repo.get_by_id("test-bookmark-4");
if (!read_result.is_error()) {
printerr("FAIL: Bookmark should have been deleted\n");
return;
}
print("PASS: test_bookmark_repository_delete\n");
}
public void test_bookmark_repository_tags() {
// Create a test database
var db = new Database(":memory:");
// Create bookmark repository
var repo = new BookmarkRepositoryImpl(db);
// Create multiple bookmarks with different tags
var bookmark1 = Bookmark.new_internal(
id: "test-bookmark-5",
feed_item_id: "test-item-5",
created_at: Time.now()
);
bookmark1.tags = ["important"];
repo.add(bookmark1);
var bookmark2 = Bookmark.new_internal(
id: "test-bookmark-6",
feed_item_id: "test-item-6",
created_at: Time.now()
);
bookmark2.tags = ["read-later"];
repo.add(bookmark2);
// Test tag-based query
var by_tag_result = repo.get_by_tag("important");
if (by_tag_result.is_error()) {
printerr("FAIL: Tag query failed: %s\n", by_tag_result.error.message);
return;
}
var bookmarks = by_tag_result.value;
if (bookmarks.length != 1) {
printerr("FAIL: Expected 1 bookmark with tag 'important', got %d\n", bookmarks.length);
return;
}
print("PASS: test_bookmark_repository_tags\n");
}
public void test_bookmark_repository_by_feed_item() {
// Create a test database
var db = new Database(":memory:");
// Create bookmark repository
var repo = new BookmarkRepositoryImpl(db);
// Create multiple bookmarks for the same feed item
var bookmark1 = Bookmark.new_internal(
id: "test-bookmark-7",
feed_item_id: "test-item-7",
created_at: Time.now()
);
repo.add(bookmark1);
var bookmark2 = Bookmark.new_internal(
id: "test-bookmark-8",
feed_item_id: "test-item-7",
created_at: Time.now()
);
repo.add(bookmark2);
// Test feed item-based query
var by_item_result = repo.get_by_feed_item("test-item-7");
if (by_item_result.is_error()) {
printerr("FAIL: Feed item query failed: %s\n", by_item_result.error.message);
return;
}
var bookmarks = by_item_result.value;
if (bookmarks.length != 2) {
printerr("FAIL: Expected 2 bookmarks for feed item, got %d\n", bookmarks.length);
return;
}
print("PASS: test_bookmark_repository_by_feed_item\n");
}
}