restructure
Some checks failed
CI - Multi-Platform Native / Build iOS (RSSuper) (push) Has been cancelled
CI - Multi-Platform Native / Build macOS (push) Has been cancelled
CI - Multi-Platform Native / Build Android (push) Has been cancelled
CI - Multi-Platform Native / Build Linux (push) Has been cancelled
CI - Multi-Platform Native / Build Summary (push) Has been cancelled

This commit is contained in:
2026-03-30 16:39:18 -04:00
parent a8e07d52f0
commit c2e1622bd8
252 changed files with 4803 additions and 17165 deletions

View File

@@ -0,0 +1,395 @@
//
// DatabaseManagerTests.swift
// RSSuperTests
//
// Created on 3/29/26.
//
import XCTest
@testable import RSSuper
final class DatabaseManagerTests: XCTestCase {
private var databaseManager: DatabaseManager!
private var testSubscriptionId: String!
override func setUp() {
super.setUp()
databaseManager = DatabaseManager.shared
testSubscriptionId = UUID().uuidString
// Clean up any existing test data
try? databaseManager.deleteSubscription(id: testSubscriptionId)
}
override func tearDown() {
// Clean up test data
try? databaseManager.deleteSubscription(id: testSubscriptionId)
databaseManager = nil
super.tearDown()
}
// MARK: - Subscription CRUD Tests
func testCreateSubscription() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com/feed.xml",
title: "Test Subscription",
category: "Technology",
enabled: true,
fetchInterval: 3600
)
XCTAssertEqual(subscription.id, testSubscriptionId)
XCTAssertEqual(subscription.url, "https://example.com/feed.xml")
XCTAssertEqual(subscription.title, "Test Subscription")
XCTAssertEqual(subscription.category, "Technology")
XCTAssertTrue(subscription.enabled)
XCTAssertEqual(subscription.fetchInterval, 3600)
}
func testFetchSubscription() throws {
// Create first
_ = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com/feed.xml",
title: "Test Subscription"
)
// Fetch
let fetched = try databaseManager.fetchSubscription(id: testSubscriptionId)
XCTAssertNotNil(fetched)
XCTAssertEqual(fetched?.id, testSubscriptionId)
XCTAssertEqual(fetched?.title, "Test Subscription")
}
func testFetchSubscriptionNotFound() throws {
let fetched = try databaseManager.fetchSubscription(id: "non-existent-id")
XCTAssertNil(fetched)
}
func testFetchAllSubscriptions() throws {
let id1 = UUID().uuidString
let id2 = UUID().uuidString
try databaseManager.createSubscription(id: id1, url: "https://example1.com", title: "Sub 1")
try databaseManager.createSubscription(id: id2, url: "https://example2.com", title: "Sub 2")
let subscriptions = try databaseManager.fetchAllSubscriptions()
XCTAssertGreaterThanOrEqual(subscriptions.count, 2)
// Cleanup
try databaseManager.deleteSubscription(id: id1)
try databaseManager.deleteSubscription(id: id2)
}
func testFetchEnabledSubscriptions() throws {
let id1 = UUID().uuidString
let id2 = UUID().uuidString
try databaseManager.createSubscription(id: id1, url: "https://example1.com", title: "Sub 1", enabled: true)
try databaseManager.createSubscription(id: id2, url: "https://example2.com", title: "Sub 2", enabled: false)
let subscriptions = try databaseManager.fetchEnabledSubscriptions()
XCTAssertTrue(subscriptions.allSatisfy { $0.enabled })
// Cleanup
try databaseManager.deleteSubscription(id: id1)
try databaseManager.deleteSubscription(id: id2)
}
func testUpdateSubscription() throws {
_ = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Original Title"
)
let updated = try databaseManager.updateSubscription(
try databaseManager.fetchSubscription(id: testSubscriptionId)!,
title: "Updated Title",
enabled: false
)
XCTAssertEqual(updated.title, "Updated Title")
XCTAssertFalse(updated.enabled)
}
func testDeleteSubscription() throws {
_ = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "To Delete"
)
try databaseManager.deleteSubscription(id: testSubscriptionId)
let fetched = try databaseManager.fetchSubscription(id: testSubscriptionId)
XCTAssertNil(fetched)
}
// MARK: - FeedItem CRUD Tests
func testCreateFeedItem() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let item = FeedItem(
id: UUID().uuidString,
title: "Test Article",
link: "https://example.com/article",
description: "Article description",
content: "Full article content",
author: "John Doe",
published: Date(),
subscriptionId: subscription.id,
subscriptionTitle: subscription.title
)
let created = try databaseManager.createFeedItem(item)
XCTAssertEqual(created.id, item.id)
XCTAssertEqual(created.title, "Test Article")
XCTAssertEqual(created.subscriptionId, testSubscriptionId)
}
func testFetchFeedItem() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let itemId = UUID().uuidString
let item = FeedItem(
id: itemId,
title: "To Fetch",
subscriptionId: subscription.id
)
_ = try databaseManager.createFeedItem(item)
let fetched = try databaseManager.fetchFeedItem(id: itemId)
XCTAssertNotNil(fetched)
XCTAssertEqual(fetched?.id, itemId)
}
func testFetchFeedItemsForSubscription() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
for i in 1...3 {
let item = FeedItem(
id: UUID().uuidString,
title: "Article \(i)",
subscriptionId: subscription.id
)
_ = try databaseManager.createFeedItem(item)
}
let items = try databaseManager.fetchFeedItems(for: testSubscriptionId)
XCTAssertEqual(items.count, 3)
}
func testFetchUnreadFeedItems() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let readItem = FeedItem(id: UUID().uuidString, title: "Read", subscriptionId: subscription.id, read: true)
let unreadItem = FeedItem(id: UUID().uuidString, title: "Unread", subscriptionId: subscription.id, read: false)
_ = try databaseManager.createFeedItem(readItem)
_ = try databaseManager.createFeedItem(unreadItem)
let unreadItems = try databaseManager.fetchUnreadFeedItems()
XCTAssertTrue(unreadItems.allSatisfy { !$0.read })
}
func testMarkAsRead() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let item1 = FeedItem(id: UUID().uuidString, title: "Item 1", subscriptionId: subscription.id, read: false)
let item2 = FeedItem(id: UUID().uuidString, title: "Item 2", subscriptionId: subscription.id, read: false)
_ = try databaseManager.createFeedItem(item1)
_ = try databaseManager.createFeedItem(item2)
try databaseManager.markAsRead(ids: [item1.id, item2.id])
let fetched1 = try databaseManager.fetchFeedItem(id: item1.id)
let fetched2 = try databaseManager.fetchFeedItem(id: item2.id)
XCTAssertTrue(fetched1?.read ?? false)
XCTAssertTrue(fetched2?.read ?? false)
}
func testDeleteFeedItem() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let item = FeedItem(id: UUID().uuidString, title: "To Delete", subscriptionId: subscription.id)
_ = try databaseManager.createFeedItem(item)
try databaseManager.deleteFeedItem(id: item.id)
let fetched = try databaseManager.fetchFeedItem(id: item.id)
XCTAssertNil(fetched)
}
// MARK: - SearchHistory Tests
func testAddToSearchHistory() throws {
let item = try databaseManager.addToSearchHistory(query: "test query")
XCTAssertEqual(item.query, "test query")
XCTAssertNotNil(item.id)
}
func testFetchSearchHistory() throws {
try databaseManager.addToSearchHistory(query: "Query 1")
try databaseManager.addToSearchHistory(query: "Query 2")
let history = try databaseManager.fetchSearchHistory()
XCTAssertGreaterThanOrEqual(history.count, 2)
}
func testClearSearchHistory() throws {
try databaseManager.addToSearchHistory(query: "To Clear")
try databaseManager.clearSearchHistory()
let history = try databaseManager.fetchSearchHistory()
XCTAssertTrue(history.isEmpty)
}
// MARK: - FTS Search Tests
func testFullTextSearch() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let searchableItem = FeedItem(
id: UUID().uuidString,
title: "Unique Title for Search Test",
description: "This has special content",
subscriptionId: subscription.id
)
let nonMatchingItem = FeedItem(
id: UUID().uuidString,
title: "Completely Different",
subscriptionId: subscription.id
)
_ = try databaseManager.createFeedItem(searchableItem)
_ = try databaseManager.createFeedItem(nonMatchingItem)
let results = try databaseManager.fullTextSearch(query: "Unique")
XCTAssertTrue(results.contains { $0.id == searchableItem.id || $0.title.contains("Unique") })
XCTAssertFalse(results.contains { $0.id == nonMatchingItem.id })
}
func testAdvancedSearch() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let item1 = FeedItem(
id: UUID().uuidString,
title: "Searchable Title",
author: "Test Author",
subscriptionId: subscription.id
)
let item2 = FeedItem(
id: UUID().uuidString,
title: "Different Title",
author: "Other Author",
subscriptionId: subscription.id
)
_ = try databaseManager.createFeedItem(item1)
_ = try databaseManager.createFeedItem(item2)
let results = try databaseManager.advancedSearch(title: "Searchable", author: "Test")
XCTAssertTrue(results.contains { $0.id == item1.id })
XCTAssertFalse(results.contains { $0.id == item2.id })
}
// MARK: - Batch Operations Tests
func testMarkAllAsRead() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
_ = try databaseManager.createFeedItem(FeedItem(id: UUID().uuidString, title: "Item 1", subscriptionId: subscription.id, read: false))
_ = try databaseManager.createFeedItem(FeedItem(id: UUID().uuidString, title: "Item 2", subscriptionId: subscription.id, read: false))
try databaseManager.markAllAsRead(for: testSubscriptionId)
let items = try databaseManager.fetchFeedItems(for: testSubscriptionId)
XCTAssertTrue(items.allSatisfy { $0.read })
}
func testCleanupOldItems() throws {
let subscription = try databaseManager.createSubscription(
id: testSubscriptionId,
url: "https://example.com",
title: "Test Sub"
)
let oldItem = FeedItem(
id: UUID().uuidString,
title: "Old Item",
published: Calendar.current.date(byAdding: .day, value: -30, to: Date()),
subscriptionId: subscription.id
)
let newItem = FeedItem(
id: UUID().uuidString,
title: "New Item",
published: Date(),
subscriptionId: subscription.id
)
_ = try databaseManager.createFeedItem(oldItem)
_ = try databaseManager.createFeedItem(newItem)
let deletedCount = try databaseManager.cleanupOldItems(olderThan: 7, for: testSubscriptionId)
XCTAssertEqual(deletedCount, 1)
let remainingItems = try databaseManager.fetchFeedItems(for: testSubscriptionId)
XCTAssertEqual(remainingItems.count, 1)
XCTAssertEqual(remainingItems.first?.id, newItem.id)
}
}