Files
linkding-ios/MarksTests/SpotlightRetrievalTests.swift
T
Krishna KumarandClaude Opus 5 69556afc08
CI / build-and-deploy (push) Successful in 26s
CI / build-and-deploy (pull_request) Successful in 25s
Fix Spotlight indexing: route the entity URL to contentURL
Every bookmark failed to reach the Spotlight index. Each item died in
translation with "Provided object for field url is of class NSURL,
expected class: NSString", so on-device search and Ask Your Bookmarks
were retrieving from an index that was effectively empty.

Left to itself, App Intents indexes BookmarkEntity's `url` property under
the attribute set's own `url` key, which Spotlight's Cascade translator
types as NSString. Giving the property an explicit
`indexingKey: \.contentURL` sends it to a URL-typed field instead — and
contentURL is the right field for "where this content lives" regardless.
Keeping the property a URL rather than retyping it to String means
existing Shortcuts that read it are unaffected.

The attribute set now sets contentURL too, and the retrieval side reads
it back, so the round trip stays on one field.

Why it went unnoticed: translation happens after `indexAppEntities`
returns, so indexing logged success the whole time. Measured on the
simulator against the live library — 202 translation failures per launch
before, 0 after.

Adds SpotlightRetrievalTests, which indexes a bookmark and retrieves it
through the assistant's own path. Nothing weaker would have caught this,
since the failure was silent at every layer above the index.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgLHztZGaEHvS3KNeGQmRM
2026-07-27 19:12:25 -05:00

41 lines
1.7 KiB
Swift

import Testing
import CoreSpotlight
@testable import Marks
/// End-to-end guard for the whole Spotlight path: index a bookmark, then
/// retrieve it the way the on-device assistant does.
///
/// Worth keeping. The bug this was written for made every item fail to
/// translate into the index while `indexAppEntities` still reported success,
/// so nothing short of a round trip would have caught it.
struct SpotlightRetrievalTests {
@Test func indexedBookmarkIsRetrievable() async throws {
let b = Bookmark(
id: 999_001,
url: "https://github.com/example/zqxjkltest",
title: "Zqxjkltest concurrency notes",
description: "A distinctive probe document about zqxjkltest.",
tagNames: ["zqxjkltest"],
dateAdded: Date(), dateModified: Date(),
isArchived: false, unread: false, shared: false,
websiteTitle: nil, websiteDescription: nil,
faviconUrl: nil, previewImageUrl: nil,
aiSummary: nil, aiTags: nil
)
await SpotlightIndexer.index([b])
var hits: [RetrievedBookmark] = []
for _ in 0..<20 {
try? await Task.sleep(for: .milliseconds(700))
hits = await SpotlightBookmarkSearch.run(query: "zqxjkltest", limit: 5)
if !hits.isEmpty { break }
}
await SpotlightIndexer.remove(ids: [999_001])
#expect(!hits.isEmpty, "Spotlight returned no hits for an indexed bookmark")
let hit = try #require(hits.first)
#expect(hit.title.contains("Zqxjkltest"))
#expect(hit.url == "https://github.com/example/zqxjkltest",
"url did not survive the round trip: \(hit.url)")
#expect(hit.host == "github.com", "host was \(hit.host)")
}
}