Skip to content

Conversation

@BrandtKruger
Copy link

Explain your changes

Entitlements and Hardcheck

Checklist

🛟 If you need help, consider asking for advice over in the Kinde community.

- Add .build/ directory to .gitignore
- Add Package.resolved to .gitignore
- Remove SPM artifacts from Git tracking
@coderabbitai
Copy link

coderabbitai bot commented Oct 8, 2025

Walkthrough

Adds API client classes and Codable response models for permissions, roles, and feature flags; introduces AnyCodable, entitlement/flag domain types, ClaimsService/EntitlementsService/FeatureFlagsService and Auth extensions; expands AuthError; updates tests, Xcode project files, .gitignore, workspace, and clears Package.resolved.

Changes

Cohort / File(s) Summary
Repo housekeeping
\.gitignore, Package.resolved
.gitignore now ignores SwiftPM artifacts (.build/, Package.resolved) and stops ignoring MockingbirdCache/. Package.resolved contents were removed.
Xcode project
KindeSDK.xcodeproj/*, KindeSDK.xcodeproj/project.pbxproj.backup
Xcode project updated with new file references, groups and build-phase entries for the added API/model sources; a full PBX backup file with SwiftPM product references was added/updated and Package.resolved entries removed from project layout.
Auth core & services
Sources/KindeSDK/Auth/Auth.swift, Sources/KindeSDK/Auth/AuthError.swift, Sources/KindeSDK/Auth/Config.swift
Added ApiOptions, AnyCodable, entitlement/flag/permission/role/org domain types, Flag/FeatureFlag helpers, ClaimsService, EntitlementsService, FeatureFlagsService, and Auth extension accessors; AuthError gained invalidURL, invalidResponse, serverError(Int), and decodingError; minor doc comment tweak in Config.
API clients
Sources/KindeSDK/APIs/PermissionsAPI.swift, Sources/KindeSDK/APIs/RolesAPI.swift, Sources/KindeSDK/APIs/FeatureFlagsAPI.swift, Sources/KindeSDK/APIs.swift
New API client classes and request-builder helpers plus async fetch methods for GET /account_api/v1/permissions, /roles, and /feature_flags; small documentation text change in APIs.swift.
Models
Sources/KindeSDK/Models/PermissionsResponse.swift, Sources/KindeSDK/Models/RolesResponse.swift, Sources/KindeSDK/Models/FeatureFlagsResponse.swift
New Codable models and helpers: PermissionsResponse/PermissionsData/PermissionItem, RolesResponse/RolesData/RoleItem, FeatureFlagsResponse/FeatureFlagsData/FeatureFlagItem; utility methods (isValid, getPermissionKeys/getRoleKeys, toFlagMap).
Tests
Tests/AuthSpec.swift, Tests/EntitlementsSpec.swift
Updated Auth tests (isAuthorized -> isAuthenticated, ApiOptions/forceApi scenarios, restructured async tests); new EntitlementsSpec covering EntitlementsService, FeatureFlagsService, ClaimsService, hard-check helpers, API fetch behaviors and error cases.
Workspace / SwiftPM
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
Added minimal Xcode workspace contents file under .swiftpm.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App as App Code
  participant Auth as Auth
  participant Claims as ClaimsService
  participant Ent as EntitlementsService
  participant FF as FeatureFlagsService
  participant API as Kinde API

  App->>Auth: configure()
  note right of Auth: exposes claims, entitlements, featureFlags

  App->>Ent: fetchEntitlements(forceApi?)
  Ent->>Auth: isAuthenticated? / getTokenResponse()
  alt Not authenticated
    Ent-->>App: throws NotAuthenticated
  else Authenticated
    Ent->>API: GET /account_api/v1/entitlements (with token)
    API-->>Ent: JSON (possibly paginated)
    Ent-->>App: Entitlements + metadata
  end

  App->>FF: isFeatureEnabled(key, default, forceApi?)
  FF->>Auth: read claims or call API (forceApi)
  FF-->>App: Bool or default

  App->>Claims: getClaim(key)
  Claims->>Auth: read token claims
  Claims-->>App: Claim(name, AnyCodable value)
Loading
sequenceDiagram
  autonumber
  actor App as App Code
  participant Ent as EntitlementsService
  participant API as Kinde API

  App->>Ent: getBooleanEntitlement(key, default)
  Ent->>Ent: lookup in claims or call API (forceApi?)
  alt Key present & convertible
    Ent-->>App: true/false
  else Missing or not-convertible
    Ent-->>App: default or throws depending on method
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Files/areas needing extra attention:

  • Sources/KindeSDK/Auth/Auth.swift — many new public types, AnyCodable encode/decode, flag/entitlement conversions and public service APIs.
  • Sources/KindeSDK/Models/FeatureFlagsResponse.swift — type mapping and toFlagMap() validation/conversion logic.
  • New API clients (PermissionsAPI.swift, RolesAPI.swift, FeatureFlagsAPI.swift) — request builder setup and authentication flags.
  • KindeSDK.xcodeproj/project.pbxproj and backup — verify file references, build-phase/group changes, and SwiftPM product wiring.
  • Tests (Tests/EntitlementsSpec.swift, Tests/AuthSpec.swift) — async test patterns and updated expectations for forceApi/unauthenticated flows.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Entitlements and Hard Check' directly matches the main feature additions in the changeset: new entitlements-related models and services, plus hard-check validation methods throughout.
Description check ✅ Passed The description 'Entitlements and Hardcheck' is directly related to the changeset, which adds entitlements and hard-check features, though it provides minimal detail beyond the title.
Docstring Coverage ✅ Passed Docstring coverage is 80.95% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c206208 and 45b6214.

📒 Files selected for processing (1)
  • KindeSDK.xcodeproj/project.pbxproj (5 hunks)
🔇 Additional comments (2)
KindeSDK.xcodeproj/project.pbxproj (2)

22-27: LGTM! Build configuration properly wired.

The new API and Model files are correctly configured across all necessary sections:

  • PBXBuildFile entries created
  • PBXFileReference entries established
  • Files properly grouped (APIs and Models)
  • Sources build phase correctly updated

The build phase wiring is correct, avoiding the Frameworks phase issue mentioned in past reviews.

Also applies to: 89-94, 227-229, 277-279, 424-429


421-422: Inconsistency with AI summary regarding obsolete entries.

The AI summary states that APIHelper.swift and APIs.swift were "removed obsolete entries...from the Sources build phase," but both files remain present in the PBXSourcesBuildPhase at these lines and are still compiled as part of the KindeSDK target.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/KindeSDK/Auth/Auth.swift (1)

161-207: Fix claim unwrapping (permissions/org helpers now always return nil).

We now wrap claim payloads in AnyCodable, but these helpers still cast the wrapper itself (claim.value as? ...). That cast always fails, so getPermissions(), getPermission(_:), getOrganization(), and getUserOrganizations() can no longer return real data. Please unwrap via .value (the underlying Any) before casting. Suggested patch:

-        if let permissionsClaim = getClaim(forKey: ClaimKey.permissions.rawValue),
-           let permissionsArray = permissionsClaim.value as? [String],
-           let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
-           let orgCode = orgCodeClaim.value as? String {
+        if let permissionsClaim = getClaim(forKey: ClaimKey.permissions.rawValue),
+           let permissionsArray = permissionsClaim.value.value as? [String],
+           let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
+           let orgCode = orgCodeClaim.value.value as? String {

Apply the same fix in the three sibling helpers above. Without this, every call now silently fails.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3bdeb6 and dff54f1.

📒 Files selected for processing (8)
  • .gitignore (1 hunks)
  • KindeSDK.xcodeproj/project.pbxproj (7 hunks)
  • KindeSDK.xcodeproj/project.pbxproj.backup (1 hunks)
  • Package.resolved (0 hunks)
  • Sources/KindeSDK/Auth/Auth.swift (5 hunks)
  • Sources/KindeSDK/Auth/AuthError.swift (2 hunks)
  • Tests/AuthSpec.swift (2 hunks)
  • Tests/EntitlementsSpec.swift (1 hunks)
💤 Files with no reviewable changes (1)
  • Package.resolved
🧰 Additional context used
🧬 Code graph analysis (3)
Tests/EntitlementsSpec.swift (3)
Tests/AuthSpec.swift (1)
  • spec (7-88)
Sources/KindeSDK/APIs.swift (1)
  • configure (120-153)
Sources/KindeSDK/Auth/Auth.swift (15)
  • getEntitlements (941-965)
  • getEntitlement (970-973)
  • getBooleanEntitlement (1120-1130)
  • getStringEntitlement (1137-1147)
  • getNumericEntitlement (1154-1164)
  • performHardCheck (1172-1179)
  • getFeatureFlags (1194-1218)
  • isFeatureEnabled (1233-1249)
  • getFeatureFlag (1223-1226)
  • getClaim (135-146)
  • getClaim (913-919)
  • fetchEntitlements (990-1040)
  • fetchEntitlement (1045-1081)
  • getAllEntitlements (1086-1097)
  • getEntitlementsDictionary (1102-1111)
Tests/AuthSpec.swift (2)
Sources/KindeSDK/Auth/Auth.swift (9)
  • isAuthenticated (103-114)
  • getUserDetails (116-132)
  • getClaim (135-146)
  • getClaim (913-919)
  • getPermissions (161-173)
  • getOrganization (189-196)
  • getUserOrganizations (198-207)
  • getFlag (635-637)
  • logout (342-346)
Sources/KindeSDK/APIs.swift (2)
  • configure (120-153)
  • logout (103-111)
Sources/KindeSDK/Auth/Auth.swift (2)
Tests/DefaultLoggerSpec.swift (1)
  • error (16-18)
Sources/KindeSDK/Auth/DefaultLogger.swift (1)
  • error (23-25)
🪛 SwiftLint (0.57.0)
Sources/KindeSDK/Auth/Auth.swift

[Warning] 1088-1088: Initializing an optional variable with nil is redundant

(redundant_optional_initialization)

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Sources/KindeSDK/Auth/Auth.swift (2)

161-205: Unwrap AnyCodable before casting.

Claim.value is now an AnyCodable, but these helpers still cast it directly to [String]/String. The casts always fail, so permissions, org, and user-org lookups now return nil. Extract the underlying value via .value first (same applies to other helpers in this file that read claim values).

-        if let permissionsClaim = getClaim(forKey: ClaimKey.permissions.rawValue),
-           let permissionsArray = permissionsClaim.value as? [String],
-           let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
-           let orgCode = orgCodeClaim.value as? String {
+        if let permissionsClaim = getClaim(forKey: ClaimKey.permissions.rawValue),
+           let permissionsArray = permissionsClaim.value.value as? [String],
+           let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
+           let orgCode = orgCodeClaim.value.value as? String {
@@
-        if let permissionsClaim = getClaim(forKey: ClaimKey.permissions.rawValue),
-           let permissionsArray = permissionsClaim.value as? [String],
-           let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
-           let orgCode = orgCodeClaim.value as? String {
+        if let permissionsClaim = getClaim(forKey: ClaimKey.permissions.rawValue),
+           let permissionsArray = permissionsClaim.value.value as? [String],
+           let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
+           let orgCode = orgCodeClaim.value.value as? String {
@@
-        if let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
-           let orgCode = orgCodeClaim.value as? String {
+        if let orgCodeClaim = getClaim(forKey: ClaimKey.organisationCode.rawValue),
+           let orgCode = orgCodeClaim.value.value as? String {
@@
-        if let userOrgsClaim = getClaim(forKey: ClaimKey.organisationCodes.rawValue,
-                                   token: .idToken),
-           let userOrgs = userOrgsClaim.value as? [String] {
+        if let userOrgsClaim = getClaim(forKey: ClaimKey.organisationCodes.rawValue,
+                                   token: .idToken),
+           let userOrgs = userOrgsClaim.value.value as? [String] {

Apply the same .value.value adjustment wherever a claim is consumed (e.g. feature-flag parsing below) to restore previous behaviour.


685-688: Also fix feature-flag claim casting.

featureFlagsClaim.value is an AnyCodable; the current cast to [String: Any] will always fail, so every flag lookup now throws FlagError.unknownError. Unwrap the payload first.

-        guard let featureFlags = featureFlagsClaim.value as? [String : Any] else {
+        guard let featureFlags = featureFlagsClaim.value.value as? [String : Any] else {
♻️ Duplicate comments (1)
Tests/EntitlementsSpec.swift (1)

292-325: Convert this spec to AsyncSpec before using await.

These examples call await expect { try await … }, but the spec still subclasses QuickSpec, so the compiler rejects the async calls (same problem noted previously). Switch to AsyncSpec and make spec() async—or drop the await expectations.

-class EntitlementsSpec: QuickSpec {
-    override class func spec() {
+class EntitlementsSpec: AsyncSpec {
+    override class func spec() async {

Also update any beforeEach/it bodies to await as needed.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dff54f1 and 30f8989.

📒 Files selected for processing (3)
  • KindeSDK.xcodeproj/project.pbxproj (3 hunks)
  • Sources/KindeSDK/Auth/Auth.swift (5 hunks)
  • Tests/EntitlementsSpec.swift (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
Sources/KindeSDK/Auth/Auth.swift (3)
Sources/KindeSDK/Utils/CodableHelper.swift (2)
  • decode (42-44)
  • encode (46-48)
Sources/KindeSDK/Utils/String+JWTTokenDecode.swift (1)
  • decode (17-48)
Sources/KindeSDK/Auth/DefaultLogger.swift (1)
  • error (23-25)
Tests/EntitlementsSpec.swift (3)
Tests/AuthSpec.swift (1)
  • spec (7-88)
Sources/KindeSDK/APIs.swift (1)
  • configure (120-153)
Sources/KindeSDK/Auth/Auth.swift (15)
  • getEntitlements (951-975)
  • getEntitlement (980-983)
  • getBooleanEntitlement (1130-1140)
  • getStringEntitlement (1147-1157)
  • getNumericEntitlement (1164-1174)
  • performHardCheck (1182-1189)
  • getFeatureFlags (1204-1228)
  • isFeatureEnabled (1243-1259)
  • getFeatureFlag (1233-1236)
  • getClaim (135-146)
  • getClaim (927-929)
  • fetchEntitlements (1000-1050)
  • fetchEntitlement (1055-1091)
  • getAllEntitlements (1096-1107)
  • getEntitlementsDictionary (1112-1121)
🪛 SwiftLint (0.57.0)
Sources/KindeSDK/Auth/Auth.swift

[Warning] 1098-1098: Initializing an optional variable with nil is redundant

(redundant_optional_initialization)

Tests/EntitlementsSpec.swift

[Warning] 41-41: TODOs should be resolved (Add proper test fixtures with ...)

(todo)


[Warning] 263-263: TODOs should be resolved (Add proper test fixtures with ...)

(todo)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@BrandtKruger BrandtKruger requested a review from a team as a code owner November 23, 2025 16:36
Copy link

@victoreronmosele victoreronmosele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears there are some missing methods being referenced in the tests.

There's also a missing ); in the project file.

Copy link

@victoreronmosele victoreronmosele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears some files are not updated as some methods are missing making the tests not compile.

@BrandtKruger BrandtKruger requested a review from a team as a code owner November 30, 2025 17:38
Copy link

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (3)
Sources/KindeSDK/APIs/PermissionsAPI.swift (1)

10-46: Same refactoring opportunities as RolesAPI.

PermissionsAPI has the same structure and SwiftLint warnings as RolesAPI. The recommendations from RolesAPI.swift apply here as well:

  • Consider using a caseless enum instead of final public class
  • Extract common request builder logic to reduce duplication

Based on static analysis hints from SwiftLint.

Sources/KindeSDK/APIs/FeatureFlagsAPI.swift (1)

10-46: Same refactoring opportunities as RolesAPI and PermissionsAPI.

FeatureFlagsAPI follows the same pattern as the other API clients. Apply the same refactoring recommendations mentioned for RolesAPI.swift.

Based on static analysis hints from SwiftLint.

Tests/EntitlementsSpec.swift (1)

319-355: Async expectations require AsyncSpec or waitUntil.

The await expect { try await ... } pattern inside a synchronous QuickSpec will not compile. Swift requires the enclosing context to be async to use await.

Convert to AsyncSpec or use waitUntil blocks:

-class EntitlementsSpec: QuickSpec {
+class EntitlementsSpec: AsyncSpec {

Or wrap each async test in waitUntil:

it("throws notAuthenticated when user is not logged in") {
    waitUntil { done in
        Task {
            do {
                _ = try await entitlementsService.fetchEntitlements()
                fail("Expected error to be thrown")
            } catch {
                expect(error).to(matchError(AuthError.notAuthenticated))
            }
            done()
        }
    }
}
🧹 Nitpick comments (12)
Sources/KindeSDK/Models/RolesResponse.swift (1)

3-28: LGTM - Well-structured response model.

The response model properly handles optional data and provides helpful utility methods. The use of compactMap correctly filters out roles with null keys.

Note: The isValid() implementation is duplicated across RolesResponse, PermissionsResponse, and FeatureFlagsResponse. Consider extracting this to a protocol for consistency and maintainability.

Sources/KindeSDK/APIs/RolesAPI.swift (2)

10-24: Address SwiftLint warning: prefer static methods.

The final public class with only class methods pattern triggers SwiftLint warnings. Since RolesAPI has no instance state, consider one of these approaches:

  1. Use a caseless enum (prevents instantiation):
-final public class RolesAPI {
+public enum RolesAPI {
+    
+    @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
+    public static func getRoles() async throws -> RolesResponse {
-    final public class func getRoles() async throws -> RolesResponse {
  1. Or use static methods directly on the class and add a private initializer to prevent instantiation.

Note: Apply the same fix to PermissionsAPI and FeatureFlagsAPI for consistency.

Based on static analysis hints from SwiftLint.


26-46: Implementation is correct but highly duplicated.

The request builder pattern is properly implemented with authentication required. However, this code is nearly identical to PermissionsAPI and FeatureFlagsAPI, differing only in the endpoint path and return type. Consider extracting a generic request builder helper to reduce duplication.

Sources/KindeSDK/Models/PermissionsResponse.swift (1)

1-52: LGTM - Consistent with RolesResponse pattern.

PermissionsResponse follows the same well-structured pattern as RolesResponse. As noted in the RolesResponse review, the isValid() method is duplicated across all response models (Permissions, Roles, FeatureFlags). Consider extracting this to a protocol for better maintainability.

Tests/EntitlementsSpec.swift (2)

349-355: Inconsistent indentation in nested describe blocks.

The getEntitlementsDictionary and Hard Check Methods describe blocks have extra indentation compared to sibling blocks. This appears to be a formatting oversight.

-                describe("getEntitlementsDictionary") {
-                    it("throws notAuthenticated when user is not logged in") {
+            describe("getEntitlementsDictionary") {
+                it("throws notAuthenticated when user is not logged in") {

41-42: TODO comments should be tracked for follow-up.

Static analysis flagged unresolved TODO comments. Consider creating issues to track adding proper test fixtures with mocked tokens, or mark these tests as pending with a clear reason.

Would you like me to help create GitHub issues to track these test fixture improvements?

Also applies to: 263-264

Sources/KindeSDK/Models/FeatureFlagsResponse.swift (1)

37-47: Consider logging unknown flag types for debugging.

Unknown flag types are silently skipped, which is safe but may make debugging difficult if the API introduces new types.

             let flagType: Flag.ValueType?
             switch item.type {
             case "Boolean":
                 flagType = .bool
             case "String":
                 flagType = .string
             case "Integer":
                 flagType = .int
             default:
+                // Silently skip unknown types - consider logging in debug builds
                 continue
             }
Sources/KindeSDK/Auth/Auth.swift (5)

1046-1073: Duplicate ValueType enum definitions in Flag and FeatureFlag.

Both Flag and FeatureFlag structs define identical ValueType enums with the same raw values and behavior. This duplication increases maintenance burden and risks divergence.

Consider extracting a shared type:

/// Shared enum for feature flag value types
public enum FlagValueType: String, Codable {
    case string = "s"
    case int = "i"
    case bool = "b"
    
    public var typeDescription: String {
        switch self {
        case .string: return "string"
        case .bool: return "boolean"
        case .int: return "integer"
        }
    }
}

Then update both structs to use FlagValueType instead of their nested enums.

Also applies to: 1089-1124


1407-1415: Redundant nil initialization.

SwiftLint correctly flags that var startingAfter: String? = nil is redundant since optionals default to nil.

     public func getAllEntitlements() async throws -> [Entitlement] {
         var allEntitlements: [Entitlement] = []
-        var startingAfter: String? = nil
+        var startingAfter: String?
         
         repeat {
             let response = try await fetchEntitlements(startingAfter: startingAfter)

1337-1343: HTTP requests lack timeout configuration.

The URLRequest objects don't set timeoutInterval, relying on system defaults (60 seconds). For production SDK usage, explicit timeouts provide better control over failure modes.

         var request = URLRequest(url: url)
         request.httpMethod = "GET"
+        request.timeoutInterval = 30 // Explicit timeout
         request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
         request.setValue("application/json", forHTTPHeaderField: "Accept")

Also applies to: 1378-1384


1219-1224: ClaimsService.getPermission return type inconsistent with Auth.getPermission.

ClaimsService.getPermission(name:) returns Bool, while Auth.getPermission(name:) returns Permission?. This inconsistency may confuse SDK users.

Consider aligning the return types:

     /// Check if a specific permission is granted
     /// - Parameter name: The permission name to check
-    /// - Returns: True if permission is granted, false otherwise
-    public func getPermission(name: String) -> Bool {
-        return auth.getPermission(name: name) != nil
+    /// - Returns: Permission if found, nil otherwise
+    public func getPermission(name: String) -> Permission? {
+        return auth.getPermission(name: name)
     }

Or rename to hasPermission if boolean return is intentional.


174-196: Async overloads throw generic NSError instead of typed AuthError.

The async methods with ApiOptions throw NSError with domain "KindeSDK" for API failures, while other parts of the codebase use typed AuthError cases. This inconsistency makes error handling less ergonomic.

Consider adding new AuthError cases and using them consistently:

public enum AuthError: Error {
    // existing cases...
    case apiError(String)
    case permissionsNotFound
    case rolesNotFound
}

Then:

-            throw NSError(domain: "KindeSDK", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to fetch permissions from API - check network and authentication"])
+            throw AuthError.apiError("Failed to fetch permissions from API")

Also applies to: 214-231, 250-272, 290-307

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 102c8d2 and 874f002.

⛔ Files ignored due to path filters (1)
  • kinde-auth.json is excluded by !**/*.json
