-
Notifications
You must be signed in to change notification settings - Fork 225
Add support for push preferences #3820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…y uses the current user
WalkthroughAdds end-to-end push notification preferences: new API endpoint/payloads, model types, Core Data entity and mappings, updater/controller methods, demo UI (SwiftUI + UIKit hosting), router integration, test coverage, fixtures, mocks, and project file updates. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant R as DemoChatChannelListRouter
participant V as PushPreferencesView (SwiftUI)
participant CC as ChatChannelController
participant W as ChannelUpdater
participant API as REST API
participant DB as Core Data
U->>R: Tap "More" → "Set Channel Push Preferences"
R->>V: Present UIHostingController (initialPreference & callbacks)
V->>CC: onSetPreferences(level) / onDisableNotifications(date)
CC->>W: setPushPreference(...) / snoozePushNotifications(...)
W->>API: POST /push_preferences
API-->>W: PushPreferencesPayloadResponse
W->>DB: Persist PushPreferenceDTO
W-->>CC: Result<PushPreference, Error>
CC-->>V: Completion (success/error) -> UI update / dismiss
sequenceDiagram
autonumber
participant U as User
participant P as UserProfileViewController
participant V as PushPreferencesView (SwiftUI)
participant CUC as CurrentChatUserController
participant Wu as CurrentUserUpdater
participant API as REST API
participant DB as Core Data
U->>P: Open profile → Push Preferences
P->>V: Present UIHostingController
V->>CUC: setPushPreference(level) / snooze(until)
CUC->>Wu: setPushPreference(payload)
Wu->>API: POST /push_preferences
API-->>Wu: Response (userPreferences)
Wu->>DB: Save CurrentUser PushPreferenceDTO
Wu-->>CUC: Result<PushPreference, Error>
CUC-->>V: Completion -> show success / dismiss
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
SDK Size
|
SDK Performance
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Nitpick comments (24)
Sources/StreamChat/Models/PushPreferences/PushPreference.swift (1)
7-13
: Public model addition: LGTM; consider Equatable/Sendable.Optional but useful for comparisons and concurrency.
-public struct PushPreference { +public struct PushPreference: Equatable, Sendable {DemoApp/StreamChat/Components/DemoChatChannelListRouter.swift (1)
710-731
: Present PushPreferencesView inside a UINavigationController so the title shows.Presented bare UIHostingController won’t display the navigation title.
- let hostingController = UIHostingController(rootView: pushPreferencesView) - hostingController.title = "Channel Push Preferences - \(cid.id)" - - rootViewController.present(hostingController, animated: true) + let hostingController = UIHostingController(rootView: pushPreferencesView) + hostingController.title = "Channel Push Preferences - \(cid.id)" + let nav = UINavigationController(rootViewController: hostingController) + rootViewController.present(nav, animated: true)Sources/StreamChat/Models/Channel.swift (1)
256-256
: Assignment OK, but ensure downstream init sites pass it.The stored property is set, but without forwarding in
replacing/changing
it may get lost (see prior comment).Sources/StreamChat/Workers/ChannelUpdater.swift (1)
722-748
: Deduplicate push-preference write logic.CurrentUserUpdater and ChannelUpdater duplicate the same request/save flow. Extract a small helper to reduce drift.
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (3)
1702-1708
: Guard channel creation state as well (consistency).Most mutations guard both
cid
andisChannelAlreadyCreated
. Do the same here to avoid calls before backend creation.Apply this diff:
- guard let channelId = cid else { + guard let channelId = cid, isChannelAlreadyCreated else { callback { completion?(.failure(ClientError.ChannelNotCreatedYet())) } return }
1731-1736
: Same here: check isChannelAlreadyCreated.Align snooze behavior with other mutations.
Apply this diff:
- guard let channelId = cid else { + guard let channelId = cid, isChannelAlreadyCreated else { callback { completion?(.failure(ClientError.ChannelNotCreatedYet())) } return }
1694-1721
: Optional: add async variants for new APIs.Consider
async throws
wrappers for parity with other controller APIs.Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
221-223
: Use actual user ID when saving current user’s push preferences
Replace the hard-coded"currentUserId"
with the current user’s real ID to match how user preferences are indexed elsewhere.Sources/StreamChat/Workers/CurrentUserUpdater.swift:221
- try $0.savePushPreference( - id: "currentUserId", + try $0.savePushPreference( + id: $0.currentUser?.user.id ?? "currentUserId",Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (2)
7-19
: Prefer precise naming: channelCid instead of channelId.The request maps to "channel_cid". Naming the property channelCid avoids ambiguity with a plain channel id.
Apply this diff and update call sites:
struct PushPreferenceRequestPayload: Encodable { let chatLevel: String? - let channelId: String? + let channelCid: String? let disabledUntil: Date? let removeDisable: Bool? enum CodingKeys: String, CodingKey { case chatLevel = "chat_level" - case channelId = "channel_cid" + case channelCid = "channel_cid" case disabledUntil = "disabled_until" case removeDisable = "remove_disable" } }
7-11
: Avoid “stringly-typed” chat level in requests.Use PushPreferenceLevel instead of String for chatLevel to prevent typos and align with the model. This pairs with making PushPreferenceLevel Codable (see separate comment).
If you make PushPreferenceLevel Codable, change:
- let chatLevel: String? + let chatLevel: PushPreferenceLevel?Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift (2)
98-104
: Disambiguate persistence key to avoid id-space collisions.Using the bare user id as PushPreferenceDTO.id can collide with channel cids if shared space is ever mixed. Prefix the id (e.g., "user:") for clarity and safety; mirror with "channel:" on channel side.
- dto.pushPreference = try savePushPreference(id: payload.id, payload: pushPreference) + dto.pushPreference = try savePushPreference(id: "user:\(payload.id)", payload: pushPreference)
211-223
: Prefetch pushPreference to avoid faults when materializing CurrentChatUser.Include the new relationship in prefetchedRelationshipKeyPaths.
Apply this diff:
extension CurrentUserDTO { override class func prefetchedRelationshipKeyPaths() -> [String] { [ KeyPath.string(\CurrentUserDTO.channelMutes), KeyPath.string(\CurrentUserDTO.currentDevice), KeyPath.string(\CurrentUserDTO.devices), KeyPath.string(\CurrentUserDTO.flaggedMessages), KeyPath.string(\CurrentUserDTO.flaggedUsers), KeyPath.string(\CurrentUserDTO.mutedUsers), - KeyPath.string(\CurrentUserDTO.user) + KeyPath.string(\CurrentUserDTO.user), + KeyPath.string(\CurrentUserDTO.pushPreference) ] } }Sources/StreamChat/Models/PushPreferences/PushPreferenceLevel.swift (2)
8-9
: Adopt Codable and Sendable.This value type is a perfect candidate for Codable and Sendable, simplifying payloads and improving concurrency safety.
-public struct PushPreferenceLevel: RawRepresentable, Equatable, ExpressibleByStringLiteral { +public struct PushPreferenceLevel: RawRepresentable, Codable, Equatable, Sendable, ExpressibleByStringLiteral {
19-25
: Make well-known levels constants (let), not vars.These should be immutable public constants.
- public static var none: PushPreferenceLevel = "none" + public static let none: PushPreferenceLevel = "none" /// Push notifications will only be delivered for mentions. - public static var mentions: PushPreferenceLevel = "mentions" + public static let mentions: PushPreferenceLevel = "mentions" /// All push notifications will be delivered. - public static var all: PushPreferenceLevel = "all" + public static let all: PushPreferenceLevel = "all"DemoApp/Screens/UserProfile/PushPreferencesView.swift (4)
56-81
: Use Button instead of onTapGesture for better accessibility.Buttons provide proper accessibility semantics, focus handling, and larger hit targets.
- ForEach([PushPreferenceLevel.all, .mentions, .none], id: \.rawValue) { level in - HStack { + ForEach([PushPreferenceLevel.all, .mentions, .none], id: \.rawValue) { level in + Button(action: { + if disableUntil == nil { selectedLevel = level } + }) { + HStack { VStack(alignment: .leading, spacing: 4) { Text(levelTitle(for: level)) .font(.headline) Text(levelDescription(for: level)) .font(.caption) .foregroundColor(.secondary) } Spacer() if selectedLevel == level { Image(systemName: "checkmark.circle.fill") .foregroundColor(.blue) } - } - .contentShape(Rectangle()) - .onTapGesture { - if disableUntil == nil { - selectedLevel = level - } - } - .disabled(disableUntil != nil) - .opacity(disableUntil != nil ? 0.5 : 1.0) + } + } + .buttonStyle(.plain) + .disabled(disableUntil != nil) + .opacity(disableUntil != nil ? 0.5 : 1.0) }
156-163
: Prefer .toolbar over deprecated navigationBarItems on iOS 15+.Modern toolbar APIs integrate better with SwiftUI navigation.
- .navigationBarItems( - leading: Button("Cancel") { - onDismiss() - } - .disabled(isLoading) - ) + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button("Cancel") { onDismiss() } + .disabled(isLoading) + } + }
109-142
: Consider system-tinted buttons for contrast/dark mode.Hard-coded listRowBackground colors can have poor contrast. Prefer .tint on Button and default list row background.
No code change required now.
22-27
: Minor: Make the DateFormatter static to avoid reallocation.A static formatter avoids repeated instantiation during view lifecycle.
- private let dateFormatter: DateFormatter = { + private static let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short return formatter }()Then call as Self.dateFormatter.
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (2)
24-27
: Fix copy/paste comment: channel update, not currentUser.Clarify the comment to avoid confusion.
- // Trigger currentUser update whenever push preference is updated. + // Trigger channel update whenever push preference is updated. if let channel = self.channel, hasPersistentChangedValues, !channel.hasChanges { channel.id = channel.id }
63-72
: Consider prefixing ids to disambiguate entity space.To avoid accidental collisions between user and channel push preferences, prefix ids (e.g., "user:", "channel:") at creation time.
No code change required here; align callers.
DemoApp/Screens/UserProfile/UserProfileViewController.swift (2)
48-52
: Fix ambiguous header/footer constraints and avoid force unwraps.
- imageView lacks a vertical constraint (ambiguous layout).
- Constraints reference
view.centerXAnchor
while the views live inside tableHeader/FooterView; prefer constraining to their superviews.- Avoid
superview!
to satisfy SwiftLint and zero‑warnings policy.As per coding guidelines
Apply this diff to fix constraints within this block (adds missing centerY and anchors to the proper containers):
NSLayoutConstraint.activate([ imageView.widthAnchor.constraint(equalToConstant: 60), imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), - imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), - updateButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + imageView.centerXAnchor.constraint(equalTo: tableView.tableHeaderView!.centerXAnchor), + imageView.centerYAnchor.constraint(equalTo: tableView.tableHeaderView!.centerYAnchor), + updateButton.centerXAnchor.constraint(equalTo: tableView.tableFooterView!.centerXAnchor), updateButton.heightAnchor.constraint(equalToConstant: 35), - updateButton.centerYAnchor.constraint(equalTo: updateButton.superview!.centerYAnchor) + updateButton.centerYAnchor.constraint(equalTo: tableView.tableFooterView!.centerYAnchor) ])Optionally, make it safer and silence force‑unwrap warnings:
guard let header = tableView.tableHeaderView, let footer = tableView.tableFooterView else { assertionFailure("Missing header/footer"); return } NSLayoutConstraint.activate([ imageView.centerXAnchor.constraint(equalTo: header.centerXAnchor), imageView.centerYAnchor.constraint(equalTo: header.centerYAnchor), updateButton.centerXAnchor.constraint(equalTo: footer.centerXAnchor), updateButton.centerYAnchor.constraint(equalTo: footer.centerYAnchor), ])Also applies to: 63-70
137-145
: Don’t use synchronous Data(contentsOf:) for remote images.Blocks a thread and bypasses caching; also lacks cancellation. Use URLSession + caching (or the project’s image loader) on a background queue, then update on main.
As per coding guidelines
Example:
let url = imageURL let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in guard let data, let image = UIImage(data: data) else { return } DispatchQueue.main.async { self?.imageView.image = image } } task.resume()If you already have an image pipeline in StreamChat/StreamChatUI, prefer that for consistency.
Sources/StreamChat/Database/DTOs/ChannelDTO.swift (1)
179-190
: Prefetch pushPreference to reduce Core Data faults.Include the new relationship in prefetched key paths to avoid extra fetches during list rendering.
Apply this diff:
[ KeyPath.string(\ChannelDTO.currentlyTypingUsers), KeyPath.string(\ChannelDTO.pinnedMessages), KeyPath.string(\ChannelDTO.messages), KeyPath.string(\ChannelDTO.members), KeyPath.string(\ChannelDTO.reads), - KeyPath.string(\ChannelDTO.watchers) + KeyPath.string(\ChannelDTO.watchers), + KeyPath.string(\ChannelDTO.pushPreference) ]Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents (1)
2-2
: Model saved with older tools version.lastSavedToolsVersion decreased (23605 -> 23507). Consider re‑saving with the current Xcode to avoid potential warnings.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (26)
DemoApp/Screens/UserProfile/PushPreferencesView.swift
(1 hunks)DemoApp/Screens/UserProfile/UnreadDetailsView.swift
(9 hunks)DemoApp/Screens/UserProfile/UserProfileViewController.swift
(1 hunks)DemoApp/StreamChat/Components/DemoChatChannelListRouter.swift
(2 hunks)Sources/StreamChat/APIClient/Endpoints/EndpointPath+OfflineRequest.swift
(1 hunks)Sources/StreamChat/APIClient/Endpoints/EndpointPath.swift
(2 hunks)Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift
(3 hunks)Sources/StreamChat/APIClient/Endpoints/Payloads/CurrentUserPayloads.swift
(3 hunks)Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
(1 hunks)Sources/StreamChat/APIClient/Endpoints/Payloads/UserPayloads.swift
(1 hunks)Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift
(1 hunks)Sources/StreamChat/Controllers/ChannelController/ChannelController.swift
(1 hunks)Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift
(1 hunks)Sources/StreamChat/Database/DTOs/ChannelDTO.swift
(4 hunks)Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift
(4 hunks)Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift
(1 hunks)Sources/StreamChat/Database/DatabaseSession.swift
(1 hunks)Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents
(4 hunks)Sources/StreamChat/Models/Channel.swift
(3 hunks)Sources/StreamChat/Models/CurrentUser.swift
(3 hunks)Sources/StreamChat/Models/Payload+asModel/ChannelPayload+asModel.swift
(1 hunks)Sources/StreamChat/Models/PushPreferences/PushPreference.swift
(1 hunks)Sources/StreamChat/Models/PushPreferences/PushPreferenceLevel.swift
(1 hunks)Sources/StreamChat/Workers/ChannelUpdater.swift
(1 hunks)Sources/StreamChat/Workers/CurrentUserUpdater.swift
(1 hunks)StreamChat.xcodeproj/project.pbxproj
(19 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
**/*.swift
: Respect .swiftlint.yml rules; do not suppress SwiftLint rules broadly—scope and justify any exceptions
Adhere to the project’s zero warnings policy—fix new warnings and avoid introducing any
Files:
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/UserPayloads.swift
Sources/StreamChat/Workers/CurrentUserUpdater.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift
Sources/StreamChat/Workers/ChannelUpdater.swift
Sources/StreamChat/Database/DatabaseSession.swift
Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift
Sources/StreamChat/Models/Payload+asModel/ChannelPayload+asModel.swift
Sources/StreamChat/APIClient/Endpoints/EndpointPath+OfflineRequest.swift
Sources/StreamChat/APIClient/Endpoints/EndpointPath.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/CurrentUserPayloads.swift
Sources/StreamChat/Models/PushPreferences/PushPreferenceLevel.swift
DemoApp/Screens/UserProfile/UserProfileViewController.swift
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift
DemoApp/StreamChat/Components/DemoChatChannelListRouter.swift
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift
Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift
Sources/StreamChat/Models/PushPreferences/PushPreference.swift
Sources/StreamChat/Models/Channel.swift
Sources/StreamChat/Database/DTOs/ChannelDTO.swift
DemoApp/Screens/UserProfile/UnreadDetailsView.swift
DemoApp/Screens/UserProfile/PushPreferencesView.swift
Sources/StreamChat/Models/CurrentUser.swift
Sources/{StreamChat,StreamChatUI}/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
When altering public API, update inline documentation comments in source
Files:
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/UserPayloads.swift
Sources/StreamChat/Workers/CurrentUserUpdater.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift
Sources/StreamChat/Workers/ChannelUpdater.swift
Sources/StreamChat/Database/DatabaseSession.swift
Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift
Sources/StreamChat/Models/Payload+asModel/ChannelPayload+asModel.swift
Sources/StreamChat/APIClient/Endpoints/EndpointPath+OfflineRequest.swift
Sources/StreamChat/APIClient/Endpoints/EndpointPath.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/CurrentUserPayloads.swift
Sources/StreamChat/Models/PushPreferences/PushPreferenceLevel.swift
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift
Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift
Sources/StreamChat/Models/PushPreferences/PushPreference.swift
Sources/StreamChat/Models/Channel.swift
Sources/StreamChat/Database/DTOs/ChannelDTO.swift
Sources/StreamChat/Models/CurrentUser.swift
🧠 Learnings (2)
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/StreamChatUITests/**/*.swift : Ensure tests cover view controllers and UI behaviors of StreamChatUI
Applied to files:
DemoApp/StreamChat/Components/DemoChatChannelListRouter.swift
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Sources/{StreamChat,StreamChatUI}/**/*.swift : When altering public API, update inline documentation comments in source
Applied to files:
StreamChat.xcodeproj/project.pbxproj
🧬 Code graph analysis (17)
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (1)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (1)
asModel
(33-35)
Sources/StreamChat/Workers/CurrentUserUpdater.swift (7)
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (1)
setPushPreference
(1698-1721)Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (1)
setPushPreference
(464-480)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (3)
asModel
(30-35)asModel
(58-60)asModel
(64-72)Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (2)
asModel
(33-35)savePushPreference
(53-59)Sources/StreamChat/Database/DatabaseContainer.swift (4)
write
(176-178)write
(188-212)write
(214-224)write
(226-237)
Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift (1)
Sources/StreamChat/Utils/KeyedDecodingContainer+Array.swift (1)
decodeArrayIfPresentIgnoringFailures
(61-69)
Sources/StreamChat/Workers/ChannelUpdater.swift (7)
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (1)
setPushPreference
(1698-1721)Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (1)
setPushPreference
(464-480)Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
setPushPreference
(207-234)Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (3)
asModel
(30-35)asModel
(58-60)asModel
(64-72)Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (2)
asModel
(33-35)savePushPreference
(53-59)Sources/StreamChat/Database/DatabaseContainer.swift (4)
write
(176-178)write
(188-212)write
(214-224)write
(226-237)
Sources/StreamChat/Database/DatabaseSession.swift (1)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (1)
savePushPreference
(53-59)
Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (3)
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (2)
setPushPreference
(1698-1721)snoozePushNotifications
(1727-1750)Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
setPushPreference
(207-234)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)
Sources/StreamChat/Models/Payload+asModel/ChannelPayload+asModel.swift (1)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (1)
asModel
(33-35)
Sources/StreamChat/APIClient/Endpoints/EndpointPath+OfflineRequest.swift (1)
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)
Sources/StreamChat/APIClient/Endpoints/EndpointPath.swift (1)
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)
DemoApp/Screens/UserProfile/UserProfileViewController.swift (3)
Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (5)
updateUserData
(251-280)synchronize
(182-202)loadAllUnreads
(440-446)setPushPreference
(464-480)snoozePushNotifications
(486-502)Sources/StreamChat/Workers/CurrentUserUpdater.swift (4)
updateUserData
(22-60)updateUserData
(334-358)loadAllUnreads
(195-205)setPushPreference
(207-234)DemoApp/Screens/AppConfigViewController/SwitchButton.swift (1)
didChangeValue
(20-22)
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
TestTools/StreamChatTestTools/Extensions/EndpoinPath+Equatable.swift (1)
_
(9-53)
DemoApp/StreamChat/Components/DemoChatChannelListRouter.swift (2)
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (2)
setPushPreference
(1698-1721)snoozePushNotifications
(1727-1750)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)
Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (3)
Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (2)
setPushPreference
(464-480)snoozePushNotifications
(486-502)Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
setPushPreference
(207-234)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)
Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift (1)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (2)
savePushPreference
(53-59)asModel
(33-35)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (5)
Sources/StreamChat/Database/DTOs/ChannelDTO.swift (5)
channel
(429-431)asModel
(508-510)create
(526-682)load
(150-153)load
(155-161)Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (3)
asModel
(30-35)asModel
(58-60)asModel
(64-72)Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift (4)
asModel
(227-227)create
(231-289)load
(50-61)load
(82-85)Sources/StreamChat/Database/DTOs/NSManagedObject+Validation.swift (1)
isNotDeleted
(19-22)Sources/StreamChat/Utils/Database/NSManagedObject+Extensions.swift (1)
insertNewObject
(14-22)
Sources/StreamChat/Database/DTOs/ChannelDTO.swift (2)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (2)
savePushPreference
(53-59)asModel
(33-35)Sources/StreamChat/Models/Payload+asModel/ChannelPayload+asModel.swift (3)
asModel
(10-74)asModel
(81-116)asModel
(122-129)
DemoApp/Screens/UserProfile/UnreadDetailsView.swift (1)
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
unreads
(41-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Test LLC (Debug)
- GitHub Check: Build Test App and Frameworks
- GitHub Check: Metrics
- GitHub Check: Metrics
🔇 Additional comments (47)
Sources/StreamChat/Database/DatabaseSession.swift (1)
69-74
: Public API addition documented and alignedSignature and doc comment match the new Core Data helper, keeping the protocol contract coherent.
Sources/StreamChat/APIClient/Endpoints/EndpointPath+OfflineRequest.swift (1)
18-19
: Confirm non-queueable.pushPreferences
.pushPreferences
is explicitly excluded from offline queuing (offline calls return immediately). Confirm this aligns with UX requirements—surface failures or defer actions—and ensure the endpoint remains idempotent for future queueing.Sources/StreamChat/APIClient/Endpoints/Payloads/UserPayloads.swift (1)
33-34
: LGTM; push_preferences is decoded in CurrentUserPayload and intentionally stripped from extraData. CurrentUserPayloads.swift decodes pushPreference; UserUpdateRequestBody excludes it.Sources/StreamChat/Models/Payload+asModel/ChannelPayload+asModel.swift (1)
71-73
: Resolved: pushPreference docs and DTO mapping verified
ChatChannel’s public API includes a documentedpushPreference
property, andChannelDTO.asModel
correctly wirespushPreference
.StreamChat.xcodeproj/project.pbxproj (19)
5743-5743
: Core Data: ensure model/schema includes PushPreferenceDTOAdding a DTO usually requires updating the xcdatamodeld (entities/attributes, migration options). Please confirm the model changes and lightweight migration are in place to avoid runtime crashes.
5933-5933
: LGTM: Payloads group wiringEntry looks correct in the Payloads group.
6092-6092
: Public API docs reminder for new modelsIf PushPreference* types are public, add/verify doc comments in source per repo conventions.
Based on learnings
6968-6969
: LGTM: New DemoApp groupUserProfile group addition in DemoApp is fine.
8688-8706
: LGTM: New groups (PushPreferences, UserProfile)Groups and children look consistent with the file refs.
11345-11345
: LGTM: PushPreferencesView in DemoApp targetIncluded in Sources as expected for Demo UI.
11369-11369
: LGTM: UnreadDetailsView in DemoApp targetIncluded in Sources as expected for Demo UI.
11600-11600
: Same concern as earlier: target membership of core modelsSee the earlier comment about keeping PushPreference.swift confined to core targets.
11624-11624
: Same concern as earlier: target membership of core modelsSee the earlier comment about keeping PushPreferenceLevel.swift confined to core targets.
11812-11812
: Same concern as earlier: target membership of core modelsSee the earlier comment about keeping PushPreferencePayloads.swift confined to core targets.
11949-11949
: Same concern as earlier: target membership of core modelsSee the earlier comment about keeping PushPreferenceDTO.swift confined to core targets.
12580-12580
: Same concern as earlier: target membership of core modelsSee the earlier comment about keeping PushPreferenceLevel.swift confined to core targets.
12663-12666
: Same concern as earlier: target membership of core modelsSee the earlier comment about avoiding compiling PushPreferencePayloads.swift / PushPreference.swift into non-core targets.
12769-12769
: Same concern as earlier: target membership of core modelsSee the earlier comment about keeping PushPreferenceDTO.swift confined to core targets.
13969-13969
: DemoApp deployment target raised to iOS 15.6 — confirm necessityIf this bump is only needed for the DemoApp (e.g., new SwiftUI APIs), fine. Please confirm the framework targets’ minimum iOS remain unchanged to avoid an unintended SDK support drop.
13994-13994
: Same as above: deployment target bumpConfirm intent and no impact on framework targets.
14020-14020
: Same as above: deployment target bumpConfirm intent and no impact on framework targets.
4314-4319
: Packaging includes new PushPreference files All new core files live inSources/StreamChat
, are part of the SwiftPMStreamChat
target, included byStreamChat.podspec
’ssource_files
glob, and referenced inproject.pbxproj
.
1431-1440
: Verified target membership – no changes neededPushPreference.swift, PushPreferenceLevel.swift, PushPreferencePayloads.swift and PushPreferenceDTO.swift are only in StreamChat and StreamChatStatic; UnreadDetailsView.swift and PushPreferencesView.swift are only in DemoApp.
Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift (3)
97-99
: Decoding defaults/order: LGTM.Using decodeIfPresent with a safe default for activeLiveLocations and optional pushPreference is consistent with existing patterns.
53-53
: Approve channel-level pushPreference wiring
Verified pushPreference is decoded, persisted (DTOs), mapped in models, and surfaced in ChatChannel/UI.
79-80
: No changes needed for pushPreference mapping
Server uses snake_case "push_preferences" in API responses.DemoApp/Screens/UserProfile/UnreadDetailsView.swift (1)
11-11
: Whitespace-only changes.No action needed.
Also applies to: 15-15, 22-22, 62-62, 79-79, 111-111, 121-121, 132-132, 212-212, 216-216, 219-219, 234-234
Sources/StreamChat/Models/CurrentUser.swift (3)
64-66
: Public API: pushPreference surfaced on CurrentChatUser — LGTM.Docstring present as required.
105-105
: Assignment: LGTM.Property is correctly initialized.
92-94
: CurrentUserDTO.asModel already maps pushPreferenceSources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (2)
482-502
: Global snoozePushNotifications API: LGTM.Correctly sets disabledUntil and preserves level semantics.
460-480
: Global setPushPreference API: resolved. Verified that CurrentUserUpdater writes using a constant ID and retrieval occurs via the pushPreference relationship on CurrentUserDTO, so the hard-coded ID does not affect consistency.DemoApp/StreamChat/Components/DemoChatChannelListRouter.swift (1)
7-7
: Import SwiftUI: LGTM.Required for hosting PushPreferencesView.
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
49-59
: pushPreferences offline queue behavior verified
EndpointPath.pushPreferences
returnsfalse
inshouldBeQueuedOffline
, so this endpoint won’t be queued offline.Sources/StreamChat/APIClient/Endpoints/EndpointPath.swift (1)
100-101
: No change required for pushPreferences path
The chat API prefixes endpoints withchat/
, so returning"push_preferences"
correctly yieldschat/push_preferences
.Sources/StreamChat/Models/Channel.swift (1)
218-220
: Constructor parameter addition looks good.Initializer wiring for
pushPreference
with a default is correct.Sources/StreamChat/APIClient/Endpoints/Payloads/CurrentUserPayloads.swift (2)
83-84
: Decoding path LGTM.
decodeIfPresent
with the new key is correct and backward compatible.
21-23
: No action needed:UserPayloadsCodingKeys
already includescase pushPreference = "push_preferences"
.Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (1)
54-61
: Confirm dropping dictionary keys is intentional.UserPushPreferencesPayload.asModel() returns only values, discarding keys. If keys have semantic meaning (e.g., per-user or per-scope), this loses information.
Is the payload guaranteed to contain at most one relevant entry (e.g., current user), making the key irrelevant?
Sources/StreamChat/Database/DTOs/CurrentUserDTO.swift (2)
250-253
: LGTM: Model mapping includes pushPreference.Correctly materializes dto.pushPreference and threads it into CurrentChatUser.
254-288
: Verify CurrentChatUser.pushPreference documentation
Unable to locate the CurrentChatUser definition to confirm if the new pushPreference parameter and property are documented. Ensure both are covered with inline doc comments per guidelines.Sources/StreamChat/Models/PushPreferences/PushPreferenceLevel.swift (1)
7-25
: Docs look good; confirm public API coverage.Struct and cases are documented. If any new public property or init was added elsewhere (e.g., on models), ensure docs exist.
As per coding guidelines
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (1)
52-59
: LGTM: save helper stores id, chatLevel, disabledUntil.Consistent with payload mapping.
Sources/StreamChat/Database/DTOs/ChannelDTO.swift (1)
636-675
: asModel mapping looks good.pushPreference is bridged and passed through to ChatChannel correctly.
Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents (3)
81-81
: ChannelDTO.pushPreference relationship: LGTM.Inverse and deletion rule are appropriate.
167-167
: CurrentUserDTO.pushPreference relationship: LGTM.Inverse and deletion rule are appropriate.
427-438
: Enable lightweight migration in DatabaseContainer
No explicitshouldMigrateStoreAutomatically
/shouldInferMappingModelAutomatically
flags were found. Confirm these are set on yourpersistentStoreDescriptions
(e.g. in DatabaseContainer.swift around lines 167–170) before callingloadPersistentStores
.
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
Show resolved
Hide resolved
SDK Size
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good ✅ There's just one retain cycle in the demo app, and of course the tests before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
StreamChat.xcodeproj/project.pbxproj (1)
13973-13999
: Undo the DemoApp deployment target bump to 15.6Raising the DemoApp’s minimum iOS target from 14.3 straight to 15.6 drops support for every device still on iOS 14.x or 15.0–15.5 without a documented requirement for that jump. Please revert to the previous target (or justify a smaller, necessary bump tied to new APIs) so we don’t unnecessarily narrow the supported install base. Don’t forget to apply the same fix to the other build configurations modified in this hunk.
🧹 Nitpick comments (4)
TestTools/StreamChatTestTools/TestData/DummyData/UserPayload.swift (1)
45-77
: ExposepushPreference
in the dummy factoryThe initializer now requires
pushPreference
, but the helper hardcodesnil
. That blocks tests from constructingCurrentUserPayload
cases with a non-nil push preference, which is exactly what the new feature needs. Please surface this as a parameter (defaulting tonil
, same asprivacySettings
) so tests can exercise those paths.static func dummy( userId: UserId, name: String = .unique, imageUrl: URL? = .unique(), role: UserRole = .admin, teamsRole: [String: UserRole]? = nil, extraData: [String: RawJSON] = [:], teams: [TeamId] = [.unique, .unique, .unique], language: String? = nil, isBanned: Bool = false, updatedAt: Date = .unique, deactivatedAt: Date? = nil, - privacySettings: UserPrivacySettingsPayload? = nil + privacySettings: UserPrivacySettingsPayload? = nil, + pushPreference: PushPreferencePayload? = nil ) -> CurrentUserPayload { .init( id: userId, name: name, imageURL: imageUrl, role: role, teamsRole: teamsRole, createdAt: .unique, updatedAt: updatedAt, deactivatedAt: deactivatedAt, lastActiveAt: .unique, isOnline: true, isInvisible: true, isBanned: isBanned, teams: teams, language: language, extraData: extraData, privacySettings: privacySettings, - pushPreference: nil + pushPreference: pushPreference ) }Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift (1)
391-394
: Use the generated user ID when seeding push preferencesWe already generate
currentUserId
; reusing it here keeps the seeded push preference consistent with the rest of the fixture data. That avoids inserting a dangling preference tied to the literal string"currentUserId"
.- try session.savePushPreference(id: "currentUserId", payload: .init(chatLevel: "mentions", disabledUntil: nil)) + try session.savePushPreference(id: currentUserId, payload: .init(chatLevel: "mentions", disabledUntil: nil))TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift (1)
214-216
: Expose pushPreference in DM/NonDM mocks
mockDMChannel
always forcespushPreference
tonil
, which makes it impossible to exercise the new push-preference flows when using this helper. Please thread the (optional) parameter through here (and mirror the change inmockNonDMChannel
) so tests relying on these convenience mocks can configure the new field.activeLiveLocations: [SharedLocation] = [], + pushPreference: PushPreference? = nil ) -> Self { self.init( … - activeLiveLocations: activeLiveLocations, - pushPreference: nil + activeLiveLocations: activeLiveLocations, + pushPreference: pushPreference ) }Apply the same pattern to
mockNonDMChannel
.Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift (1)
457-471
: Consider adding an asModel assertion for push preference.We now rely on
ChannelPayload.asModel
to surfacepushPreference
ontoChatChannel
, but this test still exercises thenil
path. A small follow-up test with a non-nil
payload would verify the mapping end-to-end.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (20)
Sources/StreamChat/APIClient/Endpoints/Payloads/CurrentUserPayloads.swift
(3 hunks)StreamChat.xcodeproj/project.pbxproj
(21 hunks)TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json
(1 hunks)TestTools/StreamChatTestTools/Fixtures/JSONs/CurrentUser.json
(1 hunks)TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift
(4 hunks)TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift
(10 hunks)TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift
(2 hunks)TestTools/StreamChatTestTools/TestData/DummyData/CurrentUserPayload.swift
(4 hunks)TestTools/StreamChatTestTools/TestData/DummyData/UserPayload.swift
(1 hunks)TestTools/StreamChatTestTools/TestData/DummyData/XCTestCase+Dummy.swift
(4 hunks)Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift
(2 hunks)Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
(4 hunks)Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift
(1 hunks)Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift
(1 hunks)Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
(1 hunks)Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift
(1 hunks)Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
(9 hunks)Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
(2 hunks)Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift
(1 hunks)Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- Sources/StreamChat/APIClient/Endpoints/Payloads/CurrentUserPayloads.swift
👮 Files not reviewed due to content moderation or server errors (1)
- TestTools/StreamChatTestTools/Fixtures/JSONs/CurrentUser.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
**/*.swift
: Respect .swiftlint.yml rules; do not suppress SwiftLint rules broadly—scope and justify any exceptions
Adhere to the project’s zero warnings policy—fix new warnings and avoid introducing any
Files:
Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift
TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
TestTools/StreamChatTestTools/TestData/DummyData/CurrentUserPayload.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift
Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift
Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift
TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift
TestTools/StreamChatTestTools/TestData/DummyData/UserPayload.swift
TestTools/StreamChatTestTools/TestData/DummyData/XCTestCase+Dummy.swift
Tests/{StreamChatTests,StreamChatUITests}/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Tests/{StreamChatTests,StreamChatUITests}/**/*.swift
: Add or extend tests in the matching module’s Tests folder
Prefer using provided test fakes/mocks in tests when possible
Files:
Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift
Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift
Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift
Tests/StreamChatTests/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Ensure tests cover core models and API surface of StreamChat
Files:
Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift
Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift
Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift
🧠 Learnings (4)
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/StreamChatTests/**/*.swift : Ensure tests cover core models and API surface of StreamChat
Applied to files:
Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift
StreamChat.xcodeproj/project.pbxproj
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/{StreamChatTests,StreamChatUITests}/**/*.swift : Prefer using provided test fakes/mocks in tests when possible
Applied to files:
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift
Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift
StreamChat.xcodeproj/project.pbxproj
TestTools/StreamChatTestTools/TestData/DummyData/XCTestCase+Dummy.swift
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/{StreamChatTests,StreamChatUITests}/**/*.swift : Add or extend tests in the matching module’s Tests folder
Applied to files:
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
StreamChat.xcodeproj/project.pbxproj
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/StreamChatUITests/**/*.swift : Ensure tests cover view controllers and UI behaviors of StreamChatUI
Applied to files:
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift
🧬 Code graph analysis (7)
Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift (1)
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift (1)
TestTools/StreamChatTestTools/Extensions/String+Date.swift (1)
toDate
(10-17)
Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift (2)
TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift (1)
dummy
(11-41)TestTools/StreamChatTestTools/TestData/DummyData/ChannelDetailPayload.swift (1)
dummy
(11-58)
Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift (1)
TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift (1)
savePushPreference
(132-134)
Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift (1)
Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)
TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift (7)
Sources/StreamChat/Database/DTOs/ChannelDTO.swift (1)
saveChannelList
(218-235)Sources/StreamChat/Database/DTOs/ReactionListQueryDTO.swift (1)
saveQuery
(53-77)Sources/StreamChat/Database/DTOs/MessageReminderDTO.swift (1)
saveReminder
(107-143)Sources/StreamChat/Database/DTOs/UserDTO.swift (1)
saveUsers
(183-189)Sources/StreamChat/Database/DTOs/MessageDTO.swift (5)
saveMessages
(1163-1178)saveMessageSearch
(1541-1546)saveMessage
(944-1159)saveMessage
(1180-1224)saveMessage
(1326-1330)Sources/StreamChat/Database/DTOs/MessageReactionDTO.swift (1)
saveReactions
(138-150)Sources/StreamChat/Database/DTOs/MemberModelDTO.swift (1)
saveMembers
(160-173)
Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift (1)
TestTools/StreamChatTestTools/Extensions/String+Date.swift (1)
toDate
(10-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build Test App and Frameworks
- GitHub Check: Build LLC + UI (Xcode 15)
- GitHub Check: Test LLC (Debug)
- GitHub Check: Automated Code Review
- GitHub Check: Metrics
🔇 Additional comments (16)
Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift (1)
409-410
: Initializer update handled correctly.Thanks for wiring the new
pushPreference
parameter (and keepingactiveLiveLocations
explicit) into the fixture builder—this keeps the helper aligned with the updatedChannelPayload
signature.Tests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swift (1)
78-85
: Nice coverage for the new endpoint path.These assertions guard both the offline queue behaviour and the raw path string, so regressions in the new push-preferences endpoint will get caught early.
TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json (1)
1608-1612
: Confirm the payload key name.The fixture uses
push_preference
(singular). Please double-check this matches the coding key inChannelPayload
(which, per the implementation summary, might expect"push_preferences"
). A mismatch here would keep the decoded valuenil
, undermining the new tests. Let's align the JSON key with the production payload.Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift (1)
56-58
: Initializer update looks correct.Good call threading the new
pushPreference
parameter through the channel payload setup so the test scaffold keeps compiling.Tests/StreamChatTests/APIClient/Endpoints/Payloads/CurrentUserPayloads_Tests.swift (1)
46-48
: Fixture assertion keeps the new field honest.Verifying both the level and
disabledUntil
timestamp against the fixture will surface decoding regressions quickly.Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift (2)
350-353
: Great to see the fixture asserting push preferences.This ensures the decoding path stays wired up once the backend starts returning the field.
563-565
: Initializer update keeps the helpers aligned.Thanks for propagating the new parameter into the minimal payload helper to prevent accidental churn later.
Tests/StreamChatTests/APIClient/Endpoints/UserEndpoints_Tests.swift (1)
87-121
: Endpoint contract well covered.The test exercises the body, HTTP verb, and connection requirements, so the new push-preference endpoint should stay stable.
Tests/StreamChatTests/Database/DTOs/CurrentUserDTO_Tests.swift (1)
73-76
: End-to-end round-trip looks solid.Setting the payload and then asserting on the model level (with tolerant date comparison) gives confidence that persistence and mapping handle the new preference correctly.
Also applies to: 111-112
TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift (1)
23-40
: Dummy payload now exposes push preferenceAdding the optional
pushPreference
with a sensible default keeps existing call sites intact while letting the tests opt into the new data. Nice and tidy.Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift (2)
350-356
: Great coverage for push preference persistenceThe round‑trip assertion guarantees the new push preference survives the save/load cycle and matches the stored level/expiry exactly—thanks for threading it through this core integration test.
Also applies to: 483-489
1134-1136
: Initializer updates stay alignedAppreciate the sweep across every direct
ChannelPayload
construction to pass the freshpushPreference
slot—keeps the fixtures compiling and explicit about intent.Also applies to: 1193-1195, 1554-1565, 1614-1620, 1645-1647, 1689-1700, 1754-1758
TestTools/StreamChatTestTools/TestData/DummyData/XCTestCase+Dummy.swift (3)
29-31
: Current-user dummy mirrors production shapeIncluding
pushPreference
in the canned current-user payload ensures the higher-level tests can exercise the new API surface without extra boilerplate.
164-216
: Channel dummy handles optional push preference cleanlyMaking
channelReads
optional and piping the optionalpushPreference
straight into the payload keeps the helper flexible while preserving the previous default behaviour.
334-336
: No-extra-data payload stays compatibleExplicitly setting
pushPreference: nil
here keeps this stripped-down builder aligned with the broadened initializer—thanks for catching it.TestTools/StreamChatTestTools/TestData/DummyData/CurrentUserPayload.swift (1)
29-53
: Current-user factories carry push preference throughBoth dummy constructors forwarding the optional push preference (and privacy settings) keeps the helpers future-proof for the new APIs.
Also applies to: 64-88
Tests/StreamChatTests/APIClient/Endpoints/Payloads/PushPreferencePayload_Tests.swift
Outdated
Show resolved
Hide resolved
TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (4)
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift (1)
907-937
: Verify the DB write and returned preferenceThe test name promises we persist the push preference, yet we only check that the completion fires without an error. A regression where
savePushPreference
stops writing (or the returnedPushPreference
no longer matches the payload) would sail through. Please assert that the spy recorded the write with the expected payload or, even better, read the storedPushPreference
back from the DB view context and compare the level/disabledUntil to the request, and also assert that the completion handed back the same model that the worker produced. Based on learnings.Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift (1)
2233-2266
: Tighten the “savesToDatabase” assertionSimilar to the user-updater test, we only verify that the completion is called. To make this test meaningful, please assert that the database spy captured a
savePushPreference
call (or read the DTO back viadatabase.viewContext
) and that thePushPreference
delivered to the completion matches the expected level/disabledUntil. Without that, a regression on persistence or payload mapping will go unnoticed. Based on learnings.Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift (2)
898-934
: Assert callback queue consistency for setPushPreferenceIn other controller tests we verify that completions are dispatched on
callbackQueue
. Here we only capture the result, so we’d miss a regression wherecallback { … }
is removed from the production code. Please add the usualAssertTestQueue(withId: callbackQueueID)
inside the completion (same for the failure branch) so we keep the scheduling contract covered.
956-993
: Mirror the callback-queue assertion for snoozePushNotificationsSame rationale as above: add
AssertTestQueue(withId: callbackQueueID)
inside the success and failure closures so that we continue to guard the callback-queue guarantee for the snooze API.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
(1 hunks)TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift
(3 hunks)TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift
(3 hunks)Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
(1 hunks)Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
(1 hunks)Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
(1 hunks)Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
**/*.swift
: Respect .swiftlint.yml rules; do not suppress SwiftLint rules broadly—scope and justify any exceptions
Adhere to the project’s zero warnings policy—fix new warnings and avoid introducing any
Files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
Tests/{StreamChatTests,StreamChatUITests}/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Tests/{StreamChatTests,StreamChatUITests}/**/*.swift
: Add or extend tests in the matching module’s Tests folder
Prefer using provided test fakes/mocks in tests when possible
Files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
Tests/StreamChatTests/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Ensure tests cover core models and API surface of StreamChat
Files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
Sources/{StreamChat,StreamChatUI}/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
When altering public API, update inline documentation comments in source
Files:
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift
🧠 Learnings (4)
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/StreamChatTests/**/*.swift : Ensure tests cover core models and API surface of StreamChat
Applied to files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/StreamChatUITests/**/*.swift : Ensure tests cover view controllers and UI behaviors of StreamChatUI
Applied to files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/{StreamChatTests,StreamChatUITests}/**/*.swift : Add or extend tests in the matching module’s Tests folder
Applied to files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to Tests/{StreamChatTests,StreamChatUITests}/**/*.swift : Prefer using provided test fakes/mocks in tests when possible
Applied to files:
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift
🧬 Code graph analysis (7)
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift (3)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift (1)
setPushPreference
(602-611)Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (2)
setPushPreference
(1698-1721)snoozePushNotifications
(1727-1750)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift (4)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift (1)
setPushPreference
(602-611)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)TestTools/StreamChatTestTools/SpyPattern/Spy/APIClient_Spy.swift (1)
test_simulateResponse
(108-111)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift (3)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift (1)
setPushPreference
(602-611)Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (1)
setPushPreference
(464-480)Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
setPushPreference
(207-234)
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift (7)
Tests/StreamChatTests/Workers/ChannelUpdater_Tests.swift (3)
test_setPushPreference_makesCorrectAPICall
(2215-2231)test_setPushPreference_successfulResponse_savesToDatabase
(2233-2266)test_setPushPreference_propagatesNetworkError
(2268-2291)TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift (1)
setPushPreference
(103-110)Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (1)
setPushPreference
(464-480)Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
setPushPreference
(207-234)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)Sources/StreamChat/APIClient/Endpoints/UserEndpoints.swift (1)
pushPreferences
(49-59)TestTools/StreamChatTestTools/SpyPattern/Spy/APIClient_Spy.swift (1)
test_simulateResponse
(108-111)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift (5)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift (1)
setPushPreference
(103-110)Sources/StreamChat/Workers/CurrentUserUpdater.swift (1)
setPushPreference
(207-234)Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (1)
setPushPreference
(1698-1721)Sources/StreamChat/Workers/ChannelUpdater.swift (1)
setPushPreference
(722-748)TestTools/StreamChatTestTools/Extensions/Result+Extensions.swift (2)
invoke
(8-10)invoke
(14-21)
Tests/StreamChatTests/Controllers/CurrentUserController/CurrentUserController_Tests.swift (2)
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift (1)
setPushPreference
(103-110)Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (2)
setPushPreference
(464-480)snoozePushNotifications
(486-502)
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (1)
Sources/StreamChat/Database/DTOs/PushPreferenceDTO.swift (1)
asModel
(33-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Automated Code Review
- GitHub Check: Test LLC (Debug)
- GitHub Check: Build Test App and Frameworks
- GitHub Check: Build LLC + UI (Xcode 15)
- GitHub Check: Metrics
🔇 Additional comments (3)
Sources/StreamChat/APIClient/Endpoints/Payloads/PushPreferencePayloads.swift (1)
71-80
: Guard against duplicate channel preferences crashing the payload parser.
Dictionary(uniqueKeysWithValues:)
traps when the flattened payload happens to contain the same channel CID twice, so a bad server payload would take the SDK down. Please merge manually (last write wins) instead of relying on the initializer.- .init(uniqueKeysWithValues: values - .flatMap { $0 } - .compactMap { key, value in - guard let channelId = try? ChannelId(cid: key) else { return nil } - return (channelId, value.asModel()) - } - ) + values + .flatMap { $0 } + .reduce(into: [ChannelId: PushPreference]()) { result, element in + guard let channelId = try? ChannelId(cid: element.key) else { return } + result[channelId] = element.value.asModel() + }TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelUpdater_Mock.swift (1)
160-164
: Push preference mock wiring looks solidThe new atomic slots, cleanup reset, and override mirror the production signature, so tests can capture parameters and drive completions deterministically. Nicely aligned with the other updater mocks.
Also applies to: 306-309, 602-610
TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/CurrentUserUpdater_Mock.swift (1)
40-43
: Good parity with the production push preference APICapturing the payload/completion and exposing a stubbed result keeps the current-user mock consistent with the channel mock, which should make the new push preference tests straightforward.
Also applies to: 103-110, 141-143
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Outdated
Show resolved
Hide resolved
Tests/StreamChatTests/Controllers/ChannelController/ChannelController_Tests.swift
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
CHANGELOG.md
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
CHANGELOG.md
📄 CodeRabbit inference engine (AGENTS.md)
Update CHANGELOG for user-visible SDK changes
Files:
CHANGELOG.md
🧠 Learnings (1)
📚 Learning: 2025-09-18T10:00:24.878Z
Learnt from: CR
PR: GetStream/stream-chat-swift#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T10:00:24.878Z
Learning: Applies to CHANGELOG.md : Update CHANGELOG for user-visible SDK changes
Applied to files:
CHANGELOG.md
🪛 markdownlint-cli2 (0.18.1)
CHANGELOG.md
9-9: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
10-10: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
11-11: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
12-12: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Test LLC (Debug)
- GitHub Check: Build LLC + UI (Xcode 15)
- GitHub Check: Automated Code Review
- GitHub Check: Metrics
|
🔗 Issue Links
https://linear.app/stream/issue/IOS-855/ios-support-push-preferences
🎯 Goal
Add support for push preferences to control the push notifications per channel and globally.
📝 Summary
CurrentChatUserController.setPushPreference(level:)
- Sets the push preferences globally for the current user.CurrentChatUserController.snoozePushNotifications(until:)
- Snoozes pushes globally for the current user.ChatChannelController.setPushPreference(level:)
- Sets the push preferences of a specific channel.ChatChannelController.snoozePushNotifications(until:)
- Snoozes pushes of a specific channel.🛠 Implementation
setPushPreferences(level:)
: This function accepts a level, which can benone
,mentions
orall
:all
: All messages will trigger a notification.mentions
: Only mentions will trigger a notification.none
: Will disable push notifications permanently until the level is changed again.snoozePushNotifications(until:)
: This function accepts a date until when the notifications should be snoozed. Once it reaches this date, the notifications will start working again. IfsetPushPreference(level:)
is called, it will remove the snooze.🎨 Showcase
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-09-26.at.12.14.06.mp4
🧪 Manual Testing Notes
Global Push Prefs:
Channel Push Prefs:
☑️ Contributor Checklist
docs-content
repoSummary by CodeRabbit
New Features
Chores
Tests