WIP: manage collections from rail

This commit is contained in:
Akshay Kolli
2026-06-30 04:01:57 -07:00
parent 16e2200244
commit 3e38514387
8 changed files with 336 additions and 10 deletions

View File

@@ -273,6 +273,57 @@ final class ClipboardPanelViewModelTests: XCTestCase {
XCTAssertEqual(restoredViewModel.collectionColorHex(named: "Client Work"), "#0A9EB8")
}
func testUpdateCollectionRenamesAssignedItemsAndColor() {
let settings = makeSettings()
let cacheService = makeCacheService()
let store = makeStore(settings: settings, cacheService: cacheService)
var research = makeTextItem("research note", createdAt: Date(timeIntervalSince1970: 100))
research.collectionName = "Research Stack"
let outside = makeTextItem("outside note", createdAt: Date(timeIntervalSince1970: 200))
store.upsert(research)
store.upsert(outside)
store.flushPersistenceForTesting()
let viewModel = ClipboardPanelViewModel(store: store, settings: settings, cacheService: cacheService)
waitForVisibleItems(in: viewModel, count: 2)
viewModel.createCollection(named: "Research Stack", colorHex: "#0A9EB8")
viewModel.updateCollection(named: "Research Stack", to: "Product Research", colorHex: "#3366FF")
store.flushPersistenceForTesting()
XCTAssertEqual(viewModel.collectionNames, ["Product Research"])
XCTAssertEqual(viewModel.collectionColorHex(named: "Product Research"), "#3366FF")
XCTAssertEqual(viewModel.selectedCollectionName, "Product Research")
XCTAssertEqual(viewModel.visibleItems.map(\.payload), ["research note"])
XCTAssertEqual(viewModel.statusMessage, "Updated Product Research")
XCTAssertEqual(store.items.first(where: { $0.payload == "research note" })?.collectionName, "Product Research")
}
func testDeleteCollectionRemovesCollectionItemsFromHistory() {
let settings = makeSettings()
let cacheService = makeCacheService()
let store = makeStore(settings: settings, cacheService: cacheService)
var client = makeTextItem("client note", createdAt: Date(timeIntervalSince1970: 100))
client.collectionName = "Client Work"
let outside = makeTextItem("outside note", createdAt: Date(timeIntervalSince1970: 200))
store.upsert(client)
store.upsert(outside)
store.flushPersistenceForTesting()
let viewModel = ClipboardPanelViewModel(store: store, settings: settings, cacheService: cacheService)
waitForVisibleItems(in: viewModel, count: 2)
viewModel.createCollection(named: "Client Work", colorHex: "#0A9EB8")
viewModel.deleteCollection(named: "Client Work")
store.flushPersistenceForTesting()
XCTAssertEqual(viewModel.collectionNames, [])
XCTAssertNil(viewModel.selectedCollectionName)
XCTAssertEqual(viewModel.visibleItems.map(\.payload), ["outside note"])
XCTAssertEqual(store.items.map(\.payload), ["outside note"])
XCTAssertEqual(viewModel.statusMessage, "Deleted Client Work")
}
func testSearchTextRecomputesVisibleItemsImmediately() {
let settings = makeSettings()
let cacheService = makeCacheService()

View File

@@ -221,6 +221,42 @@ final class ClipboardPanelViewTests: XCTestCase {
XCTAssertEqual(fixture.view.debugFirstCardFooterDetailText, "17 characters")
}
func testCollectionChipsExposeManagementMenuActions() {
let fixture = makePanelFixture()
fixture.viewModel.createCollection(named: "Research Stack", colorHex: "#0A9EB8")
drainMainQueue()
fixture.window.contentView?.layoutSubtreeIfNeeded()
XCTAssertEqual(fixture.view.debugCustomCollectionMenuTitles(named: "Research Stack"), ["Edit Collection...", "-", "Delete Collection"])
}
func testCollectionChipManagementRenamesAndDeletesCollections() {
let fixture = makePanelFixture()
fixture.viewModel.createCollection(named: "Research Stack", colorHex: "#0A9EB8")
var item = makeTextItem("Collect this note", store: fixture.store)
item.collectionName = "Research Stack"
fixture.store.upsert(item)
drainMainQueue()
fixture.window.contentView?.layoutSubtreeIfNeeded()
fixture.view.debugEditCollection(named: "Research Stack", to: "Product Research", colorHex: "#3366FF")
drainMainQueue()
fixture.window.contentView?.layoutSubtreeIfNeeded()
XCTAssertEqual(fixture.view.debugCustomCollectionTitles, ["Product Research"])
XCTAssertEqual(fixture.view.debugSelectedCollectionTitle, "Product Research")
XCTAssertEqual(fixture.view.debugFirstCardHeaderTitle, "Product Research")
XCTAssertEqual(fixture.view.debugFirstCardHeaderColorHex, "#3366FF")
fixture.view.debugDeleteCollection(named: "Product Research")
drainMainQueue()
fixture.window.contentView?.layoutSubtreeIfNeeded()
XCTAssertEqual(fixture.view.debugCustomCollectionTitles, [])
XCTAssertEqual(fixture.viewModel.visibleItems.map(\.payload), [])
XCTAssertEqual(fixture.store.items.map(\.payload), [])
}
func testSelectedCardActionsRespectSelectedKind() {
let fixture = makePanelFixture()
fixture.store.upsert(makeTextItem("Plain text", store: fixture.store))

View File

@@ -49,4 +49,32 @@ final class SettingsModelTests: XCTestCase {
XCTAssertEqual(restored.customCollectionNames, ["Research Stack", "Client Work"])
XCTAssertEqual(restored.collectionColorHex(forCollectionNamed: "Research Stack"), "#FF3355")
}
func testCustomCollectionsCanBeUpdatedAndDeleted() {
let suiteName = "com.clipbored.settingsmodel.\(UUID().uuidString)"
let defaults = UserDefaults(suiteName: suiteName)!
defer {
defaults.removePersistentDomain(forName: suiteName)
}
let settings = SettingsModel(defaults: defaults)
settings.ensureCollection(named: "Research Stack", colorHex: "#0A9EB8")
settings.ensureCollection(named: "Client Work", colorHex: "#FF3355")
let updatedName = settings.updateCollection(named: "research stack", to: "Product Research", colorHex: "#3366FF")
XCTAssertEqual(updatedName, "Product Research")
XCTAssertEqual(settings.customCollectionNames, ["Product Research", "Client Work"])
XCTAssertNil(settings.collectionColorHex(forCollectionNamed: "Research Stack"))
XCTAssertEqual(settings.collectionColorHex(forCollectionNamed: "Product Research"), "#3366FF")
settings.deleteCollection(named: "client work")
XCTAssertEqual(settings.customCollectionNames, ["Product Research"])
XCTAssertNil(settings.collectionColorHex(forCollectionNamed: "Client Work"))
let restored = SettingsModel(defaults: defaults)
XCTAssertEqual(restored.customCollectionNames, ["Product Research"])
XCTAssertEqual(restored.collectionColorHex(forCollectionNamed: "Product Research"), "#3366FF")
}
}