📒 Files selected for processing (13)
  • .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata (1 hunks)
  • KindeSDK.xcodeproj/project.pbxproj (8 hunks)
  • Sources/KindeSDK/APIs.swift (1 hunks)
  • Sources/KindeSDK/APIs/FeatureFlagsAPI.swift (1 hunks)
  • Sources/KindeSDK/APIs/PermissionsAPI.swift (1 hunks)
  • Sources/KindeSDK/APIs/RolesAPI.swift (1 hunks)
  • Sources/KindeSDK/Auth/Auth.swift (12 hunks)
  • Sources/KindeSDK/Auth/Config.swift (1 hunks)
  • Sources/KindeSDK/Models/FeatureFlagsResponse.swift (1 hunks)
  • Sources/KindeSDK/Models/PermissionsResponse.swift (1 hunks)
  • Sources/KindeSDK/Models/RolesResponse.swift (1 hunks)
  • Tests/AuthSpec.swift (4 hunks)
  • Tests/EntitlementsSpec.swift (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
  • Sources/KindeSDK/Auth/Config.swift
🧰 Additional context used
🧬 Code graph analysis (6)
Sources/KindeSDK/APIs/RolesAPI.swift (5)
Sources/KindeSDK/APIs.swift (2)
  • macOS (60-83)
  • execute (55-58)
Sources/KindeSDK/APIs/FeatureFlagsAPI.swift (1)
  • macOS (21-24)
Sources/KindeSDK/APIs/PermissionsAPI.swift (1)
  • macOS (21-24)
Sources/KindeSDK/Auth/Auth.swift (3)
  • getRoles (250-272)
  • getRoles (276-288)
  • getRoles (1228-1230)
Sources/KindeSDK/Utils/APIHelper.swift (1)
  • rejectNilHeaders (23-33)
Tests/EntitlementsSpec.swift (3)
Tests/AuthSpec.swift (1)
  • spec (7-200)
Sources/KindeSDK/APIs.swift (1)
  • configure (120-153)
Sources/KindeSDK/Auth/Auth.swift (26)
  • getEntitlements (1262-1286)
  • getEntitlement (1291-1294)
  • getBooleanEntitlement (1441-1451)
  • getStringEntitlement (1458-1468)
  • getNumericEntitlement (1475-1485)
  • performHardCheck (1493-1500)
  • validatePermission (1507-1513)
  • validateRole (1520-1528)
  • validateFeatureFlag (1535-1543)
  • validateEntitlement (1550-1561)
  • isUserAuthenticated (1565-1567)
  • getUserOrganization (1571-1576)
  • getUserSubscriptionTier (1580-1582)
  • getFeatureFlags (1597-1621)
  • isFeatureEnabled (1636-1652)
  • getFeatureFlag (1626-1629)
  • getRoles (250-272)
  • getRoles (276-288)
  • getRoles (1228-1230)
  • getRole (290-307)
  • getRole (312-324)
  • getRole (1235-1237)
  • fetchEntitlements (1311-1361)
  • fetchEntitlement (1366-1402)
  • getAllEntitlements (1407-1418)
  • getEntitlementsDictionary (1423-1432)
Sources/KindeSDK/Models/FeatureFlagsResponse.swift (2)
Sources/KindeSDK/Models/PermissionsResponse.swift (1)
  • isValid (15-17)
Sources/KindeSDK/Models/RolesResponse.swift (1)
  • isValid (15-17)
Sources/KindeSDK/APIs/FeatureFlagsAPI.swift (3)
Sources/KindeSDK/APIs.swift (2)
  • macOS (60-83)
  • execute (55-58)
Sources/KindeSDK/Auth/Auth.swift (1)
  • getFeatureFlags (1597-1621)
Sources/KindeSDK/Utils/APIHelper.swift (1)
  • rejectNilHeaders (23-33)
Sources/KindeSDK/Models/PermissionsResponse.swift (2)
Sources/KindeSDK/Models/FeatureFlagsResponse.swift (1)
  • isValid (15-17)
Sources/KindeSDK/Models/RolesResponse.swift (1)
  • isValid (15-17)
Sources/KindeSDK/Auth/Auth.swift (3)
Sources/KindeSDK/Models/PermissionsResponse.swift (1)
  • getPermissionKeys (21-27)
Sources/KindeSDK/Models/RolesResponse.swift (1)
  • getRoleKeys (21-27)
Sources/KindeSDK/Models/FeatureFlagsResponse.swift (1)
  • toFlagMap (22-53)
🪛 SwiftLint (0.57.0)
Sources/KindeSDK/APIs/RolesAPI.swift

[Warning] 21-21: Prefer static over final class

(static_over_final_class)


[Warning] 31-31: Prefer static over final class

(static_over_final_class)

Sources/KindeSDK/APIs/PermissionsAPI.swift

[Warning] 21-21: Prefer static over final class

(static_over_final_class)


[Warning] 31-31: Prefer static over final class

(static_over_final_class)

Tests/EntitlementsSpec.swift

[Warning] 41-41: TODOs should be resolved (Add proper test fixtures with ...)

(todo)


[Warning] 263-263: TODOs should be resolved (Add proper test fixtures with ...)

(todo)

Sources/KindeSDK/APIs/FeatureFlagsAPI.swift

[Warning] 21-21: Prefer static over final class

(static_over_final_class)


[Warning] 31-31: Prefer static over final class

(static_over_final_class)

Sources/KindeSDK/Auth/Auth.swift

[Warning] 1409-1409: Initializing an optional variable with nil is redundant

(redundant_optional_initialization)

🔇 Additional comments (14)
Sources/KindeSDK/APIs.swift (1)

115-115: LGTM - Documentation improvement.

The updated terminology "Kinde SDK APIs" more accurately describes the SDK's scope.

Sources/KindeSDK/Models/RolesResponse.swift (2)

30-41: LGTM - Correct JSON mapping.

The CodingKeys properly map org_code from the API response to orgCode in Swift.


43-51: LGTM - Appropriate model structure.

Optional properties correctly handle potentially missing fields from the API response.

KindeSDK.xcodeproj/project.pbxproj (2)

23-28: LGTM - New API and model files properly integrated.

The new API clients (PermissionsAPI, RolesAPI, FeatureFlagsAPI) and their corresponding response models are correctly added to the project structure, groups, and build phases.

Also applies to: 93-98, 234-236, 284-286, 432-437


64-65: These files do not exist in the repository.

Claims.swift and MobileEntitlements.swift are not present in the project and have no references in the project.pbxproj file. The review comment references code that does not exist in the current state of the codebase.

Likely an incorrect or invalid review comment.

Tests/AuthSpec.swift (4)

9-15: LGTM - Proper test setup.

Adding beforeEach to configure KindeSDKAPI ensures consistent test state. The API method name change from isAuthorized() to isAuthenticated() appears intentional.


50-51: Verify error type change from notFound to unknownError.

The test expectations changed from FlagError.notFound to FlagError.unknownError across multiple flag retrieval scenarios. This is a significant behavioral change that could affect existing code.

Please confirm:

  1. Is this change intentional?
  2. Does this align with new error handling semantics?
  3. Are there any breaking changes for existing SDK users?

Also applies to: 55-56, 65-66, 75-76


99-177: LGTM - Good test coverage for new async APIs.

The new test suites properly cover:

  • ApiOptions initialization and default values
  • getAllFlags behavior when not authenticated
  • async API methods with forceApi option

The use of waitUntil with timeout and pending placeholders for authenticated scenarios is appropriate.


179-198: LGTM - Consistent async test patterns.

The async flag tests follow the established testing patterns and properly handle default values and error cases.

Tests/EntitlementsSpec.swift (1)

6-16: Setup looks reasonable for integration-style tests.

The test setup initializes the SDK and obtains service references from the shared auth instance. This approach works for basic smoke tests but limits testability since there's no mock injection.

Sources/KindeSDK/Models/FeatureFlagsResponse.swift (1)

1-54: Well-structured response model following established patterns.

The FeatureFlagsResponse implementation correctly mirrors the patterns used in PermissionsResponse and RolesResponse. The toFlagMap() method properly validates keys and values before constructing Flag objects.

Sources/KindeSDK/Auth/Auth.swift (3)

94-104: Lazy service properties provide convenient access.

The lazy initialization pattern ensures services are only created when accessed and maintains a single instance per Auth object.


991-1044: AnyCodable now properly handles arrays, dictionaries, and null.

The implementation correctly decodes nested structures and handles NSNull for nil values, addressing the previous review concern about scalar-only support.


1631-1652: This review comment is incorrect and should be dismissed.

The methods isFeatureEnabled() and getFeatureFlag() do not exist in the codebase. The code snippet shown (lines 1631-1652) also does not exist in Auth.swift, which contains only 704 lines total. Additionally, EntitlementsSpec.swift does not exist in the repository.

The actual feature flag methods in Auth.swift are getFlag(), getBooleanFlag(), getStringFlag(), and getIntegerFlag(), all of which consistently use the code: parameter. Parameter naming is already consistent and there is no issue to address.

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (2)
Tests/EntitlementsSpec.swift (2)

269-277: getClaimValue(forKey:) tests may not compile or will always fail without fixtures.

Two separate issues to double‑check here:

  1. API existence: From the surrounding context, ClaimsService clearly exposes getClaim(forKey:), but it’s not obvious that a getClaimValue(forKey:) helper actually exists. If it doesn’t, these tests won’t compile. Either:

    • add getClaimValue(forKey:) to ClaimsService (likely returning Any? from the underlying Claim), or
    • rewrite the tests to use getClaim(forKey:) and assert on the Claim’s value.
  2. Fixture setup: The "returns claim value when claim exists" example uses "test_claim" without seeding any token/claim, so the result will be nil in the current setup and expect(result).to(beAKindOf(Any.self)) will fail. As with the entitlements tests you already marked pending, you’ll need either a mocked token with that claim or to mark this example pending until fixtures are added.

#!/bin/bash
# Verify whether getClaimValue is actually defined anywhere.
rg -n "getClaimValue" Sources Tests -C2

321-355: Async await expect { try await … } blocks in QuickSpec are likely to fail to compile.

These it blocks call await expect { try await … } but EntitlementsSpec currently subclasses QuickSpec and spec() itself is not async. Unless you’re on a Quick version where QuickSpec supports async it closures, this will trigger the usual 'async' call in a function that does not support concurrency build error.

Options:

  • Switch this spec to an async variant (e.g., AsyncSpec) and make spec() async so you can safely await inside it closures, or
  • Keep QuickSpec but wrap the async calls using a pattern like waitUntil / toEventually, or test your Auth/entitlements HTTP error cases via synchronous stubs instead of real async functions.
Quick & Nimble async: For a Swift test using Quick, is `await expect { try await foo() }` supported inside a `QuickSpec` `it` closure, or must the spec subclass `AsyncSpec` / use an async `spec()` instead?
🧹 Nitpick comments (2)
Tests/EntitlementsSpec.swift (2)

41-42: Align TODO-style comments with SwiftLint and your pending tests.

SwiftLint is warning on these // TODO: Add proper test fixtures… comments. Since the corresponding examples are already marked pending, you could either:

  • remove or rephrase the TODO (e.g., reference a ticket ID instead), or
  • adjust your SwiftLint config if you intentionally track work via TODOs in tests.

This keeps the lint signal focused on actionable issues.

Also applies to: 264-265


57-61: Several tests assert only on static types/fallbacks without seeding entitlements/flags.

In these examples (string-bool/string-numeric entitlements, malformed/null/type-conversion edge cases, hard-check permission/role/flag/entitlement, and “feature flags dictionary when claim exists”), no token/claims/entitlements are set up. The assertions effectively only confirm:

  • the functions return their declared types, or
  • the documented default value paths work when nothing is present.

They do not currently exercise the “string value”, “malformed claim”, or “claim exists” branches suggested by the test names and comments.

Consider either:

  • seeding a mock token / entitlements / feature flags for the specific keys under test, or
  • marking these as pending (or renaming them) until fixtures exist, to avoid a misleading sense of coverage.

Also applies to: 76-80, 95-99, 121-124, 126-129, 131-138, 160-165, 172-180, 214-217

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 874f002 and b75d2c6.

📒 Files selected for processing (1)
  • Tests/EntitlementsSpec.swift (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Tests/EntitlementsSpec.swift (1)
Sources/KindeSDK/Auth/Auth.swift (28)
  • getEntitlements (1262-1286)
  • getEntitlement (1291-1294)
  • getBooleanEntitlement (1441-1451)
  • getStringEntitlement (1458-1468)
  • getNumericEntitlement (1475-1485)
  • performHardCheck (1493-1500)
  • validatePermission (1507-1513)
  • validateRole (1520-1528)
  • validateFeatureFlag (1535-1543)
  • validateEntitlement (1550-1561)
  • isUserAuthenticated (1565-1567)
  • getUserOrganization (1571-1576)
  • getUserSubscriptionTier (1580-1582)
  • getFeatureFlags (1597-1621)
  • isFeatureEnabled (1636-1652)
  • getFeatureFlag (1626-1629)
  • getClaim (148-159)
  • getClaim (1215-1217)
  • getRoles (250-272)
  • getRoles (276-288)
  • getRoles (1228-1230)
  • getRole (290-307)
  • getRole (312-324)
  • getRole (1235-1237)
  • fetchEntitlements (1311-1361)
  • fetchEntitlement (1366-1402)
  • getAllEntitlements (1407-1418)
  • getEntitlementsDictionary (1423-1432)
🪛 SwiftLint (0.57.0)
Tests/EntitlementsSpec.swift

[Warning] 41-41: TODOs should be resolved (Add proper test fixtures with ...)

(todo)


[Warning] 264-264: TODOs should be resolved (Add proper test fixtures with ...)

(todo)

🔇 Additional comments (1)
Tests/EntitlementsSpec.swift (1)

18-120: Nice structural coverage of EntitlementsService behaviors.

The spec does a good job covering empty vs non-existent entitlements, default values, and the basic performHardCheck behavior. This gives you a solid baseline around the public surface, with more detailed happy-path checks to be filled in once fixtures/tokens are available.

@victoreronmosele
Copy link

Code updates look good. Testing next.

Copy link

@victoreronmosele victoreronmosele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove references to Claims.swift and MobileEntitlements.swift as those files don't exist in the project and are making the build not complete.

Copy link

@victoreronmosele victoreronmosele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove references to Package.resolved since we're ignoring it in dff54f1 and it's prevent successful builds.

I highlighted the lines below.

Addresses review comments from victoreronmosele:
- Remove PBXBuildFile entry for Package.resolved
- Remove PBXFileReference entry for Package.resolved
- Remove from main group
- Remove from Resources build phase

Since Package.resolved is now in .gitignore, it should not be referenced in the Xcode project.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
KindeSDK.xcodeproj/project.pbxproj (1)

126-127: Consider adding Claims and MobileEntitlements to a visible group

Claims.swift and MobileEntitlements.swift have PBXFileReference entries and are compiled, but they don’t appear under any PBXGroup’s children. Adding them (likely to the Auth group) would make them visible in the Xcode navigator and easier to maintain.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b75d2c6 and c206208.

📒 Files selected for processing (1)
  • KindeSDK.xcodeproj/project.pbxproj (8 hunks)
🔇 Additional comments (7)
KindeSDK.xcodeproj/project.pbxproj (7)

22-27: New API and response PBXBuildFile entries are correctly wired

Each of the new Permissions*, Roles*, and FeatureFlags* entries has a valid fileRef and is later included in the Sources build phase, so the framework will compile these new files as expected.


63-64: Claims and MobileEntitlements build file entries are now correct

Claims.swift and MobileEntitlements.swift are defined as PBXBuildFile entries targeting Sources (not Frameworks), matching their use later in the main target’s PBXSourcesBuildPhase. This fixes the previous wiring issue.


91-96: File references for new APIs and responses look consistent

The PBXFileReference definitions for PermissionsAPI.swift, RolesAPI.swift, FeatureFlagsAPI.swift and the three *Response.swift models are well‑formed and align with their corresponding build files and group placements.


231-233: APIs group updated appropriately for new endpoints

The APIs group now includes PermissionsAPI.swift, RolesAPI.swift, and FeatureFlagsAPI.swift alongside OAuthAPI.swift, matching the new file references and build entries.


281-283: Models group correctly includes new response types

PermissionsResponse.swift, RolesResponse.swift, and FeatureFlagsResponse.swift are added under the Models group, consistent with their file references and inclusion in the Sources build phase.


425-433: New API and response sources are properly added to the main target

All newly introduced API and response files are listed in the KindeSDK target’s PBXSourcesBuildPhase, so they will be compiled into the framework. No duplicate entries or obvious ordering/syntax issues here.


455-456: Claims and MobileEntitlements are now part of the KindeSDK Sources build phase

Claims.swift and MobileEntitlements.swift are correctly added to the main target’s Sources build phase, with a single entry each and no lingering framework-phase wiring. This should resolve prior build issues around these files.

These files don't exist in the project and were causing build failures.
Removed all references from:
- PBXBuildFile section
- PBXFileReference section
- Sources build phase

Addresses review comment from victoreronmosele.
Copy link

@victoreronmosele victoreronmosele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add the EntitlementSpec file to the XCode project to run and verify the tests.

Here are some suggested changes.

3B41B1FB2A0E5F9100EFD9E4 /* FeatureFlagsAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B41B1FA2A0E5F9100EFD9E4 /* FeatureFlagsAPI.swift */; };
3B41B1FD2A0E5F9100EFD9E4 /* PermissionsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B41B1FC2A0E5F9100EFD9E4 /* PermissionsResponse.swift */; };
3B41B1FF2A0E5F9100EFD9E4 /* RolesResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B41B1FE2A0E5F9100EFD9E4 /* RolesResponse.swift */; };
3B41B2012A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B41B2002A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift */; };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3B41B2012A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B41B2002A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift */; };
3B41B2012A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B41B2002A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift */; };
8D6DE2E32EE0F34000476C3F /* EntitlementsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D6DE2E22EE0F34000476C3F /* EntitlementsSpec.swift */; };

