Skip to content

Commit

Permalink
Merge pull request #105 from mattrubin/tests
Browse files Browse the repository at this point in the history
Add tests for validation and parsing failures
  • Loading branch information
mattrubin authored Nov 13, 2016
2 parents f719aea + 61da660 commit 326ed07
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 5 deletions.
6 changes: 5 additions & 1 deletion OneTimePasswordLegacyTests/OTPTokenSerializationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// OTPTokenSerializationTests.m
// OneTimePassword
//
// Copyright (c) 2013-2015 Matt Rubin and the OneTimePassword authors
// Copyright (c) 2013-2016 Matt Rubin and the OneTimePassword authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -374,8 +374,12 @@ - (void)testTokenWithInvalidURLs
@"otpauth://foo", // invalid type
@"otpauth://totp/bar", // missing secret
@"otpauth://totp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&period=0", // invalid period
@"otpauth://totp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&period=x", // non-numeric period
@"otpauth://totp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&algorithm=MD5", // invalid algorithm
@"otpauth://totp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&digits=2", // invalid digits
@"otpauth://totp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&digits=x", // non-numeric digits
@"otpauth://hotp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&counter=1.5", // invalid counter
@"otpauth://hotp/bar?secret=AAAQEAYEAUDAOCAJBIFQYDIOB4&counter=x", // non-numeric counter
];

for (NSString *badURL in badURLs) {
Expand Down
4 changes: 1 addition & 3 deletions Sources/Token+URL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ private func tokenFromURL(url: NSURL, secret externalSecret: NSData? = nil) -> T
if string == kFactorCounterKey {
if let counter: UInt64 = parse(queryDictionary[kQueryCounterKey],
with: {
errno = 0
let counterValue = strtoull(($0 as NSString).UTF8String, nil, 10)
guard errno == 0 else {
guard let counterValue = UInt64($0, radix: 10) else {
return nil
}
return counterValue
Expand Down
70 changes: 69 additions & 1 deletion Tests/GeneratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// GeneratorTests.swift
// OneTimePassword
//
// Copyright (c) 2014-2015 Matt Rubin and the OneTimePassword authors
// Copyright (c) 2014-2016 Matt Rubin and the OneTimePassword authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -148,6 +148,62 @@ class GeneratorTests: XCTestCase {
}
}

func testPasswordAtInvalidTime() {
guard let generator = Generator(
factor: .Timer(period: 30),
secret: NSData(),
algorithm: .SHA1,
digits: 6
) else {
XCTFail("Failed to initialize a Generator.")
return
}

let badTime: NSTimeInterval = -100
do {
_ = try generator.passwordAtTime(badTime)
} catch Generator.Error.InvalidTime {
// This is the expected type of error
return
} catch {
XCTFail("passwordAtTime(\(badTime)) threw an unexpected type of error: \(error))")
return
}
XCTFail("passwordAtTime(\(badTime)) should throw an error)")
}

func testPasswordWithInvalidPeriod() {
let generator = Generator(unvalidatedFactor: .Timer(period: 0))
let time: NSTimeInterval = 100

do {
_ = try generator.passwordAtTime(time)
} catch Generator.Error.InvalidPeriod {
// This is the expected type of error
return
} catch {
XCTFail("passwordAtTime(\(time)) threw an unexpected type of error: \(error))")
return
}
XCTFail("passwordAtTime(\(time)) should throw an error)")
}

func testPasswordWithInvalidDigits() {
let generator = Generator(unvalidatedDigits: 3)
let time: NSTimeInterval = 100

do {
_ = try generator.passwordAtTime(time)
} catch Generator.Error.InvalidDigits {
// This is the expected type of error
return
} catch {
XCTFail("passwordAtTime(\(time)) threw an unexpected type of error: \(error))")
return
}
XCTFail("passwordAtTime(\(time)) should throw an error)")
}

// The values in this test are found in Appendix D of the HOTP RFC
// https://tools.ietf.org/html/rfc4226#appendix-D
func testHOTPRFCValues() {
Expand Down Expand Up @@ -225,3 +281,15 @@ class GeneratorTests: XCTestCase {
}
}
}

private extension Generator {
init(unvalidatedFactor factor: Factor = .Timer(period: 30),
unvalidatedSecret secret: NSData = NSData(),
unvalidatedAlgorithm algorithm: Algorithm = .SHA1,
unvalidatedDigits digits: Int = 8) {
self.factor = factor
self.secret = secret
self.algorithm = algorithm
self.digits = digits
}
}

0 comments on commit 326ed07

Please sign in to comment.