Skip to content

Commit 7b295f1

Browse files
author
Yanko Dimitrov
committed
Added PasscodeLockIncorrectPasscodeNotification
1 parent d984b86 commit 7b295f1

5 files changed

Lines changed: 76 additions & 4 deletions

File tree

PasscodeLock/PasscodeLock/EnterPasscodeState.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,25 @@
88

99
import Foundation
1010

11+
public let PasscodeLockIncorrectPasscodeNotification = "passcode.lock.incorrect.passcode.notification"
12+
1113
struct EnterPasscodeState: PasscodeLockStateType {
1214

1315
let title: String
1416
let description: String
1517
let isCancellableAction = false
1618
var isTouchIDAllowed = true
1719

20+
private var inccorectPasscodeAttempts = 0
21+
private var isNotificationSent = false
22+
1823
init() {
1924

2025
title = localizedStringFor("PasscodeLockEnterTitle", comment: "Enter passcode title")
2126
description = localizedStringFor("PasscodeLockEnterDescription", comment: "Enter passcode description")
2227
}
2328

24-
func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType) {
29+
mutating func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType) {
2530

2631
guard let currentPasscode = lock.repository.passcode else {
2732
assertionFailure("There is no saved passcode")
@@ -34,7 +39,25 @@ struct EnterPasscodeState: PasscodeLockStateType {
3439

3540
} else {
3641

42+
inccorectPasscodeAttempts += 1
43+
44+
if inccorectPasscodeAttempts >= lock.configuration.maximumInccorectPasscodeAttempts {
45+
46+
postNotification()
47+
}
48+
3749
lock.delegate?.passcodeLockDidFail(lock)
3850
}
3951
}
52+
53+
private mutating func postNotification() {
54+
55+
guard !isNotificationSent else { return }
56+
57+
let center = NSNotificationCenter.defaultCenter()
58+
59+
center.postNotificationName(PasscodeLockIncorrectPasscodeNotification, object: nil)
60+
61+
isNotificationSent = true
62+
}
4063
}

PasscodeLock/Protocols/PasscodeLockConfigurationType.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ public protocol PasscodeLockConfigurationType {
1414
var passcodeLength: Int {get}
1515
var isTouchIDAllowed: Bool {get set}
1616
var shouldRequestTouchIDImmediately: Bool {get}
17-
var maximumFailedAttempts: Int {get}
17+
var maximumInccorectPasscodeAttempts: Int {get}
1818
}

PasscodeLock/Protocols/PasscodeLockStateType.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ public protocol PasscodeLockStateType {
1515
var isCancellableAction: Bool {get}
1616
var isTouchIDAllowed: Bool {get}
1717

18-
func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType)
18+
mutating func acceptPasscode(passcode: [String], fromLock lock: PasscodeLockType)
1919
}

PasscodeLockTests/Fakes/FakePasscodeLockConfiguration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class FakePasscodeLockConfiguration: PasscodeLockConfigurationType {
1313
let repository: PasscodeRepositoryType
1414
let passcodeLength = 4
1515
var isTouchIDAllowed = false
16-
let maximumFailedAttempts = 3
16+
let maximumInccorectPasscodeAttempts = 3
1717
let shouldRequestTouchIDImmediately = false
1818

1919
init(repository: PasscodeRepositoryType) {

PasscodeLockTests/PasscodeLock/EnterPasscodeStateTests.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@
88

99
import XCTest
1010

11+
class NotificaionObserver: NSObject {
12+
13+
var called = false
14+
var callCounter = 0
15+
16+
func observe(notification: String) {
17+
18+
let center = NSNotificationCenter.defaultCenter()
19+
20+
center.addObserver(self, selector: "handle:", name: notification, object: nil)
21+
}
22+
23+
func handle(notification: NSNotification) {
24+
25+
called = true
26+
callCounter += 1
27+
}
28+
}
29+
1130
class EnterPasscodeStateTests: XCTestCase {
1231

1332
var passcodeLock: FakePasscodeLock!
@@ -64,4 +83,34 @@ class EnterPasscodeStateTests: XCTestCase {
6483

6584
XCTAssertEqual(delegate.called, true, "Should call the delegate when the passcode is incorrect")
6685
}
86+
87+
func testIncorrectPasscodeNotification() {
88+
89+
let observer = NotificaionObserver()
90+
91+
observer.observe(PasscodeLockIncorrectPasscodeNotification)
92+
93+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
94+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
95+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
96+
97+
XCTAssertEqual(observer.called, true, "Should send a notificaiton when the maximum number of incorrect attempts is reached")
98+
}
99+
100+
func testIncorrectPasscodeSendNotificationOnce() {
101+
102+
let observer = NotificaionObserver()
103+
104+
observer.observe(PasscodeLockIncorrectPasscodeNotification)
105+
106+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
107+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
108+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
109+
110+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
111+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
112+
passcodeState.acceptPasscode(["0"], fromLock: passcodeLock)
113+
114+
XCTAssertEqual(observer.callCounter, 1, "Should send the notification only once")
115+
}
67116
}

0 commit comments

Comments
 (0)