3B41B1FA2A0E5F9100EFD9E4 /* FeatureFlagsAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlagsAPI.swift; sourceTree = "<group>"; };
3B41B1FC2A0E5F9100EFD9E4 /* PermissionsResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PermissionsResponse.swift; sourceTree = "<group>"; };
3B41B1FE2A0E5F9100EFD9E4 /* RolesResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RolesResponse.swift; sourceTree = "<group>"; };
3B41B2002A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlagsResponse.swift; sourceTree = "<group>"; };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3B41B2002A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlagsResponse.swift; sourceTree = "<group>"; };
3B41B2002A0E5F9100EFD9E4 /* FeatureFlagsResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlagsResponse.swift; sourceTree = "<group>"; };
8D6DE2E22EE0F34000476C3F /* EntitlementsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntitlementsSpec.swift; sourceTree = "<group>"; };

Comment on lines 182 to 188
children = (
3B41B1AD2A0E5F8500EFD9E4 /* AuthSpec.swift */,
3B41B1AE2A0E5F8500EFD9E4 /* StringJWTTokenDecodeSpec.swift */,
3B41B1AF2A0E5F8500EFD9E4 /* AuthErrorSpec.swift */,
3B41B1B02A0E5F8500EFD9E4 /* DefaultLoggerSpec.swift */,
3B41B1B12A0E5F8500EFD9E4 /* ConfigSpec.swift */,
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should include the EntitlementSpec file.

