@@ -313,6 +313,82 @@ struct PubSubIntegratedTests {
313313 }
314314 }
315315
316+ @Test
317+ @available ( valkeySwift 1 . 0 , * )
318+ func testClientTrackingBroadcastSinglePrefix( ) async throws {
319+ let ( stream, cont) = AsyncStream . makeStream ( of: Void . self)
320+ var logger = Logger ( label: " Valkey " )
321+ logger. logLevel = . trace
322+ try await withValkeyClient ( . hostname( valkeyHostname, port: 6379 ) , logger: logger) { client in
323+ try await client. withConnection { connection in
324+ // Enable tracking with broadcast mode and a single prefix "user:"
325+ try await connection. clientTracking ( status: . on, prefixes: [ " user: " ] , bcast: true )
326+
327+ try await withThrowingTaskGroup ( of: Void . self) { group in
328+ group. addTask {
329+ try await connection. subscribeKeyInvalidations { keys in
330+ cont. finish ( )
331+ var iterator = keys. makeAsyncIterator ( )
332+ let key = try await iterator. next ( )
333+ #expect( key == " user:123 " )
334+ }
335+ }
336+
337+ await stream. first { _ in true }
338+
339+ // This should trigger invalidation (matches prefix)
340+ try await connection. set ( " user:123 " , value: " data " )
341+
342+ try await group. waitForAll ( )
343+ }
344+ }
345+ }
346+ }
347+
348+ @Test
349+ @available ( valkeySwift 1 . 0 , * )
350+ func testClientTrackingBroadcastMultiplePrefixes( ) async throws {
351+ let ( stream, cont) = AsyncStream . makeStream ( of: Void . self)
352+ var logger = Logger ( label: " Valkey " )
353+ logger. logLevel = . trace
354+ try await withValkeyClient ( . hostname( valkeyHostname, port: 6379 ) , logger: logger) { client in
355+ try await client. withConnection { connection in
356+ // Enable tracking with broadcast mode and two prefixes: "user:" and "order:"
357+ try await connection. clientTracking ( status: . on, prefixes: [ " user: " , " order: " ] , bcast: true )
358+
359+ try await withThrowingTaskGroup ( of: Void . self) { group in
360+ group. addTask {
361+ try await connection. subscribeKeyInvalidations { keys in
362+ cont. finish ( )
363+ var iterator = keys. makeAsyncIterator ( )
364+
365+ // Should receive invalidation for user:123
366+ let key1 = try await iterator. next ( )
367+ #expect( key1 == " user:123 " )
368+
369+ // Should receive invalidation for order:789
370+ let key2 = try await iterator. next ( )
371+ #expect( key2 == " order:789 " )
372+ }
373+ }
374+
375+ await stream. first { _ in true }
376+
377+ // This should trigger invalidation (matches "user:" prefix)
378+ try await connection. set ( " user:123 " , value: " user_data " )
379+
380+ // This should NOT trigger invalidation
381+ try await connection. set ( " not-matching-prefix:123 " , value: " not_matching_data " )
382+
383+ // This should trigger invalidation (matches "order:" prefix)
384+ try await connection. set ( " order:789 " , value: " order_data " )
385+
386+ try await group. waitForAll ( )
387+ }
388+ }
389+ }
390+ }
391+
316392 @Test
317393 @available ( valkeySwift 1 . 0 , * )
318394 func testKeyspaceSubscription( ) async throws {
0 commit comments