Skip to content

Commit

Permalink
add more auth tests
Browse files Browse the repository at this point in the history
  • Loading branch information
grdsdev committed Jan 27, 2025
1 parent 92dbbc2 commit 18c23fb
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 2 deletions.
25 changes: 23 additions & 2 deletions .swiftpm/xcode/xcshareddata/xcschemes/Auth.xcscheme
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1530"
version = "1.7">
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
Expand All @@ -27,8 +27,29 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Auth"
BuildableName = "Auth"
BlueprintName = "Auth"
ReferencedContainer = "container:">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AuthTests"
BuildableName = "AuthTests"
BlueprintName = "AuthTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
135 changes: 135 additions & 0 deletions Tests/AuthTests/AuthClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ final class AuthClientTests: XCTestCase {

XCTAssertEqual(events, [.initialSession, .signedIn])
XCTAssertEqual(sessions, [nil, session])

XCTAssertEqual(sut.currentSession, session)
XCTAssertEqual(sut.currentUser, session.user)
}

func testSignInWithOAuth() async throws {
Expand Down Expand Up @@ -883,6 +886,138 @@ final class AuthClientTests: XCTestCase {
}
#endif

func testSessionWithURL_implicitFlow() async throws {
Mock(
url: clientURL.appendingPathComponent("user"),
statusCode: 200,
data: [
.get: MockData.user
]
)
.snapshotRequest {
#"""
curl \
--header "Authorization: bearer accesstoken" \
--header "X-Client-Info: auth-swift/0.0.0" \
--header "X-Supabase-Api-Version: 2024-01-01" \
--header "apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0" \
"http://localhost:54321/auth/v1/user"
"""#
}
.register()

let sut = makeSUT(flowType: .implicit)

let url = URL(
string:
"https://dummy-url.com/callback#access_token=accesstoken&expires_in=60&refresh_token=refreshtoken&token_type=bearer"
)!
try await sut.session(from: url)
}

func testSessionWithURL_implicitFlow_invalidURL() async throws {
let sut = makeSUT(flowType: .implicit)

let url = URL(
string:
"https://dummy-url.com/callback#invalid_key=accesstoken&expires_in=60&refresh_token=refreshtoken&token_type=bearer"
)!

do {
try await sut.session(from: url)
} catch let AuthError.implicitGrantRedirect(message) {
XCTAssertEqual(message, "Not a valid implicit grant flow URL: \(url)")
}
}

func testSessionWithURL_implicitFlow_error() async throws {
let sut = makeSUT(flowType: .implicit)

let url = URL(
string:
"https://dummy-url.com/callback#error_description=Invalid+code&error=invalid_grant"
)!

do {
try await sut.session(from: url)
} catch let AuthError.implicitGrantRedirect(message) {
XCTAssertEqual(message, "Invalid code")
}
}

func testSessionWithURL_implicitFlow_recoveryType() async throws {
Mock(
url: clientURL.appendingPathComponent("user"),
statusCode: 200,
data: [
.get: MockData.user
]
)
.snapshotRequest {
#"""
curl \
--header "Authorization: bearer accesstoken" \
--header "X-Client-Info: auth-swift/0.0.0" \
--header "X-Supabase-Api-Version: 2024-01-01" \
--header "apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0" \
"http://localhost:54321/auth/v1/user"
"""#
}
.register()

let sut = makeSUT(flowType: .implicit)

let url = URL(
string:
"https://dummy-url.com/callback#access_token=accesstoken&expires_in=60&refresh_token=refreshtoken&token_type=bearer&type=recovery"
)!

let eventsTask = Task {
await sut.authStateChanges.prefix(3).collect().map(\.event)
}

await Task.yield()

try await sut.session(from: url)

let events = await eventsTask.value
XCTAssertEqual(events, [.initialSession, .signedIn, .passwordRecovery])
}

func testSessionWithURL_pkceFlow_error() async throws {
let sut = makeSUT()

let url = URL(
string:
"https://dummy-url.com/callback#error_description=Invalid+code&error=invalid_grant&error_code=500"
)!

do {
try await sut.session(from: url)
} catch let AuthError.pkceGrantCodeExchange(message, error, code) {
XCTAssertEqual(message, "Invalid code")
XCTAssertEqual(error, "invalid_grant")
XCTAssertEqual(code, "500")
}
}

func testSessionWithURL_pkceFlow_error_noErrorDescription() async throws {
let sut = makeSUT()

let url = URL(
string:
"https://dummy-url.com/callback#error=invalid_grant&error_code=500"
)!

do {
try await sut.session(from: url)
} catch let AuthError.pkceGrantCodeExchange(message, error, code) {
XCTAssertEqual(message, "Error in URL with unspecified error_description.")
XCTAssertEqual(error, "invalid_grant")
XCTAssertEqual(code, "500")
}
}

func testSessionFromURLWithMissingComponent() async {
let sut = makeSUT()

Expand Down
45 changes: 45 additions & 0 deletions Tests/AuthTests/PKCETests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Crypto
import XCTest

@testable import Auth

final class PKCETests: XCTestCase {
let sut = PKCE.live

func testGenerateCodeVerifierLength() {
// The code verifier should generate a string of appropriate length
// Base64 encoding of 64 random bytes should result in ~86 characters
let verifier = sut.generateCodeVerifier()
XCTAssertGreaterThanOrEqual(verifier.count, 85)
XCTAssertLessThanOrEqual(verifier.count, 87)
}

func testGenerateCodeVerifierUniqueness() {
// Each generated code verifier should be unique
let verifier1 = sut.generateCodeVerifier()
let verifier2 = sut.generateCodeVerifier()
XCTAssertNotEqual(verifier1, verifier2)
}

func testGenerateCodeChallenge() {
// Test with a known input-output pair
let testVerifier = "test_verifier"
let challenge = sut.generateCodeChallenge(testVerifier)

// Expected value from the current implementation
let expectedChallenge = "0Ku4rR8EgR1w3HyHLBCxVLtPsAAks5HOlpmTEt0XhVA"
XCTAssertEqual(challenge, expectedChallenge)
}

func testPKCEBase64Encoding() {
// Create data that will produce Base64 with special characters
let testData = Data([251, 255, 191]) // This will produce Base64 with padding and special chars
let encoded = testData.pkceBase64EncodedString()

XCTAssertFalse(encoded.contains("+"), "Should not contain '+'")
XCTAssertFalse(encoded.contains("/"), "Should not contain '/'")
XCTAssertFalse(encoded.contains("="), "Should not contain '='")
XCTAssertTrue(encoded.contains("-"), "Should contain '-' as replacement for '+'")
XCTAssertTrue(encoded.contains("_"), "Should contain '_' as replacement for '/'")
}
}

0 comments on commit 18c23fb

Please sign in to comment.