Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,25 @@
//
//===----------------------------------------------------------------------===//

import XCTest
import Foundation
import Testing
@testable import WebAuthn

final class AuthenticatorAttestationGloballyUniqueIDTests: XCTestCase {
func testByteCoding() throws {
struct AuthenticatorAttestationGloballyUniqueIDTests {
@Test
func byteCoding() {
let aaguid = AuthenticatorAttestationGloballyUniqueID(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
XCTAssertNotNil(aaguid)
XCTAssertEqual(aaguid?.bytes, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f])
XCTAssertEqual(aaguid?.id, UUID(uuid: (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f)))
XCTAssertEqual(aaguid, AuthenticatorAttestationGloballyUniqueID(uuid: UUID(uuid: (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f))))
XCTAssertEqual(aaguid, AuthenticatorAttestationGloballyUniqueID(uuidString: "00010203-0405-0607-0809-0A0B0C0D0E0F" ))
#expect(aaguid != nil)
#expect(aaguid?.bytes == [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f])
#expect(aaguid?.id == UUID(uuid: (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f)))
#expect(aaguid == AuthenticatorAttestationGloballyUniqueID(uuid: UUID(uuid: (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f))))
#expect(aaguid == AuthenticatorAttestationGloballyUniqueID(uuidString: "00010203-0405-0607-0809-0A0B0C0D0E0F" ))
}

func testInvalidByteDecoding() throws {
XCTAssertNil(AuthenticatorAttestationGloballyUniqueID(bytes: []))
XCTAssertNil(AuthenticatorAttestationGloballyUniqueID(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]))
XCTAssertNil(AuthenticatorAttestationGloballyUniqueID(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]))
@Test
func invalidByteDecoding() {
#expect(AuthenticatorAttestationGloballyUniqueID(bytes: []) == nil)
#expect(AuthenticatorAttestationGloballyUniqueID(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) == nil)
#expect(AuthenticatorAttestationGloballyUniqueID(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) == nil)
}
}
15 changes: 8 additions & 7 deletions Tests/WebAuthnTests/DurationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
//
//===----------------------------------------------------------------------===//

import XCTest
import Testing
@testable import WebAuthn

final class DurationTests: XCTestCase {
func testMilliseconds() throws {
XCTAssertEqual(Duration.milliseconds(1234).milliseconds, 1234)
XCTAssertEqual(Duration.milliseconds(-1234).milliseconds, -1234)
XCTAssertEqual(Duration.microseconds(12345).milliseconds, 12)
XCTAssertEqual(Duration.microseconds(-12345).milliseconds, -12)
struct DurationTests {
@Test
func milliseconds() {
#expect(Duration.milliseconds(1234).milliseconds == 1234)
#expect(Duration.milliseconds(-1234).milliseconds == -1234)
#expect(Duration.microseconds(12345).milliseconds == 12)
#expect(Duration.microseconds(-12345).milliseconds == -12)
}
}
18 changes: 10 additions & 8 deletions Tests/WebAuthnTests/HelpersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@
//
//===----------------------------------------------------------------------===//

import XCTest

import Foundation
import Testing
@testable import WebAuthn

final class HelpersTests: XCTestCase {
func testBase64URLEncodeReturnsCorrectString() {
struct HelpersTests {
@Test
func base64URLEncodeReturnsCorrectString() {
let input: [UInt8] = [1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0]
let expectedBase64 = "AQABAAEBAAEAAQEAAAABAA=="
let expectedBase64URL = "AQABAAEBAAEAAQEAAAABAA"

let base64Encoded = input.base64EncodedString()
let base64URLEncoded = input.base64URLEncodedString()

XCTAssertEqual(expectedBase64, base64Encoded.asString())
XCTAssertEqual(expectedBase64URL, base64URLEncoded.asString())
#expect(expectedBase64 == base64Encoded.asString())
#expect(expectedBase64URL == base64URLEncoded.asString())
}

func testEncodeBase64Codable() throws {
@Test
func encodeBase64Codable() throws {
let base64 = EncodedBase64("AQABAAEBAAEAAQEAAAABAA==")
let json = try JSONEncoder().encode(base64)
let decodedBase64 = try JSONDecoder().decode(EncodedBase64.self, from: json)
XCTAssertEqual(base64, decodedBase64)
#expect(base64 == decodedBase64)
}
}
16 changes: 7 additions & 9 deletions Tests/WebAuthnTests/Utils/assert+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@
//
//===----------------------------------------------------------------------===//

import XCTest
import Testing
import WebAuthn

func assertThrowsError<T, E: Error>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can probably drop this helper altogether now, can't we?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this helper is beneficial. Why would we want to drop it?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Doesn't swift Testing have a new #expect(throws: ...) { ... } that would replace this helper?

Copy link
Member

Choose a reason for hiding this comment

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

It does yes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But doesn’t this work the same as XCTAssertThrowsError?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great, I’ll work on that

Copy link
Collaborator

Choose a reason for hiding this comment

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

But doesn’t this work the same as XCTAssertThrowsError?

I assume these were there because XCTAssert didn't handle async code very well, so this abstracted over that with a single signature

_ expression: @autoclosure () async throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line,
sourceLocation: SourceLocation = #_sourceLocation,
_ errorHandler: (_ error: E) -> Void = { _ in }
) async {
do {
_ = try await expression()
XCTFail(message(), file: file, line: line)
Issue.record("\(message())", sourceLocation: sourceLocation)
} catch {
guard let error = error as? E else {
XCTFail("""
Issue.record("""
Error was thrown, but didn't match expected type '\(E.self)'.
Got error of type '\(type(of: error))'.
Error: \(error)
Expand All @@ -40,11 +39,10 @@ func assertThrowsError<T, E: Error>(
func assertThrowsError<T, E: Error & Equatable>(
_ expression: @autoclosure () async throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line,
sourceLocation: SourceLocation = #_sourceLocation,
expect: E
) async {
try await assertThrowsError(await expression(), message(), file: file, line: line) { error in
XCTAssertEqual(error, expect, message(), file: file, line: line)
try await assertThrowsError(await expression(), sourceLocation: sourceLocation) { error in
#expect(error == expect, Comment("\(message())"), sourceLocation: sourceLocation)
}
}
16 changes: 7 additions & 9 deletions Tests/WebAuthnTests/Utils/assert+expect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@
//
//===----------------------------------------------------------------------===//

import XCTest
import Testing
import WebAuthn

func assertThrowsError<T, E: Error>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here

_ expression: @autoclosure () throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line,
sourceLocation: SourceLocation = #_sourceLocation,
_ errorHandler: (_ error: E) -> Void = { _ in }
) {
do {
_ = try expression()
XCTFail(message(), file: file, line: line)
Issue.record("\(message())", sourceLocation: sourceLocation)
} catch {
guard let error = error as? E else {
XCTFail("""
Issue.record("""
Error was thrown, but didn't match expected type '\(E.self)'.
Got error of type '\(type(of: error))'.
Error: \(error)
Expand All @@ -40,11 +39,10 @@ func assertThrowsError<T, E: Error>(
func assertThrowsError<T, E: Error & Equatable>(
_ expression: @autoclosure () throws -> T,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line,
sourceLocation: SourceLocation = #_sourceLocation,
expect: E
) {
try assertThrowsError(expression(), message(), file: file, line: line) { error in
XCTAssertEqual(error, expect, message(), file: file, line: line)
try assertThrowsError(expression(), message(), sourceLocation: sourceLocation) { error in
#expect(error == expect, Comment("\(message())"), sourceLocation: sourceLocation)
}
}
50 changes: 30 additions & 20 deletions Tests/WebAuthnTests/WebAuthnManagerAuthenticationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@
//===----------------------------------------------------------------------===//

@testable import WebAuthn
import XCTest
import Testing
import Foundation
import SwiftCBOR
import Crypto

final class WebAuthnManagerAuthenticationTests: XCTestCase {
struct WebAuthnManagerAuthenticationTests {
var webAuthnManager: WebAuthnManager!

let challenge: [UInt8] = [1, 0, 1]
let relyingPartyID = "example.com"
let relyingPartyName = "Testy test"
let relyingPartyOrigin = "https://example.com"

override func setUp() {
init() {
let configuration = WebAuthnManager.Configuration(
relyingPartyID: relyingPartyID,
relyingPartyName: relyingPartyName,
Expand All @@ -33,35 +34,39 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
webAuthnManager = .init(configuration: configuration, challengeGenerator: .mock(generate: challenge))
}

func testBeginAuthentication() async throws {
@Test
func beginAuthentication() async throws {
let allowCredentials: [PublicKeyCredentialDescriptor] = [.init(type: .publicKey, id: [1, 0, 2, 30])]
let options = try webAuthnManager.beginAuthentication(
timeout: .seconds(1234),
allowCredentials: allowCredentials,
userVerification: .preferred
)

XCTAssertEqual(options.challenge, challenge)
XCTAssertEqual(options.timeout, .seconds(1234))
XCTAssertEqual(options.relyingPartyID, relyingPartyID)
XCTAssertEqual(options.allowCredentials, allowCredentials)
XCTAssertEqual(options.userVerification, .preferred)
#expect(options.challenge == challenge)
#expect(options.timeout == .seconds(1234))
#expect(options.relyingPartyID == relyingPartyID)
#expect(options.allowCredentials == allowCredentials)
#expect(options.userVerification == .preferred)
}

func testFinishAuthenticationFailsIfCredentialTypeIsInvalid() throws {
@Test
func finishAuthenticationFailsIfCredentialTypeIsInvalid() throws {
try assertThrowsError(
finishAuthentication(type: "invalid"),
expect: WebAuthnError.invalidAssertionCredentialType
)
}

func testFinishAuthenticationFailsIfClientDataJSONDecodingFails() throws {
@Test
func finishAuthenticationFailsIfClientDataJSONDecodingFails() throws {
try assertThrowsError(finishAuthentication(clientDataJSON: [0])) { (_: DecodingError) in
return
}
}

func testFinishAuthenticationFailsIfCeremonyTypeDoesNotMatch() throws {

@Test
func finishAuthenticationFailsIfCeremonyTypeDoesNotMatch() throws {
var clientDataJSON = TestClientDataJSON()
clientDataJSON.type = "webauthn.create"
try assertThrowsError(
Expand All @@ -70,7 +75,8 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
)
}

func testFinishAuthenticationFailsIfRelyingPartyIDHashDoesNotMatch() throws {
@Test
func finishAuthenticationFailsIfRelyingPartyIDHashDoesNotMatch() throws {
try assertThrowsError(
finishAuthentication(
authenticatorData: TestAuthDataBuilder()
Expand All @@ -83,7 +89,8 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
)
}

func testFinishAuthenticationFailsIfUserPresentFlagIsNotSet() throws {
@Test
func finishAuthenticationFailsIfUserPresentFlagIsNotSet() throws {
try assertThrowsError(
finishAuthentication(
authenticatorData: TestAuthDataBuilder()
Expand All @@ -96,7 +103,8 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
)
}

func testFinishAuthenticationFailsIfUserIsNotVerified() throws {
@Test
func finishAuthenticationFailsIfUserIsNotVerified() throws {
try assertThrowsError(
finishAuthentication(
authenticatorData: TestAuthDataBuilder()
Expand All @@ -110,7 +118,8 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
)
}

func testFinishAuthenticationFailsIfCredentialCounterIsNotUpToDate() throws {
@Test
func finishAuthenticationFailsIfCredentialCounterIsNotUpToDate() throws {
try assertThrowsError(
finishAuthentication(
authenticatorData: TestAuthDataBuilder()
Expand All @@ -124,7 +133,8 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
)
}

func testFinishAuthenticationSucceeds() throws {
@Test
func finishAuthenticationSucceeds() throws {
let credentialID = TestConstants.mockCredentialID
let oldSignCount: UInt32 = 0

Expand Down Expand Up @@ -152,8 +162,8 @@ final class WebAuthnManagerAuthenticationTests: XCTestCase {
credentialCurrentSignCount: oldSignCount
)

XCTAssertEqual(verifiedAuthentication.credentialID, credentialID.base64URLEncodedString())
XCTAssertEqual(verifiedAuthentication.newSignCount, oldSignCount + 1)
#expect(verifiedAuthentication.credentialID == credentialID.base64URLEncodedString())
#expect(verifiedAuthentication.newSignCount == oldSignCount + 1)
}

/// Using the default parameters `finishAuthentication` should succeed.
Expand Down
Loading
Loading