Skip to content
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

Test that token refreshes merge the results correctly #195

Merged
merged 1 commit into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/AuthFoundation/JWT/Protocols/Claim.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public protocol HasClaims {
/// Unlike the ``claims`` property, this returns values as strings.
var customClaims: [String] { get }

/// Raw paylaod of claims, as a dictionary representation.
/// Raw payload of claims, as a dictionary representation.
var payload: [String: Any] { get }
}

Expand Down
41 changes: 37 additions & 4 deletions Tests/AuthFoundationTests/CredentialRefreshTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ final class CredentialRefreshTests: XCTestCase, OAuth2ClientDelegate {
case none
case error
case openIdOnly
case refresh(count: Int)
case refresh(count: Int, rotate: Bool = false)
}

func credential(for token: Token, expectAPICalls: APICalls = .refresh(count: 1), expiresIn: TimeInterval = 3600) throws -> Credential {
Expand All @@ -61,19 +61,19 @@ final class CredentialRefreshTests: XCTestCase, OAuth2ClientDelegate {
data: try data(from: .module, for: "openid-configuration", in: "MockResponses"),
contentType: "application/json")

case .refresh(let count):
case .refresh(let count, let rotate):
urlSession.expect("https://example.com/.well-known/openid-configuration",
data: try data(from: .module, for: "openid-configuration", in: "MockResponses"),
contentType: "application/json")
for _ in 1 ... count {
for index in 1 ... count {
urlSession.expect("https://example.com/oauth2/v1/token",
data: data(for: """
{
"token_type": "Bearer",
"expires_in": \(expiresIn),
"access_token": "\(String.mockAccessToken)",
"scope": "openid profile offline_access",
"refresh_token": "therefreshtoken",
"refresh_token": "therefreshtoken\(rotate ? "-\(index)" : "")",
"id_token": "\(String.mockIdToken)"
}
"""))
Expand Down Expand Up @@ -310,6 +310,39 @@ final class CredentialRefreshTests: XCTestCase, OAuth2ClientDelegate {
XCTAssertEqual(request.value(forHTTPHeaderField: "Authorization"),
"Bearer \(credential.token.accessToken)")
}

func testRotatingRefreshTokens() throws {
let credential = try credential(for: Token.mockToken(expiresIn: 1),
expectAPICalls: .refresh(count: 3, rotate: true),
expiresIn: 1)

// Initial refresh token
XCTAssertEqual(credential.token.refreshToken, "abc123")

// First refresh
var refreshExpectation = expectation(description: "First refresh")
credential.refresh { _ in
refreshExpectation.fulfill()
}
wait(for: [refreshExpectation], timeout: .standard)
XCTAssertEqual(credential.token.refreshToken, "therefreshtoken-1")

// Second refresh
refreshExpectation = expectation(description: "Second refresh")
credential.refresh { _ in
refreshExpectation.fulfill()
}
wait(for: [refreshExpectation], timeout: .standard)
XCTAssertEqual(credential.token.refreshToken, "therefreshtoken-2")

// Third refresh
refreshExpectation = expectation(description: "Third refresh")
credential.refresh { _ in
refreshExpectation.fulfill()
}
wait(for: [refreshExpectation], timeout: .standard)
XCTAssertEqual(credential.token.refreshToken, "therefreshtoken-3")
}

#if swift(>=5.5.1)
@available(iOS 13.0, tvOS 13.0, macOS 10.15, watchOS 6, *)
Expand Down
Loading