commit d71aee9b866565002fb14122be9b965694741a9f
parent b23aa20c561bf9b83097c8af7dd09e50cb0c7299
Author: Michael Camilleri <[email protected]>
Date: Thu, 21 May 2026 13:35:33 +0900
Use consistent puzzle title
Diffstat:
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/Crossmate/Sync/SessionMonitor.swift b/Crossmate/Sync/SessionMonitor.swift
@@ -240,7 +240,7 @@ actor SessionMonitor {
gameReq.predicate = NSPredicate(format: "id == %@", gameID as CVarArg)
gameReq.fetchLimit = 1
let game = try? ctx.fetch(gameReq).first
- let title = game?.title ?? ""
+ let title = PuzzleNotificationText.title(for: game)
var name = ""
if let game {
diff --git a/Tests/Unit/Sync/SessionMonitorTests.swift b/Tests/Unit/Sync/SessionMonitorTests.swift
@@ -217,6 +217,48 @@ struct SessionMonitorTests {
))
}
+ @Test("End-of-session summary uses the same puzzle title as session start")
+ @MainActor func endSummaryUsesFormattedPuzzleTitle() async throws {
+ let persistence = makeTestPersistence()
+ let context = persistence.viewContext
+ let gameID = UUID()
+ let date = try #require(Calendar(identifier: .gregorian).date(
+ from: DateComponents(year: 2001, month: 1, day: 1)
+ ))
+
+ let game = GameEntity(context: context)
+ game.id = gameID
+ game.title = "Saturday Puzzle"
+ game.cachedPublisher = "The Daily Crossword"
+ game.cachedPuzzleDate = date
+ game.puzzleSource = ""
+ game.createdAt = date
+ game.updatedAt = date
+ game.ckRecordName = "game-\(gameID.uuidString)"
+
+ let player = PlayerEntity(context: context)
+ player.authorID = "alice"
+ player.ckRecordName = "player-\(gameID.uuidString)-alice"
+ player.name = "Alice"
+ player.updatedAt = date
+ player.game = game
+
+ try context.save()
+
+ let scheduler = RecordingNotificationScheduler()
+ let monitor = SessionMonitor(
+ persistence: persistence,
+ localAuthorIDProvider: { nil },
+ notificationCenter: scheduler
+ )
+
+ await monitor.ingest([makeDelta(gameID: gameID, authorID: "alice", added: 1)])
+
+ let body = try #require(scheduler.added.first?.content.body)
+ let expectedTitle = PuzzleNotificationText.title(for: game)
+ #expect(body == "Alice added 1 letter in the puzzle '\(expectedTitle)'")
+ }
+
@Test("consumeOnOpen returns hydrated summaries and clears the buckets")
@MainActor func consumeOnOpenReturnsAndClears() async {
let scheduler = RecordingNotificationScheduler()