Use OpenAPI model and v2 endpoint for role search#4167
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (18)
📒 Files selected for processing (1)
Disabled knowledge base sources:
📝 WalkthroughWalkthroughRole search now uses generated public ChangesRole search API migration
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant RoleSearchController
participant RolesRepository
participant RoleEndpoints
participant SearchRolesResponse
RoleSearchController->>RolesRepository: searchRoles(query)
RolesRepository->>RoleEndpoints: build searchRoles endpoint
RoleEndpoints->>SearchRolesResponse: decode response
RolesRepository-->>RoleSearchController: return response.roles
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
| optionalize_property Role createdAt | ||
| optionalize_property Role updatedAt |
There was a problem hiding this comment.
Avoids API breaking change (cleanup for v6).
| queryItems: [ | ||
| "id": APIHelper.convertAnyToString(id) | ||
| ], | ||
| queryItems: APIHelper.mapValuesToQueryDictionary([ | ||
| "id": id | ||
| ]), |
There was a problem hiding this comment.
New function from StreamCore and generated by the OpenAPI generator. Fixes nil handling for optional query items.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
Tests/StreamChatTests/APIClient/Endpoints/Payloads/RolePayloads_Tests.swift (1)
30-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider updating test method names to match the migrated types.
Several test method names still reference the old
RolePayload/RoleListPayloadtypes and concepts (mapsCustomKeyToIsCustom,asModel_mapsAllFields,roleListPayload_*) but now decode intoRoleandSearchRolesResponse. Most notably,test_rolePayload_mapsCustomKeyToIsCustomassertspayload.customrather than the deprecatedisCustom, making the name actively misleading.♻️ Suggested renames
- func test_rolePayload_mapsCustomKeyToIsCustom() throws { + func test_role_decodesCustomKeyCorrectly() throws {- func test_rolePayload_asModel_mapsAllFields() { + func test_role_init_mapsAllFields() {- func test_roleListPayload_isDecodedCorrectly() throws { + func test_searchRolesResponse_isDecodedCorrectly() throws {- func test_roleListPayload_whenEmpty_isDecodedCorrectly() throws { + func test_searchRolesResponse_whenEmpty_isDecodedCorrectly() throws {Also applies to: 62-78, 80-104, 106-117
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Tests/StreamChatTests/APIClient/Endpoints/Payloads/RolePayloads_Tests.swift` around lines 30 - 42, Rename the affected tests to reference the migrated types and current behavior: update role payload names to Role, replace mapsCustomKeyToIsCustom with a name describing the custom field, rename asModel_mapsAllFields to reflect Role decoding, and rename roleListPayload_* tests to reference SearchRolesResponse. Keep each test’s assertions unchanged.Tests/StreamChatTests/Models/Role_Tests.swift (1)
49-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winInequality test doesn't isolate the field under test.
Each
Role.dummy()call generates uniquecreatedAt/updatedAtviaDate.unique, so every assertion passes due to timestamp differences alone — not due to thename,custom, orscopesdifferences the test claims to verify. IfRole.Equatableignoredcustomorscopes, these assertions would still pass, masking a potential bug.♻️ Proposed fix: pass explicit timestamps to isolate each field
func test_equatable_whenDifferentValues_thenNotEqual() { - let role = Role.dummy(name: "admin") - - XCTAssertNotEqual(role, Role.dummy(name: "moderator")) - XCTAssertNotEqual(role, Role.dummy(custom: true, name: "admin")) - XCTAssertNotEqual(role, Role.dummy(name: "admin", scopes: ["user"])) + let createdAt = Date.unique + let updatedAt = Date.unique + let role = Role.dummy(createdAt: createdAt, custom: false, name: "admin", scopes: [], updatedAt: updatedAt) + + XCTAssertNotEqual(role, Role.dummy(createdAt: createdAt, custom: false, name: "moderator", scopes: [], updatedAt: updatedAt)) + XCTAssertNotEqual(role, Role.dummy(createdAt: createdAt, custom: true, name: "admin", scopes: [], updatedAt: updatedAt)) + XCTAssertNotEqual(role, Role.dummy(createdAt: createdAt, custom: false, name: "admin", scopes: ["user"], updatedAt: updatedAt)) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Tests/StreamChatTests/Models/Role_Tests.swift` around lines 49 - 55, Update test_equatable_whenDifferentValues_thenNotEqual to pass identical explicit createdAt and updatedAt values to every Role.dummy instance, isolating each assertion to only the differing name, custom, or scopes field. Reuse shared timestamp constants or variables so timestamp differences cannot cause the inequality assertions to pass.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Sources/StreamChat/Models/Role`+Identifiable.swift:
- Around line 1-14: Add Sources/StreamChat/Models/Role+Identifiable.swift to the
StreamChat target by registering it in StreamChat.xcodeproj/project.pbxproj,
including the file reference, build-file entry, and target Sources build phase.
Verify the Role extension is compiled by the app target.
---
Nitpick comments:
In `@Tests/StreamChatTests/APIClient/Endpoints/Payloads/RolePayloads_Tests.swift`:
- Around line 30-42: Rename the affected tests to reference the migrated types
and current behavior: update role payload names to Role, replace
mapsCustomKeyToIsCustom with a name describing the custom field, rename
asModel_mapsAllFields to reflect Role decoding, and rename roleListPayload_*
tests to reference SearchRolesResponse. Keep each test’s assertions unchanged.
In `@Tests/StreamChatTests/Models/Role_Tests.swift`:
- Around line 49-55: Update test_equatable_whenDifferentValues_thenNotEqual to
pass identical explicit createdAt and updatedAt values to every Role.dummy
instance, isolating each assertion to only the differing name, custom, or scopes
field. Reuse shared timestamp constants or variables so timestamp differences
cannot cause the inequality assertions to pass.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e34c3837-2532-4787-8c1e-3dbbc63c29d3
⛔ Files ignored due to path filters (3)
Sources/StreamChat/Generated/OpenAPI/APIs/DefaultEndpoints.swiftis excluded by!**/generated/**Sources/StreamChat/Generated/OpenAPI/models/Role.swiftis excluded by!**/generated/**Sources/StreamChat/Generated/OpenAPI/models/SearchRolesResponse.swiftis excluded by!**/generated/**
📒 Files selected for processing (19)
Package.swiftScripts/openapi_generate.shSources/StreamChat/APIClient/Endpoints/EndpointPath+OfflineRequest.swiftSources/StreamChat/APIClient/Endpoints/Payloads/RolePayloads.swiftSources/StreamChat/APIClient/Endpoints/RoleEndpoints.swiftSources/StreamChat/Models/Role+Identifiable.swiftSources/StreamChat/Models/Role.swiftSources/StreamChat/Repositories/RolesRepository.swiftStreamChat.xcodeproj/project.pbxprojTests/StreamChatTests/APIClient/Endpoints/EndpointPath_Tests.swiftTests/StreamChatTests/APIClient/Endpoints/Payloads/RolePayloads_Tests.swiftTests/StreamChatTests/APIClient/Endpoints/RoleEndpoints_Tests.swiftTests/StreamChatTests/Controllers/RoleSearchController/RoleSearchController+Combine_Tests.swiftTests/StreamChatTests/Controllers/RoleSearchController/RoleSearchController_Tests.swiftTests/StreamChatTests/MentionSuggestions/EnhancedMentionSuggestionsProvider_Tests.swiftTests/StreamChatTests/Models/Role_Tests.swiftTests/StreamChatTests/Repositories/RolesRepository_Tests.swiftTests/StreamChatTests/StateLayer/RoleSearchState_Tests.swiftTests/StreamChatTests/StateLayer/RoleSearch_Tests.swift
💤 Files with no reviewable changes (2)
- Sources/StreamChat/APIClient/Endpoints/Payloads/RolePayloads.swift
- Sources/StreamChat/Models/Role.swift
Generated by 🚫 Danger |
SDK Performance
|
| ) | ||
| } | ||
|
|
||
| static func searchRoles(query: String, limit: Int?, nameGt: String?, roleType: String?, includeGlobalRoles: Bool?, requiresConnectionId: Bool = false) -> Endpoint<SearchRolesResponse> { |
There was a problem hiding this comment.
we should align these in new lines, didn't we have a formatter for that?
There was a problem hiding this comment.
We don't enforce it with linter/formatter at the moment so this stays unchanged when formatter goes over it (there is no maxWidth currently set). I will apply this on the generator level, nicer if less formatting is needed when code is generated.
Checked that the DefaultAPI template does the same so probably better to keep templates as is.
There was a problem hiding this comment.
Added special instruction only for openAPI output. Fixed.
Public Interface+ public final class Role: Sendable, Codable, JSONEncodable
+
+ case createdAt = "created_at"
+ case custom
+ case name
+ case scopes
+ case updatedAt = "updated_at"
+
+
+ public let createdAt: Date?
+ public let custom: Bool
+ public let name: String
+ public let scopes: [String]
+ public let updatedAt: Date?
+ extension Role: Identifiable
+
+ public var id: String
+ @available(*, deprecated, renamed: "custom") public var isCustom: Bool
- public struct Role: Equatable, Identifiable, Sendable
-
- public let name: String
- public let isCustom: Bool
- public let scopes: [String]
- public let createdAt: Date?
- public let updatedAt: Date?
- public var id: String
|
SDK Size
|
StreamChat XCSize
Show 13 more objects
|
|



🔗 Issue Links
Resolves: IOS-1832
🎯 Goal
Migrate the roles search endpoint to the OpenAPI-generated model and the v2 endpoint.
📝 Summary
Rolemodel andRolePayloadswith the OpenAPI-generatedRoleandSearchRolesResponse. OpenAPI model is the public model now.searchRolesat the v2GET /api/v2/roles/searchoperation.🛠 Implementation
SearchRoles/SearchRolesResponse/Roletoallowed_endpoints/allowed_modelsinScripts/openapi_generate.sh(both lists kept alphabetical) and regenerate.rolesSearchcase from theinject_v1_endpoint_pathsheredocs.Role+Identifiableto keep the existing conformance.🎨 Showcase
Not applicable.
🧪 Manual Testing Notes
Verified in the demo app that role search returns the expected results:
☑️ Contributor Checklist
docs-contentrepoSummary by CodeRabbit
/api/v2/roles/searchand returnsSearchRolesResponse.Rolenow exposesidderived fromnameand usescustom(with legacyisCustomdeprecated).RoleAPI.