Please update to:

			children = (
+				8D6DE2E22EE0F34000476C3F /* EntitlementsSpec.swift */,
				3B41B1AD2A0E5F8500EFD9E4 /* AuthSpec.swift */,
				3B41B1AE2A0E5F8500EFD9E4 /* StringJWTTokenDecodeSpec.swift */,
				3B41B1AF2A0E5F8500EFD9E4 /* AuthErrorSpec.swift */,
				3B41B1B02A0E5F8500EFD9E4 /* DefaultLoggerSpec.swift */,
				3B41B1B12A0E5F8500EFD9E4 /* ConfigSpec.swift */,
			);

Comment on lines 457 to 464
files = (
3B41B1B32A0E5F8500EFD9E4 /* StringJWTTokenDecodeSpec.swift in Sources */,
3B41B1B52A0E5F8500EFD9E4 /* DefaultLoggerSpec.swift in Sources */,
3B41B1B62A0E5F8500EFD9E4 /* ConfigSpec.swift in Sources */,
3B41B1B42A0E5F8500EFD9E4 /* AuthErrorSpec.swift in Sources */,
3B41B1B22A0E5F8500EFD9E4 /* AuthSpec.swift in Sources */,
3BA67F872A0A5FF600399C6A /* kinde-auth.json in Sources */,
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should include the EntitlementSpec file.

Please update to:

			files = (
+				8D6DE2E32EE0F34000476C3F /* EntitlementsSpec.swift in Sources */,
				3B41B1B32A0E5F8500EFD9E4 /* StringJWTTokenDecodeSpec.swift in Sources */,
				3B41B1B52A0E5F8500EFD9E4 /* DefaultLoggerSpec.swift in Sources */,
				3B41B1B62A0E5F8500EFD9E4 /* ConfigSpec.swift in Sources */,
				3B41B1B42A0E5F8500EFD9E4 /* AuthErrorSpec.swift in Sources */,
				3B41B1B22A0E5F8500EFD9E4 /* AuthSpec.swift in Sources */,
				3BA67F872A0A5FF600399C6A /* kinde-auth.json in Sources */,
			);

Copy link

@victoreronmosele victoreronmosele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are needed to get the EntitlementsSpec tests to compile and pass.

it("maintains consistent state with auth service") {
let entitlements1 = auth.entitlements.getEntitlements()
let entitlements2 = entitlementsService.getEntitlements()
expect(entitlements1).to(equal(entitlements2))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current check has a compile error: Type 'Any' cannot conform to 'Equatable' since the entitlements are of type [String : Any].

We can cast the entitlements to NSDictionary to remove the error.

Suggested change
expect(entitlements1).to(equal(entitlements2))
expect(entitlements1 as NSDictionary).to(equal(entitlements2 as NSDictionary))

Comment on lines +276 to +277
let result = claimsService.getClaimValue(forKey: "test_claim")
expect(result).to(beAKindOf(Any.self))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests doesn't pass as it requires the mock token just like its similar test for the getClaim method.

We can add this pending note here.

Suggested change
let result = claimsService.getClaimValue(forKey: "test_claim")
expect(result).to(beAKindOf(Any.self))
// This would require a mock token with specific claims
// TODO: Add proper test fixtures with mocked tokens
pending("Requires mock token with claims") {}

import KindeSDK
import Foundation

class EntitlementsSpec: QuickSpec {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests for fetchEntitlements and getAllEntitlements have async functions and require using the AsyncSpec to be able to run the tests without a compilation error.

Suggested change
class EntitlementsSpec: QuickSpec {
class EntitlementsSpec: AsyncSpec {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants